• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 
19 #include "pvmf_clientserver_socket_node.h"
20 #include "oscl_string_utils.h"
21 #include "pvmf_basic_errorinfomessage.h"
22 #include "pvmf_errorinfomessage_extension.h"
23 #include "oscl_byte_order.h"
24 #include "pvmf_media_cmd.h"
25 #include "pvmf_media_msg_format_ids.h"
26 #include "oscl_tickcount.h"
27 #include "oscl_rand.h"
28 #include "oscl_time.h"
29 #include "oscl_bin_stream.h"
30 
31 // Use default DLL entry point for Symbian
32 #include "oscl_dll.h"
33 
34 //////////////////////////////////////////////////
35 // Standard Node APIs
36 //////////////////////////////////////////////////
37 
PVMFClientServerSocketNode(OsclTCPSocket * aSocketHandle,int32 aPriority)38 OSCL_EXPORT_REF PVMFClientServerSocketNode::PVMFClientServerSocketNode(OsclTCPSocket* aSocketHandle, int32 aPriority)
39         : OsclActiveObject(aPriority, "PVMFClientServerSocketNode")
40         , iSockServ(NULL)
41         , TIMEOUT_CONNECT(-1)
42         , TIMEOUT_SEND(-1)
43         , TIMEOUT_RECV(-1)
44         , TIMEOUT_SHUTDOWN(-1)
45         , iSocketHandle(aSocketHandle)
46         , iSockConfig(NULL)
47 {
48     iLogger = NULL;
49     iDataPathLogger = NULL;
50     iOsclErrorTrapImp = NULL;
51     iExtensionRefCount = 0;
52     iMaxTcpRecvBufferSize = SNODE_DEFAULT_SOCKET_TCP_BUFFER_SIZE;
53     iMaxTcpRecvBufferCount = SNODE_DEFAULT_SOCKET_TCP_BUFFER_COUNT;
54     iSocketID = 0;
55     iCommandErrorCode = PVMFSocketNodeErrorEventStart;
56     iErrorEventErrorCode = PVMFSocketNodeErrorEventStart;
57 
58     iPVMFPort = NULL;
59     iNumStopPortActivityPending = (-1);//inactive.
60 
61     int32 err;
62     OSCL_TRY(err,
63 
64              iPendingCmdQueue.Construct(PVMF_SOCKET_NODE_COMMAND_ID_START,
65                                         PVMF_SOCKET_NODE_COMMAND_VECTOR_RESERVE);
66 
67              //Create the "current command" queue.  It will only contain one
68              //command at a time, so use a reserve of 1.
69              iCurrentCmdQueue.Construct(0, 1);
70              iCancelCmdQueue.Construct(0, 1);
71             );
72 
73     if (err != OsclErrNone)
74     {
75         //if a leave happened, cleanup and re-throw the error
76         iPendingCmdQueue.clear();
77         iCurrentCmdQueue.clear();
78         iCancelCmdQueue.clear();
79         if (iPVMFPort)
80         {
81             iPVMFPort->Disconnect();
82             delete iPVMFPort;
83             iPVMFPort = NULL;
84         }
85         OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
86         OSCL_CLEANUP_BASE_CLASS(OsclActiveObject);
87         OSCL_LEAVE(err);
88     }
89 }
90 
91 
~PVMFClientServerSocketNode()92 OSCL_EXPORT_REF PVMFClientServerSocketNode::~PVMFClientServerSocketNode()
93 {
94     Cancel();
95 
96     //thread logoff
97     if (IsAdded())
98         RemoveFromScheduler();
99 
100     /* Cleanup allocated ports */
101     CleanupPorts();
102 
103     //Cleanup commands
104     while (!iCurrentCmdQueue.empty())
105     {
106         CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFFailure);
107     }
108     while (!iPendingCmdQueue.empty())
109     {
110         CommandComplete(iPendingCmdQueue, iPendingCmdQueue.front(), PVMFFailure);
111     }
112     while (!iCancelCmdQueue.empty())
113     {
114         CommandComplete(iCancelCmdQueue, iCancelCmdQueue.front(), PVMFFailure);
115     }
116 }
117 
118 
ThreadLogon()119 OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::ThreadLogon()
120 {
121     switch (iInterfaceState)
122     {
123         case EPVMFNodeCreated:
124             if (!IsAdded())
125                 AddToScheduler();
126             iLogger = PVLogger::GetLoggerObject("PVMFClientServerSocketNode");
127             iDataPathLogger = PVLogger::GetLoggerObject("datapath.socketnode");
128             iOsclErrorTrapImp = OsclErrorTrap::GetErrorTrapImp();
129             SetState(EPVMFNodeIdle);
130             return PVMFSuccess;
131         default:
132             return PVMFErrInvalidState;
133     }
134 }
135 
136 
ThreadLogoff()137 OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::ThreadLogoff()
138 {
139     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:ThreadLogoff"));
140 
141     switch (iInterfaceState)
142     {
143         case EPVMFNodeIdle:
144         {
145             if (IsAdded())
146                 RemoveFromScheduler();
147             iLogger = NULL;
148             iDataPathLogger = NULL;
149             iOsclErrorTrapImp = NULL;
150             SetState(EPVMFNodeCreated);
151             return PVMFSuccess;
152         }
153         default:
154             return PVMFErrInvalidState;
155     }
156 }
157 
158 
GetCapability(PVMFNodeCapability & aNodeCapability)159 OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::GetCapability(PVMFNodeCapability& aNodeCapability)
160 {
161     OSCL_UNUSED_ARG(aNodeCapability);
162     return PVMFSuccess;
163 }
164 
GetPorts(const PVMFPortFilter * aFilter)165 OSCL_EXPORT_REF PVMFPortIter* PVMFClientServerSocketNode::GetPorts(const PVMFPortFilter* aFilter)
166 {
167     OSCL_UNUSED_ARG(aFilter);
168     //retrive a port iterator
169     return (PVMFPortIter*)iPVMFPort;
170 }
171 
QueryUUID(PVMFSessionId s,const PvmfMimeString & aMimeType,Oscl_Vector<PVUuid,OsclMemAllocator> & aUuids,bool aExactUuidsOnly,const OsclAny * aContext)172 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
173         Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
174         bool aExactUuidsOnly,
175         const OsclAny* aContext)
176 {
177     PVMFSocketNodeCommand cmd;
178     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_QUERYUUID, aMimeType, aUuids, aExactUuidsOnly, aContext);
179     return QueueCommandL(cmd);
180 }
181 
QueryInterface(PVMFSessionId s,const PVUuid & aUuid,PVInterface * & aInterfacePtr,const OsclAny * aContext)182 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::QueryInterface(PVMFSessionId s, const PVUuid& aUuid,
183         PVInterface*& aInterfacePtr,
184         const OsclAny* aContext)
185 {
186     PVMFSocketNodeCommand cmd;
187     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
188     return QueueCommandL(cmd);
189 }
190 
RequestPort(PVMFSessionId s,int32 aPortTag,const PvmfMimeString * aPortConfig,const OsclAny * aContext)191 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::RequestPort(PVMFSessionId s, int32 aPortTag, const PvmfMimeString* aPortConfig, const OsclAny* aContext)
192 {
193     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:RequestPort"));
194     PVMFSocketNodeCommand cmd;
195     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_REQUESTPORT, aPortTag, aPortConfig, aContext);
196     return QueueCommandL(cmd);
197 }
198 
ReleasePort(PVMFSessionId s,PVMFPortInterface & aPort,const OsclAny * aContext)199 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
200 {
201     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:ReleasePort"));
202     PVMFSocketNodeCommand cmd;
203     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_RELEASEPORT, aPort, aContext);
204     return QueueCommandL(cmd);
205 }
206 
Init(PVMFSessionId s,const OsclAny * aContext)207 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Init(PVMFSessionId s, const OsclAny* aContext)
208 {
209     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Init"));
210     PVMFSocketNodeCommand cmd;
211     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_INIT, aContext);
212     return QueueCommandL(cmd);
213 }
214 
Prepare(PVMFSessionId s,const OsclAny * aContext)215 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Prepare(PVMFSessionId s, const OsclAny* aContext)
216 {
217     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Init"));
218     PVMFSocketNodeCommand cmd;
219     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_PREPARE, aContext);
220     return QueueCommandL(cmd);
221 }
222 
Start(PVMFSessionId s,const OsclAny * aContext)223 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Start(PVMFSessionId s, const OsclAny* aContext)
224 {
225     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Start"));
226     PVMFSocketNodeCommand cmd;
227     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_START, aContext);
228     return QueueCommandL(cmd);
229 }
230 
Stop(PVMFSessionId s,const OsclAny * aContext)231 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Stop(PVMFSessionId s, const OsclAny* aContext)
232 {
233     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Stop"));
234     PVMFSocketNodeCommand cmd;
235     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_STOP, aContext);
236     return QueueCommandL(cmd);
237 }
238 
Flush(PVMFSessionId s,const OsclAny * aContext)239 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Flush(PVMFSessionId s, const OsclAny* aContext)
240 {
241     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Flush"));
242     PVMFSocketNodeCommand cmd;
243     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_FLUSH, aContext);
244     return QueueCommandL(cmd);
245 }
246 
Pause(PVMFSessionId s,const OsclAny * aContext)247 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Pause(PVMFSessionId s, const OsclAny* aContext)
248 {
249     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Pause"));
250     PVMFSocketNodeCommand cmd;
251     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_PAUSE, aContext);
252     return QueueCommandL(cmd);
253 }
254 
Reset(PVMFSessionId s,const OsclAny * aContext)255 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Reset(PVMFSessionId s, const OsclAny* aContext)
256 {
257     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Reset"));
258     PVMFSocketNodeCommand cmd;
259     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_RESET, aContext);
260     return QueueCommandL(cmd);
261 }
262 
CancelAllCommands(PVMFSessionId s,const OsclAny * aContext)263 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
264 {
265     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:CancelAllCommands"));
266     PVMFSocketNodeCommand cmd;
267     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_CANCELALLCOMMANDS, aContext);
268     return QueueCommandL(cmd);
269 }
270 
CancelCommand(PVMFSessionId s,PVMFCommandId aCmdId,const OsclAny * aContext)271 OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
272 {
273     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:CancelCommand"));
274     PVMFSocketNodeCommand cmd;
275     cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_CANCELCOMMAND, aCmdId, aContext);
276     return QueueCommandL(cmd);
277 }
278 
279 //Port activity handler
HandlePortActivity(const PVMFPortActivity & aActivity)280 void PVMFClientServerSocketNode::HandlePortActivity(const PVMFPortActivity &aActivity)
281 {
282     PVMFClientServerSocketPort* sockPort = NULL;
283     switch (aActivity.iType)
284     {
285         case PVMF_PORT_ACTIVITY_CONNECT:
286         {
287             sockPort = OSCL_STATIC_CAST(PVMFClientServerSocketPort*, aActivity.iPort);
288             OSCL_ASSERT(sockPort && sockPort->iConfig);
289             *iSockConfig = *sockPort->iConfig;
290 
291             setSocketPortMemAllocator(aActivity.iPort, sockPort->iAllocSharedPtr);
292 
293             //Receives may have been blocked waiting on the port to be connected, so check here.
294             if (CanReceive())
295                 StartRecvOperation();
296         }
297         break;
298 
299         case PVMF_PORT_ACTIVITY_INCOMING_MSG:
300         {
301             sockPort = (PVMFClientServerSocketPort*)(aActivity.iPort);
302             OSCL_ASSERT(sockPort && sockPort->iConfig);
303 
304             //Try to process this message now.
305             if (CanProcessIncomingMsg())
306                 ProcessIncomingMsg();
307             //Otherwise, ignore this event now.  Other code will check
308             //the input queue as needed.
309         }
310         break;
311 
312         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
313         {
314             sockPort = (PVMFClientServerSocketPort*)(aActivity.iPort);
315             OSCL_ASSERT(sockPort && sockPort->iConfig);
316             SocketPortConfig& aSockConfig = *sockPort->iConfig;
317 
318             if (aSockConfig.iState.iRecvOperation == EPVSocketPortRecvOperation_WaitOnConnectedPort)
319             {
320                 RecvOperationComplete(PVMFSuccess, NULL);
321             }
322 
323             //Otherwise ignore this event now.  Other code will check connected
324             //port status as needed.
325         }
326         break;
327 
328         default:
329             //all other events can be ignored.
330             break;
331     }
332 }
333 
334 
addRef()335 OSCL_EXPORT_REF void PVMFClientServerSocketNode::addRef()
336 {
337     ++iExtensionRefCount;
338 }
339 
removeRef()340 OSCL_EXPORT_REF void PVMFClientServerSocketNode::removeRef()
341 {
342     --iExtensionRefCount;
343 }
344 
queryInterface(const PVUuid & uuid,PVInterface * & iface)345 OSCL_EXPORT_REF bool PVMFClientServerSocketNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
346 {
347     OSCL_UNUSED_ARG(uuid);
348     OSCL_UNUSED_ARG(iface);
349     return false;
350 }
351 
Run()352 void PVMFClientServerSocketNode::Run()
353 {
354     //Process node commands
355     while (CanProcessCommand())
356         ProcessCommand(iPendingCmdQueue, iPendingCmdQueue.front());
357 }
358 
359 
CanProcessCommand()360 bool PVMFClientServerSocketNode::CanProcessCommand()
361 {
362     return (!iPendingCmdQueue.empty()
363             && (iCurrentCmdQueue.empty()
364                 || (iPendingCmdQueue.front().hipri() && iCancelCmdQueue.empty())));
365 }
366 
367 //Process an input command.
ProcessCommand(PVMFSocketNodeCmdQ & aCmdQ,PVMFSocketNodeCommand & aCmd)368 void PVMFClientServerSocketNode::ProcessCommand(PVMFSocketNodeCmdQ& aCmdQ, PVMFSocketNodeCommand& aCmd)
369 {
370     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFSocketNodeCommand::ProcessCommand() in"));
371 
372     PVMFStatus status = PVMFFailure;
373     iCommandErrorCode = PVMFSocketNodeErrorEventStart; //no error
374 
375     if (aCmd.hipri())
376     {
377         //calling logic should prevent multiple cancels in progress.
378         OSCL_ASSERT(iCancelCmdQueue.empty());
379 
380         switch (aCmd.iCmd)
381         {
382             case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
383                 status = DoCancelAllCommands(aCmd);
384                 break;
385 
386             case PVMF_GENERIC_NODE_CANCELCOMMAND:
387                 status = DoCancelCommand(aCmd);
388                 break;
389 
390             default://unknown command type
391                 status = PVMFFailure;
392                 break;
393         }
394 
395         //If the command was not finished in this call, then move it to the
396         //"cancel cmd" queue where it will remain until it is completed.
397         if (status == PVMFPending)
398         {
399             //move the new cmd to the "cancel cmd" queue where it will
400             //remain until complete.
401             int32 err;
402             OSCL_TRY(err, iCancelCmdQueue.StoreL(aCmd););
403 
404             //we reserved space in the CancelCmdQueue already, so
405             //it should not be possible to fail here.
406             OSCL_ASSERT(err == OsclErrNone);
407 
408             //erase the original command
409             aCmdQ.Erase(&aCmd);
410         }
411         else
412         {
413             CommandComplete(aCmdQ, aCmd, status, NULL);
414         }
415     }
416     else
417     {
418         //calling logic should prevent multiple commands in progress.
419         OSCL_ASSERT(iCurrentCmdQueue.empty());
420 
421         OsclAny* eventData = NULL;
422 
423         switch (aCmd.iCmd)
424         {
425             case PVMF_GENERIC_NODE_QUERYUUID:
426                 status = DoQueryUuid(aCmd);
427                 break;
428 
429             case PVMF_GENERIC_NODE_QUERYINTERFACE:
430                 status = DoQueryInterface(aCmd);
431                 break;
432 
433             case PVMF_GENERIC_NODE_REQUESTPORT:
434             {
435                 status = DoRequestPort(aCmd);
436                 eventData = iPVMFPort;
437                 break;
438             }
439 
440             case PVMF_GENERIC_NODE_RELEASEPORT:
441                 status = DoReleasePort(aCmd);
442                 break;
443 
444             case PVMF_GENERIC_NODE_INIT:
445                 status = DoInit(aCmd);
446                 break;
447 
448             case PVMF_GENERIC_NODE_PREPARE:
449                 status = DoPrepare(aCmd);
450                 if (status == PVMFSuccess)
451                 {
452                     ChangeExternalState(EPVMFNodePrepared);
453                 }
454                 break;
455 
456             case PVMF_GENERIC_NODE_START:
457                 status = DoStart(aCmd);
458                 break;
459 
460             case PVMF_GENERIC_NODE_STOP:
461                 status = DoStop(aCmd);
462                 break;
463 
464             case PVMF_GENERIC_NODE_FLUSH:
465                 status = DoFlush(aCmd);
466                 break;
467 
468             case PVMF_GENERIC_NODE_PAUSE:
469                 status = DoPause(aCmd);
470                 break;
471 
472             case PVMF_GENERIC_NODE_RESET:
473                 status = DoReset(aCmd);
474                 break;
475 
476             default://unknown command type
477                 status = PVMFFailure;
478                 break;
479         }
480 
481         if (status == PVMFPending)
482         {
483             int32 err;
484             OSCL_TRY(err, iCurrentCmdQueue.StoreL(aCmd););
485             OSCL_ASSERT(err == OsclErrNone);
486 
487             //erase the original command
488             aCmdQ.Erase(&aCmd);
489         }
490         else
491         {
492             CommandComplete(aCmdQ, aCmd, status, eventData);
493         }
494     }
495 }
496 
497 //Called to complete a node command.
CommandComplete(PVMFSocketNodeCmdQ & aCmdQ,PVMFSocketNodeCommand & aCmd,PVMFStatus aStatus,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)498 void PVMFClientServerSocketNode::CommandComplete(PVMFSocketNodeCmdQ& aCmdQ,
499         PVMFSocketNodeCommand& aCmd,
500         PVMFStatus aStatus,
501         OsclAny* aEventData,
502         PVUuid* aEventUUID,
503         int32* aEventCode)
504 
505 {
506     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
507                     , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
508 
509     bool canProcess = CanProcessCommand();
510 
511     PVMFStatus status = aStatus;
512 
513     if (aStatus == PVMFSuccess)
514     {
515         switch (aCmd.iCmd)
516         {
517             case PVMF_GENERIC_NODE_INIT:
518                 ChangeExternalState(EPVMFNodeInitialized);
519                 break;
520 
521             case PVMF_GENERIC_NODE_PREPARE:
522                 ChangeExternalState(EPVMFNodePrepared);
523                 break;
524 
525             case PVMF_GENERIC_NODE_START:
526                 ChangeExternalState(EPVMFNodeStarted);
527                 break;
528 
529             case PVMF_GENERIC_NODE_STOP:
530                 ChangeExternalState(EPVMFNodePrepared);
531                 break;
532 
533             case PVMF_GENERIC_NODE_PAUSE:
534                 ChangeExternalState(EPVMFNodePaused);
535                 break;
536 
537             case PVMF_GENERIC_NODE_RESET:
538                 ChangeExternalState(EPVMFNodeCreated);
539 
540                 //Complete the reset command.
541                 {
542                     //cleanup all ports.
543                     CleanupPorts();
544                     SetState(EPVMFNodeIdle);
545                 }
546                 break;
547 
548             case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
549                 //Complete the reset command.
550             {
551                 //Since "cancel all" is effectively used as a Reset,
552                 //go ahead and cleanup all ports.
553                 CleanupPorts();
554             }
555             break;
556             default:
557                 break;
558         }
559     }
560 
561     PVInterface* extif = NULL;
562     PVMFBasicErrorInfoMessage* errormsg = NULL;
563     if (aEventUUID && aEventCode)
564     {
565         errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
566         extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
567     }
568     //else if no error input, see if "command error code" was set.
569     else if (iCommandErrorCode != PVMFSocketNodeErrorEventStart)
570     {
571         PVUuid eventuuid = PVMFSocketNodeEventTypeUUID;
572         errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (iCommandErrorCode, eventuuid, NULL));
573         extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
574     }
575 
576     //create response
577     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, status, extif, aEventData);
578     PVMFSessionId session = aCmd.iSession;
579 
580     //Erase the command from the queue.
581     aCmdQ.Erase(&aCmd);
582 
583     //Report completion to the session observer.
584     ReportCmdCompleteEvent(session, resp);
585 
586     if (errormsg)
587     {
588         errormsg->removeRef();
589     }
590     iCommandErrorCode = PVMFSocketNodeErrorEventStart;//reset.
591 
592     //See if there was a pending cancel waiting on the current command to
593     //complete.
594     if (!iCancelCmdQueue.empty()
595             && iCancelCmdQueue.front().iCmd == PVMF_GENERIC_NODE_CANCELCOMMAND)
596     {
597         CommandComplete(iCancelCmdQueue, iCancelCmdQueue.front(), PVMFSuccess);
598     }
599 
600     //May need to resume command handling if the AO was blocked
601     //waiting on asynchronous command completion, but it's unblocked now.
602     if (!canProcess
603             && CanProcessCommand()
604             && IsAdded())
605     {
606         RunIfNotReady();
607     }
608 }
609 
QueueCommandL(PVMFSocketNodeCommand & aCmd)610 PVMFCommandId PVMFClientServerSocketNode::QueueCommandL(PVMFSocketNodeCommand& aCmd)
611 {
612     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::QueueCommandL()"));
613     PVMFCommandId id;
614 
615     id = iPendingCmdQueue.AddL(aCmd);
616 
617     //This may be a processing trigger.
618     //Wakeup the AO if needed.
619     if (IsAdded()
620             && CanProcessCommand())
621     {
622         RunIfNotReady();
623     }
624 
625     return id;
626 }
627 
628 //This is the callback from Oscl Sockets for socket operation completion.
HandleSocketEvent(int32 aId,TPVSocketFxn aFxn,TPVSocketEvent aEvent,int32 aError)629 OSCL_EXPORT_REF  void PVMFClientServerSocketNode::HandleSocketEvent(int32 aId, TPVSocketFxn aFxn, TPVSocketEvent aEvent, int32 aError)
630 {
631     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::HandleSocketEvent() In aId=%d, aFxn=%d, aEvent=%d, aError=%d", aId, aFxn, aEvent, aError));
632 
633     if (iSockConfig && aEvent == EPVSocketSuccess)
634     {
635         PVMFSocketActivity activity((aEvent == EPVSocketSuccess) ? PVMFSuccess : PVMFFailure, aId, aFxn, aEvent, aError);
636 
637         //Call the appropriate handler
638         switch (aFxn)
639         {
640             case EPVSocketRecv:
641                 OSCL_ASSERT(iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_Recv);
642 
643                 RecvOperationComplete(activity.iStatus, &activity);
644                 break;
645 
646             case EPVSocketSend:
647                 OSCL_ASSERT(iSockConfig->iState.iSendOperation == EPVSocketPortSendOperation_Send);
648 
649                 SendOperationComplete(activity.iStatus, &activity);
650                 break;
651 
652             case EPVSocketShutdown:
653                 //OSCL_ASSERT(iSockConfig->iState.iConnectOperation==EPVSocketPortConnectOperation_Shutdown);
654                 SequenceComplete(PVMFSuccess);
655                 //ConnectOperationComplete(activity.iStatus,&activity);
656                 break;
657 
658             default:
659                 OSCL_ASSERT(0);//unexpected
660                 break;
661         }
662     }
663     else if (aEvent == EPVSocketCancel)
664     {
665         switch (aFxn)
666         {
667             case EPVSocketRecv:
668                 if (iSockConfig->iState.iSendOperation == EPVSocketPortSendOperation_Send
669                         && iSockConfig->iState.iSendOperationCanceled == false)
670                 {//if does hv anything to send, cancel it
671                     CancelSendOperation();
672                 }
673                 else
674                 {   //shutdown
675                     CloseSocketConnection();
676                 }
677                 break;
678 
679             case EPVSocketSend:
680                 if (iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_Recv
681                         && iSockConfig->iState.iRecvOperationCanceled == false)
682                 {
683                     CancelRecvOperation();
684                 }
685                 else
686                 {
687                     //shutdown
688                     CloseSocketConnection();
689                 }
690                 break;
691 
692             case EPVSocketShutdown:
693                 //quite difficult to cancel shutdown
694                 break;
695 
696             default:
697                 OSCL_ASSERT(0);//unexpected
698                 break;
699         }
700     }
701     else
702     {//failure
703         switch (aFxn)
704         {
705             case EPVSocketRecv:
706                 iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_None;
707                 iSockConfig->iState.iRecvOperationCanceled = true;
708                 break;
709 
710             case EPVSocketSend:
711                 iSockConfig->iState.iSendOperation = EPVSocketPortSendOperation_None;
712                 iSockConfig->iState.iSendOperationCanceled = true;
713                 break;
714 
715             case EPVSocketShutdown:
716             default:
717                 OSCL_ASSERT(0);//unexpected
718                 break;
719         }
720     }
721 }
722 
723 
724 //Allocate a node port and add it to the port vector.
AddPort(int32 tag)725 PVMFStatus PVMFClientServerSocketNode::AddPort(int32 tag)
726 {
727     iPVMFPort = new PVMFClientServerSocketPort((int32)tag,
728             this,
729             DEFAULT_DATA_QUEUE_CAPACITY,
730             DEFAULT_DATA_QUEUE_CAPACITY,
731             DEFAULT_READY_TO_RECEIVE_THRESHOLD_PERCENT,
732             //the output queue is empty because
733             //this node pushes data directly to the
734             //connecte port's input.
735             0, 0, 0);
736 
737     return PVMFSuccess;
738 }
739 
740 
AllocatePortMemPool(int32 tag,PVMFSocketNodeMemPool * & aMemPool)741 PVMFStatus PVMFClientServerSocketNode::AllocatePortMemPool(int32 tag, PVMFSocketNodeMemPool* & aMemPool)
742 {
743     aMemPool = NULL;
744     OsclAny *MemPtr = NULL;
745     MemPtr = iAlloc.ALLOCATE(sizeof(PVMFSocketNodeMemPool));
746     if (MemPtr == NULL)
747     {
748         return PVMFErrNoMemory;
749     }
750 
751     int32 errcode = 0;
752     OSCL_TRY(errcode, aMemPool = OSCL_PLACEMENT_NEW(MemPtr, PVMFSocketNodeMemPool(SNODE_DEFAULT_NUMBER_MEDIADATA_IN_MEMPOOL);));
753     if (errcode != OsclErrNone)
754     {
755         PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::DoRequestPort: PVMFSocketNodeMemPool Construct Failed Ln %d", errcode, __LINE__));
756         iAlloc.deallocate(MemPtr);
757         return PVMFErrNoMemory;
758     }
759 
760     aMemPool->iPortTag = tag;
761     return PVMFSuccess;
762 }
763 
764 
CancelSendOperation()765 PVMFStatus PVMFClientServerSocketNode::CancelSendOperation()
766 {
767     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::CancelSendOperation()"));
768 
769     PVMFStatus status = PVMFSuccess;
770 
771     switch (iSockConfig->iState.iSendOperation)
772     {
773         case EPVSocketPortSendOperation_None:
774             break;
775 
776         case EPVSocketPortSendOperation_Send:
777             if (iSockConfig->iTCPSocket)
778             {
779                 if (!iSockConfig->iState.iSendOperationCanceled)
780                 {
781                     iSockConfig->iState.iSendOperationCanceled = true;
782                     iSockConfig->iTCPSocket->CancelSend();
783                 }
784                 status = PVMFPending;
785                 //wait on send to complete in HandleSocketEvent
786             }
787             break;
788 
789         default:
790             OSCL_ASSERT(0);
791             status = PVMFFailure;
792             break;
793     }
794     return status;
795 }
796 
797 
DoStopNodeActivity()798 PVMFStatus PVMFClientServerSocketNode::DoStopNodeActivity()
799 {
800     if (iNumStopPortActivityPending > 0)
801         return PVMFPending;
802 
803     //Stop socket activity on all ports.
804     uint32 nPortsPending = 0;
805     if (iSockConfig)
806     {
807         // discard any saved socket activity events
808         iSockConfig->iSocketRecvActivity.iValid = false;
809 
810         //if a request port is going on, be sure to complete the command,
811         //although we will interrupt the current processing.
812         if (iSockConfig->iState.iSequence == EPVSocketPortSequence_RequestPort
813                 && iCurrentCmdQueue.size()
814                 && iCurrentCmdQueue.front().iCmd == PVMF_GENERIC_NODE_REQUESTPORT)
815         {
816             CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFErrCancelled, NULL);
817         }
818 
819         //if a cleanup is already underway, just keep waiting for it to complete,
820         //else start a new sequence
821         if (iSockConfig->iState.iSequence == EPVSocketPortSequence_SocketCleanup)
822         {
823             nPortsPending++;
824         }
825         else if (StartSequence(iSockConfig->iState.iSequence = EPVSocketPortSequence_SocketCleanup) == PVMFPending)
826         {
827             nPortsPending++;
828         }
829     }
830 
831     if (nPortsPending > 0)
832         iNumStopPortActivityPending = nPortsPending;
833 
834     if (iNumStopPortActivityPending > 0)
835         return PVMFPending; //wait on completion in SequenceComplete.
836 
837     return PVMFSuccess;
838 }
839 
840 //Flush is implemented for this node, but hasn't been tested.
DoFlush(PVMFSocketNodeCommand & aCmd)841 PVMFStatus PVMFClientServerSocketNode::DoFlush(PVMFSocketNodeCommand& aCmd)
842 {
843     OSCL_UNUSED_ARG(aCmd);
844     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoFlush() In"));
845 
846     if ((iInterfaceState != EPVMFNodeStarted) && (iInterfaceState != EPVMFNodePaused))
847     {
848         return PVMFErrInvalidState;
849     }
850 
851     PVMFStatus status = PVMFSuccess;
852     {
853         iPVMFPort->SuspendInput();
854         if (status != PVMFPending
855                 && iPVMFPort->IncomingMsgQueueSize() > 0)
856         {
857             status = PVMFPending;//Wait on this queue to empty.
858             //Completion is detected in SequenceComplete.
859         }
860     }
861     return status;
862 }
863 
864 //Pause is a do-nothing for this node.
DoPause(PVMFSocketNodeCommand & aCmd)865 PVMFStatus PVMFClientServerSocketNode::DoPause(PVMFSocketNodeCommand& aCmd)
866 {
867     OSCL_UNUSED_ARG(aCmd);
868     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoPause() In"));
869 
870     if (iInterfaceState == EPVMFNodePaused)
871     {
872         return PVMFSuccess;
873     }
874 
875     if (iInterfaceState != EPVMFNodeStarted)
876     {
877         return PVMFErrInvalidState;
878     }
879 
880     return PVMFSuccess;
881 }
882 
883 
DoReset(PVMFSocketNodeCommand & aCmd)884 PVMFStatus PVMFClientServerSocketNode::DoReset(PVMFSocketNodeCommand& aCmd)
885 {
886     OSCL_UNUSED_ARG(aCmd);
887     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoReset()"));
888 
889     /* This node allows a reset from any state */
890 
891     return DoStopNodeActivity();
892 }
893 
DoQueryUuid(PVMFSocketNodeCommand & aCmd)894 PVMFStatus PVMFClientServerSocketNode::DoQueryUuid(PVMFSocketNodeCommand& aCmd)
895 {
896     OSCL_UNUSED_ARG(aCmd);
897     /*  //This node supports Query UUID from any state
898 
899         OSCL_String* mimetype;
900         Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
901         bool exactmatch;
902         aCmd.PVMFSocketNodeCommandBase::Parse(mimetype,uuidvec,exactmatch);
903 
904         //Try to match the input mimetype against any of
905         //the custom interfaces for this node
906 
907         //Match against custom interface1...
908         if (*mimetype==PVMF_SOCKET_NODE_EXTENSION_INTERFACE_MIMETYPE
909             //also match against base mimetypes for custom interface1,
910             //unless exactmatch is set.
911             || (!exactmatch && *mimetype==PVMF_SOCKET_NODE_MIMETYPE)
912             || (!exactmatch && *mimetype==PVMF_SOCKET_NODE_BASEMIMETYPE))
913         {
914 
915             PVUuid uuid(PVMF_SOCKET_NODE_EXTENSION_INTERFACE_UUID);
916             uuidvec->push_back(uuid);
917         }*/
918     return PVMFSuccess;
919 }
920 
921 
DoQueryInterface(PVMFSocketNodeCommand & aCmd)922 PVMFStatus PVMFClientServerSocketNode::DoQueryInterface(PVMFSocketNodeCommand&  aCmd)
923 {
924     OSCL_UNUSED_ARG(aCmd);
925     return PVMFSuccess;
926 }
927 
DoRequestPort(PVMFSocketNodeCommand & aCmd)928 PVMFStatus PVMFClientServerSocketNode::DoRequestPort(PVMFSocketNodeCommand& aCmd)
929 {
930     OSCL_UNUSED_ARG(aCmd);
931     //retrieve port tag.
932     int32 tag;
933     OSCL_String* portconfig;
934     aCmd.PVMFSocketNodeCommandBase::Parse(tag, portconfig);
935 
936     PVMFStatus status = AddPort(tag);
937     if (status != PVMFSuccess)
938         return status;
939 
940     //create the socket config
941     iSockConfig = OSCL_NEW(SocketPortConfig, ());
942     iPVMFPort->iConfig = iSockConfig;
943     iSockConfig->iPVMFPort = iPVMFPort;
944 
945     iSockConfig->iContainer = this;
946     iSockConfig->iSockId = iSocketID++;
947     iSockConfig->iTag = tag;
948     iSockConfig->iTCPSocket = iSocketHandle;
949 
950     //create the mem pool
951     PVMFSocketNodeMemPool* memPool;
952     status = AllocatePortMemPool(tag, memPool);
953     if (status == PVMFSuccess)
954         iSockConfig->iMemPool = memPool;
955     return status;
956 }
957 
958 
959 //Release ports is a do-nothing for this node.
DoReleasePort(PVMFSocketNodeCommand & aCmd)960 PVMFStatus PVMFClientServerSocketNode::DoReleasePort(PVMFSocketNodeCommand& aCmd)
961 {
962     OSCL_UNUSED_ARG(aCmd);
963     return PVMFSuccess;
964 }
965 
966 
DoInit(PVMFSocketNodeCommand & aCmd)967 PVMFStatus PVMFClientServerSocketNode::DoInit(PVMFSocketNodeCommand& aCmd)
968 {
969     OSCL_UNUSED_ARG(aCmd);
970     if (iInterfaceState != EPVMFNodeIdle)
971     {
972         return PVMFErrInvalidState;
973     }
974     return PVMFSuccess;
975 }
976 
977 
978 //Prepare is a do-nothing for this node.
DoPrepare(PVMFSocketNodeCommand & aCmd)979 PVMFStatus PVMFClientServerSocketNode::DoPrepare(PVMFSocketNodeCommand& aCmd)
980 {
981     OSCL_UNUSED_ARG(aCmd);
982     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::DoPrepare() In"));
983 
984     if (iInterfaceState != EPVMFNodeInitialized)
985     {
986         return PVMFErrInvalidState;
987     }
988     return PVMFSuccess;
989 }
990 
991 
DoStart(PVMFSocketNodeCommand & aCmd)992 PVMFStatus PVMFClientServerSocketNode::DoStart(PVMFSocketNodeCommand& aCmd)
993 {
994     OSCL_UNUSED_ARG(aCmd);
995     if (iInterfaceState == EPVMFNodeStarted)
996     {
997         return PVMFSuccess;//already started.
998     }
999 
1000     if (iInterfaceState != EPVMFNodePrepared &&
1001             iInterfaceState != EPVMFNodePaused)
1002     {
1003         return PVMFErrInvalidState;
1004     }
1005 
1006     TPVMFNodeInterfaceState curState = iInterfaceState;
1007     ChangeExternalState(EPVMFNodeStarted);
1008 
1009     PVMFStatus status = PVMFSuccess;
1010     if (iSockConfig)
1011     {
1012         //Start handling incoming messages
1013         if (CanProcessIncomingMsg())
1014             ProcessIncomingMsg();
1015 
1016         //Start the receives.
1017         if (CanReceive())
1018         {
1019             status = StartRecvOperation();
1020             if (status == PVMFPending)
1021             {
1022                 status = PVMFSuccess;
1023             }
1024             else if (status != PVMFSuccess)
1025             {
1026                 ChangeExternalState(curState);
1027             }
1028         }
1029     }
1030     return status;
1031 }
1032 
1033 
1034 
DoStop(PVMFSocketNodeCommand & aCmd)1035 PVMFStatus PVMFClientServerSocketNode::DoStop(PVMFSocketNodeCommand& aCmd)
1036 {
1037     OSCL_UNUSED_ARG(aCmd);
1038     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoStop() In"));
1039 
1040     if ((iInterfaceState != EPVMFNodeStarted) && (iInterfaceState != EPVMFNodePaused))
1041     {
1042         return PVMFErrInvalidState;
1043     }
1044     return PVMFSuccess;
1045 }
1046 
1047 
DoCancelCommand(PVMFSocketNodeCommand & aCmd)1048 PVMFStatus PVMFClientServerSocketNode::DoCancelCommand(PVMFSocketNodeCommand& aCmd)
1049 {
1050     OSCL_UNUSED_ARG(aCmd);
1051     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoCancelCommand() Called"));
1052 
1053     // extract the command ID from the parameters.
1054     PVMFCommandId cmdId;
1055     aCmd.PVMFSocketNodeCommandBase::Parse(cmdId);
1056 
1057     if (!iCurrentCmdQueue.empty()
1058             && iCurrentCmdQueue.front().iId == cmdId)
1059     {
1060         return DoCancelCurrentCommand(iCurrentCmdQueue, iCurrentCmdQueue.front());
1061         //wait on current command to complete.  The cancel command
1062         //will ultimately be completed in the "CommandComplete" for the current command.
1063     }
1064 
1065     {
1066         // start at element 1 since this cancel command is element 0
1067         PVMFSocketNodeCommand* cmd = iPendingCmdQueue.FindById(cmdId, 1);
1068         if (cmd)
1069         {
1070             // cancel the queued command.  Note this will complete out-of-order.
1071             CommandComplete(iPendingCmdQueue, *cmd, PVMFErrCancelled);
1072             // no further action is required.
1073             return PVMFSuccess;
1074         }
1075     }
1076 
1077     //this command fails if the given command is not queued or in progress.
1078     return PVMFErrArgument;
1079 }
1080 
DoCancelAllCommands(PVMFSocketNodeCommand & aCmd)1081 PVMFStatus PVMFClientServerSocketNode::DoCancelAllCommands(PVMFSocketNodeCommand& aCmd)
1082 {
1083     OSCL_UNUSED_ARG(aCmd);
1084     PVMFStatus status = DoStopNodeActivity();
1085 
1086     if (!iCurrentCmdQueue.empty())
1087         CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFErrCancelled);
1088 
1089     //Cancel all other pending commands, except for this one which is
1090     //element 0 in the queue
1091     for (uint32 i = 1; i < iPendingCmdQueue.size(); i++)
1092         CommandComplete(iPendingCmdQueue, iPendingCmdQueue[i], PVMFErrCancelled);
1093 
1094     //May need to wait on completion of StopNodeActivity.
1095     return status;
1096 }
1097 
1098 
DoCancelCurrentCommand(PVMFSocketNodeCmdQ & aCmdQ,PVMFSocketNodeCommand & aCmd)1099 PVMFStatus PVMFClientServerSocketNode::DoCancelCurrentCommand(PVMFSocketNodeCmdQ& aCmdQ, PVMFSocketNodeCommand& aCmd)
1100 {
1101     OSCL_UNUSED_ARG(aCmdQ);
1102     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoCancelCurrentCommand()"));
1103     switch (aCmd.iCmd)
1104     {
1105 
1106         case PVMF_GENERIC_NODE_REQUESTPORT:
1107             //there may be a connect operation pending-- cancel it.
1108         {
1109             if (iPVMFPort)
1110             {
1111                 //SocketPortConfig* iSockConfig=iRequestedPort->iConfig;
1112                 if (iSockConfig)
1113                 {
1114                     //  CancelConnectOperation();
1115                     return PVMFPending;//wait on the operation to complete
1116                     //in HandleSocketEvent or HandleDNSEvent
1117                 }
1118             }
1119             //shouldn't get here...
1120             return PVMFFailure;
1121         }
1122         break;
1123 
1124         case PVMF_GENERIC_NODE_RESET:
1125             //it's too complicated to cancel a reset, so just wait on completion
1126             return PVMFPending;
1127 
1128         case PVMF_GENERIC_NODE_FLUSH:
1129             //to cancel a flush, just discard all remaining port messages
1130             //and keep waiting on completion of current message.
1131         {
1132             iPVMFPort->ClearMsgQueues();
1133         }
1134         return PVMFPending;//keep waiting on flush completion in SequenceComplete.
1135 
1136         case PVMF_GENERIC_NODE_CANCELCOMMAND:
1137         case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
1138             //these have asynchronous completion, but the command handling prevents
1139             //processing a cancel during a cancel, so we shouldn't get here.
1140             OSCL_ASSERT(0);
1141             return PVMFFailure;
1142 
1143         default:
1144             //no other node commands have asynchronous completion, so this is unexpected.
1145             OSCL_ASSERT(0);
1146             return PVMFFailure;
1147     }
1148 }
1149 
CancelRecvOperation()1150 PVMFStatus PVMFClientServerSocketNode::CancelRecvOperation()
1151 {
1152     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::CancelRecvOperation() In"));
1153 
1154     PVMFStatus status = PVMFSuccess;
1155 
1156     switch (iSockConfig->iState.iRecvOperation)
1157     {
1158         case EPVSocketPortRecvOperation_None:
1159             break;
1160 
1161         case EPVSocketPortRecvOperation_Recv:
1162             if (iSockConfig->iTCPSocket)
1163             {
1164                 if (!iSockConfig->iState.iRecvOperationCanceled)
1165                 {
1166                     iSockConfig->iState.iRecvOperationCanceled = true;
1167                     iSockConfig->iTCPSocket->CancelRecv();
1168                 }
1169                 status = PVMFPending;
1170                 //wait on recv to complete in HandleSocketEvent
1171             }
1172             break;
1173 
1174         case EPVSocketPortRecvOperation_WaitOnConnectedPort:
1175             //just clear the state
1176             iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_None;
1177             //also discard the received data and the associated recv activity
1178             if (iSockConfig->iSocketRecvActivity.iValid)
1179                 iSockConfig->iSocketRecvActivity.iValid = false;
1180             if (iSockConfig->iPendingRecvMediaData.GetRep())
1181                 iSockConfig->iPendingRecvMediaData.Unbind();
1182             break;
1183 
1184         case EPVSocketPortRecvOperation_WaitOnMemory:
1185             if (iSockConfig->iMemPool != NULL)
1186                 iSockConfig->iMemPool->CancelFreeChunkAvailableCallback();
1187             //clear the state
1188             iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_None;
1189             break;
1190 
1191         default:
1192             OSCL_ASSERT(0);//add code for this case
1193             status = PVMFFailure;
1194             break;
1195     }
1196     return status;
1197 }
1198 
1199 //a memory pool callback
freechunkavailable(OsclAny * aContextData)1200 void SocketPortConfig::freechunkavailable(OsclAny* aContextData)
1201 {
1202     OSCL_UNUSED_ARG(aContextData);
1203     //complete the "wait on memory" state
1204     if (iState.iRecvOperation == EPVSocketPortRecvOperation_WaitOnMemory)
1205     {
1206         iContainer->RecvOperationComplete(PVMFSuccess, NULL);   //*this,
1207     }
1208 }
1209 
1210 
CleanupTCP()1211 void PVMFClientServerSocketNode::CleanupTCP()
1212 {
1213     //cleanup media messages
1214     if (iSockConfig->iPendingRecvMediaData.GetRep() != NULL)
1215     {
1216         iSockConfig->iPendingRecvMediaData.Unbind();
1217 
1218     }
1219     if (iSockConfig->iPendingSendMediaData.GetRep() != NULL)
1220     {
1221         iSockConfig->iPendingSendMediaData.Unbind();
1222     }
1223 }
1224 
1225 
CleanupPorts()1226 void PVMFClientServerSocketNode::CleanupPorts()
1227 {
1228     if (iPVMFPort)
1229     {
1230         SocketPortConfig* it = iPVMFPort->iConfig;
1231         if (it)
1232         {
1233             //unlink the PVMFPort so we won't try to send any EOS msg
1234             //during the TCP cleanup.
1235             it->iPVMFPort = NULL;
1236             it->CleanupMemPools();
1237             OSCL_DELETE(it);
1238             iPVMFPort->iConfig = NULL;
1239         }
1240 
1241         iPVMFPort->Disconnect();
1242         delete iPVMFPort;
1243         iPVMFPort = NULL;
1244     }
1245 }
1246 
1247 
PVMFSocketNodeMemPool(uint32 aMemPoolNumBufs)1248 PVMFSocketNodeMemPool::PVMFSocketNodeMemPool(uint32 aMemPoolNumBufs)
1249         : iMediaDataMemPool(NULL)
1250 {
1251     iMediaDataMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (aMemPoolNumBufs, MEDIA_DATA_CLASS_SIZE));
1252     iInternalAlloc = NULL;
1253 }
1254 
1255 
DoSetSocketPortMemAllocator(PVLogger * aLogger,OsclSharedPtr<PVMFSharedSocketDataBufferAlloc> aAlloc)1256 void SocketPortConfig::DoSetSocketPortMemAllocator(PVLogger* aLogger, OsclSharedPtr<PVMFSharedSocketDataBufferAlloc> aAlloc)
1257 {
1258     if (aAlloc.GetRep())
1259     {
1260         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, aLogger, PVLOGMSG_INFO, (0, "SocketPortConfig::DoSetSocketPortMemAllocator() Using input mem allocator"));
1261         /*
1262          * Deletion of any previously created allocators is handled as part of
1263          * reset / node delete. So just re-assign the shared ptr here.
1264          */
1265         if (iMemPool->iSocketAllocSharedPtr.GetRep() != NULL)
1266         {
1267             iMemPool->iSocketAllocSharedPtr.Unbind();
1268         }
1269         iMemPool->iSocketAllocSharedPtr = aAlloc;
1270     }
1271     else
1272     {
1273         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, aLogger, PVLOGMSG_INFO, (0, "SocketPortConfig::DoSetSocketPortMemAllocator() no mem allocator. Create one"));
1274 
1275         uint aligned_socket_alloc_size = oscl_mem_aligned_size(sizeof(PVMFSMSharedBufferAllocWithReSize));
1276 
1277         uint aligned_refcnt_size =  oscl_mem_aligned_size(sizeof(OsclRefCounterSA<PVMFSharedSocketDataBufferAllocCleanupSA>));
1278 
1279         OsclMemAllocator my_alloc;
1280         uint8 *my_ptr = (uint8*) my_alloc.ALLOCATE(aligned_refcnt_size + aligned_socket_alloc_size);
1281         OsclRefCounter *my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA<PVMFSharedSocketDataBufferAllocCleanupSA>(my_ptr));
1282         my_ptr += aligned_refcnt_size;
1283 
1284         // allow one resize for a maximum mempool size of TCP_BUFFER_SIZE*TCP_BUFFER_IN_MEMPOOL
1285         iMemPool->iInternalAlloc = OSCL_NEW(PVMFSMSharedBufferAllocWithReSize, (
1286                                                 iContainer->iMaxTcpRecvBufferSize * (iContainer->iMaxTcpRecvBufferCount - 1), "TCPsocketBuffer",
1287                                                 1, iContainer->iMaxTcpRecvBufferSize));
1288 
1289         PVMFSharedSocketDataBufferAlloc *alloc_ptr = OSCL_PLACEMENT_NEW(my_ptr, PVMFSharedSocketDataBufferAlloc(iMemPool->iInternalAlloc));
1290 
1291         OsclSharedPtr<PVMFSharedSocketDataBufferAlloc> shared_alloc(alloc_ptr, my_refcnt);
1292         iMemPool->iSocketAllocSharedPtr = shared_alloc;
1293     }
1294 }
1295 
CleanupMemPools()1296 void SocketPortConfig::CleanupMemPools()
1297 {
1298     if (iMemPool->iInternalAlloc != NULL)
1299     {
1300         iMemPool->iInternalAlloc->DecrementKeepAliveCount();
1301         uint32 numOutStandingBuffers =
1302             iMemPool->iInternalAlloc->getNumOutStandingBuffers();
1303         if (numOutStandingBuffers == 0)
1304         {
1305             OSCL_DELETE((iMemPool->iInternalAlloc));
1306             iMemPool->iInternalAlloc = NULL;
1307         }
1308     }
1309     PVMFSocketNodeAllocator alloc;
1310     iMemPool->~PVMFSocketNodeMemPool();
1311     alloc.deallocate((OsclAny*)(iMemPool));
1312     iMemPool = NULL;
1313 }
1314 
1315 
ReportErrorEvent(PVMFEventType aEventType,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)1316 void PVMFClientServerSocketNode::ReportErrorEvent(PVMFEventType aEventType,
1317         OsclAny* aEventData,
1318         PVUuid* aEventUUID,
1319         int32* aEventCode)
1320 {
1321     if (aEventUUID && aEventCode)
1322     {
1323         PVMFBasicErrorInfoMessage* eventmsg =
1324             OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
1325         PVMFAsyncEvent asyncevent(PVMFErrorEvent,
1326                                   aEventType,
1327                                   NULL,
1328                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
1329                                   aEventData,
1330                                   NULL,
1331                                   0);
1332         PVMFNodeInterface::ReportErrorEvent(asyncevent);
1333         eventmsg->removeRef();
1334     }
1335     else
1336     {
1337         PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
1338     }
1339 }
1340 
ReportInfoEvent(PVMFEventType aEventType,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)1341 void PVMFClientServerSocketNode::ReportInfoEvent(PVMFEventType aEventType,
1342         OsclAny* aEventData,
1343         PVUuid* aEventUUID,
1344         int32* aEventCode)
1345 {
1346     if (aEventUUID && aEventCode)
1347     {
1348         PVMFBasicErrorInfoMessage* eventmsg =
1349             OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
1350         PVMFAsyncEvent asyncevent(PVMFInfoEvent,
1351                                   aEventType,
1352                                   NULL,
1353                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
1354                                   aEventData,
1355                                   NULL,
1356                                   0);
1357         PVMFNodeInterface::ReportInfoEvent(asyncevent);
1358         eventmsg->removeRef();
1359     }
1360     else
1361     {
1362         PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
1363     }
1364 }
1365 
setSocketPortMemAllocator(PVMFPortInterface * aInPort,OsclSharedPtr<PVMFSharedSocketDataBufferAlloc> aAlloc)1366 OSCL_EXPORT_REF bool PVMFClientServerSocketNode::setSocketPortMemAllocator(PVMFPortInterface* aInPort,
1367         OsclSharedPtr<PVMFSharedSocketDataBufferAlloc> aAlloc)
1368 {
1369 
1370     PVMFClientServerSocketPort* aPort = OSCL_STATIC_CAST(PVMFClientServerSocketPort*, aInPort);
1371     SocketPortConfig* tmpSockConfig = (aPort) ? aPort->iConfig : NULL;
1372     if (NULL != tmpSockConfig)
1373     {
1374         tmpSockConfig->DoSetSocketPortMemAllocator(iLogger, aAlloc);
1375         return true;
1376     }
1377     return false;
1378 }
1379 
1380 
CanProcessIncomingMsg()1381 bool PVMFClientServerSocketNode::CanProcessIncomingMsg()
1382 {
1383     return
1384         //node is started
1385         iInterfaceState == EPVMFNodeStarted
1386         //port has input messages
1387         && iSockConfig->iPVMFPort && iSockConfig->iPVMFPort->IncomingMsgQueueSize() > 0
1388         //port is not busy with any sequence
1389         && iSockConfig->iState.iSequence == EPVSocketPortSequence_None;
1390 }
1391 
1392 
ProcessIncomingMsg()1393 void PVMFClientServerSocketNode::ProcessIncomingMsg()
1394 {
1395     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::ProcessIncomingMsg: aPort=0x%x", iSockConfig->iPVMFPort));
1396 
1397     //Dequeue the incoming message
1398     PVMFSharedMediaMsgPtr msg;
1399     PVMFStatus status = iSockConfig->iPVMFPort->DequeueIncomingMsg(msg);
1400     if (status != PVMFSuccess)
1401     {
1402         PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::ProcessIncomingDataMsg: Error - DequeueIncomingMsg failed"));
1403         ReportErrorEvent(PVMFErrPortProcessing);
1404         return ;
1405     }
1406 
1407     OSCL_ASSERT(iSockConfig->iState.iSequence == EPVSocketPortSequence_None);
1408 
1409     //Handle 3 types of messages
1410     if (msg->getFormatID() == PVMF_MEDIA_CMD_SOCKET_DISCONNECT_FORMAT_ID)
1411     {
1412         //Disconnect message
1413         StartSequence(EPVSocketPortSequence_InputDisconnectMsg);
1414     }
1415     else if (msg->getFormatID() == PVMF_MEDIA_MSG_DATA_FORMAT_ID)
1416     {
1417         //Start the sequence
1418         StartSequence(EPVSocketPortSequence_InputDataMsg, (OsclAny*)&msg);
1419     }
1420     else
1421     {
1422         //unexpected message type
1423         ReportErrorEvent(PVMFErrPortProcessing);
1424     }
1425 }
1426 
1427 
StartSendOperation(PVMFSharedMediaMsgPtr & aMsg)1428 PVMFStatus PVMFClientServerSocketNode::StartSendOperation(PVMFSharedMediaMsgPtr& aMsg)
1429 {
1430     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::StartSendOperation() In"));
1431 
1432     //caller should have verified we can send now.
1433     OSCL_ASSERT(iSockConfig->iState.iSendOperation == EPVSocketPortSendOperation_None);
1434 
1435     //caller should provide a media data message as input
1436     OSCL_ASSERT(aMsg->getFormatID() == PVMF_MEDIA_MSG_DATA_FORMAT_ID);
1437 
1438     //there should be either a UDP or TCP socket on this port
1439     if (!iSockConfig->iTCPSocket)
1440     {
1441         return PVMFFailure;
1442     }
1443 
1444     // Retrieve memory fragment to write to
1445     if (iSockConfig->iPendingSendMediaData.GetRep())
1446         iSockConfig->iPendingSendMediaData.Unbind();
1447 
1448     convertToPVMFMediaData(iSockConfig->iPendingSendMediaData, aMsg);
1449     OsclRefCounterMemFrag refCtrMemFragOut;
1450     iSockConfig->iPendingSendMediaData->getMediaFragment(0, refCtrMemFragOut);
1451 
1452     PVMFStatus status = PVMFFailure;
1453 
1454     if (iSockConfig->iTCPSocket)
1455     {
1456         iSockConfig->iState.iSendOperation = EPVSocketPortSendOperation_Send;
1457 
1458         TPVSocketEvent retVal = iSockConfig->iTCPSocket->Send((uint8*)refCtrMemFragOut.getMemFragPtr(),
1459                                 refCtrMemFragOut.getMemFragSize(),
1460                                 TIMEOUT_SEND);
1461 
1462         if (retVal == EPVSocketPending)
1463             status = PVMFPending;//wait on HandleSocketEvent callback
1464         else
1465             status = PVMFFailure;
1466 
1467         if (PVMFPending != status)
1468         {
1469             PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::StartSendOperation: TCP - Error. status=%d", status));
1470         }
1471     }
1472 
1473     //Handle synchronous completion or failures
1474     if (status != PVMFPending)
1475         status = SendOperationComplete(status, NULL);
1476 
1477     return status;
1478 }
1479 
1480 
SendOperationComplete(PVMFStatus aStatus,PVMFSocketActivity * aSocketActivity)1481 PVMFStatus PVMFClientServerSocketNode::SendOperationComplete(PVMFStatus aStatus, PVMFSocketActivity* aSocketActivity)
1482 {
1483     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::SendOperationComplete()"));
1484 
1485     OSCL_ASSERT(aStatus != PVMFPending);
1486 
1487     PVMFStatus status = aStatus;
1488 
1489     //Update the send state
1490     TPVSocketPortSendOperation curOp = iSockConfig->iState.iSendOperation;
1491     iSockConfig->iState.iSendOperation = EPVSocketPortSendOperation_None;
1492     iSockConfig->iState.iSendOperationStatus = aStatus;
1493     iSockConfig->iState.iSendOperationCanceled = false;
1494 
1495     //Release the media buffer after each send operation, regardless of success/fail.
1496     if (iSockConfig->iPendingSendMediaData.GetRep() != NULL)
1497         iSockConfig->iPendingSendMediaData.Unbind();
1498 
1499     if (aSocketActivity)
1500     {
1501         //Datapath logging
1502         switch (aSocketActivity->iEvent)
1503         {
1504             case EPVSocketSuccess:
1505                 //PVMF_SOCKETNODE_LOGDATATRAFFIC_I((0,"PVMFClientServerSocketNode::SendOperationComplete - Success - SockId=%d, Mime=%s", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
1506                 break;
1507             case EPVSocketTimeout:
1508                 //PVMF_SOCKETNODE_LOGDATATRAFFIC_E((0,"PVMFClientServerSocketNode::SendOperationComplete - TimeOut - SockId=%d, Mime=%s", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
1509                 break;
1510             case EPVSocketFailure:
1511                 //PVMF_SOCKETNODE_LOGDATATRAFFIC_E((0,"PVMFClientServerSocketNode::SendOperationComplete - Failed - SockId=%d, Mime=%s", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
1512                 break;
1513             case EPVSocketCancel:
1514                 //PVMF_SOCKETNODE_LOGDATATRAFFIC_E((0,"PVMFClientServerSocketNode::SendOperationComplete - Cancelled - SockId=%d, Mime=%s", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
1515                 break;
1516             default:
1517                 OSCL_ASSERT(0);
1518                 break;
1519         }
1520     }
1521 
1522     //report TCP errors.
1523     if (aStatus != PVMFSuccess
1524             && curOp == EPVSocketPortSendOperation_Send)
1525     {
1526         ReportSocketNodeError(PVMFErrResource, PVMFSocketNodeErrorTCPSocketSendError);
1527     }
1528 
1529     //This completes an input data message sequence
1530     if (iSockConfig->iState.iSequence == EPVSocketPortSequence_InputDataMsg)
1531         SequenceComplete(aStatus);
1532     return status;
1533 }
1534 
1535 
CanReceive()1536 bool PVMFClientServerSocketNode::CanReceive()
1537 {
1538     return
1539         //node is started
1540         iInterfaceState == EPVMFNodeStarted
1541         //port is connected
1542         && iSockConfig->iPVMFPort && iSockConfig->iPVMFPort->IsConnected()
1543         //socket exists (gets created during request port or connect sequence)
1544         && (iSockConfig->iTCPSocket)
1545         //port is not busy with any sequence other than sending data
1546         && (iSockConfig->iState.iSequence == EPVSocketPortSequence_None
1547             || iSockConfig->iState.iSequence == EPVSocketPortSequence_InputDataMsg)
1548         //port is not busy with any receive operation.
1549         && iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_None
1550         //there's no node stop going on.
1551         && iNumStopPortActivityPending < 0;
1552 }
1553 
1554 //Enter the "wait on memory" state
StartRecvWaitOnMemory(int32 aSize)1555 void PVMFClientServerSocketNode::StartRecvWaitOnMemory(int32 aSize)
1556 {
1557     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::StartRecvWaitOnMemory() In"));
1558 
1559     iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_WaitOnMemory;
1560 
1561     if (aSize)
1562     {//wait on data buffer
1563         iSockConfig->iMemPool->notifyfreechunkavailable(*iSockConfig, aSize, NULL);
1564     }
1565     else
1566     {//wait on media data wrapper
1567         iSockConfig->iMemPool->iMediaDataMemPool->notifyfreechunkavailable(*iSockConfig, NULL);
1568     }
1569 }
1570 
1571 //Enter the "wait on connected port" state
StartRecvWaitOnConnectedPort(PVMFSocketActivity & aSocketActivity)1572 void PVMFClientServerSocketNode::StartRecvWaitOnConnectedPort(PVMFSocketActivity& aSocketActivity)
1573 {
1574     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::StartRecvWaitOnConnectedPort() In"));
1575 
1576     //outgoing queue is busy-- must queue this event for later processing
1577     switch (aSocketActivity.iFxn)
1578     {
1579         case EPVSocketRecv:
1580         case EPVSocketRecvFrom:
1581             iSockConfig->iSocketRecvActivity.Set(aSocketActivity.iStatus
1582                                                  , aSocketActivity.iId
1583                                                  , aSocketActivity.iFxn
1584                                                  , aSocketActivity.iEvent
1585                                                  , aSocketActivity.iError);
1586             break;
1587         default:
1588             OSCL_ASSERT(false);//invalid input arg.
1589             break;
1590     }
1591 
1592     //current state shoudl be idle
1593     OSCL_ASSERT(iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_None);
1594 
1595     iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_WaitOnConnectedPort;
1596 }
1597 
1598 
StartRecvOperation()1599 PVMFStatus PVMFClientServerSocketNode::StartRecvOperation()
1600 {
1601     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::StartRecvOperation() In"));
1602 
1603     //caller should have verified we can receive data right now.
1604     OSCL_ASSERT(iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_None);
1605 
1606     //there should be either a UDP or TCP socket on this port and a memory pool.
1607     if (!iSockConfig->iTCPSocket)
1608     {
1609         return PVMFFailure;
1610     }
1611     if (!iSockConfig->iMemPool)
1612     {
1613         return PVMFFailure;
1614     }
1615 
1616     PVMFStatus status = PVMFFailure;
1617 
1618     if (iSockConfig->iTCPSocket)
1619     {
1620         iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_Recv;
1621 
1622         //Allocate memory
1623         int32 err;
1624         OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl;
1625         OSCL_TRY(err,
1626                  mediaDataImpl = iSockConfig->iMemPool->getMediaDataImpl(iMaxTcpRecvBufferSize););
1627         if (err != OsclErrNone)
1628         {
1629             StartRecvWaitOnMemory(iMaxTcpRecvBufferSize);
1630             status = PVMFPending;
1631             //wait on memory pool callback "notifyfreechunkavailable"
1632         }
1633 
1634         else
1635         {
1636             OSCL_TRY(err, iSockConfig->iPendingRecvMediaData = PVMFMediaData::createMediaData(
1637                          mediaDataImpl, iSockConfig->iMemPool->iMediaDataMemPool););
1638             if (err != OsclErrNone)
1639             {
1640                 StartRecvWaitOnMemory();
1641                 status = PVMFPending;
1642                 //wait on memory pool callback "notifyfreechunkavailable"
1643             }
1644 
1645             else
1646             {
1647                 // Retrieve memory fragment to write to
1648                 OsclRefCounterMemFrag refCtrMemFragOut;
1649                 iSockConfig->iPendingRecvMediaData->getMediaFragment(0, refCtrMemFragOut);
1650 
1651                 //Issue the Oscl socket request
1652                 TPVSocketEvent retVal = iSockConfig->iTCPSocket->Recv((uint8*)refCtrMemFragOut.getMemFragPtr()
1653                                         , refCtrMemFragOut.getCapacity()
1654                                         , TIMEOUT_RECV);
1655                 if (EPVSocketPending != retVal)
1656                 {
1657                     status = PVMFFailure;
1658                 }
1659                 else
1660                 {
1661                     status = PVMFPending;
1662                     //wait on HandleSocketEvent callback.
1663                 }
1664             }
1665         }
1666     }
1667     else    //for (iTCPSocket==NULL)
1668     {
1669         PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::StartRecvOperation() Unexpected error, no socket"));
1670     }
1671 
1672     //Handle synchronous completion or failure.
1673     if (status != PVMFPending
1674             && status != PVMFFailure)
1675     {
1676         PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::StartRecvOperation: Error. status=%d", status));
1677     }
1678 
1679     if (status != PVMFPending)
1680         status = RecvOperationComplete(status, NULL);
1681 
1682     return status;
1683 }
1684 
RecvOperationComplete(PVMFStatus aStatus,PVMFSocketActivity * aSocketActivity)1685 PVMFStatus PVMFClientServerSocketNode::RecvOperationComplete(PVMFStatus aStatus, PVMFSocketActivity* aSocketActivity)
1686 {
1687     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::RecvOperationComplete() In"));
1688 
1689     //status should never be pending here
1690     OSCL_ASSERT(aStatus != PVMFPending);
1691 
1692     PVMFStatus status = aStatus;
1693     bool recvOperationCanceled = iSockConfig->iState.iRecvOperationCanceled;
1694 
1695     //check the condition of reset here
1696     if (iSockConfig->iState.iSequence == EPVSocketPortSequence_SocketCleanup
1697             || recvOperationCanceled)
1698     {
1699         return PVMFSuccess;
1700     }
1701 
1702     //Update the state
1703     TPVSocketPortRecvOperation curOp = iSockConfig->iState.iRecvOperation;
1704     iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_None;
1705     iSockConfig->iState.iRecvOperationStatus = aStatus;
1706     iSockConfig->iState.iRecvOperationCanceled = false;
1707 
1708     switch (curOp)
1709     {
1710         case EPVSocketPortRecvOperation_WaitOnMemory:
1711             //a memory wait is complete.
1712             //PVMF_SOCKETNODE_LOGDATATRAFFIC_I((0, "PVMFClientServerSocketNode::RecvOperationComplete WaitOnMemory - SockId=%d, Mime=%s ", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
1713             break;
1714 
1715         case EPVSocketPortRecvOperation_WaitOnConnectedPort:
1716             //a port wait is complete
1717             if (iSockConfig->iSocketRecvActivity.iValid)
1718             {
1719                 iSockConfig->iSocketRecvActivity.iValid = false;
1720 
1721                 switch (iSockConfig->iSocketRecvActivity.iFxn)
1722                 {
1723                     case EPVSocketRecv:
1724                         HandleRecvComplete(iSockConfig->iSocketRecvActivity.iStatus
1725                                            , &iSockConfig->iSocketRecvActivity, recvOperationCanceled);
1726                         break;
1727                     default:
1728                         OSCL_ASSERT(0);//invalid arg
1729                         break;
1730                 }
1731             }
1732             break;
1733 
1734         case EPVSocketPortRecvOperation_Recv:
1735             HandleRecvComplete(aStatus, aSocketActivity, recvOperationCanceled);
1736             break;
1737 
1738         default:
1739             OSCL_ASSERT(0);//add code for this case
1740             break;
1741     }
1742 
1743     if (CanReceive())
1744         status = StartRecvOperation();
1745 
1746     return status;
1747 }
1748 
1749 
HandleRecvComplete(PVMFStatus aStatus,PVMFSocketActivity * aSocketActivity,bool aRecvOperationCanceled)1750 void PVMFClientServerSocketNode::HandleRecvComplete(PVMFStatus aStatus, PVMFSocketActivity* aSocketActivity, bool aRecvOperationCanceled)
1751 {
1752     OSCL_UNUSED_ARG(aRecvOperationCanceled);
1753     PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::HandleRecvComplete() In"));
1754 
1755     //operation should be complete when this is called.
1756     OSCL_ASSERT(aStatus != PVMFPending);
1757 
1758     //If there's no socket activity input, then this must be a failure in initiating
1759     //a Recv operation.
1760     if (!aSocketActivity || !iSockConfig->iPVMFPort
1761             || !iSockConfig->iPVMFPort->IsConnected())
1762     {
1763         OSCL_ASSERT(aStatus != PVMFSuccess);
1764         ReportSocketNodeError(PVMFErrResource, PVMFSocketNodeErrorSocketFailure);
1765         //release media data
1766         if (iSockConfig->iPendingRecvMediaData.GetRep())
1767             iSockConfig->iPendingRecvMediaData.Unbind();
1768         return;
1769     }
1770 
1771     if (aSocketActivity->iEvent == EPVSocketSuccess)
1772     {
1773         if (iSockConfig->iPVMFPort->IsOutgoingQueueBusy())
1774         {
1775             //wait on port so we can send recv data.
1776             StartRecvWaitOnConnectedPort(*aSocketActivity);
1777             return;
1778         }
1779     }
1780 
1781     //If we get here then it's time to process the recv result.
1782 
1783     //Release media data on failure
1784     if (aStatus != PVMFSuccess)
1785     {
1786         if (iSockConfig->iPendingRecvMediaData.GetRep())
1787             iSockConfig->iPendingRecvMediaData.Unbind();
1788     }
1789 
1790     switch (aSocketActivity->iEvent)
1791     {
1792         case EPVSocketSuccess:
1793         {
1794             //Get data length and set media buffer size
1795             int32 len;
1796             iSockConfig->iTCPSocket->GetRecvData(&len);
1797             if (len <= 0)
1798             {
1799                 PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::HandleRecvComplete - Sucessful Recv With Zero Length"));
1800                 OSCL_ASSERT(false);
1801             }
1802             iSockConfig->iPendingRecvMediaData->setMediaFragFilledLen(0, len);
1803 
1804             // Resize the buffer
1805             if (iSockConfig->iMemPool)
1806             {
1807                 OsclSharedPtr<PVMFMediaDataImpl> mediaMsgImpl;
1808                 iSockConfig->iPendingRecvMediaData->getMediaDataImpl(mediaMsgImpl);
1809                 iSockConfig->iMemPool->resizeSocketDataBuffer(mediaMsgImpl);
1810             }
1811             else
1812             {
1813                 PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::HandleRecvComplete() ERROR:mempool not found"));
1814                 OSCL_ASSERT(0);
1815                 return ;
1816             }
1817 
1818             //queue to next port
1819             PVMFSharedMediaMsgPtr aMediaMsgPtr;
1820             convertToPVMFMediaMsg(aMediaMsgPtr, iSockConfig->iPendingRecvMediaData);
1821 
1822             PVMFStatus status = iSockConfig->iPVMFPort->QueueOutgoingMsg(aMediaMsgPtr);
1823             if (status != PVMFSuccess)
1824             {
1825                 ReportErrorEvent(PVMFErrPortProcessing);
1826                 return ;
1827             }
1828         }
1829         break;
1830 
1831         case EPVSocketTimeout:
1832         {
1833             ReportSocketNodeError(PVMFErrTimeout, PVMFSocketNodeErrorSocketTimeOut);
1834         }
1835         break;
1836 
1837         case EPVSocketCancel:
1838             break;
1839 
1840         case EPVSocketFailure:
1841         {
1842             //After a receive failure, we may need to do a TCP shutdown.
1843             //Check what else is currently happening on the port.
1844             switch (iSockConfig->iState.iSequence)
1845             {
1846                 case EPVSocketPortSequence_RequestPort:
1847                 case EPVSocketPortSequence_InputDisconnectMsg:
1848                 case EPVSocketPortSequence_SocketCleanup:
1849                     break;
1850 
1851                 case EPVSocketPortSequence_None:
1852                 case EPVSocketPortSequence_InputDataMsg:
1853                     //for these cases, start a shutdown sequence
1854                     //start the sequence
1855                     iSockConfig->iState.iSequence = EPVSocketPortSequence_SocketCleanup;
1856                     StartSequence(EPVSocketPortSequence_SocketCleanup);
1857                     break;
1858 
1859                 default:
1860                     //need code to handle this case.
1861                     OSCL_ASSERT(0);
1862                     break;
1863             }
1864         }
1865         break;
1866 
1867         default:
1868             OSCL_ASSERT(0);
1869             break;
1870     }
1871 }
1872 
1873 
1874 
SetMaxTCPRecvBufferSize(uint32 aBufferSize)1875 OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::SetMaxTCPRecvBufferSize(uint32 aBufferSize)
1876 {
1877     if ((aBufferSize > 0) && (aBufferSize < SNODE_DEFAULT_MAX_TCP_RECV_BUFFER_SIZE))
1878     {
1879         iMaxTcpRecvBufferSize = aBufferSize;
1880         return PVMFSuccess;
1881     }
1882     return PVMFErrArgument;
1883 }
1884 
GetMaxTCPRecvBufferSize(uint32 & aSize)1885 OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::GetMaxTCPRecvBufferSize(uint32& aSize)
1886 {
1887     aSize = iMaxTcpRecvBufferSize;
1888     return PVMFSuccess;
1889 }
1890 
SetMaxTCPRecvBufferCount(uint32 aBufferSize)1891 OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::SetMaxTCPRecvBufferCount(uint32 aBufferSize)
1892 {
1893     iMaxTcpRecvBufferCount = aBufferSize;
1894     return PVMFSuccess;
1895 }
1896 
GetMaxTCPRecvBufferCount(uint32 & aSize)1897 OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::GetMaxTCPRecvBufferCount(uint32& aSize)
1898 {
1899     aSize = iMaxTcpRecvBufferCount;
1900     return PVMFSuccess;
1901 }
1902 
StartSequence(TPVSocketPortSequence aSequence,OsclAny * aParam)1903 PVMFStatus PVMFClientServerSocketNode::StartSequence(TPVSocketPortSequence aSequence, OsclAny* aParam)
1904 {
1905     PVMFStatus status = PVMFFailure;
1906     //Set the sequence.
1907     iSockConfig->iState.iSequence = aSequence;
1908 
1909     switch (aSequence)
1910     {
1911         case EPVSocketPortSequence_InputDataMsg:
1912         {
1913             OSCL_ASSERT(aParam);
1914             return StartSendOperation(*((PVMFSharedMediaMsgPtr*)aParam));
1915         }
1916 
1917         case EPVSocketPortSequence_InputDisconnectMsg:
1918         {
1919             status = CloseSocketConnection();
1920         }
1921         break;
1922 
1923         case EPVSocketPortSequence_SocketCleanup:
1924             if (iSockConfig->iTCPSocket)
1925             {
1926                 //CancelRecvOperation();
1927                 //CancelSendOperation();
1928                 status = CloseSocketConnection();
1929             }
1930             break;
1931 
1932         default:
1933         {
1934             OSCL_ASSERT(0);
1935             return PVMFFailure;
1936         }
1937     }
1938 
1939     if (status != PVMFPending)
1940     {
1941         //nothing needed.
1942         SequenceComplete(PVMFSuccess);
1943         return PVMFSuccess;
1944     }
1945     return status;
1946 }
1947 
1948 
1949 
CloseSocketConnection()1950 PVMFStatus PVMFClientServerSocketNode::CloseSocketConnection()
1951 {
1952     PVMFStatus status;
1953     iSockConfig->iState.iSequence = EPVSocketPortSequence_SocketCleanup;
1954     if (!iSockConfig->iTCPSocket)
1955     {
1956         status = PVMFFailure;//unexpected
1957         return status;
1958     }
1959     //Initiate a socket shutdown.
1960     TPVSocketEvent ret = iSockConfig->iTCPSocket->Shutdown(EPVSocketBothShutdown, TIMEOUT_SHUTDOWN);
1961     if (ret == EPVSocketPending)
1962     {
1963         status = PVMFPending;
1964         //wait on the socket shutdown to complete in HandleSocketEvent callback
1965     }
1966     else
1967     {
1968         status = PVMFFailure;
1969     }
1970     return status;
1971 }
1972 
1973 
SequenceComplete(PVMFStatus aStatus)1974 void PVMFClientServerSocketNode::SequenceComplete(PVMFStatus aStatus)
1975 {
1976     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::SequenceComplete() Sequence %d Status %d ", iSockConfig->iState.iSequence, aStatus));
1977 
1978     TPVSocketPortSequence curSequence = iSockConfig->iState.iSequence;
1979     iSockConfig->iState.iSequence = EPVSocketPortSequence_None;
1980     iSockConfig->iState.iSequenceStatus = aStatus;
1981 
1982     switch (curSequence)
1983     {
1984         case EPVSocketPortSequence_RequestPort:
1985             //may need to complete the node command
1986             if (iCurrentCmdQueue.size()
1987                     && iCurrentCmdQueue.front().iCmd == PVMF_GENERIC_NODE_REQUESTPORT)
1988             {
1989                 CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), aStatus, iPVMFPort);
1990             }
1991             break;
1992 
1993         case EPVSocketPortSequence_InputDisconnectMsg:
1994         case EPVSocketPortSequence_InputDataMsg:
1995             //If we've just completed an input port message, this may complete a node Flush command
1996             if (!iCurrentCmdQueue.empty()
1997                     && iCurrentCmdQueue.front().iCmd == PVMF_GENERIC_NODE_FLUSH)
1998             {
1999                 //Flush is done when all input ports are empty.
2000                 if (iPVMFPort->IncomingMsgQueueSize() > 0)
2001                     return;//keep waiting
2002                 CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFSuccess);
2003             }
2004             break;
2005 
2006 
2007         case EPVSocketPortSequence_SocketCleanup:
2008         {
2009             iPVMFPort->SuspendInput();
2010             iPVMFPort->ClearMsgQueues();
2011 
2012             CleanupPorts();
2013             //This port is done-- decrement the counter
2014             iNumStopPortActivityPending--;
2015 
2016             //When counter reaches zero, all ports are done and the sequence is complete.
2017             if (iNumStopPortActivityPending == 0)
2018             {
2019                 //Reset the counter to the "idle" value.
2020                 iNumStopPortActivityPending = (-1);
2021 
2022                 //There may be a Reset or CancelAll command waiting on
2023                 //this to complete.
2024                 if (!iCurrentCmdQueue.empty()
2025                         && iCurrentCmdQueue.front().iCmd == PVMF_GENERIC_NODE_RESET)
2026                 {
2027                     CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFSuccess);
2028                 }
2029                 else if (!iCancelCmdQueue.empty()
2030                          && iCancelCmdQueue.front().iCmd == PVMF_GENERIC_NODE_CANCELALLCOMMANDS)
2031                 {
2032                     CommandComplete(iCancelCmdQueue, iCancelCmdQueue.front(), PVMFSuccess);
2033                 }
2034                 return;
2035             }
2036         }
2037         break;
2038 
2039         default:
2040             break;
2041     }
2042 
2043     if (curSequence != EPVSocketPortSequence_InputDataMsg
2044             && CanReceive())
2045     {
2046         StartRecvOperation();
2047     }
2048 
2049     if (CanProcessIncomingMsg())
2050         ProcessIncomingMsg();
2051 }
2052