source: qutecom-coip/wifo/owsl/src/protocols/owsl_base.c @ 125:d648f4cb122f

Last change on this file since 125:d648f4cb122f was 125:d648f4cb122f, checked in by laurent, 3 years ago

wengo => qutecom

File size: 10.0 KB
Line 
1/*
2 * QuteCom Socket Library
3 * Copyright (C) 2010 Mbdsys
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20#include "owsl_base.h"
21
22#include <memory.h>
23#include <errno.h>
24
25int
26owsl_base_system_socket_blocking_mode_set
27(
28        OWSLSocketInfo * socket_info_with_system_socket,
29        OWSLBlockingMode mode
30)
31{
32        OWSLSocketInfo_with_SystemSocket * socket = (OWSLSocketInfo_with_SystemSocket *) socket_info_with_system_socket ;
33        return owsl_system_socket_blocking_mode_set (socket->system_socket, mode) ;
34}
35
36int
37owsl_base_system_socket_reuse_set
38(
39        OWSLSocketInfo * socket_info_with_system_socket
40)
41{
42        OWSLSocketInfo_with_SystemSocket * socket = (OWSLSocketInfo_with_SystemSocket *) socket_info_with_system_socket ;
43        return owsl_system_socket_reuse_set (socket->system_socket) ;
44}
45
46struct sockaddr *
47owsl_base_remote_address_get
48(
49        OWSLSocketInfo * socket_info_with_connected_system_socket
50)
51{
52        OWSLSocketInfo_with_ConnectedSystemSocket * socket = (OWSLSocketInfo_with_ConnectedSystemSocket *) socket_info_with_connected_system_socket ;
53        if (socket->remote_address_length > 0 && ((struct sockaddr *) (& socket->remote_address))->sa_family != AF_MAX)
54        {
55                return (struct sockaddr *) & socket->remote_address ;
56        }
57        else
58        {
59                return NULL ;
60        }
61}
62
63void
64owsl_base_in_queue_callback_with_monitor
65(
66        OWQueue * queue,
67        OWQueueEvent event,
68        void * socket_info_with_system_socket
69)
70{
71        OWSLSocketInfo_with_SystemSocket * socket = socket_info_with_system_socket ;
72
73        if (queue != socket->in_queue)
74        {
75                return ;
76        }
77
78        if (event & OWQUEUE_SPACE_NEEDED)
79        {
80                owsl_monitor_event_remove (socket->system_socket, OWSL_MONITOR_READ) ;
81        }
82        if (event & OWQUEUE_SPACE_AVAILABLE)
83        {
84                owsl_monitor_event_add (socket->system_socket, OWSL_MONITOR_READ) ;
85        }
86
87        return ;
88}
89
90void
91owsl_base_out_queue_callback_with_monitor
92(
93        OWQueue * queue,
94        OWQueueEvent event,
95        void * socket_info_with_system_socket
96)
97{
98        OWSLSocketInfo_with_SystemSocket * socket = socket_info_with_system_socket ;
99
100        if (queue != socket->out_queue)
101        {
102                return ;
103        }
104
105        if (event & OWQUEUE_SPACE_AVAILABLE)
106        {
107                owsl_notify ((OWSLSocketInfo *) socket, OWSL_EVENT_WRITE) ;
108        }
109        if (event & OWQUEUE_NOT_EMPTY)
110        {
111                owsl_monitor_event_add (socket->system_socket, OWSL_MONITOR_WRITE) ;
112        }
113        if (event & OWQUEUE_EMPTY)
114        {
115                owsl_monitor_event_remove (socket->system_socket, OWSL_MONITOR_WRITE) ;
116        }
117
118        return ;
119}
120
121void
122owsl_base_in_out_queues_callback_with_monitor
123(
124        OWQueue * queue,
125        OWQueueEvent event,
126        void * _socket_info_with_system_socket
127)
128{
129        owsl_base_in_queue_callback_with_monitor (queue, event, _socket_info_with_system_socket) ;
130        owsl_base_out_queue_callback_with_monitor (queue, event, _socket_info_with_system_socket) ;
131        return ;
132}
133
134static int
135owsl_base_register_in_monitor_for_read
136(
137        OWSLSocketInfo_with_SystemSocket * socket,
138        OWSLMonitorCallback callback_function
139)
140{
141        void * callback_user_data = socket ;
142        if (owsl_monitor_socket_add (socket->system_socket, callback_function, callback_user_data))
143        {
144                return -1 ;
145        }
146        if (owsl_monitor_event_add (socket->system_socket, OWSL_MONITOR_READ))
147        {
148                owsl_monitor_socket_remove (socket->system_socket) ;
149                return -1 ;
150        }
151        return 0 ;
152}
153
154int
155owsl_base_udp_open
156(
157        OWSLSocketInfo_with_SystemSocket * socket,
158        OWSLAddressFamily address_family,
159        OWSLMonitorCallback callback_function
160)
161{
162        socket->system_socket = owsl_system_socket_open (address_family, OWSL_MODE_DATAGRAM) ;
163        if (! owsl_system_socket_is_valid (socket->system_socket))
164        {
165                return -1 ;
166        }
167
168        if (owsl_base_register_in_monitor_for_read (socket, callback_function))
169        {
170                owsl_monitor_socket_remove (socket->system_socket) ;
171                return -1 ;
172        }
173
174        return 0 ;
175}
176
177int
178owsl_base_udp_close
179(
180        OWSLSocketInfo_with_SystemSocket * socket
181)
182{
183        int return_code = 0 ;
184        return_code |= owsl_monitor_socket_remove (socket->system_socket) ;
185        return_code |= owsl_system_socket_close (socket->system_socket) ;
186        return return_code ;
187}
188
189int
190owsl_base_tcp_open
191(
192        OWSLSocketInfo_with_ConnectedSystemSocket * socket,
193        OWSLAddressFamily address_family,
194        OWSLMonitorCallback callback_function
195)
196{
197        socket->system_socket = owsl_system_socket_open (address_family, OWSL_MODE_STREAM) ;
198        if (! owsl_system_socket_is_valid (socket->system_socket))
199        {
200                return -1 ;
201        }
202
203        if (owsl_base_register_in_monitor_for_read ((OWSLSocketInfo_with_SystemSocket *) socket, callback_function))
204        {
205                owsl_monitor_socket_remove (socket->system_socket) ;
206                return -1 ;
207        }
208
209        memset (& socket->remote_address, 0, sizeof (socket->remote_address)) ;
210        ((struct sockaddr *) (& socket->remote_address))->sa_family = AF_MAX ;
211        socket->remote_address_length = 0 ;
212
213        socket->remotely_closed = 0 ;
214
215        return 0 ;
216}
217
218int
219owsl_base_tcp_set
220(
221        OWSLSocketInfo_with_ConnectedSystemSocket * socket,
222        OWSLConnection * connection,
223        OWSLMonitorCallback callback_function
224)
225{
226        socket->system_socket = connection->system_socket ;
227        if (socket->system_socket < 0)
228        {
229                return -1 ;
230        }
231
232        if (owsl_base_register_in_monitor_for_read ((OWSLSocketInfo_with_SystemSocket *) socket, callback_function))
233        {
234                owsl_monitor_socket_remove (socket->system_socket) ;
235                return -1 ;
236        }
237
238        memset (& socket->remote_address, 0, sizeof (socket->remote_address)) ;
239        memcpy (& socket->remote_address, & connection->remote_address, connection->remote_address_length) ;
240        socket->remote_address_length = connection->remote_address_length ;
241
242        socket->remotely_closed = 0 ;
243
244        return 0 ;
245}
246
247int
248owsl_base_tcp_close
249(
250        OWSLSocketInfo_with_ConnectedSystemSocket * socket
251)
252{
253        int return_code = 0 ;
254        return_code |= owsl_monitor_socket_remove (socket->system_socket) ;
255        return_code |= owsl_system_socket_close (socket->system_socket) ;
256        return return_code ;
257}
258
259int
260owsl_base_bind
261(
262        OWSLSocketInfo * socket_info_with_system_socket,
263        struct sockaddr * address,
264        socklen_t address_length
265)
266{
267        int ret;
268        OWSLSocketInfo_with_SystemSocket * socket = (OWSLSocketInfo_with_SystemSocket *) socket_info_with_system_socket ;
269        ret = bind (socket->system_socket, address, address_length) ;
270        if (!ret)
271        {
272            socklen_t slen = address_length;
273            getsockname(socket->system_socket, address, &slen);
274        }
275        return ret;
276}
277
278int
279owsl_base_in_queue_listen
280(
281        OWSLSocketInfo * socket_info_with_system_socket,
282        int pending_max
283)
284{
285        OWSLSocketInfo_with_SystemSocket * socket = (OWSLSocketInfo_with_SystemSocket *) socket_info_with_system_socket ;
286        if (listen (socket->system_socket, pending_max))
287        {
288                return -1 ;
289        }
290        if (socket->out_queue != NULL)
291        {
292                if (owqueue_free (socket->out_queue))
293                {
294                        return -1 ;
295                }
296                socket->out_queue = NULL ;
297        }
298        if (owqueue_free (socket->in_queue))
299        {
300                return -1 ;
301        }
302        /* queue size must be exactly a multiple of connection size to allow callback when it is just full */
303        /* if full, callback will disable monitoring for incoming connections */
304        socket->in_queue = owqueue_new
305        (
306                sizeof (OWSLConnection) * (pending_max / 2 + 1),   /* usable size */
307                OWQUEUE_PACKET,                                    /* mode */
308                pending_max / 2 + 1,                               /* packet maximum */
309                0                                                  /* packet info size */
310        ) ;
311        if (socket->in_queue == NULL)
312        {
313                return -1 ;
314        }
315        return 0 ;
316}
317
318int
319owsl_base_in_queue_recv
320(
321        OWSLSocketInfo * socket,
322        void * buffer,
323        int size,
324        int flags
325)
326{
327        int read_bytes = owqueue_read (socket->in_queue, buffer, size, NULL, 0) ;
328        if (read_bytes <= 0)
329        {
330                if (read_bytes == 0)
331                {
332                        OW_SET_ERROR (EAGAIN) ;
333                }
334                read_bytes = -1 ;
335        }
336        return read_bytes ;
337}
338
339int
340owsl_base_in_queue_connected_recv
341(
342        OWSLSocketInfo * socket_info_with_connected_system_socket,
343        void * buffer,
344        int size,
345        int flags
346)
347{
348        OWSLSocketInfo_with_ConnectedSystemSocket * socket = (OWSLSocketInfo_with_ConnectedSystemSocket *) socket_info_with_connected_system_socket ;
349
350        int read_bytes = owqueue_read (socket->in_queue, buffer, size, NULL, socket->remotely_closed ? OWQUEUE_NON_BLOCKING : 0) ;
351        if (read_bytes <= 0)
352        {
353                if (socket->remotely_closed)
354                {
355                        read_bytes = 0 ;
356                }
357                else
358                {
359                        read_bytes = -1 ;
360                }
361        }
362        return read_bytes ;
363}
364
365int
366owsl_base_in_queue_recvfrom
367(
368        OWSLSocketInfo * socket,
369        void * buffer,
370        int size,
371        int flags,
372        struct sockaddr * address,
373        socklen_t * address_length
374)
375{
376        OWSLRemoteAddress info ;
377
378        int read_bytes = owqueue_read (socket->in_queue, buffer, size, & info, 0) ;
379        if (read_bytes > 0)
380        {
381                OW_MEMCPY (address, address_length, & info.remote_address, info.remote_address_length) ;
382        }
383        else
384        {
385                read_bytes = -1 ;
386        }
387
388        return read_bytes ;
389}
390
391int
392owsl_base_in_queue_connected_recvfrom
393(
394        OWSLSocketInfo * socket_info_with_connected_system_socket,
395        void * buffer,
396        int size,
397        int flags,
398        struct sockaddr * address,
399        socklen_t * address_length
400)
401{
402        OWSLSocketInfo_with_ConnectedSystemSocket * socket = (OWSLSocketInfo_with_ConnectedSystemSocket *) socket_info_with_connected_system_socket ;
403
404        int read_bytes = owqueue_read (socket->in_queue, buffer, size, NULL, socket->remotely_closed ? OWQUEUE_NON_BLOCKING : 0) ;
405        if (read_bytes > 0)
406        {
407                OW_MEMCPY (address, address_length, & socket->remote_address, socket->remote_address_length) ;
408        }
409        else
410        {
411                if (socket->remotely_closed)
412                {
413                        read_bytes = 0 ;
414                }
415                else
416                {
417                        read_bytes = -1 ;
418                }
419        }
420
421        return read_bytes ;
422}
423
424int
425owsl_base_out_queue_send
426(
427        OWSLSocketInfo * socket,
428        const void * buffer,
429        int length,
430        int flags
431)
432{
433        return owqueue_write (socket->out_queue, buffer, length, NULL, 0) ;
434}
435
436int
437owsl_base_out_queue_sendto
438(
439        OWSLSocketInfo * socket,
440        const void * buffer,
441        int length,
442        int flags,
443        const struct sockaddr * address,
444        socklen_t address_length
445)
446{
447        /* address and address_length are ignored */
448        return owqueue_write (socket->out_queue, buffer, length, NULL, 0) ;
449}
Note: See TracBrowser for help on using the repository browser.