bluetoothcommsprofiles/btpan/bnep/CBnepChannelController.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2004-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 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include <bluetooth/logger.h>
       
    22 #include <comms-infras/eintsock.h>
       
    23 #include "CBnepBridge.h"
       
    24 #include "CBnepChannelController.h"
       
    25 #include "CBnepLink.h"
       
    26 #include "RBnepSetupConnectionRequestControl.h"
       
    27 #include "RBnepSetupConnectionResponseControl.h"
       
    28 #include "bneputils.h"
       
    29 #include "RBnepFilterNetTypeSetRequestControl.h"
       
    30 #include "RBnepFilterNetTypeResponseControl.h"
       
    31 #include "RBnepFilterMultiAddrSetRequestControl.h"
       
    32 #include "RBnepFilterMultiAddrResponseControl.h"
       
    33 
       
    34 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
    35 #include "panmessages.h"
       
    36 
       
    37 using namespace ESock;
       
    38 using namespace Messages;
       
    39 
       
    40 #ifdef ESOCK_EXTLOG_ACTIVE
       
    41 _LIT8(KBnepSubTag, "bnep");
       
    42 #endif
       
    43 
       
    44 #endif
       
    45 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
    46 
       
    47 #ifdef __FLOG_ACTIVE
       
    48 _LIT8(KLogComponent, LOG_COMPONENT_PAN_BNEP);
       
    49 #endif
       
    50 
       
    51 /**
       
    52 Implement cleanup for an RBnepControl object allocated on the heap.
       
    53 */
       
    54 void CleanupControl(TAny* aControl)
       
    55     {
       
    56     LOG_STATIC_FUNC
       
    57     RBnepControl* control = static_cast<RBnepControl*>(aControl);
       
    58     control->Free();
       
    59     delete control;
       
    60     }
       
    61 
       
    62 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
    63 CBnepChannelController::CBnepChannelController (const TNodeId& aNotify, CPacketDriverOwner& aPktDrvOwner)
       
    64     : iPanConnectionNotify(aNotify), iPktDrvOwner(aPktDrvOwner)
       
    65     {
       
    66     NM_LOG_NODE_CREATE(KBnepSubTag, CBnepChannelController);
       
    67     CONNECT_LOGGER
       
    68     LOG_FUNC
       
    69     iPktDrvOwner.Open();
       
    70     }
       
    71 
       
    72 #else
       
    73 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
    74 CBnepChannelController::CBnepChannelController (MPanConnectionNotify& aNotify)
       
    75         :iNotify(aNotify)
       
    76     {
       
    77     LOG_FUNC
       
    78     }
       
    79 #endif
       
    80 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
    81 
       
    82 CBnepChannelController::~CBnepChannelController()
       
    83     {
       
    84     /**
       
    85        Close all objects that we're reponsible for - including the socket.
       
    86        @internalComponent
       
    87     */
       
    88     LOG_FUNC
       
    89     if(iLink)
       
    90         {
       
    91         delete iLink;
       
    92         //  iLink must be reset to zero after deletion to prevent a later panic.
       
    93         iLink = NULL;
       
    94         }
       
    95 
       
    96 
       
    97     iProceedCallBack->Cancel();
       
    98     delete iProceedCallBack;
       
    99 
       
   100 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   101     NM_LOG_NODE_DESTROY(KBnepSubTag, CBnepChannelController);
       
   102     CLOSE_LOGGER
       
   103     iPktDrvOwner.Close();
       
   104 #endif
       
   105     }
       
   106 
       
   107 void CBnepChannelController::BnepRoleRequestFromLocalDevice (TBluetoothPanRole aRequestedLocalRole, TBluetoothPanRole aRequestedRemoteRole)
       
   108     {
       
   109     /**
       
   110        Call from the agent to request that we set a certain role.
       
   111        @internalComponent
       
   112     */
       
   113     LOG_FUNC
       
   114     iLink->SuspendDataTransfer();
       
   115 
       
   116 	TRAPD(err, CreateAndQueueConnectionSetupRequestL(aRequestedLocalRole, aRequestedRemoteRole));
       
   117 	if(!err)
       
   118 		{
       
   119     	iLink->Proceed();
       
   120 		}
       
   121 	else
       
   122 		{
       
   123 		iLink->ResumeDataTransfer();
       
   124 		}
       
   125     }
       
   126 
       
   127 void CBnepChannelController::SetUplinkAccessAllowedForBnepLink(TBool aAllowed)
       
   128 	{
       
   129 	iLink->SetUplinkAccessAllowedForBnepLink(aAllowed);
       
   130 	}
       
   131 	
       
   132 
       
   133 /**
       
   134 Response to a remote request for a given set of roles -- generate control
       
   135 packet and pass it back to the remote device.
       
   136 @internalComponent
       
   137 */
       
   138 void CBnepChannelController::BnepRoleResponseFromLocalDevice (TBnepSetupConnectionResponseMessage aRoleResponseCode)
       
   139     {
       
   140 	// This may fail if it cannot allocate the response.  However,
       
   141 	// we will just continue and do the same as if it had succeeded
       
   142 	// as we won't get another prompt to continue.  The remote may
       
   143 	// resend its ConnectionSetupRequest when we don't respond, or
       
   144 	// may disconnect the link.
       
   145 	TRAP_IGNORE(CreateAndQueueConnectionSetupResponseL(aRoleResponseCode));
       
   146 
       
   147     // All control processing has been suspended while awaiting this event, 
       
   148     // so we can now free things up again.
       
   149     SetAwaitingResponse(EFalse);
       
   150     iLink->ResumeDataTransfer();	// enable the link for data transfer	
       
   151     
       
   152     if(EOperationSuccessful == aRoleResponseCode)
       
   153         {
       
   154         //In case this is the first negotiation, we only want to trigger LinkLayerUp if the 
       
   155 	    //negotiation is successful
       
   156         iLink->RemoteDeviceReady();
       
   157         }
       
   158         
       
   159 	//If iProceedCallBack is already active then BNEP must be processing the next command inside 
       
   160 	//the same frame. We don't have to don't anything here. The callback will complete when all the
       
   161 	//commands are processed.
       
   162     if(!iProceedCallBack->IsActive())
       
   163     	{
       
   164     	__ASSERT_DEBUG(!iProceedCallBack->IsAdded(), BnepUtils::Panic(Bnep::ECallBackAlreadyAdded));
       
   165 		CActiveScheduler::Add(iProceedCallBack);
       
   166 	    iProceedCallBack->CallBack();
       
   167     	}
       
   168     }
       
   169 
       
   170 TInt CBnepChannelController::ProceedCb(TAny* aPtr)
       
   171 	{
       
   172 	static_cast<CBnepChannelController*>(aPtr)->Proceed();
       
   173 	
       
   174 	return KErrNone;
       
   175 	}
       
   176 	
       
   177 void CBnepChannelController::Proceed()
       
   178 	{
       
   179 	iProceedCallBack->Deque();
       
   180     // Carry on processing any outstanding controls and data transfers.
       
   181     iLink->Proceed();
       
   182     }
       
   183 
       
   184 /**
       
   185    Close this channel. This has the effect of deleting the coupled CBnepLink.
       
   186    @internalComponent
       
   187 */
       
   188 void CBnepChannelController::Close ()
       
   189     {
       
   190     LOG_FUNC
       
   191     delete this;
       
   192     }
       
   193 
       
   194 /**
       
   195    Create the channel controller and the link object.
       
   196    Ownership of all these objects is a little strange -- the channel controller
       
   197    owns the underlying link, and the channel controller itself is owned by the
       
   198    agent (in another dll...).  Destruction paths can therefore look a little
       
   199    confusing.
       
   200    @internalComponent
       
   201 */
       
   202 void CBnepChannelController::ConstructL (CBnepBridge& aBridge, RInternalSocket& aConnectedSocket)
       
   203     {
       
   204     LOG_FUNC
       
   205     iLink = CBnepLink::NewL(aBridge, aConnectedSocket, *this);
       
   206     
       
   207     iProceedCallBack = new (ELeave) CAsyncCallBack(KBnepProceedCallBackPriority);
       
   208     TCallBack proceedCb(ProceedCb, this);
       
   209     iProceedCallBack->Set(proceedCb);
       
   210     //Remove the callback from active scheduler whenever it is not used because it is
       
   211     //used only in role request and has a high priority.
       
   212     iProceedCallBack->Deque();
       
   213     }
       
   214 
       
   215 /**
       
   216    Having received a SetupConnectionRequest from a remote device, the controller 
       
   217    must hand off the request to the agent. This may be asynchronous, in which case
       
   218    the method returns immediately, having suspended further control processing 
       
   219    until the agent responds. However, the agent may call back into the controller 
       
   220    synchronously. This has implications for how controls are processed by the link.
       
   221    @internalComponent
       
   222 */
       
   223 void CBnepChannelController::Handle (RBnepSetupConnectionRequestControl* aSetupRequest)
       
   224     {
       
   225     LOG_FUNC
       
   226     __ASSERT_DEBUG(aSetupRequest,BnepUtils::Panic(Bnep::ENullPointer));
       
   227     if(aSetupRequest)
       
   228         {
       
   229         TUUID localRole;
       
   230         TUUID remoteRole;
       
   231         TInt err1 = aSetupRequest->LocalRole(localRole);
       
   232         TInt err2 = aSetupRequest->RemoteRole(remoteRole);
       
   233         // The control object must be freed and deleted now, before the request is 
       
   234         // passed out, to ensure that the controller is re-entrant and doesn't leak memory.
       
   235         aSetupRequest->Free();
       
   236         delete aSetupRequest;
       
   237         if(!err1 && !err2)
       
   238             {
       
   239             // Suspend further link processing for the time being.
       
   240             SetAwaitingResponse(ETrue);
       
   241                         
       
   242 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   243             TPanMessage::TRoleRequestFromRemoteDevice msg(localRole, remoteRole);
       
   244             RClientInterface::OpenPostMessageClose(Id(),iPanConnectionNotify,msg);
       
   245 #else
       
   246             iNotify.BnepRoleRequestFromRemoteDevice(localRole, remoteRole);
       
   247 #endif
       
   248             }
       
   249         else
       
   250             {
       
   251 			// The UUIDSize is not within spec, so we need to tell the remote end.
       
   252 			// This may leave if we fail to allocate the new response.  Unfortunately
       
   253 			// there's not a lot we can do in that circumstance.  Just drop our response
       
   254 			// and wait for the remote to timeout.
       
   255 			TRAP_IGNORE(CreateAndQueueConnectionSetupResponseL(EInvalidServiceUuidSize));
       
   256             }
       
   257         }
       
   258     }
       
   259 
       
   260 /**
       
   261    The remote device has sent a response to our Setup request. If it has 
       
   262    been successful we can resume data transfer operations on the link. 
       
   263    The agent is notified of the response.
       
   264    @param aSetupResponse A control containing the remote end's response to our 
       
   265    request to set up a connection.
       
   266    @internalComponent
       
   267 */
       
   268 void CBnepChannelController::Handle (RBnepSetupConnectionResponseControl* aSetupResponse)
       
   269     {
       
   270     LOG_FUNC
       
   271     __ASSERT_DEBUG(aSetupResponse,BnepUtils::Panic(Bnep::ENullPointer));
       
   272     if(aSetupResponse)
       
   273         {
       
   274         TBnepSetupConnectionResponseMessage responseCode = EOperationSuccessful;
       
   275         TRAPD(err,aSetupResponse->ConnectionSetupResponseL(responseCode));
       
   276 		
       
   277 		if(!err)
       
   278 			{
       
   279 			iLink->ResumeDataTransfer();
       
   280 	        if(EOperationSuccessful == responseCode)
       
   281 	            {
       
   282 	            //In case this is the first negotiation, we only want to trigger LinkLayerUp if the 
       
   283 	            //negotiation is successful
       
   284 	            iLink->RemoteDeviceReady();
       
   285 	            }
       
   286 	        // The control object must be freed and deleted now, before the request is 
       
   287 	        // passed out, to ensure that the controller is re-entrant and doesn't leak memory.            
       
   288 	        aSetupResponse->Free();
       
   289 	        delete aSetupResponse;        
       
   290 	        
       
   291 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   292             TPanMessage::TRoleResponseFromRemoteDevice msg(responseCode);
       
   293             RClientInterface::OpenPostMessageClose(Id(),iPanConnectionNotify,msg);	        
       
   294 #else
       
   295 	        iNotify.BnepRoleResponseFromRemoteDevice(responseCode);
       
   296 #endif
       
   297 			}
       
   298 		else
       
   299 			{
       
   300 			// They sent us bobbins, just drop it.
       
   301 	        aSetupResponse->Free();
       
   302 	        delete aSetupResponse; 
       
   303 			}
       
   304         }
       
   305     }
       
   306 
       
   307 /**
       
   308    Handle an attempt, by a remote device, to set network packet type filters.
       
   309    @param aFilterNetTypeSetRequest A control containing a network packet type 
       
   310    filter set message.
       
   311    @internalComponent
       
   312 */
       
   313 void CBnepChannelController::Handle (RBnepFilterNetTypeSetRequestControl* aFilterNetTypeSetRequest)
       
   314     {
       
   315     LOG_FUNC
       
   316     __ASSERT_DEBUG(aFilterNetTypeSetRequest,BnepUtils::Panic(Bnep::ENullPointer));
       
   317 
       
   318     if(aFilterNetTypeSetRequest)
       
   319         {
       
   320         TFilterNetTypeResponse response;        
       
   321         // Specification requires that we check the validity of the filter request 
       
   322         // before it is implementeted in BNEP.                                     
       
   323         TUint16 typeListSize ;
       
   324         TInt err1 = aFilterNetTypeSetRequest->NetworkProtocolTypeListLength(typeListSize);
       
   325         if(!err1)
       
   326             {
       
   327             LOG1(_L8("NetworkProtocolTypeListLength = %d"),typeListSize); 
       
   328             if((2*KMaxNetTypeFilters*KSizeOfNetType) < typeListSize)
       
   329                 {
       
   330                 response = EFilterNetTypeTooManyFilters;
       
   331                 }
       
   332             else
       
   333                 {
       
   334                 CNetTypeFilterTable* netTypeFilterTable = new CNetTypeFilterTable;
       
   335 
       
   336                 if(netTypeFilterTable)
       
   337                     {
       
   338                     TUint index = 0;
       
   339                     do
       
   340                         {
       
   341                         TUint16 startValue;
       
   342                         TUint16 endValue;
       
   343                         err1 = aFilterNetTypeSetRequest->NetworkProtocolTypeRange(startValue, endValue, index);
       
   344                         index++;
       
   345                         LOG2(_L8("Net type filter request: startValue: %d , endValue: %d"),startValue, endValue);
       
   346                         if( KErrGeneral == err1 )
       
   347                             {
       
   348                             // This one is because the advertised length doesn't match what's 
       
   349                             // actually in the packet.
       
   350                             response = EFilterNetTypeUnsupportedRequest;
       
   351                             break;
       
   352                             }
       
   353                         if( KErrArgument == err1 )
       
   354                             {
       
   355                             // This one means they've somehow got their start and end 
       
   356                             // addresses in the wrong order.
       
   357                             response = EFilterNetTypeInvalidNetworkingProtocolTypeRange;
       
   358                             break;
       
   359                             }
       
   360                         if(KErrNotFound != err1)
       
   361                             {
       
   362                             TInt err2 = netTypeFilterTable->Insert(startValue, endValue);
       
   363                             if( KErrArgument == err2 )
       
   364                                 {
       
   365                                 // This one means they've somehow got their start and end 
       
   366                                 // addresses in the wrong order, and we didn't catch it earlier.
       
   367                                 response = EFilterNetTypeInvalidNetworkingProtocolTypeRange;
       
   368                                 break;
       
   369                                 }  
       
   370                             if( KErrTooBig == err2 )
       
   371                                 {
       
   372                                 // This one means that they've asked for more filters than 
       
   373                                 // we currently support.
       
   374                                 response = EFilterNetTypeTooManyFilters;
       
   375                                 break;
       
   376                                 }  
       
   377                             response = EFilterNetTypeOperationSuccessful;  
       
   378                             }
       
   379                         else
       
   380                             {
       
   381                             netTypeFilterTable->Reset(); // This is going to be an empty table
       
   382                             response = EFilterNetTypeOperationSuccessful; // This is supported
       
   383                             err1 = KErrEof; // Nothing more to be done
       
   384                             }
       
   385                         }while( KErrEof != err1 );
       
   386                     if(EFilterNetTypeOperationSuccessful == response)
       
   387                         {
       
   388                         // We can now adopt the new filter table.
       
   389                         // The link will own it and be responsible for it's deletion.
       
   390                         iLink->Install(netTypeFilterTable);
       
   391                         }
       
   392                     else
       
   393                         {
       
   394                         // That request failed for some reason, so drop the new table.
       
   395                         delete netTypeFilterTable;
       
   396                         }
       
   397                     }
       
   398                 else
       
   399                     {
       
   400                     // If we get here, then we have failed to construct a CNetTypeFilterTable. 
       
   401                     // There is nothing in the protocol that allows us to pass back a generic 
       
   402                     // "Request Unsuccessful" message, so the nearest we could come up with was 
       
   403                     // "Too Many Filters", which is a bit more truthful that "Unsupported Request".
       
   404                     response = EFilterNetTypeTooManyFilters;
       
   405                     }
       
   406                 }
       
   407             }
       
   408         else
       
   409             {
       
   410             response = EFilterNetTypeUnsupportedRequest;
       
   411             }
       
   412         // The control object must be freed and deleted now, before the response is 
       
   413         // generated, to ensure that the controller is re-entrant and doesn't leak memory.
       
   414         aFilterNetTypeSetRequest->Free();
       
   415         delete aFilterNetTypeSetRequest;
       
   416 
       
   417 		// This may leave if we fail to allocate the new response.  Unfortunately
       
   418 		// there's not a lot we can do in that circumstance.  Just drop our response
       
   419 		// and wait for the remote to timeout.
       
   420 		TRAP_IGNORE(CreateAndQueueFilterNetTypeResponseL(response));
       
   421         }
       
   422     }
       
   423 
       
   424 /**
       
   425    This overloaded method is a placeholder for the code that will handle 
       
   426    responses from the remote end after BNEP hass emitted a Filter Net Type 
       
   427    Request.This version of BNEP does not emit these requests.
       
   428    @internalComponent
       
   429 */
       
   430 void CBnepChannelController::Handle (RBnepFilterNetTypeResponseControl* aFilterNetTypeResponse)
       
   431     {
       
   432     LOG_FUNC
       
   433     __ASSERT_DEBUG(aFilterNetTypeResponse,BnepUtils::Panic(Bnep::ENullPointer));
       
   434     // We don't do anything with this yet
       
   435     if(aFilterNetTypeResponse)
       
   436         {
       
   437         aFilterNetTypeResponse->Free();
       
   438         delete aFilterNetTypeResponse;
       
   439         }
       
   440     }
       
   441 
       
   442 /**
       
   443    Handle an attempt by a remote device to set multicast adddress filters
       
   444    @internalComponent
       
   445 */
       
   446 void CBnepChannelController::Handle (RBnepFilterMultiAddrSetRequestControl* aFilterMultiAddrSetRequest)
       
   447     {
       
   448     LOG_FUNC
       
   449     __ASSERT_DEBUG(aFilterMultiAddrSetRequest,BnepUtils::Panic(Bnep::ENullPointer));
       
   450 
       
   451     if(aFilterMultiAddrSetRequest)  
       
   452         {
       
   453         TInt err1;
       
   454         TBnepBTDevAddr startAddr;
       
   455         TBnepBTDevAddr endAddr;
       
   456         TFilterMultiAddrResponse response;
       
   457         // Specification requires that we check the validity of the filter request 
       
   458         // before it is implementeted in BNEP.                                     
       
   459         TUint16 typeListSize = aFilterMultiAddrSetRequest->MulticastAddressListLength();
       
   460         LOG1(_L8("MulticastAddressListLength = %d"),typeListSize); 
       
   461         if((2*KMaxMultiAddrFilters*KSizeOfMultiAddr) < typeListSize)
       
   462             {
       
   463             LOG(_L8("Too many filters"));
       
   464             response = EFilterMultiAddrTooManyFilters;
       
   465             }
       
   466         else
       
   467             {
       
   468             CMultiAddrFilterTable* multiAddrFilterTable = new CMultiAddrFilterTable;
       
   469 
       
   470             if(multiAddrFilterTable)
       
   471                 {
       
   472                 TUint index = 0;
       
   473                 do
       
   474                     {
       
   475                     err1 = aFilterMultiAddrSetRequest->MultiAddrRange(startAddr, endAddr, index);
       
   476                     if(KErrArgument == err1)
       
   477                         {
       
   478                         response = EFilterMultiAddrUnsupportedRequest;
       
   479                         break; // Stop processing this request
       
   480                         }
       
   481                     if(KErrNotFound != err1)
       
   482                         {
       
   483                         TInt err2 = multiAddrFilterTable->Insert(startAddr, endAddr);
       
   484                         if( KErrArgument == err2 )
       
   485                             {
       
   486                             response = EFilterMultiAddrUnsupportedRequest;
       
   487                             break; // Stop processing this request
       
   488                             }  
       
   489                         if( KErrTooBig == err2 )
       
   490                             {
       
   491                             response = EFilterMultiAddrTooManyFilters;
       
   492                             break; // Stop processing this request
       
   493                             }  
       
   494                         response = EFilterMultiAddrOperationSuccessful; // Must be good if we got here.
       
   495                         ++index;
       
   496                         }
       
   497                     else
       
   498                         {
       
   499                         multiAddrFilterTable->Reset(); // This is going to be an empty table
       
   500                         response = EFilterMultiAddrOperationSuccessful; // This is supported
       
   501                         err1 = KErrEof; // Nothing more to be done
       
   502                         }
       
   503                     } while( KErrEof != err1 );
       
   504                 if(EFilterMultiAddrOperationSuccessful == response)
       
   505                     {
       
   506                     // We can adopt the new filter table.
       
   507                     // The link will own it and be responsible for it's deletion.
       
   508                     iLink->Install(multiAddrFilterTable);
       
   509                     }
       
   510                 else
       
   511                     {
       
   512                     // That request failed for some reason, so drop the new table unused.
       
   513                     delete multiAddrFilterTable;
       
   514                     }
       
   515                 }
       
   516             else
       
   517                 {
       
   518                 // If we get here, then we have failed to construct a CMultiAddrFilterTable. 
       
   519                 // There is nothing in the protocol that allows us to pass back a generic 
       
   520                 //  "Request Unsuccessful" message, so the nearest we could come up with was 
       
   521                 //  "Too Many Filters", which is a bit more truthful that "Unsupported Request".
       
   522                 response = EFilterMultiAddrTooManyFilters;
       
   523                 }
       
   524             }
       
   525         // The control object must be freed and deleted now, before the request is 
       
   526         // honoured, to ensure that the controller is re-entrant and doesn't leak memory.
       
   527         aFilterMultiAddrSetRequest->Free();
       
   528         delete aFilterMultiAddrSetRequest;    
       
   529 
       
   530 		// This may leave if we fail to allocate the new response.  Unfortunately
       
   531 		// there's not a lot we can do in that circumstance.  Just drop our response
       
   532 		// and wait for the remote to timeout.
       
   533 		TRAP_IGNORE(CreateAndQueueFilterMultiAddrResponseL(response));
       
   534         }
       
   535     }
       
   536 
       
   537 /**
       
   538    This overloaded method is a placeholder for the code that will handle 
       
   539    responses from the remote end after BNEP hass emitted a Multicast Address Filter 
       
   540    Request.This version of BNEP does not emit these requests.
       
   541    @internalComponent
       
   542 */
       
   543 void CBnepChannelController::Handle (RBnepFilterMultiAddrResponseControl* aFilterMultiAddrResponse)
       
   544     {
       
   545     LOG_FUNC
       
   546     __ASSERT_DEBUG(aFilterMultiAddrResponse,BnepUtils::Panic(Bnep::ENullPointer));
       
   547     // We don't do anything with this yet.
       
   548     if(aFilterMultiAddrResponse)
       
   549         {
       
   550         aFilterMultiAddrResponse->Free();
       
   551         delete aFilterMultiAddrResponse;
       
   552         }
       
   553     }
       
   554 
       
   555 /**
       
   556    Handle a control that we don't understand.
       
   557    @internalComponent
       
   558 */
       
   559 void CBnepChannelController::HandleUnknownCommandPacket (RBnepControl* aControl)
       
   560     {
       
   561     LOG_FUNC
       
   562     __ASSERT_DEBUG(aControl,BnepUtils::Panic(Bnep::ENullPointer));
       
   563 
       
   564     if(aControl)
       
   565         {
       
   566         TUint8 controlType = static_cast<TUint8>(aControl->ControlType());
       
   567         // The control object must be freed and deleted now, before the response is 
       
   568         // generated, to ensure that the controller is re-entrant and doesn't leak memory.      
       
   569         aControl->Free();
       
   570         delete aControl;
       
   571 		
       
   572 		// This may leave if we fail to allocate the new response.  Unfortunately
       
   573 		// there's not a lot we can do in that circumstance.  Just drop our response
       
   574 		// and wait for the remote to timeout.
       
   575 		TRAP_IGNORE(CreateAndQueueNotUnderstoodResponseL(controlType));
       
   576 		}
       
   577     }
       
   578 
       
   579 void CBnepChannelController::CreateAndQueueConnectionSetupRequestL(TBluetoothPanRole aRequestedLocalRole, TBluetoothPanRole aRequestedRemoteRole)
       
   580 	{
       
   581 	LOG_FUNC
       
   582 
       
   583     RBnepSetupConnectionRequestControl* controlSetup = new(ELeave)RBnepSetupConnectionRequestControl();
       
   584 	CleanupStack::PushL(TCleanupItem(CleanupControl, controlSetup));
       
   585 
       
   586     controlSetup->InitL();
       
   587 
       
   588     TUUID localRole(aRequestedLocalRole);
       
   589     TUUID remoteRole(aRequestedRemoteRole);
       
   590 	controlSetup->SetRolesL(localRole, remoteRole);
       
   591 
       
   592 	CleanupStack::Pop(controlSetup);
       
   593     iLink->QueueOnOutput(controlSetup);
       
   594 	}
       
   595 
       
   596 void CBnepChannelController::CreateAndQueueConnectionSetupResponseL(TBnepSetupConnectionResponseMessage aRoleResponseCode)
       
   597 	{
       
   598 	LOG_FUNC
       
   599 
       
   600 	RBnepSetupConnectionResponseControl* responseControl = new(ELeave)RBnepSetupConnectionResponseControl();
       
   601 	CleanupStack::PushL(TCleanupItem(CleanupControl, responseControl));
       
   602 
       
   603 	responseControl->InitL();
       
   604 	responseControl->SetConnectionSetupResponseL(aRoleResponseCode);
       
   605 
       
   606 	CleanupStack::Pop(responseControl);
       
   607 	iLink->QueueOnOutput(responseControl);
       
   608 	}
       
   609 
       
   610 void CBnepChannelController::CreateAndQueueNotUnderstoodResponseL(TUint8 aControlType)
       
   611 	{	
       
   612 	LOG_FUNC
       
   613 
       
   614     RBnepNotUnderstoodResponseControl* responseControl = new(ELeave)RBnepNotUnderstoodResponseControl();
       
   615 	CleanupStack::PushL(TCleanupItem(CleanupControl, responseControl));
       
   616 
       
   617 	responseControl->InitL();
       
   618 	responseControl->SetUnknownControlType(aControlType);
       
   619 
       
   620 	CleanupStack::Pop(responseControl);
       
   621 	iLink->QueueOnOutput(responseControl);
       
   622 	}
       
   623 
       
   624 void CBnepChannelController::CreateAndQueueFilterNetTypeResponseL(TFilterNetTypeResponse aResponse)
       
   625 	{	
       
   626 	LOG_FUNC
       
   627 
       
   628 	RBnepFilterNetTypeResponseControl* responseControl = new(ELeave)RBnepFilterNetTypeResponseControl();
       
   629 	CleanupStack::PushL(TCleanupItem(CleanupControl, responseControl));
       
   630 
       
   631 	responseControl->InitL();
       
   632 	responseControl->SetNetTypeResponseL(aResponse);
       
   633 
       
   634 	CleanupStack::Pop(responseControl);
       
   635 	iLink->QueueOnOutput(responseControl);
       
   636 	}
       
   637 
       
   638 void CBnepChannelController::CreateAndQueueFilterMultiAddrResponseL(TFilterMultiAddrResponse aResponse)
       
   639 	{	
       
   640 	LOG_FUNC
       
   641 
       
   642 	RBnepFilterMultiAddrResponseControl* responseControl = new(ELeave)RBnepFilterMultiAddrResponseControl();
       
   643 	CleanupStack::PushL(TCleanupItem(CleanupControl, responseControl));
       
   644 
       
   645 	responseControl->InitL();
       
   646 	responseControl->SetMultiAddrResponseL(aResponse);
       
   647 
       
   648 	CleanupStack::Pop(responseControl);
       
   649 	iLink->QueueOnOutput(responseControl);
       
   650 	}
       
   651 
       
   652 /**
       
   653    Create a command parser/channel controller for a specific BNEP link.
       
   654    The controller is owned by the agent objects.
       
   655    @param aBridge The packet router
       
   656    @param aConnectedSocket The socket to run the link over (already connected to the remote device)
       
   657    @internalComponent
       
   658 */
       
   659 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   660 CBnepChannelController* CBnepChannelController::NewL (CBnepBridge& aBridge, RInternalSocket& aConnectedSocket, const TNodeId& aNotify, CPacketDriverOwner& aPktDrvOwner)
       
   661     {
       
   662     LOG_STATIC_FUNC
       
   663     CBnepChannelController* self = new(ELeave) CBnepChannelController(aNotify, aPktDrvOwner);
       
   664     CleanupStack::PushL(self);
       
   665     self->ConstructL(aBridge, aConnectedSocket);
       
   666     CleanupStack::Pop(self);
       
   667     return(self);
       
   668     }
       
   669 
       
   670 #else
       
   671 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   672 CBnepChannelController* CBnepChannelController::NewL (CBnepBridge& aBridge, RInternalSocket& aConnectedSocket, MPanConnectionNotify& aNotify)
       
   673     {
       
   674     LOG_FUNC
       
   675     CBnepChannelController* self = new(ELeave) CBnepChannelController(aNotify);
       
   676     CleanupStack::PushL(self);
       
   677     self->ConstructL(aBridge, aConnectedSocket);
       
   678     CleanupStack::Pop(self);
       
   679     return(self);
       
   680     }
       
   681 #endif
       
   682 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   683 
       
   684 /**
       
   685    Process incoming BNEP control commands.
       
   686    This upcall is called repeatedly by the packet parsing code if multiple
       
   687    commands are present in the packet.
       
   688    @internalComponent
       
   689 */
       
   690 void CBnepChannelController::Execute (RBnepControl* aControl)
       
   691     {
       
   692     LOG_FUNC
       
   693     __ASSERT_DEBUG(aControl,BnepUtils::Panic(Bnep::ENullPointer));
       
   694 
       
   695     if(aControl)
       
   696         {
       
   697         switch (aControl->ControlType())
       
   698             {                                                                                                  
       
   699             case EBnepSetupConnectionRequestMessage:  
       
   700                 LOG1(_L8("CBnepChannelController[%x]: EBnepSetupConnectionRequestMessage"), this);         	
       
   701                 Handle(static_cast<RBnepSetupConnectionRequestControl*>(aControl));
       
   702                 break;
       
   703 
       
   704             case EBnepSetupConnectionResponseMessage:
       
   705                 LOG1(_L8("CBnepChannelController[%x]: EBnepSetupConnectionResponseMessage"), this);
       
   706                 Handle(static_cast<RBnepSetupConnectionResponseControl*>(aControl));
       
   707                 break;
       
   708 
       
   709             case EBnepFilterNetTypeSetMsg:
       
   710                 LOG1(_L8("CBnepChannelController[%x]: EBnepFilterNetTypeSetMsg"), this);
       
   711                 Handle(static_cast<RBnepFilterNetTypeSetRequestControl*>(aControl));
       
   712                 break;
       
   713 
       
   714             case EBnepFilterNetTypeResponse:
       
   715                 LOG1(_L8("CBnepChannelController[%x]: EBnepFilterNetTypeResponse"), this);
       
   716                 Handle(static_cast<RBnepFilterNetTypeResponseControl*>(aControl));
       
   717                 break;
       
   718 
       
   719             case EBnepFilterMultiAddrSetMsg:
       
   720                 LOG1(_L8("CBnepChannelController[%x]: EBnepFilterMultiAddrSetMsg"), this);
       
   721                 Handle(static_cast<RBnepFilterMultiAddrSetRequestControl*>(aControl));
       
   722                 break;
       
   723 
       
   724             case EBnepFilterMultiAddrResponseMsg:
       
   725                 LOG1(_L8("CBnepChannelController[%x]: EBnepFilterMultiAddrResponseMsg"), this);
       
   726                 Handle(static_cast<RBnepFilterMultiAddrResponseControl*>(aControl));
       
   727                 break;
       
   728 
       
   729             case EBnepControlCommandNotUnderstood:
       
   730                 LOG1(_L8("CBnepChannelController[%x]: EBnepControlCommandNotUnderstood"), this);
       
   731                 aControl->Free();
       
   732                 delete aControl;
       
   733                 break;
       
   734 
       
   735             default:
       
   736                 LOG1(_L8("CBnepChannelController[%x]: default"), this);
       
   737                 HandleUnknownCommandPacket(aControl);
       
   738             }
       
   739         }
       
   740     }
       
   741 
       
   742 /**
       
   743    Remote device has terminated the connection. 
       
   744    We have to dismantle the link and notify the agent.
       
   745    @internalComponent
       
   746 */
       
   747 void CBnepChannelController::RemoteDeviceDisconnect (TInt aError)
       
   748     {
       
   749     LOG_FUNC
       
   750 
       
   751 	// This call can result in the CBnepChannelController being deleted.
       
   752 	// No code should be placed after this call.
       
   753 
       
   754 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   755     TPanMessage::TRemoteDeviceDisconnect msg(aError);
       
   756     RClientInterface::OpenPostMessageClose(Id(),iPanConnectionNotify,msg);	        
       
   757 #else
       
   758     iNotify.RemoteDeviceDisconnect(aError);
       
   759 #endif
       
   760     }
       
   761 
       
   762 
       
   763 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   764 
       
   765 void CBnepChannelController::ReceivedL(const Messages::TRuntimeCtxId& /* aSender */, const Messages::TNodeId& /* aRecipient */, Messages::TSignatureBase& aCFMessage)
       
   766     {
       
   767     // IMPORTANT NOTE:
       
   768     // We register/deregister the pan messages for this thread with the
       
   769     // Comms Transport in CBnepBridge and therefore the lifetime of the
       
   770     // registration is the same as CBnepBridge. Instances of
       
   771     // CBnepChannelController can live past the deletion ofthe CBnepBridge.
       
   772     // After CBnepBridge has gone no custom message signatures can be
       
   773     // received, but this is ok since the only message we expect to receive
       
   774     // is TCloseChannelController which uses the SigVoid signature from
       
   775     // ESock. If this expectation changes an additional registration/deregistration
       
   776     // will need to be added to CBnepChannelController's c'tor/d'tor.
       
   777     
       
   778 	if (aCFMessage.MessageId().Realm() == TPanMessage::ERealmId)
       
   779     	{
       
   780         switch (aCFMessage.MessageId().MessageId())
       
   781             {
       
   782             case TPanMessage::TRoleRequestFromLocalDevice::EId:
       
   783                 {
       
   784                 TPanMessage::TRoleRequestFromLocalDevice& msg = message_cast<TPanMessage::TRoleRequestFromLocalDevice>(aCFMessage);
       
   785                 BnepRoleRequestFromLocalDevice(msg.iRequestedLocalRole, msg.iRequestedRemoteRole);
       
   786                 }
       
   787                 break;            
       
   788             
       
   789             case TPanMessage::TRoleResponseFromLocalDevice::EId:
       
   790                 {
       
   791                 TPanMessage::TRoleResponseFromLocalDevice& msg = message_cast<TPanMessage::TRoleResponseFromLocalDevice>(aCFMessage);
       
   792                 BnepRoleResponseFromLocalDevice(msg.iSetupResponse);
       
   793                 }
       
   794                 break;            
       
   795 
       
   796             case TPanMessage::TCloseChannelController::EId:
       
   797                 {
       
   798                 // Don't put anything accessing "this" after the call to Close() - it wont be there
       
   799                 Close();
       
   800                 }
       
   801                 break;            
       
   802 
       
   803             case TPanMessage::TSetUplinkAccessAllowedForBnepLink::EId:
       
   804                 {
       
   805                 TPanMessage::TSetUplinkAccessAllowedForBnepLink& msg = message_cast<TPanMessage::TSetUplinkAccessAllowedForBnepLink>(aCFMessage);
       
   806                 SetUplinkAccessAllowedForBnepLink(msg.iValue);
       
   807                 }
       
   808                 break;            
       
   809 
       
   810             default:
       
   811                 __ASSERT_DEBUG(EFalse, BnepUtils::Panic(Bnep::EUnexpectedMessage));
       
   812             }
       
   813     	}
       
   814     else
       
   815         {
       
   816         __ASSERT_DEBUG(EFalse, BnepUtils::Panic(Bnep::EUnexpectedMessage));
       
   817         }
       
   818     
       
   819     // Absorb messages
       
   820     aCFMessage.ClearMessageId();
       
   821     }
       
   822 #endif
       
   823