• 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 ** Socket implementation for PV socket server
20 */
21 
22 #include "oscl_socket_tuneables.h"
23 #if(PV_SOCKET_SERVER)
24 #include "oscl_socket_imp_pv.h"
25 #include "oscl_socket_serv_imp_pv.h"
26 #include "oscl_socket_method.h"
27 
28 //Stats macros for use with OsclSocketI
29 #if(PV_OSCL_SOCKET_STATS_LOGGING)
30 #define ADD_STATS(x,y) iStats.Add(x,y)
31 #define CONSTRUCT_STATS(x,y) iStats.Construct(x,y)
32 #else
33 #define ADD_STATS(x,y)
34 #define CONSTRUCT_STATS(x,y)
35 #endif
36 
OsclSocketI(Oscl_DefAlloc & a)37 OsclSocketI::OsclSocketI(Oscl_DefAlloc &a) : OsclSocketIBase(a)
38 {
39     iSocketServ = NULL;
40     InitSocket(false);
41 
42     iSockServAcceptRequest.iSocketI = this;
43     iSockServConnectRequest.iSocketI = this;
44     iSockServRecvRequest.iSocketI = this;
45     iSockServRecvFromRequest.iSocketI = this;
46     iSockServSendRequest.iSocketI = this;
47     iSockServSendToRequest.iSocketI = this;
48     iSockServShutdownRequest.iSocketI = this;
49     iLogger = PVLogger::GetLoggerObject("osclsocket");
50 }
51 
~OsclSocketI()52 OsclSocketI::~OsclSocketI()
53 {
54     Close();
55 }
56 
NewL(Oscl_DefAlloc & a)57 OsclSocketI* OsclSocketI::NewL(Oscl_DefAlloc &a)
58 {
59     OsclAny*p = a.ALLOCATE(sizeof(OsclSocketI));
60     OsclError::LeaveIfNull(p);
61     OsclSocketI *self = OSCL_PLACEMENT_NEW(p, OsclSocketI(a));
62     OsclError::LeaveIfNull(self);
63     return self;
64 }
65 
Close()66 int32 OsclSocketI::Close()
67 {
68     int sockerr = 0;
69 
70     //cleanup the OS-level socket
71     if (iSocketValid)
72     {
73 #ifdef OsclCloseSocket
74         //call the platform socket close routine...
75         bool ok;
76         OsclCloseSocket(iSocket, ok, sockerr);
77 #else
78         sockerr = PVSOCK_ERR_NOT_IMPLEMENTED;
79 #endif
80     }
81 
82     InitSocket(false);
83     return sockerr;
84 
85 }
86 
HasAsyncBind()87 bool OsclSocketIBase::HasAsyncBind()
88 {
89     return false;
90 }
91 
Bind(OsclNetworkAddress & anAddr)92 int32 OsclSocketI::Bind(OsclNetworkAddress& anAddr)
93 {
94 #ifdef OsclBind
95     TOsclSockAddr addr;
96     MakeAddr(anAddr, addr);
97     int err;
98     bool ok;
99     OsclBind(iSocket, addr, ok, err);
100     if (!ok)
101         return err;
102 #if (PV_OSCL_SOCKET_1MB_RECV_BUF)
103     int bufsize = (1024 * 1024);
104     OsclSetRecvBufferSize(iSocket, bufsize, ok, err);
105 #endif
106     return OsclErrNone;
107 #else
108     return PVSOCK_ERR_NOT_IMPLEMENTED;
109 #endif
110 }
111 
Join(OsclNetworkAddress & anAddr)112 int32 OsclSocketI::Join(OsclNetworkAddress& anAddr)
113 {
114 #ifdef OsclJoin
115     TOsclSockAddr addr;
116     MakeAddr(anAddr, addr);
117     int err;
118     bool ok;
119     OsclJoin(iSocket, addr, ok, err);
120     if (!ok)
121         return err;
122     return OsclErrNone;
123 #else
124     OSCL_UNUSED_ARG(anAddr);
125     OSCL_LEAVE(OsclErrNotSupported);
126     return 0;
127 #endif
128 }
129 
HasAsyncListen()130 bool OsclSocketIBase::HasAsyncListen()
131 {
132     return false;
133 }
134 
Listen(uint32 qSize)135 int32 OsclSocketI::Listen(uint32 qSize)
136 {
137 #ifdef OsclListen
138     //note: it's ok to do multiple listens to update the queue size
139     bool ok;
140     int err;
141     OsclListen(iSocket, qSize, ok, err);
142     if (!ok)
143         return err;
144     return OsclErrNone;
145 #else
146     OSCL_UNUSED_ARG(qSize);
147     return PVSOCK_ERR_NOT_IMPLEMENTED;
148 #endif
149 }
150 
SetRecvBufferSize(uint32 size)151 int32 OsclSocketI::SetRecvBufferSize(uint32 size)
152 {
153 #ifdef OsclSetRecvBufferSize
154     int err;
155     int ok;
156     OsclSetRecvBufferSize(iSocket, size, ok, err);
157     if (!ok)
158         return err;
159     return OsclErrNone;
160 #else
161     OSCL_UNUSED_ARG(size);
162     OSCL_LEAVE(OsclErrNotSupported);
163     return 0;
164 #endif
165 }
166 
Send(SendParam & param,OsclSocketRequestAO & ao)167 inline void OsclSocketI::Send(SendParam &param, OsclSocketRequestAO& ao)
168 {
169     if (!IsReady(ao))
170         return;
171     //send/recv behavior is undefined when socket is
172     //not connected, so disallow it.
173     if (!IsConnected(ao))
174         return ;
175     iSockServSendRequest.Activate(&param, ao);
176 }
177 
SendSuccess(SendParam & param)178 inline void OsclSocketI::SendSuccess(SendParam &param)
179 {
180     //nothing needed
181     OSCL_UNUSED_ARG(param);
182 }
183 
CancelSend()184 inline void OsclSocketI::CancelSend()
185 {
186     iSockServSendRequest.CancelRequest();
187 }
188 
SendTo(SendToParam & param,OsclSocketRequestAO & ao)189 inline void OsclSocketI::SendTo(SendToParam &param, OsclSocketRequestAO& ao)
190 {
191     if (!IsReady(ao))
192         return;
193     iSockServSendToRequest.Activate(&param, ao);
194 }
195 
SendToSuccess(SendToParam & param)196 inline void OsclSocketI::SendToSuccess(SendToParam &param)
197 {
198     //nothing needed
199     OSCL_UNUSED_ARG(param);
200 }
201 
CancelSendTo()202 inline void OsclSocketI::CancelSendTo()
203 {
204     iSockServSendToRequest.CancelRequest();
205 }
206 
Recv(RecvParam & param,OsclSocketRequestAO & ao)207 inline void OsclSocketI::Recv(RecvParam& param, OsclSocketRequestAO& ao)
208 {
209     if (!IsReady(ao))
210         return;
211     //send/recv behavior is undefined when socket is
212     //not connected, so disallow it.
213     if (!IsConnected(ao))
214         return ;
215     iSockServRecvRequest.Activate(&param, ao);
216 }
217 
RecvSuccess(RecvParam & param)218 inline void OsclSocketI::RecvSuccess(RecvParam& param)
219 {
220     //nothing needed
221     OSCL_UNUSED_ARG(param);
222 }
223 
CancelRecv()224 inline void OsclSocketI::CancelRecv()
225 {
226     iSockServRecvRequest.CancelRequest();
227 }
228 
RecvFrom(RecvFromParam & param,OsclSocketRequestAO & ao)229 inline void OsclSocketI::RecvFrom(RecvFromParam &param, OsclSocketRequestAO& ao)
230 {
231     if (!IsReady(ao))
232         return;
233     iSockServRecvFromRequest.Activate(&param, ao);
234 }
235 
RecvFromSuccess(RecvFromParam & param)236 inline void OsclSocketI::RecvFromSuccess(RecvFromParam& param)
237 {
238     //nothing needed
239     OSCL_UNUSED_ARG(param);
240 }
241 
CancelRecvFrom()242 inline void OsclSocketI::CancelRecvFrom()
243 {
244     iSockServRecvFromRequest.CancelRequest();
245 }
246 
Connect(ConnectParam & param,OsclSocketRequestAO & ao)247 inline void OsclSocketI::Connect(ConnectParam &param, OsclSocketRequestAO& ao)
248 {
249     if (!IsReady(ao))
250         return;
251     iSockServConnectRequest.Activate(&param, ao);
252 }
253 
CancelConnect()254 inline void OsclSocketI::CancelConnect()
255 {
256     iSockServConnectRequest.CancelRequest();
257 }
258 
Accept(AcceptParam & param,OsclSocketRequestAO & ao)259 inline void OsclSocketI::Accept(AcceptParam& param, OsclSocketRequestAO& ao)
260 {
261     if (!IsReady(ao))
262         return;
263     iSockServAcceptRequest.Activate(&param, ao);
264 }
265 
CancelAccept()266 inline void OsclSocketI::CancelAccept()
267 {
268     iSockServAcceptRequest.CancelRequest();
269 }
270 
Shutdown(ShutdownParam & param,OsclSocketRequestAO & ao)271 inline void OsclSocketI::Shutdown(ShutdownParam &param, OsclSocketRequestAO& ao)
272 {
273     if (!IsReady(ao))
274         return;
275     iSockServShutdownRequest.Activate(&param, ao);
276 }
277 
CancelShutdown()278 inline void OsclSocketI::CancelShutdown()
279 {
280     iSockServShutdownRequest.CancelRequest();
281 }
282 
MakeAddr(OsclNetworkAddress & in,TOsclSockAddr & addr)283 bool OsclSocketI::MakeAddr(OsclNetworkAddress& in, TOsclSockAddr& addr)
284 {
285     //convert OsclNetworkAddress to TOsclSockAddr.
286 #ifdef OsclMakeSockAddr
287     bool ok;
288     OsclMakeSockAddr(addr, in.port, in.ipAddr.Str(), ok);
289     return ok;
290 #else
291     //default-- for older configurations that don't have the OsclMakeSockAddr macro.
292     addr.sin_family = OSCL_AF_INET;
293     addr.sin_port = htons(in.port);
294     addr.sin_addr.s_addr = inet_addr((const char*)in.ipAddr.Str());
295     return (addr.sin_addr.s_addr != INADDR_NONE);
296 #endif
297 }
298 
MakeAddr(TOsclSockAddr & in,OsclNetworkAddress & addr)299 void OsclSocketI::MakeAddr(TOsclSockAddr& in, OsclNetworkAddress& addr)
300 {
301 #ifdef OsclUnMakeSockAddr
302     //convert TOsclSockAddrOut to OsclNetworkAddress
303     char* str;
304     OsclUnMakeSockAddr(in, str);
305     addr.ipAddr.Set(str);
306 #else
307     addr.ipAddr.Set(inet_ntoa(in.sin_addr));
308 #endif
309 }
310 
Open(OsclSocketServI & aServer,uint32 addrFamily,uint32 sockType,uint32 protocol)311 int32 OsclSocketI::Open(OsclSocketServI& aServer, uint32 addrFamily, uint32 sockType, uint32 protocol)
312 //used to open a new tcp or udp socket.
313 {
314 #if(PV_OSCL_SOCKET_STATS_LOGGING)
315     iStats.Construct(this, &aServer);
316 #endif
317 
318     bool ok;
319     int err = 0;
320 
321     //create OS level socket.
322 #ifdef OsclSocket
323     OsclSocket(iSocket, addrFamily, sockType, protocol, ok, err);
324 #else
325     OSCL_UNUSED_ARG(addrFamily);
326     OSCL_UNUSED_ARG(sockType);
327     OSCL_UNUSED_ARG(protocol);
328     ok = false;
329     err = PVSOCK_ERR_NOT_IMPLEMENTED;
330 #endif
331 
332     InitSocket(ok);
333     if (!ok)
334         return err;
335 
336     if (protocol == OSCL_IPPROTO_UDP)
337     {
338         int32 bufsize = 65536;
339         OsclSetRecvBufferSize(iSocket, bufsize, ok, err);
340     }
341 
342     //set socket to non-blocking mode.
343 #ifdef OsclSetNonBlocking
344     OsclSetNonBlocking(iSocket, ok, err);
345 #else
346     ok = false;
347     err = PVSOCK_ERR_NOT_IMPLEMENTED;
348 #endif
349 
350     if (!ok)
351     {
352         Close();
353         return err;
354     }
355     return Open(aServer);
356 }
357 
Open(OsclSocketServI & aServer)358 int32 OsclSocketI::Open(OsclSocketServI& aServer)
359 //used to open an accepted socket.
360 {
361     CONSTRUCT_STATS(this, &aServer);
362 
363     iSocketServ = &aServer;
364 
365     //nothing needed-- the pv server doesn't need
366     //to know about the socket yet.
367     return OsclErrNone;
368 }
369 
IsOpen()370 inline bool OsclSocketI::IsOpen()
371 //see whether socket has been opened successfully.
372 {
373     return iSocketValid;
374 }
375 
IsReady(OsclSocketRequestAO & ao)376 bool OsclSocketI::IsReady(OsclSocketRequestAO& ao)
377 //this routine does some error checks and will
378 //set socket error and complete the request for errors.
379 {
380     //make sure this socket is open
381     if (!IsOpen())
382     {
383         ao.iSocketError = PVSOCK_ERR_SOCK_NOT_OPEN;
384         ao.PendComplete(OSCL_REQUEST_ERR_GENERAL);
385         return false;
386     }
387     //make sure server is ok.
388     if (!iSocketServ)
389     {
390         ao.iSocketError = PVSOCK_ERR_SOCK_NO_SERV;
391         ao.PendComplete(OSCL_REQUEST_ERR_GENERAL);
392         return false;
393     }
394     if (!iSocketServ->IsServConnected())
395     {
396         //report the error from the server, if any.
397         ao.iSocketError = iSocketServ->iServError;
398         if (ao.iSocketError == 0)
399             ao.iSocketError = PVSOCK_ERR_SERV_NOT_CONNECTED;
400         ao.PendComplete(OSCL_REQUEST_ERR_GENERAL);
401         return false;
402     }
403     return true;
404 }
405 
IsConnected(OsclSocketRequestAO & ao)406 bool OsclSocketI::IsConnected(OsclSocketRequestAO& ao)
407 {
408     if (!iSocketConnected)
409     {
410         ao.iSocketError = PVSOCK_ERR_SOCK_NOT_CONNECTED;
411         ao.PendComplete(OSCL_REQUEST_ERR_GENERAL);
412         return false;
413     }
414     return true;
415 }
416 
InitSocket(bool valid)417 void OsclSocketI::InitSocket(bool valid)
418 {
419     iSocketValid = valid;
420     iSocketConnected = false;
421 }
422 
423 #endif //pv socket server
424 
425 
426 
427 
428 
429 
430 
431 
432