bluetoothengine/btsac/src/btsacStateStreaming.cpp
changeset 0 f63038272f30
child 1 6a1fe72036e3
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  In this state, streaming is active.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "btsacStateStreaming.h"
       
    23 #include "btsacStateListening.h"
       
    24 #include "btsacStateSuspended.h"
       
    25 #include "btsacStateConnected.h"
       
    26 #include "btsacStateAborting.h"
       
    27 #include "btsacactive.h"
       
    28 #include "btsacGavdp.h"
       
    29 #include "btsacSEPManager.h"
       
    30 #include "btsacStreamerController.h"
       
    31 #include "debug.h"
       
    32 
       
    33 // A2DP codec-specific element definitions
       
    34 // in bluetoothAV.h
       
    35 using namespace SymbianBluetoothAV;   
       
    36 
       
    37 // Subband codec-specific values
       
    38 // in bluetoothAV.h
       
    39 using namespace SymbianSBC;   
       
    40 
       
    41 
       
    42 // ================= MEMBER FUNCTIONS =======================
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CBtsacStreaming::NewL
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 CBtsacStreaming* CBtsacStreaming::NewL(CBTSAController& aParent, TAudioOpenedBy aAudioOpenedBy, TBool aStartCollision)
       
    49     {
       
    50     CBtsacStreaming* self = new( ELeave ) CBtsacStreaming(aParent, aAudioOpenedBy, aStartCollision);
       
    51     return self;
       
    52     }
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // CBtsacStreaming::CBtsacStreaming
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 CBtsacStreaming::CBtsacStreaming(CBTSAController& aParent, TAudioOpenedBy aAudioOpenedBy, TBool aStartCollision)
       
    59 :   CBtsacState(aParent, EStateStreaming), iSuspending(EFalse), iAudioOpenedBy(aAudioOpenedBy),
       
    60 	iStartCollision(aStartCollision)
       
    61     {
       
    62     }
       
    63   
       
    64 // -----------------------------------------------------------------------------
       
    65 // CBtsacStreaming::~CBtsacStreaming
       
    66 // -----------------------------------------------------------------------------
       
    67 //    
       
    68 CBtsacStreaming::~CBtsacStreaming()
       
    69     {
       
    70     TRACE_FUNC
       
    71     }
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CBtsacStreaming::EnterL
       
    75 // -----------------------------------------------------------------------------
       
    76 //
       
    77 void CBtsacStreaming::EnterL()
       
    78     {
       
    79 	TRACE_STATE(_L("[BTSAC State] Streaming"))
       
    80 	_LIT(KName, "CBtsacStateStreaming");
       
    81 	const TDesC& Name = KName;
       
    82 	Parent().iGavdp->RegisterObserver(this, Name);
       
    83 	if( iAudioOpenedBy == EAudioOpenedByAcc )
       
    84 	 	{
       
    85  		Parent().AccessoryOpenedAudio(Parent().GetRemoteAddr());
       
    86 	 	}
       
    87     }
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CBtsacStreaming::CancelActionL
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 void CBtsacStreaming::CancelActionL(TInt aError, TBTSACGavdpResetReason aGavdpReset)
       
    94 	{
       
    95 	TRACE_FUNC
       
    96 	TInt ret = Parent().iStreamer->StopStream();
       
    97 	if ( ret )
       
    98 		{
       
    99 		TRACE_INFO((_L("CBtsacStreaming::Cancel() iStreamer.StopStream() returned error(%d) !!!"), ret))
       
   100 		}
       
   101 	Parent().CompletePendingRequests(KCompleteAllReqs, aError);
       
   102 	Parent().ChangeStateL(CBtsacListening::NewL(Parent(), aGavdpReset, aError));
       
   103 	}
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // CBtsacStreaming::OpenAudioLinkL
       
   107 // -----------------------------------------------------------------------------
       
   108 //
       
   109 void CBtsacStreaming::OpenAudioLinkL(const TBTDevAddr& /*aAddr*/)
       
   110 	{  
       
   111 	TRACE_FUNC
       
   112 	// It is not allowed to open audio in streaming state, audio is allready opened
       
   113 	// by an accessory. Inform accessory fw about this by returning KErrInUse.
       
   114 	Parent().CompletePendingRequests(KOpenAudioReq, KErrInUse);
       
   115 	}
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CBtsacStreaming::CloseAudioLinkL
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 void CBtsacStreaming::CloseAudioLinkL(const TBTDevAddr& /*aAddr*/)
       
   122 	{  
       
   123 	TRACE_FUNC
       
   124 	iStartCollision = EFalse;
       
   125 	TInt ret = Parent().iStreamer->StopStream();
       
   126 	if ( ret )
       
   127 		{
       
   128 		TRACE_INFO((_L("CBtsacStreaming::CloseAudio() iStreamer.StopStream() returned error(%d) !!!"), ret))
       
   129 		}
       
   130 	TAvdtpSEPInfo SEPInfo;
       
   131 	ret = Parent().iRemoteSEPs->GetInfo(Parent().GetSEPIndex(), SEPInfo); 
       
   132 	if ( ret )
       
   133 		{
       
   134 		TRACE_INFO((_L("CBtsacStreaming::CloseAudio() Couldn't retrieve SEP Info !")))
       
   135 		CancelActionL(KErrCancel, EGavdpResetReasonGeneral); 
       
   136  		return;   
       
   137 		}
       
   138 	// Suspend audio
       
   139 	TSEID remoteSEPid = SEPInfo.SEID(); 	
       
   140 	TRACE_INFO((_L("CBtsacStreaming::CloseAudio() Suspending remote SEID(%d)"), remoteSEPid.SEID()))	
       
   141 	iSuspending = ETrue;
       
   142 	Parent().iGavdp->SuspendStreams(remoteSEPid);
       
   143 	}
       
   144 
       
   145 // -----------------------------------------------------------------------------
       
   146 // CBtsacStreaming::CancelCloseAudioLink
       
   147 // -----------------------------------------------------------------------------
       
   148 //
       
   149 void CBtsacStreaming::CancelCloseAudioLink(const TBTDevAddr& /*aAddr*/)
       
   150 	{
       
   151 	TRACE_FUNC
       
   152 	// For safety sake complete all pending requests
       
   153 	Parent().CompletePendingRequests(KCompleteAllReqs, KErrNone);
       
   154 	TRAP_IGNORE(Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EGavdpResetReasonGeneral, KErrDisconnected)));
       
   155 	}
       
   156 
       
   157 
       
   158 // -----------------------------------------------------------------------------
       
   159 // CBtsacStreaming::StartRecording
       
   160 // -----------------------------------------------------------------------------
       
   161 //
       
   162 void CBtsacStreaming::StartRecording()
       
   163 	{  
       
   164 	TRACE_FUNC	
       
   165 	iStartCollision = EFalse;
       
   166 	if ( Parent().iStreamer->StartStream(Parent().iStreamingSockets[0], Parent().iStreamer->FrameLength()) != KErrNone ) 
       
   167 	 	{
       
   168 		TRACE_INFO((_L("CBtsacStreaming::StartRecording() [ERR] Could not start streaming!")))	
       
   169 		TInt err = Parent().AbortStream();
       
   170 		if(err)
       
   171 			{
       
   172 			TRACE_INFO((_L("CBtsacStreaming::StartRecording() Couldn't abort stream.")))	
       
   173 			}
       
   174 		TRAP_IGNORE(Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EGavdpResetReasonNone, KErrDisconnected)));
       
   175 	 	}
       
   176 	}
       
   177 
       
   178 // -----------------------------------------------------------------------------
       
   179 // CBtsacStreaming::DisconnectL
       
   180 // -----------------------------------------------------------------------------
       
   181 //
       
   182 void CBtsacStreaming::DisconnectL()
       
   183 	{
       
   184 	TRACE_FUNC
       
   185 	TInt ret = Parent().iStreamer->StopStream();
       
   186 	if ( ret )
       
   187 		{
       
   188 		TRACE_INFO((_L("CBtsacStreaming::DisconnectL() StopStream() returned error: %d"), ret))	
       
   189 		}
       
   190 	Parent().CompletePendingRequests(KDisconnectReq, ret);
       
   191 	Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EGavdpResetReasonDisconnect, KErrNone));
       
   192 	}
       
   193 
       
   194 // -----------------------------------------------------------------------------
       
   195 // CBtsacStreaming::GAVDP_SuspendStreamsConfirm
       
   196 // -----------------------------------------------------------------------------
       
   197 //
       
   198 void CBtsacStreaming::GAVDP_SuspendStreamsConfirm()
       
   199 	{
       
   200 	TRACE_FUNC
       
   201     // so remote supports suspend 
       
   202     iSuspending = EFalse;
       
   203 	Parent().CompletePendingRequests(KCloseAudioReq, KErrNone);
       
   204 	TRAP_IGNORE(Parent().ChangeStateL(CBtsacSuspended::NewL(Parent())));
       
   205 	}
       
   206 
       
   207 // -----------------------------------------------------------------------------
       
   208 // CBtsacStreaming::GAVDP_AbortIndication
       
   209 // -----------------------------------------------------------------------------
       
   210 //	
       
   211 void CBtsacStreaming::GAVDP_AbortIndication(TSEID aSEID)
       
   212 	{
       
   213 	TRACE_INFO((_L("CBtsacStreaming::GAVDP_AbortIndication() Local SEP Id: %d"), aSEID.SEID()))	
       
   214 	(void)aSEID;
       
   215 	TInt ret = Parent().iStreamer->StopStream();
       
   216 	if ( ret )
       
   217 		{
       
   218 		TRACE_INFO((_L("CBtsacStreaming::Cancel() iStreamer.StopStream() returned error(%d) !!!"), ret))
       
   219 		}
       
   220 	
       
   221 	// It is possible the remote disconnected while we have active close audio request.
       
   222 	Parent().CompletePendingRequests(KCompleteAllReqs, KErrNone);
       
   223     TRAP_IGNORE(Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EGavdpResetReasonNone, KErrDisconnected)));
       
   224 	}
       
   225 
       
   226 // -----------------------------------------------------------------------------
       
   227 // CBtsacStreaming::GAVDP_ReleaseIndication
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 void CBtsacStreaming::GAVDP_ReleaseIndication(TSEID aSEID)
       
   231 	{
       
   232 	TRACE_INFO((_L("CBtsacStreaming::GAVDP_ReleaseIndication() aSEID: %d"), aSEID.SEID()))	
       
   233 	(void)aSEID;
       
   234 	if(!iSuspending)
       
   235 		{		
       
   236 		TInt ret = Parent().iStreamer->StopStream();
       
   237 		if ( ret ) 
       
   238 		 	{
       
   239 			TRACE_INFO((_L("CBtsacStreaming::GAVDP_ReleaseIndication() [ERR: %d] Could not stop streaming!"), ret))	
       
   240 		 	}
       
   241 	 	Parent().AccessoryClosedAudio(Parent().GetRemoteAddr());
       
   242 		}
       
   243 	else
       
   244 		{
       
   245 		// We are trying to suspend the stream and remote end has sent release indication.
       
   246 		// Stream is already stopped but we have pending close audio request, complete it.
       
   247 		Parent().CompletePendingRequests(KCloseAudioReq, KErrNone);
       
   248 		}
       
   249 	Parent().CleanSockets();
       
   250 	TRAP_IGNORE(Parent().ChangeStateL(CBtsacConnected::NewL(Parent(), EConnExists)));
       
   251 	}
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // CBtsacStreaming::GAVDP_SuspendIndication
       
   255 // -----------------------------------------------------------------------------
       
   256 //	
       
   257 TInt CBtsacStreaming::GAVDP_SuspendIndication(TSEID aSEID)
       
   258 	{
       
   259 	TRACE_INFO((_L("CBtsacStreaming::GAVDP_SuspendIndication() aSEID: %d"), aSEID.SEID()))	
       
   260 	(void)aSEID;
       
   261 	if(!iSuspending)
       
   262 		{		
       
   263 		TInt ret = Parent().iStreamer->StopStream();
       
   264 		if ( ret )
       
   265 			{
       
   266 			TRACE_INFO((_L("CBtsacStreaming::GAVDP_SuspendIndication() iStreamer.StopStream() returned error(%d) !!!"), ret))	
       
   267 			}
       
   268 		Parent().AccessorySuspendedAudio(Parent().GetRemoteAddr());
       
   269 		TRAPD(err, Parent().ChangeStateL(CBtsacSuspended::NewL(Parent())));
       
   270 		if(err)
       
   271 			{
       
   272 			return KErrNoMemory;
       
   273 			}
       
   274 		}
       
   275 	return KErrNone;
       
   276 	}
       
   277 
       
   278 // -----------------------------------------------------------------------------
       
   279 // CBtsacStreaming::HandleGavdpErrorL
       
   280 // -----------------------------------------------------------------------------
       
   281 //	
       
   282 void CBtsacStreaming::HandleGavdpErrorL(TInt aError)
       
   283 	{
       
   284 	TRACE_FUNC
       
   285 	TInt err = KErrNone;
       
   286 
       
   287 	if(aError == (KErrAvdtpSignallingErrorBase - EAvdtpBadState) && iStartCollision)
       
   288 		{
       
   289 		// Start stream collision has happened (src and snk have sent start stream cmd simultaneously).
       
   290 		// iStreamStartIndCollision flag is set in configured state to indicate possible collision
       
   291 		// situations.
       
   292 		// Error can be ignored and we can continue streaming.
       
   293 		iStartCollision = EFalse;
       
   294 		TRACE_INFO((_L("CBtsacStreaming::HandleGavdpErrorL() Ignore error, continue streaming.")))
       
   295 		return;
       
   296 		}
       
   297 
       
   298 	if(iSuspending)
       
   299 		{
       
   300 		iSuspending = EFalse;
       
   301 		if(aError == (KErrAvdtpSignallingErrorBase - EAvdtpBadState)) // -18094
       
   302 			{
       
   303 			// For some reason remote rejected our suspend command. According to the specification
       
   304 			// it is acceptor's responsibilty to cope with this situation, so we can move to suspended
       
   305 			// state and wait for acceptor's reaction.
       
   306 	        Parent().CompletePendingRequests(KCloseAudioReq, KErrNone);
       
   307 			Parent().ChangeStateL(CBtsacSuspended::NewL(Parent()));
       
   308 		    return;
       
   309 			}
       
   310 		else if(aError == (KErrAvdtpSignallingErrorBase - EAvdtpNotSupportedCommand)) // -18070 
       
   311 			{
       
   312 			// remote doesn't support suspend so close audio 
       
   313 			Parent().CleanSockets();
       
   314 	        Parent().CompletePendingRequests(KCloseAudioReq, KErrNone);
       
   315 			Parent().ChangeStateL(CBtsacConnected::NewL(Parent(), EConnExists));
       
   316 		    return;
       
   317 			}
       
   318 		}
       
   319 	else
       
   320 		{
       
   321 		err = Parent().iStreamer->StopStream();
       
   322 		if (err)
       
   323 	 		{
       
   324 			TRACE_INFO((_L("CBtsacStreaming::HandleGavdpErrorL() [error: %d] Could not stop streaming!"), err))
       
   325 	 		}
       
   326 		}
       
   327 	
       
   328 	switch (aError)
       
   329 		{
       
   330 		case KErrAvdtpRequestTimeout: // -18005
       
   331 		case (KErrAvdtpSignallingErrorBase - EAvdtpBadState): // 18094
       
   332 			{
       
   333 			err = Parent().AbortStream();
       
   334 			if(!err)
       
   335 				{
       
   336 				// Complete pending requests in Aborting state
       
   337 				Parent().ChangeStateL(CBtsacAborting::NewL(Parent()));
       
   338 				}
       
   339 			else
       
   340 				{
       
   341 				Parent().CompletePendingRequests(KCompleteAllReqs, aError);
       
   342 				Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EGavdpResetReasonGeneral, KErrDisconnected));
       
   343 				}
       
   344 			break;
       
   345 			}
       
   346 		case KErrHCILinkDisconnection: // -6305
       
   347 		case KErrDisconnected: // -36
       
   348 			{
       
   349 			Parent().CompletePendingRequests(KCompleteAllReqs, aError);
       
   350 			Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EGavdpResetReasonNone, aError));
       
   351 			break;
       
   352 			}
       
   353 		default:
       
   354 			{
       
   355 			// Unknown error. For safety's sake let's disconnect a2dp link and inform btaudioman
       
   356 			TRACE_INFO((_L("CBtsacStreaming::HandleGavdpErrorL() Unknown error, goes to listening")))
       
   357 			Parent().CompletePendingRequests(KCompleteAllReqs, aError);
       
   358 			Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EGavdpResetReasonGeneral, KErrDisconnected));
       
   359 			break;
       
   360 			}
       
   361 		}
       
   362 	}
       
   363 	
       
   364 //  End of File