• 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 "osclconfig_io.h"
20 #include "oscl_scheduler_ao.h"
21 #include "oscl_socket_method.h"
22 #include "oscl_socket_imp.h"
23 #include "oscl_assert.h"
24 
25 
26 static const char* const TPVSocketFxnStr[] =
27 {
28     "EPVSocketSend"
29     , "EPVSocketSendTo"
30     , "EPVSocketRecv"
31     , "EPVSocketRecvFrom"
32     , "EPVSocketConnect"
33     , "EPVSocketAccept"
34     , "EPVSocketShutdown"
35     , "EPVSocketBindUdp"
36     , "EPVSocketBindTcp"
37     , "EPVSocketListen"
38 } ;
39 static const char* const TPVSocketEventStr[] =
40 {
41     "EPVSocketSuccess"
42     , "EPVSocketPending"
43     , "EPVSocketTimeout"
44     , "EPVSocketFailure"
45     , "EPVSocketCancel"
46 };
47 
48 /** OsclSocketRequestAO is the base class for all the AOs that
49   interact directly with the socket server.  This object
50   is contained within an OsclSocketMethod object
51   */
52 
GetSocketError()53 inline int OsclSocketRequestAO::GetSocketError()
54 {
55 #if  (PV_SOCKET_SERVER)
56 
57     //Errors from PV socket server are in
58     //iSocketError.
59     return iSocketError;
60 
61 #else
62 
63 #error No Implementation!
64 
65 #endif
66 }
67 
68 //Stats macros for use with OsclSocketRequestAO
69 #if(PV_OSCL_SOCKET_STATS_LOGGING)
70 #define ADD_STATS(a,b) SocketI()->iStats.Add(a,b)
71 #define LOG_STATS(a) SocketI()->iStats.Log(a)
72 #define CLEAR_STATS(a) SocketI()->iStats.Clear(a)
73 #else
74 #define ADD_STATS(a,b)
75 #define LOG_STATS(a)
76 #define CLEAR_STATS(a)
77 #endif
78 
79 #define LOGINFOMED(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG,iContainer.iContainer.iLogger,PVLOGMSG_DEBUG,m);
80 
Run()81 void OsclSocketRequestAO::Run()
82 {
83     //The server has completed the socket request.
84 
85     RequestDone();
86 
87 
88     // Check the request completion status
89     switch (Status())
90     {
91         case OSCL_REQUEST_ERR_NONE:
92             ADD_STATS(iContainer.iSocketFxn, EOsclSocket_RequestAO_Success);
93             Success();
94             LOGINFOMED((0, "OsclSocket(0x%x): %s %s ", SocketI(), TPVSocketFxnStr[iContainer.iSocketFxn], TPVSocketEventStr[EPVSocketSuccess]));
95             LOG_STATS(iContainer.iSocketFxn);
96             CLEAR_STATS(iContainer.iSocketFxn);
97             SocketObserver()->HandleSocketEvent(Id(), iContainer.iSocketFxn, EPVSocketSuccess, 0);
98             break;
99 
100         case OSCL_REQUEST_ERR_CANCEL:
101             ADD_STATS(iContainer.iSocketFxn, EOsclSocket_RequestAO_Canceled);
102             //Request was cancelled, either due to an API call or due to the
103             //socket server shutting down before completing the operation.
104             LOGINFOMED((0, "OsclSocket(0x%x): %s %s ", SocketI(), TPVSocketFxnStr[iContainer.iSocketFxn], TPVSocketEventStr[EPVSocketCancel]));
105             LOG_STATS(iContainer.iSocketFxn);
106             CLEAR_STATS(iContainer.iSocketFxn);
107             SocketObserver()->HandleSocketEvent(Id(), iContainer.iSocketFxn, EPVSocketCancel, 0);
108             break;
109 
110         default:
111             ADD_STATS(iContainer.iSocketFxn, EOsclSocket_RequestAO_Error);
112             //Some error.
113             LOGINFOMED((0, "OsclSocket(0x%x): %s %s %d", SocketI(), TPVSocketFxnStr[iContainer.iSocketFxn], TPVSocketEventStr[EPVSocketFailure], GetSocketError()));
114             LOG_STATS(iContainer.iSocketFxn);
115             CLEAR_STATS(iContainer.iSocketFxn);
116             SocketObserver()->HandleSocketEvent(Id(), iContainer.iSocketFxn, EPVSocketFailure, GetSocketError());
117             break;
118     }
119 }
120 
NewRequest(const uint32 size)121 OsclAny* OsclSocketRequestAO::NewRequest(const uint32 size)
122 {
123     //Activate the AO.  The socket server will complete the request.
124     PendForExec();
125 
126     bool reallocate = (!iParam || size != iParamSize);
127 
128     //Cleanup any previous parameters.
129     CleanupParam(reallocate);
130 
131     LOGINFOMED((0, "OsclSocket(0x%x): New Request %s", SocketI(), TPVSocketFxnStr[iContainer.iSocketFxn]));
132 
133     //Allocate space for new parameters, or recycle current space.
134     if (reallocate)
135     {
136         iParamSize = size;
137         return Alloc().ALLOCATE(size);
138     }
139     else
140         return iParam;
141 }
142 
CleanupParam(bool aDeallocate)143 void OsclSocketRequestAO::CleanupParam(bool aDeallocate)
144 {
145     //cleanup the socket request parameters-- can't use
146     //virtual destructor because an allocator was used and
147     //destructor is called explicitly.
148     if (iParam)
149     {
150         switch (iContainer.iSocketFxn)
151         {
152             case EPVSocketRecvFrom:
153                 ((RecvFromParam*)iParam)->~RecvFromParam();
154                 break;
155             case EPVSocketRecv:
156                 ((RecvParam*)iParam)->~RecvParam();
157                 break;
158             case EPVSocketSendTo:
159                 ((SendToParam*)iParam)->~SendToParam();
160                 break;
161             case EPVSocketSend:
162                 ((SendParam*)iParam)->~SendParam();
163                 break;
164             case EPVSocketAccept:
165                 ((AcceptParam*)iParam)->~AcceptParam();
166                 break;
167             case EPVSocketConnect:
168                 ((ConnectParam*)iParam)->~ConnectParam();
169                 break;
170             case EPVSocketShutdown:
171                 ((ShutdownParam*)iParam)->~ShutdownParam();
172                 break;
173             case EPVSocketBind:
174                 ((BindParam*)iParam)->~BindParam();
175                 break;
176             case EPVSocketListen:
177                 ((ListenParam*)iParam)->~ListenParam();
178                 break;
179             default:
180                 OSCL_ASSERT(false);
181                 break;
182         }
183         //free memory if needed.
184         if (aDeallocate)
185         {
186             Alloc().deallocate(iParam);
187             iParam = NULL;
188             iParamSize = 0;
189         }
190     }
191 }
192 
193 
194 /** OsclSocketMethod is the base class for all the AOs that
195   implement asynchronous socket requests.  It implements the timeout.
196   */
197 
StartMethod(int32 aTimeoutMsec)198 bool OsclSocketMethod::StartMethod(int32 aTimeoutMsec)
199 {
200     //make sure there's not already a request
201     //in progress
202     if (iSocketRequestAO->IsBusy()
203             || IsBusy())
204         return false;
205 
206     if (!iSocketRequestAO->IsAdded())
207         iSocketRequestAO->AddToScheduler();
208 
209     //set the timeout if any.  Timeout <= 0 indicates infinite wait.
210     if (aTimeoutMsec > 0)
211     {
212         if (!IsAdded())
213             AddToScheduler();
214         After(aTimeoutMsec*MSEC_TO_MICROSEC);
215     }
216 
217     iSocketRequestAO->iSocketError = 0;
218 
219     return true;
220 }
221 
222 //Stats macros for use with OsclSocketMethod
223 #undef ADD_STATS
224 #undef LOG_STATS
225 #undef CLEAR_STATS
226 #if(PV_OSCL_SOCKET_STATS_LOGGING)
227 #define ADD_STATS(a,b) iSocketRequestAO->SocketI()->iStats.Add(a,b)
228 #define LOG_STATS(a) iSocketRequestAO->SocketI()->iStats.Log(a)
229 #define CLEAR_STATS(a) iSocketRequestAO->SocketI()->iStats.Clear(a)
230 #else
231 #define ADD_STATS(a,b)
232 #define LOG_STATS(a)
233 #define CLEAR_STATS(a)
234 #endif
235 
Run()236 void OsclSocketMethod::Run()
237 {
238     ADD_STATS(iSocketFxn, EOsclSocket_RequestAO_Timeout);
239     //The socket request has timed out.
240     MethodDone();
241     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iContainer.iLogger, PVLOGMSG_DEBUG
242                     , (0, "OsclSocket: %s %s ", TPVSocketFxnStr[iSocketFxn], TPVSocketEventStr[EPVSocketTimeout]));
243     LOG_STATS(iSocketFxn);
244     CLEAR_STATS(iSocketFxn);
245     iContainer.iObserver->HandleSocketEvent(iContainer.iId, iSocketFxn, EPVSocketTimeout, 0);
246 }
247 
248 
249