telephonyserver/etelserverandcore/SETEL/ET_PHONE.CPP
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
child 32 58332560b319
equal deleted inserted replaced
23:6b1d113cdff3 24:6638e7f4bd8f
    18 */
    18 */
    19 
    19 
    20 #include "ET_SSTD.H"
    20 #include "ET_SSTD.H"
    21 #include "et_record.h"
    21 #include "et_record.h"
    22 #include "et_phone_util.h"
    22 #include "et_phone_util.h"
    23 
    23 #include "et_patchdata.h"
    24 //
    24 //
    25 // CReqEntry class definitions
    25 // CReqEntry class definitions
    26 //
    26 //
    27 
    27 
    28 CReqEntry* CReqEntry::NewL(TTsyReqHandle aTsyReqHandle, const RMessage2& aMessage, CTelSession* aSession, CBuffer* aBuffer, const CTelObject* aTelObject, TInt aFunction, RHeap* aHeap)
    28 CReqEntry* CReqEntry::NewL(TTsyReqHandle aTsyReqHandle, const RMessage2& aMessage, CTelSession* aSession, CBuffer* aBuffer, const CTelObject* aTelObject, TInt aFunction, RHeap* aHeap)
   334 EXPORT_C CTelObject::~CTelObject()
   334 EXPORT_C CTelObject::~CTelObject()
   335 //
   335 //
   336 // Destructor
   336 // Destructor
   337 //
   337 //
   338 	{
   338 	{
       
   339 	delete iDeliveryObject;
   339 	delete iDestroyDummySubSession;
   340 	delete iDestroyDummySubSession;
   340 	}
   341 	}
   341 
   342 
   342 EXPORT_C void CTelObject::CTelObject_Reserved1()
   343 EXPORT_C void CTelObject::CTelObject_Reserved1()
   343 //
   344 //
   466 			{
   467 			{
   467 			reqEntry->iClientInterested=EFalse;
   468 			reqEntry->iClientInterested=EFalse;
   468 			__ASSERT_ALWAYS(iActiveReqCount>=0,Fault(EEtelFaultNegativeActiveReqCount));
   469 			__ASSERT_ALWAYS(iActiveReqCount>=0,Fault(EEtelFaultNegativeActiveReqCount));
   469 			if (reqEntry->iCancelFnCalled==FALSE)
   470 			if (reqEntry->iCancelFnCalled==FALSE)
   470 				{
   471 				{
       
   472 			    TReqMode reqMode = reqEntry->iReqMode;
       
   473 				
   471 				if (reqEntry->iPlacedRequest)
   474 				if (reqEntry->iPlacedRequest)
   472 					{
   475 					{
   473 					LOGTEXT2("Calling Cancel Service ActiveReq TsyReq=%d", reqEntry->iTsyReqHandle);
   476 					LOGTEXT2("Calling Cancel Service ActiveReq TsyReq=%d", reqEntry->iTsyReqHandle);
   474 					reqEntry->iCancelFnCalled=ETrue;
   477 					reqEntry->iCancelFnCalled=ETrue;
   475 					CancelService(reqEntry->iFunction,reqEntry->iTsyReqHandle);
   478 					CancelService(reqEntry->iFunction,reqEntry->iTsyReqHandle);
   487 					if (PhoneOwner()->ReqActiveList().IsEmpty() == EFalse)
   490 					if (PhoneOwner()->ReqActiveList().IsEmpty() == EFalse)
   488 						{
   491 						{
   489 						iter.Set(*PhoneOwner()->ReqActiveList().First());
   492 						iter.Set(*PhoneOwner()->ReqActiveList().First());
   490 						}
   493 						}
   491 					else
   494 					else
   492 
       
   493 						{
   495 						{
   494 						break;
   496 						break;
   495 						}
   497 						}
   496 					}
   498 					}
   497 				else
   499 				else 
   498 					{
   500 					{
   499 					LOGTEXT("Destroying request");
   501 		            if (reqMode&KReqModeMultipleCompletionWithInterestLevel && iDeliveryObject)
   500 					DestroyReq(reqEntry);
   502 		                {
   501 					CheckAndDestroyDummySubSession();
   503 		                iDeliveryObject->DeletedReqEntry(reqEntry);
       
   504 		                }
       
   505 					
       
   506                         LOGTEXT("Destroying request");
       
   507                         DestroyReq(reqEntry);
       
   508                         CheckAndDestroyDummySubSession();
   502 					}
   509 					}
   503 				}
   510 				}
   504 			}
   511 			}
   505 		}
   512 		}
   506 	}
   513 	}
   836 //
   843 //
   837 	{
   844 	{
   838 	HEtelBufC8* buf8=NULL;
   845 	HEtelBufC8* buf8=NULL;
   839 	HEtelBufC16* buf16=NULL;
   846 	HEtelBufC16* buf16=NULL;
   840 	CReqEntry* reqEntry=NULL;
   847 	CReqEntry* reqEntry=NULL;
   841 	
   848 
   842 	reqEntry = PhoneOwner()->FindSameClientEntry(aSession,aMessage.Int3(),aMessage.Function());
   849 	reqEntry = PhoneOwner()->FindSameClientEntry(aSession,aMessage.Int3(),aMessage.Function());
   843 	if (reqEntry) 
   850 	if (reqEntry) 
   844 		{	
   851 		{	
   845 		if (aReqMode&KReqModeRePostImmediately)	
   852 		if (aReqMode&KReqModeRePostImmediately)	
   846 			{
   853 			{
   913 	// Now create the request entry for this client request - even if it's not to be passed
   920 	// Now create the request entry for this client request - even if it's not to be passed
   914 	// down to the TSY in the case of MultipleCompletion.
   921 	// down to the TSY in the case of MultipleCompletion.
   915 	//
   922 	//
   916 	reqEntry=PhoneOwner()->NewReqL(aMessage,aSession,buffer,this,aMessage.Function());
   923 	reqEntry=PhoneOwner()->NewReqL(aMessage,aSession,buffer,this,aMessage.Function());
   917 	CleanupStack::Pop();
   924 	CleanupStack::Pop();
   918 	if (aReqMode&KReqModeMultipleCompletionEnabled)
   925 
   919 				// this client has not currently got this request outstanding
   926 	reqEntry->iInterestCategory = FindInterestCategory(aMessage.SecureId());
   920 				// but another client may have 
   927 
   921 		{
   928     if ( aReqMode & (KReqModeMultipleCompletionEnabled | KReqModeMultipleCompletionWithInterestLevel) )
   922 		CReqEntry* previousReq=NULL;
   929 		// this client has not currently got this request outstanding but another client may have 
       
   930 		{
       
   931         CReqEntry* previousReq=NULL;
   923 		previousReq=PhoneOwner()->FindByIpcAndTelObject(aMessage.Function(),this, buffer->Size());	// search in active list
   932 		previousReq=PhoneOwner()->FindByIpcAndTelObject(aMessage.Function(),this, buffer->Size());	// search in active list
   924 		if (previousReq)
   933 		if (previousReq)
   925 			{
   934 			{
   926 			reqEntry->iTsyReqHandle=previousReq->iTsyReqHandle;
   935 			reqEntry->iTsyReqHandle=previousReq->iTsyReqHandle;
   927 			reqEntry->iReqMode=aReqMode;
   936 			reqEntry->iReqMode=aReqMode;
   980 			{
   989 			{
   981 			RECORD_COMPLETE_SUB(aMessage.Session(), this, aMessage.Int3(), aMessage.Function(), res);
   990 			RECORD_COMPLETE_SUB(aMessage.Session(), this, aMessage.Int3(), aMessage.Function(), res);
   982 			aMessage.Complete(res);
   991 			aMessage.Complete(res);
   983 			return;
   992 			return;
   984 			}
   993 			}
       
   994 
       
   995         // If a call is session based then it can only be used
       
   996         // when the client is the session owner.
       
   997         if (reqMode&KReqModeSessionBased && IsSessionInProgress() 
       
   998                 /*&& aMessage.Int3() != iSessionOwner.iSubSessionId TODO*/)
       
   999             {
       
  1000             // Each type of session only allowed to have one ongoing 'session/dialogue'.
       
  1001 			RECORD_COMPLETE_SUB(aMessage.Session(), this, aMessage.Int3(), aMessage.Function(), res);
       
  1002             aMessage.Complete(KErrServerBusy);
       
  1003             return;
       
  1004             }
       
  1005 			
   985 		if (aNewReqEntry==NULL)
  1006 		if (aNewReqEntry==NULL)
   986 			{
  1007 			{
   987 			TRAP(res,reqEntry=ReqAnalyserL(aMessage,aSession,reqMode));
  1008 			TRAP(res,reqEntry=ReqAnalyserL(aMessage,aSession,reqMode));
   988 			if (res)
  1009 			if (res)
   989 				{
  1010 				{
  1068 				RECORD_COMPLETE_SUB(aMessage.Session(), this, aMessage.Int3(), aMessage.Function(), KErrNone);
  1089 				RECORD_COMPLETE_SUB(aMessage.Session(), this, aMessage.Int3(), aMessage.Function(), KErrNone);
  1069 				aMessage.Complete(KErrNone);
  1090 				aMessage.Complete(KErrNone);
  1070 				return;
  1091 				return;
  1071 				}
  1092 				}
  1072 				// so now we know the client must have the request outstanding
  1093 				// so now we know the client must have the request outstanding
  1073 			if (reqMode&KReqModeMultipleCompletionEnabled && !(reqEntry->iPlacedRequest))
  1094             if ((reqMode&KReqModeMultipleCompletionEnabled || reqMode&KReqModeMultipleCompletionWithInterestLevel) && !(reqEntry->iPlacedRequest))
  1074 				{
  1095 				{
       
  1096 				if (iDeliveryObject)
       
  1097 				    {
       
  1098 					iDeliveryObject->DeletedReqEntry(reqEntry);
       
  1099 				    }
       
  1100 
  1075 				CompleteAndDestroyReq(reqEntry,KErrCancel);	// the request hadn't been passed to the TSY
  1101 				CompleteAndDestroyReq(reqEntry,KErrCancel);	// the request hadn't been passed to the TSY
  1076 				RECORD_COMPLETE_SUB(aMessage.Session(), this, aMessage.Int3(), aMessage.Function(), KErrNone);
  1102 				RECORD_COMPLETE_SUB(aMessage.Session(), this, aMessage.Int3(), aMessage.Function(), KErrNone);
  1077 				aMessage.Complete(KErrNone);
  1103 				aMessage.Complete(KErrNone);
  1078 				return;
  1104 				return;
  1079 				}
  1105 				}
  1103 	default:
  1129 	default:
  1104 		PanicClient(EEtelPanicInvalidRequestType,aMessage);
  1130 		PanicClient(EEtelPanicInvalidRequestType,aMessage);
  1105 		break;
  1131 		break;
  1106 		}
  1132 		}
  1107 	}
  1133 	}
       
  1134 
       
  1135 void CTelObject::AcceptIncoming(const RMessage2& aMessage,CTelSession* aSession)
       
  1136     {
       
  1137     TInt status = KErrNotReady;
       
  1138     if (iDeliveryObject)
       
  1139         {
       
  1140         status = iDeliveryObject->ClientsDecision(aMessage, aSession, ETrue);
       
  1141         }
       
  1142     aMessage.Complete(status);
       
  1143     }
       
  1144 
       
  1145 void CTelObject::RejectIncoming(const RMessage2& aMessage,CTelSession* aSession)
       
  1146     {
       
  1147     TInt status = KErrNotReady;
       
  1148     if (iDeliveryObject)
       
  1149         {
       
  1150         if (iDeliveryObject->DeliveryInProgress())
       
  1151             {
       
  1152             status = iDeliveryObject->ClientsDecision(aMessage, aSession, EFalse);
       
  1153             }
       
  1154         else
       
  1155             {
       
  1156             // Rejecting when the time out has occurred will lead to a KErrNone
       
  1157             // error rather than KErrTimedOut.
       
  1158             status = KErrNone;
       
  1159             }
       
  1160         }
       
  1161     aMessage.Complete(status);
       
  1162     }
  1108 
  1163 
  1109 EXPORT_C void CTelObject::ReqCompleted(const TTsyReqHandle aTsyReqHandle,const TInt aError)
  1164 EXPORT_C void CTelObject::ReqCompleted(const TTsyReqHandle aTsyReqHandle,const TInt aError)
  1110 //
  1165 //
  1111 // General complete function for all CTelObject derived classes
  1166 // General complete function for all CTelObject derived classes
  1112 //
  1167 //
  1130 		//  Multiple-completion malarky.
  1185 		//  Multiple-completion malarky.
  1131 		//	Don't copy data across to other buffers and complete their reqs if TSY knows about
  1186 		//	Don't copy data across to other buffers and complete their reqs if TSY knows about
  1132 		//  each client that has called it. In that case, 
  1187 		//  each client that has called it. In that case, 
  1133 		//  TSY will fill in the appropriate client's buffer and complete each separately.
  1188 		//  TSY will fill in the appropriate client's buffer and complete each separately.
  1134 		if (reqMode&KReqModeMultipleCompletionEnabled)
  1189 		if (reqMode&KReqModeMultipleCompletionEnabled)
       
  1190 		    {
       
  1191 			
  1135 			PhoneOwner()->CheckAndCompleteAllActive(updatedReqEntry,reqMode,ipc,aError);
  1192 			PhoneOwner()->CheckAndCompleteAllActive(updatedReqEntry,reqMode,ipc,aError);
  1136 
  1193 		    }
       
  1194         else if (reqMode&KReqModeMultipleCompletionWithInterestLevel && error ==KErrNone)
       
  1195             {
       
  1196             // TODO if delivery is active for this req then return 
       
  1197             // KErrInUse / KErrServerBusy?
       
  1198             // TODO what if one CTelObject has multiple requests which are 
       
  1199             // KReqModeMultipleCompletionWithInterestLevel. Would we need multiple
       
  1200             // delivery managers?
       
  1201             if (!IsSessionInProgress())
       
  1202                 {
       
  1203                 // Find an owner for the new session by offering it to the 
       
  1204                 // interested clients one by one.
       
  1205                 DeliverReqL(updatedReqEntry,reqMode, ipc, aError);
       
  1206                 }
       
  1207             else
       
  1208                 {
       
  1209                 // Route response direct to session owner
       
  1210 				FindReq(updatedReqEntry, reqMode, ipc, aError);
       
  1211                }
       
  1212 
       
  1213             }
       
  1214 			
  1137 		if (reqMode&KReqModeRePostImmediately && error==KErrNone)
  1215 		if (reqMode&KReqModeRePostImmediately && error==KErrNone)
  1138 			nextPostedReqEntry = updatedReqEntry;					
  1216 			nextPostedReqEntry = updatedReqEntry;					
  1139 		updatedReqEntry->iBuffer->IncWrite();
  1217 		updatedReqEntry->iBuffer->IncWrite();
  1140 		}
  1218 		}
  1141 	else	// if a cancel comes from the TSY, then if it is a notification 
  1219 	else	// if a cancel comes from the TSY, then if it is a notification 
  1142 			// there may be other clients who have also called the notification and who 
  1220 			// there may be other clients who have also called the notification and who 
  1143 			// have entries in active list, so one of these must be re-posted.
  1221 			// have entries in active list, so one of these must be re-posted.
  1144 		{
  1222 		{
  1145 		if (reqMode&KReqModeMultipleCompletionEnabled)
  1223 
  1146 			nextPostedReqEntry = PhoneOwner()->FindThisReqByAnotherClient(updatedReqEntry->iSession,updatedReqEntry->iMessage.Int3(),ipc,updatedReqEntry->iBuffer->Size(),this);
  1224 		if ( reqMode&KReqModeMultipleCompletionEnabled || reqMode&KReqModeMultipleCompletionWithInterestLevel)
       
  1225 		    {
       
  1226 			nextPostedReqEntry = PhoneOwner()->FindThisReqByAnotherClient(updatedReqEntry->iSession,
       
  1227 			        updatedReqEntry->iMessage.Int3(),ipc,updatedReqEntry->iBuffer->Size(),this);
       
  1228 			}
       
  1229 			
  1147 		if (!nextPostedReqEntry)
  1230 		if (!nextPostedReqEntry)
  1148 			// then we don't want to post any other client's requests in place of this one
  1231 			// then we don't want to post any other client's requests in place of this one
  1149 			{
  1232 			{
  1150 			nextPostedReqEntry = PhoneOwner()->FindNonCancelledClientReq(updatedReqEntry->iSession,updatedReqEntry->iMessage.Int3(),ipc);
  1233 			nextPostedReqEntry = PhoneOwner()->FindNonCancelledClientReq(updatedReqEntry->iSession,updatedReqEntry->iMessage.Int3(),ipc);
  1151 			__ASSERT_DEBUG(updatedReqEntry!=nextPostedReqEntry, Fault(EEtelFaultCancelErrorWithoutCancelled));
  1234 			__ASSERT_DEBUG(updatedReqEntry!=nextPostedReqEntry, Fault(EEtelFaultCancelErrorWithoutCancelled));
  1156 				if (ret!=KErrNone)
  1239 				if (ret!=KErrNone)
  1157 					error=ret;	// so the KErrCancel wouldn't reach the client
  1240 					error=ret;	// so the KErrCancel wouldn't reach the client
  1158 				}
  1241 				}
  1159 			}
  1242 			}
  1160 		}
  1243 		}
       
  1244 		
       
  1245 	if (error && reqMode&KReqModeMultipleCompletionWithInterestLevel && iDeliveryObject)
       
  1246         {
       
  1247         // We need to do this before the updatedReqEntry is destroyed
       
  1248         iDeliveryObject->DeletedReqEntry(updatedReqEntry);
       
  1249         }
       
  1250 	
  1161 	if (reqMode & KReqModeRePostImmediately)
  1251 	if (reqMode & KReqModeRePostImmediately)
  1162 		UpdateAndCompleteIfNecessary(updatedReqEntry,error);	// this will destroy the reqEntry
  1252 		{
  1163 																// if an error occurred.
  1253 		// this will destroy the reqEntry if an error occurred.
       
  1254 		UpdateAndCompleteIfNecessary(updatedReqEntry,error);	
       
  1255 		}														
  1164 	else
  1256 	else
       
  1257 		{
  1165 		WriteBackAndCompleteReq(updatedReqEntry,error);
  1258 		WriteBackAndCompleteReq(updatedReqEntry,error);
       
  1259 		}
       
  1260 	
  1166 	if (nextPostedReqEntry)	// will be NULL if no following request for TSY
  1261 	if (nextPostedReqEntry)	// will be NULL if no following request for TSY
  1167 		{
  1262 		{
  1168 		if(nextPostedReqEntry->iReqMode&KReqModeFlowControlObeyed)
  1263 		if(nextPostedReqEntry->iReqMode&KReqModeFlowControlObeyed && 
       
  1264 								!(nextPostedReqEntry->iReqMode&KReqModeMultipleCompletionWithInterestLevel))
  1169 			{ // since the request mode is flow control obeyed, increment the flow control counter
  1265 			{ // since the request mode is flow control obeyed, increment the flow control counter
  1170 			FlowControlSuspend();
  1266 			FlowControlSuspend();
  1171 			}
  1267 			}
  1172 		Service(nextPostedReqEntry->iMessage,nextPostedReqEntry);
  1268 		Service(nextPostedReqEntry->iMessage,nextPostedReqEntry);
  1173 		}
  1269 		}
  1174 
  1270 
  1175 	
  1271 	
  1176 	if (!(reqMode&KReqModeFlowControlObeyed)) // If flow control not enabled, go home
  1272 	if (!(reqMode&KReqModeFlowControlObeyed)) // If flow control not enabled, go home
       
  1273 		{
  1177 		ret=ETrue;
  1274 		ret=ETrue;
  1178 
  1275 		}
       
  1276 		
  1179 // So everything below assumes it obeyed flow control
  1277 // So everything below assumes it obeyed flow control
  1180 // Resume Flow control ...
  1278 // Resume Flow control ...
  1181 	if (!ret)
  1279 	if (!ret)
       
  1280 		{
  1182 		FlowControlResume();
  1281 		FlowControlResume();
       
  1282 		}
  1183 //
  1283 //
  1184 // Check and destroying the dummy session
  1284 // Check and destroying the dummy session
  1185 //
  1285 //
  1186 	CheckAndDestroyDummySubSession();
  1286 	CheckAndDestroyDummySubSession();
  1187 	}
  1287 	}
       
  1288 
       
  1289 TInt CTelObject::DeliverReqL(CReqEntry* aUpdatedReqEntry,const TReqMode aReqMode,const TInt aIpc, const TInt aError)
       
  1290     {
       
  1291     // There is no active session therefore we have to work out who to deliver it to. 
       
  1292     if (!iDeliveryObject)
       
  1293         {
       
  1294 		iDeliveryObject = CMmDeliveryObject::NewL(*this); 
       
  1295         }
       
  1296     
       
  1297     if (iDeliveryObject->DeliveryInProgress())
       
  1298         {
       
  1299 		// Session in progress.
       
  1300         return KErrPermissionDenied;
       
  1301         }
       
  1302 
       
  1303 	return iDeliveryObject->DeliverReqL(PhoneOwner()->ReqActiveList(), aUpdatedReqEntry, aReqMode, aIpc, aError);
       
  1304     }
       
  1305 	
       
  1306 void CTelObject::FindReq(CReqEntry* aUpdatedReqEntry,const TReqMode aReqMode,const TInt aIpc,const TInt aError)
       
  1307     {
       
  1308 	CReqEntry* reqEntry;
       
  1309 	TDblQueIter<CReqEntry> iter(PhoneOwner()->ReqActiveList());
       
  1310 	while(reqEntry = iter++, reqEntry!=NULL)
       
  1311 		{
       
  1312 		if(reqEntry->iFunction==aIpc 
       
  1313 			&& reqEntry->iTelObject==aUpdatedReqEntry->iTelObject 
       
  1314 			&& reqEntry->iBuffer->Size()==aUpdatedReqEntry->iBuffer->Size()
       
  1315 			/*&& IsSessionOwner(reqEntry)*/)    
       
  1316 			{
       
  1317 			if (aUpdatedReqEntry != reqEntry)
       
  1318 				{
       
  1319 				// Copy data from the 'placed' request to the one
       
  1320 				// that is owned by the client.
       
  1321 				PhoneOwner()->UpdateBuffer(aUpdatedReqEntry,reqEntry);
       
  1322 				}
       
  1323 			OfferToClient(reqEntry, aUpdatedReqEntry, aReqMode, aError);
       
  1324 			RepostRequest(aUpdatedReqEntry, aError);
       
  1325 			}
       
  1326 		}   
       
  1327 	}
       
  1328 	
       
  1329 void CTelObject::OfferToClient(CReqEntry* aReqEntry,CReqEntry* aUpdatedReqEntry,const TReqMode aReqMode,const TInt aError)
       
  1330     {
       
  1331    if (aReqEntry == aUpdatedReqEntry)
       
  1332         {
       
  1333         aUpdatedReqEntry->iBuffer->IncWrite();
       
  1334         if (aReqMode&KReqModeRePostImmediately)
       
  1335 			{
       
  1336 			// this will destroy the reqEntry if an error occurred.
       
  1337             UpdateAndCompleteIfNecessary(aUpdatedReqEntry,aError);                         
       
  1338 			}
       
  1339         else
       
  1340 			{
       
  1341             WriteBackAndCompleteReq(aUpdatedReqEntry,aError);
       
  1342 			}
       
  1343         }
       
  1344     else
       
  1345         {
       
  1346         TInt error = ResolveError(aReqEntry->iSession,aError); // set error as either low or high byte
       
  1347         if (aReqMode&KReqModeRePostImmediately)
       
  1348 			{
       
  1349             UpdateAndCompleteIfNecessary(aReqEntry,error);    
       
  1350 			}			
       
  1351         else
       
  1352 			{
       
  1353             WriteBackAndCompleteReq(aReqEntry,error);
       
  1354 			}
       
  1355         }
       
  1356     
       
  1357     CheckAndDestroyDummySubSession(); //TODO
       
  1358     }
       
  1359 
       
  1360 void CTelObject::RepostRequest(CReqEntry* aUpdatedReqEntry, const TInt aError)
       
  1361     {
       
  1362 	TReqMode reqMode = aUpdatedReqEntry->iReqMode;
       
  1363     TBool ret=EFalse;
       
  1364     
       
  1365     CReqEntry* nextPostedReqEntry = NULL;
       
  1366     if (reqMode&KReqModeRePostImmediately && aError==KErrNone) 
       
  1367 		{
       
  1368 		nextPostedReqEntry = aUpdatedReqEntry;
       
  1369 		}
       
  1370 		
       
  1371     if (nextPostedReqEntry) // will be NULL if no following request for TSY
       
  1372         {
       
  1373         if(nextPostedReqEntry->iReqMode&KReqModeFlowControlObeyed)
       
  1374             { // since the request mode is flow control obeyed, increment the flow control counter
       
  1375             FlowControlSuspend();
       
  1376             }
       
  1377         Service(nextPostedReqEntry->iMessage,nextPostedReqEntry);
       
  1378         }
       
  1379     
       
  1380     if (!(reqMode&KReqModeFlowControlObeyed && aError == KErrNone)) // If flow control not enabled, go home
       
  1381             ret=ETrue;
       
  1382 
       
  1383     // So everything below assumes it obeyed flow control
       
  1384     // Resume Flow control ...
       
  1385         if (!ret)
       
  1386             FlowControlResume();
       
  1387     }
       
  1388 
       
  1389 void CTelObject::SetSessionOwner(TInt aSessionHandle, TInt aSubSessionHandle)
       
  1390     {
       
  1391 	iDeliveryObject->iSessionOwner = TPhoneClientId(aSessionHandle, aSubSessionHandle);
       
  1392     // TODO notify TSY that the session owner has changed 
       
  1393     }
       
  1394 
       
  1395 // TODO can be used by the TSY to set the session owner to the current request.
       
  1396 // For each request the CTSY is given a TsyReqHandle so this is a sensible thing
       
  1397 // for it to be dealing with.
       
  1398 // TODO note that once a session has an owner the reserved state is irrelevant.
       
  1399 
       
  1400 EXPORT_C void CTelObject::SetSessionOwnerByTsyHandle(const TTsyReqHandle aTsyReqHandle)
       
  1401     {
       
  1402 //    const TInt owningsession = PhoneOwner()->FindSessionByTsyHandle( aTsyReqHandle );
       
  1403 //    const TInt owningsubsession = PhoneOwner()->FindSubSessionByTsyHandle( aTsyReqHandle );
       
  1404 	
       
  1405 //	iSessionOwner = TPhoneClientId(owningsession, owningsubsession);
       
  1406     // TODO notify TSY that the session owner has changed 
       
  1407     }
       
  1408 
       
  1409 
       
  1410 TBool CTelObject::IsSessionOwner(CReqEntry* aReqEntry) const
       
  1411     {
       
  1412 	// TODO Neil's experimental update
       
  1413     TPhoneClientId clientId(reinterpret_cast<TInt>(aReqEntry->iSession),aReqEntry->iMessage.Int3());
       
  1414 	return (clientId == iDeliveryObject->iSessionOwner);
       
  1415     }
       
  1416 
       
  1417 TInterestCategory CTelObject::FindInterestCategory( const TSecureId aSid)
       
  1418 	{
       
  1419 	if (aSid == KUssdPriorityClientSid)
       
  1420 	    {
       
  1421 	    return EInterestCategoryPriority;
       
  1422 	    }
       
  1423 	else if(aSid == KUssdDefaultClientSid)
       
  1424 	    {
       
  1425 	    return EInterestCategoryDefault;
       
  1426 	    }
       
  1427 	else
       
  1428 	    return EInterestCategoryStandard;
       
  1429 	}	
       
  1430 
       
  1431 EXPORT_C TBool CTelObject::IsSessionInProgress() const
       
  1432     {
       
  1433 	// TODO Neil's experimental update
       
  1434 	if (iDeliveryObject)
       
  1435 		{
       
  1436 		return iDeliveryObject->iSessionOwner != TPhoneClientId();
       
  1437 		}
       
  1438 	return EFalse;
       
  1439     }
       
  1440 
       
  1441 EXPORT_C TInt CTelObject::ReserveSession()
       
  1442     {
       
  1443 	// TODO Neil's experimental update
       
  1444 	ASSERT(iDeliveryObject);
       
  1445     if (iDeliveryObject->iSessionReserved)
       
  1446         {
       
  1447         return KErrInUse;
       
  1448         }
       
  1449     iDeliveryObject->iSessionReserved = ETrue;
       
  1450 	return KErrNone;
       
  1451     }
       
  1452 
       
  1453 EXPORT_C TBool CTelObject::IsSessionReserved() const
       
  1454     {
       
  1455 	// TODO Neil's experimental update
       
  1456     return iDeliveryObject->iSessionReserved;
       
  1457     }
       
  1458 
       
  1459 EXPORT_C void CTelObject::CancelReserveSession()
       
  1460     {
       
  1461 	// TODO Neil's experimental update
       
  1462     iDeliveryObject->iSessionReserved = EFalse;
       
  1463     }
       
  1464 
       
  1465 EXPORT_C void CTelObject::EndSession()
       
  1466     {
       
  1467 	// TODO Neil's experimental update
       
  1468     iDeliveryObject->iSessionOwner = TPhoneClientId();
       
  1469     iDeliveryObject->iSessionReserved = EFalse;
       
  1470     }
  1188 
  1471 
  1189 TInt CTelObject::ResolveError(CTelSession* aSession, const TInt aError) const
  1472 TInt CTelObject::ResolveError(CTelSession* aSession, const TInt aError) const
  1190 /**
  1473 /**
  1191  * Converts a coded error into the correct error to return.  The coded error value
  1474  * Converts a coded error into the correct error to return.  The coded error value
  1192  * allows an extended error code to be present allong with a basic error code.  If
  1475  * allows an extended error code to be present allong with a basic error code.  If
  1553 				}
  1836 				}
  1554 				
  1837 				
  1555 			if (basicMessageType==EIsaUnicodeDoubleDesTobeRead)
  1838 			if (basicMessageType==EIsaUnicodeDoubleDesTobeRead)
  1556 				{
  1839 				{
  1557 				TDes16* dataDes2=BufferDes2u(aReqEntry->iBuffer,CBuffer::ESlotRead);
  1840 				TDes16* dataDes2=BufferDes2u(aReqEntry->iBuffer,CBuffer::ESlotRead);
  1558 				__ASSERT_ALWAYS(dataDes2!=NULL,Fault(EEtelFaultDes2DoesNotExist));
       
  1559 
  1841 
  1560 				TRAP(ret,aReqEntry->iMessage.WriteL(2,*dataDes2));
  1842 				TRAP(ret,aReqEntry->iMessage.WriteL(2,*dataDes2));
  1561 				if(ret!=KErrNone)
  1843 				if(ret!=KErrNone)
  1562 					{
  1844 					{
  1563 					PanicClient(EEtelPanicBadDescriptor,aReqEntry->iMessage);
  1845 					PanicClient(EEtelPanicBadDescriptor,aReqEntry->iMessage);
  1803 
  2085 
  1804 void CTelObject::RemoveDummySubSessionDestroyer()
  2086 void CTelObject::RemoveDummySubSessionDestroyer()
  1805 	{
  2087 	{
  1806 	iDestroyDummySubSession = NULL;
  2088 	iDestroyDummySubSession = NULL;
  1807 	}
  2089 	}
  1808 
  2090 	
  1809 //
  2091 //
  1810 //
  2092 //
  1811 // CSubSessionExtBase
  2093 // CSubSessionExtBase
  1812 //
  2094 //
  1813 //
  2095 //