bluetooth/btstack/linkmgr/VendorSAP.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "VendorSAP.h"
       
    17 #include "vendorspecific.h"
       
    18 #include "linkmgr.h"
       
    19 #include "hcifacade.h"
       
    20 #include "BTSec.h"
       
    21 
       
    22 
       
    23 //Diagnostic string for security check failures, in builds without platsec
       
    24 //diagnostics this will be NULL.
       
    25 const char* const KVENDOR_SAP_NAME_DIAG = __PLATSEC_DIAGNOSTIC_STRING("Vendor SAP");
       
    26 
       
    27 // only does IOCTLs
       
    28 
       
    29 CVendorSAP* CVendorSAP::NewL(CLinkMgrProtocol& aProtocol)
       
    30 	{
       
    31 	return new(ELeave) CVendorSAP(aProtocol);
       
    32 	}
       
    33 
       
    34 CVendorSAP::CVendorSAP(CLinkMgrProtocol& aProtocol)
       
    35 : iDebugEventQueue(_FOFF(TVendorDebugEvent, iEventLink)),
       
    36   iProtocol(aProtocol)
       
    37 	{
       
    38 	iProtocol.iVendorSpecificSAP = this;
       
    39 	}
       
    40 
       
    41 CVendorSAP::~CVendorSAP()
       
    42 	{
       
    43 	iProtocol.iVendorSpecificSAP = NULL;
       
    44 	
       
    45 	//need to empty the queue.
       
    46 	while (!(iDebugEventQueue.IsEmpty()))
       
    47 		{
       
    48 		TVendorDebugEvent* theEvent = iDebugEventQueue.First();
       
    49 		theEvent->iEventLink.Deque();
       
    50 		delete theEvent;
       
    51 		}
       
    52 	}
       
    53 
       
    54 void CVendorSAP::Ioctl(TUint aLevel,TUint aName,TDes8* aOption)
       
    55 /**
       
    56 **/
       
    57 	{
       
    58 	__ASSERT_DEBUG(iIoctlLevel == 0, Panic(EVendorTwoIoctls));
       
    59 	__ASSERT_DEBUG(iIoctlName == 0, Panic(EVendorTwoIoctls));
       
    60 	
       
    61 	iIoctlLevel = aLevel;
       
    62 	iIoctlName = aName;
       
    63 	
       
    64 	//Do security check on following Ioctls
       
    65 	TInt rerr = KErrNone;
       
    66 	switch(aName)
       
    67 		{
       
    68 		case KHCIWaitForVendorSpecificDebugEventIoctl:
       
    69 		case KHCIWriteVendorSpecificFrameIoctl:
       
    70 		case KHCIWriteVendorSpecificFrameNoEventExpectedIoctl:
       
    71 			{
       
    72 			//The above Ioctl require additional security checking, NetworkControl
       
    73 			//in addition to the LocalServices that was required to create the SAP
       
    74 			__ASSERT_DEBUG(iSecurityChecker, User::Panic(KSECURITY_PANIC, EBTPanicNullSecurityChecker));
       
    75 			rerr = iSecurityChecker->CheckPolicy(KNETWORK_CONTROL, KVENDOR_SAP_NAME_DIAG);
       
    76 			if (rerr != KErrNone)
       
    77 				{
       
    78 				NotifyIoctlComplete(rerr,
       
    79 									KSolBtHCI,
       
    80 									aName,
       
    81 									NULL);
       
    82 				}								
       
    83 			break;
       
    84 			}
       
    85 		default:
       
    86 		//	Other Ioctls require just LocalServices - effectively policed when BT socket is created/transferred
       
    87 		break;	
       
    88 		}
       
    89 	if (rerr != KErrNone)
       
    90 		{
       
    91 		return;				
       
    92 		}
       
    93 	
       
    94 	// have passed security check so continue to handle ioctl		
       
    95 	switch(aName)
       
    96 		{
       
    97 		case KHCIWaitForVendorSpecificDebugEventIoctl:
       
    98 			{
       
    99 
       
   100 			/*
       
   101 			If VendorSpecificWaitForDebugEvent ioctl 
       
   102 			See if we can complete it synchronously
       
   103 			*/
       
   104 			TryToCompleteVendorDebugEventIoctl();	
       
   105 			break;
       
   106 			}
       
   107 		case KHCIWriteVendorSpecificFrameIoctl:
       
   108 			{
       
   109 			if(aOption->Length() != sizeof(THCIWriteVendorSpecificFrameIoctl))
       
   110 				{
       
   111 				NotifyIoctlComplete(KErrBadDescriptor,
       
   112 						KSolBtHCI,
       
   113 						KHCIWriteVendorSpecificFrameIoctl,
       
   114 						NULL);
       
   115 				return;
       
   116 				}
       
   117 			const THCIWriteVendorSpecificFrameIoctl* ioctl =
       
   118 				reinterpret_cast<const THCIWriteVendorSpecificFrameIoctl*>(aOption->Ptr());
       
   119 			
       
   120 			TRAPD(err,iProtocol.HCIFacade().VendorSpecificCommandL(ioctl->iOpcode, ioctl->iParams));
       
   121 			if (err)
       
   122 				{
       
   123 				NotifyIoctlComplete(err,
       
   124 									KSolBtHCI,
       
   125 									KHCIWriteVendorSpecificFrameIoctl,
       
   126 									NULL);
       
   127 				}
       
   128 			// if no error wait for event before completing
       
   129 
       
   130 			break;
       
   131 			}
       
   132 		case KHCIWriteVendorSpecificFrameNoEventExpectedIoctl:
       
   133 			{
       
   134 			if(aOption->Length() != sizeof(THCIWriteVendorSpecificFrameIoctl))
       
   135 				{
       
   136 				NotifyIoctlComplete(KErrBadDescriptor,
       
   137 						KSolBtHCI,
       
   138 						KHCIWriteVendorSpecificFrameNoEventExpectedIoctl,
       
   139 						NULL);
       
   140 				return;
       
   141 				}
       
   142 			const THCIWriteVendorSpecificFrameIoctl* ioctl =
       
   143 				reinterpret_cast<const THCIWriteVendorSpecificFrameIoctl*>(aOption->Ptr());
       
   144 			
       
   145 			TRAPD(err,iProtocol.HCIFacade().VendorSpecificCommandL(ioctl->iOpcode, ioctl->iParams));
       
   146 			// notify completion now though really could wait until delivered from q
       
   147 			NotifyIoctlComplete(err,
       
   148 								KSolBtHCI,
       
   149 								KHCIWriteVendorSpecificFrameNoEventExpectedIoctl,
       
   150 								NULL);
       
   151 			break;
       
   152 			}
       
   153 		default:
       
   154 			NotifyIoctlComplete(
       
   155 				KErrNotSupported,
       
   156 				iIoctlLevel,
       
   157 				iIoctlName,
       
   158 				NULL
       
   159 			);
       
   160 			break;
       
   161 		} // END Switch
       
   162 	}
       
   163 
       
   164 
       
   165 void CVendorSAP::VendorCommandCompleteEvent(TInt aErr, const TDesC8* aEvent)
       
   166 	{
       
   167 	if(iIoctlName == KHCIWriteVendorSpecificFrameIoctl)
       
   168 		{
       
   169 		/*
       
   170 		A client is waiting for this.
       
   171 		*/
       
   172 		NotifyIoctlComplete(aErr, iIoctlLevel, KHCIWriteVendorSpecificFrameIoctl, aEvent);
       
   173 		}
       
   174 	}
       
   175 
       
   176 void CVendorSAP::VendorDebugEvent(TInt aErr, const TDesC8* aEvent)
       
   177 	{
       
   178 	// Some events will not contain an event descriptor.
       
   179 	TPtrC8 eventDesc = aEvent?*aEvent:KNullDesC8; 
       
   180 	
       
   181 	// Holds the data from an *expected* event (expected as in conduit said so!).
       
   182 	TVendorDebugEvent* newEvent = NewDebugEventData(eventDesc, aErr);	
       
   183 	
       
   184 	if(newEvent)
       
   185 		{
       
   186 		iDebugEventQueue.AddLast(*newEvent); // add this event to the end of the list of events already queued
       
   187 		}
       
   188 	else
       
   189 		{
       
   190 		NotifyIoctlComplete(KErrNoMemory,
       
   191 							iIoctlLevel,
       
   192 							iIoctlName,
       
   193 							NULL);
       
   194 		return;
       
   195 		}
       
   196 	TryToCompleteVendorDebugEventIoctl();
       
   197 	}
       
   198 
       
   199 
       
   200 TInt CVendorSAP::SecurityCheck(MProvdSecurityChecker *aSecurityChecker)
       
   201 	{
       
   202 	__ASSERT_ALWAYS(aSecurityChecker, User::Panic(KSECURITY_PANIC, EBTPanicNullSecurityChecker));
       
   203 		
       
   204 	iSecurityChecker = aSecurityChecker;
       
   205 	return iSecurityChecker->CheckPolicy(KLOCAL_SERVICES, KVENDOR_SAP_NAME_DIAG);				
       
   206 	}
       
   207 
       
   208 void CVendorSAP::NotifyIoctlComplete(TInt aErr, TUint aLevel, TUint aName, const TDesC8* aBuffer)
       
   209 	{
       
   210 	if (iIoctlLevel == aLevel && iIoctlName == aName)
       
   211 		{
       
   212 		if (aErr == KErrNone)
       
   213 			{
       
   214 			if(iSocket)
       
   215 				iSocket->IoctlComplete(const_cast<TDesC8*>(aBuffer));
       
   216 			}
       
   217 		else
       
   218 			{
       
   219 			if(iSocket)
       
   220 				iSocket->Error(aErr, MSocketNotify::EErrorIoctl);
       
   221 			}
       
   222 		}
       
   223 	
       
   224 	iIoctlLevel=0;
       
   225 	iIoctlName=0;
       
   226 	}
       
   227 	
       
   228 
       
   229 CVendorSAP::TVendorDebugEvent* CVendorSAP::NewDebugEventData(const TDesC8& aBuf, TInt aError)
       
   230 /**
       
   231 @param aBuf The Vendor event buffer. Must not be NULL
       
   232 **/
       
   233 	{
       
   234 	TVendorDebugEvent* event = new TVendorDebugEvent;
       
   235 	if(!event)
       
   236 		{
       
   237 		return 0;
       
   238 		}
       
   239 	event->iEventBuf.Copy(aBuf.Left(Min(CHctlCommandFrame::KHCIMaxCommandLength, aBuf.Length())));
       
   240 	event->iEventError = aError;
       
   241 	return event;
       
   242 	}
       
   243 
       
   244 void CVendorSAP::TryToCompleteVendorDebugEventIoctl()
       
   245 	{
       
   246 	// check to see if anyone expecting a debug event completion
       
   247 	if (iIoctlName != KHCIWaitForVendorSpecificDebugEventIoctl)
       
   248 		{
       
   249 		return;
       
   250 		}
       
   251 
       
   252 	// nothing to do
       
   253 	if(iDebugEventQueue.IsEmpty())
       
   254 		{
       
   255 		return;
       
   256 		}
       
   257 
       
   258 	TVendorDebugEvent* theEvent = iDebugEventQueue.First();
       
   259 
       
   260 	// belt and braces!
       
   261 	if(theEvent == NULL)
       
   262 		{
       
   263 		return;
       
   264 		}
       
   265 	
       
   266 	// De-queue the event, as it is being consumed
       
   267 	theEvent->iEventLink.Deque();
       
   268 
       
   269 	// Complete the waiting ioctl, passing the the first appropriate
       
   270 	// event in the queue back up.
       
   271 	NotifyIoctlComplete(
       
   272 		theEvent->iEventError,
       
   273 		KSolBtHCI,
       
   274 		KHCIWaitForVendorSpecificDebugEventIoctl,
       
   275 		&(theEvent->iEventBuf)
       
   276 		);
       
   277 
       
   278 	// Event has been consumed, may now be deleted
       
   279 	delete theEvent;
       
   280 		
       
   281 	}
       
   282 
       
   283 
       
   284 void CVendorSAP::Start()
       
   285 	{
       
   286 	// do nothing
       
   287 	}
       
   288 
       
   289 void CVendorSAP::LocalName(TSockAddr& /*aAddr*/) const
       
   290 	{
       
   291 	Panic(EVendorSAPBadCall);
       
   292 	}
       
   293 
       
   294 TInt CVendorSAP::SetLocalName(TSockAddr& /*aAddr*/)
       
   295 	{
       
   296 	Panic(EVendorSAPBadCall);
       
   297 	return KErrNotSupported;
       
   298 	}
       
   299 
       
   300 void CVendorSAP::RemName(TSockAddr& /*aAddr*/) const
       
   301 	{
       
   302 	Panic(EVendorSAPBadCall);
       
   303 	}
       
   304 
       
   305 TInt CVendorSAP::SetRemName(TSockAddr& /*aAddr*/)
       
   306 	{
       
   307 	Panic(EVendorSAPBadCall);
       
   308 	return KErrNotSupported;
       
   309 	}
       
   310 
       
   311 TInt CVendorSAP::GetOption(TUint /*aLevel*/,TUint /*aName*/,TDes8& /*aOption*/) const
       
   312 	{
       
   313 	Panic(EVendorSAPBadCall);
       
   314 	return KErrNotSupported;
       
   315 	}
       
   316 
       
   317 void CVendorSAP::CancelIoctl(TUint __DEBUG_ONLY(aLevel),TUint __DEBUG_ONLY(aName))
       
   318 	{
       
   319 	__ASSERT_DEBUG(iIoctlLevel == aLevel, Panic(EVendorSAPBadIoctlCancel));
       
   320 	__ASSERT_DEBUG(iIoctlName == aName, Panic(EVendorSAPBadIoctlCancel));
       
   321 	
       
   322 	iIoctlName = 0;
       
   323 	iIoctlLevel = 0;
       
   324 	}
       
   325 
       
   326 TInt CVendorSAP::SetOption(TUint /*aLevel*/,TUint /*aName*/,const TDesC8& /*aOption*/)
       
   327 	{
       
   328 	Panic(EVendorSAPBadCall);
       
   329 	return KErrNotSupported;
       
   330 	}
       
   331 
       
   332 void CVendorSAP::ActiveOpen()
       
   333 	{
       
   334 	Panic(EVendorSAPBadCall);
       
   335 	}
       
   336 
       
   337 void CVendorSAP::ActiveOpen(const TDesC8& /*aConnectionData*/)
       
   338 	{
       
   339 	Panic(EVendorSAPBadCall);
       
   340 	}
       
   341 
       
   342 TInt CVendorSAP::PassiveOpen(TUint /*aQueSize*/)
       
   343 	{
       
   344 	Panic(EVendorSAPBadCall);
       
   345 	return KErrNotSupported;
       
   346 	}
       
   347 
       
   348 TInt CVendorSAP::PassiveOpen(TUint /*aQueSize*/,const TDesC8& /*aConnectionData*/)
       
   349 	{
       
   350 	Panic(EVendorSAPBadCall);
       
   351 	return KErrNotSupported;
       
   352 	}
       
   353 
       
   354 void CVendorSAP::AutoBind()
       
   355 	{
       
   356 	Panic(EVendorSAPBadCall);
       
   357 	}
       
   358 
       
   359 TUint CVendorSAP::Write(const TDesC8& /*aDesc*/, TUint /*aOptions*/, TSockAddr* /*aAddr*/)
       
   360 	{
       
   361 	Panic(EVendorSAPBadCall);
       
   362 	return 0;
       
   363 	}
       
   364 
       
   365 void CVendorSAP::GetData(TDes8& /*aDesc*/,TUint /*aOptions*/,TSockAddr* /*aAddr*/)
       
   366 	{
       
   367 	Panic(EVendorSAPBadCall);
       
   368 	}
       
   369 
       
   370 void CVendorSAP::Shutdown(TCloseType aCloseType)
       
   371 	{
       
   372 	if (aCloseType == ENormal)
       
   373 		{
       
   374 		iSocket->CanClose();
       
   375 		}
       
   376 	}
       
   377 
       
   378 void CVendorSAP::Shutdown(TCloseType /*aOption*/,const TDesC8& /*aDisconnectionData*/)
       
   379 	{
       
   380 	Panic(EVendorSAPBadCall);
       
   381 	}
       
   382