source: qutecom-coip/wifo/owsl/src/core/owsl_socket.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: 6.5 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_internal.h"
21
22#include <stdlib.h>
23#include <memory.h>
24
25/* mapping between a socket handle and its info structure */
26static OWSLSocketInfo * owsl_socket_array [OWSL_SOCKET_MAX] ;
27/* last allocated handle (for allocation increment) */
28static int owsl_last_socket ;
29
30int
31owsl_socket_initialize
32(void)
33{
34        memset (owsl_socket_array, 0, sizeof (owsl_socket_array)) ;
35        owsl_last_socket = OWSL_SOCKET_MAX ;
36        return 0 ;
37}
38
39int
40owsl_socket_terminate
41(void)
42{
43        OWSLSocket socket ;
44        int return_code = 0 ;
45
46        for (socket = 1 ; socket <= OWSL_SOCKET_MAX ; socket ++)
47        {
48                if (owsl_socket_info_get (socket) != NULL)
49                {
50                        return_code |= owsl_close (socket) ;
51                }
52        }
53
54        return return_code ;
55}
56
57OWSLSocket
58owsl_socket_handle_get_new
59(void)
60{
61        OWSLSocket socket = owsl_last_socket ;
62        while (1)
63        {
64                /* socket must be in [1..OWSL_SOCKET_MAX] */
65                socket = socket % OWSL_SOCKET_MAX + 1 ;
66                if (owsl_socket_array [socket - 1] == NULL)
67                {
68                        return socket ;  /* a free handle is found */
69                }
70                if (socket == owsl_last_socket)
71                {
72                        return -1 ;   /* full */
73                }
74        }
75}
76
77void
78owsl_socket_handle_set
79(
80        OWSLSocket socket,
81        OWSLSocketInfo * socket_info
82)
83{
84        owsl_socket_array [socket - 1] = socket_info ;
85        owsl_last_socket = socket ;
86        return ;
87}
88
89void
90owsl_socket_handle_free
91(
92        OWSLSocket socket
93)
94{
95        owsl_socket_array [socket - 1] = NULL ;
96        return ;
97}
98
99OWSLSocketInfo *
100owsl_socket_info_new
101(
102        OWSLSocketType type,
103        size_t size,
104        int in_queue_usable_size,
105        OWQueuePacketMode in_queue_packet_mode,
106        int in_queue_packet_max,
107        int in_queue_packet_info_size,
108        int out_queue_usable_size,
109        OWQueuePacketMode out_queue_packet_mode,
110        int out_queue_packet_max,
111        int out_queue_packet_info_size
112)
113{
114        OWSLSocketInfo * socket_info = malloc (size) ;
115        if (socket_info != NULL)
116        {
117                socket_info->type_info = owsl_socket_type_info_get (type) ;
118                socket_info->blocking_mode = OWSL_BLOCKING ;
119                if (in_queue_usable_size > 0)
120                {
121                        socket_info->in_queue = owqueue_new
122                        (
123                                in_queue_usable_size,
124                                in_queue_packet_mode,
125                                in_queue_packet_max,
126                                in_queue_packet_info_size
127                        ) ;
128                        if (socket_info->in_queue == NULL)
129                        {
130                                free (socket_info) ;
131                                return NULL ;
132                        }
133                        owqueue_callback_set (socket_info->in_queue, (owsl_socket_type_info_get (type))->on_queue_event, socket_info) ;
134                }
135                else
136                {
137                        socket_info->in_queue = NULL ;
138                }
139                if (out_queue_usable_size > 0)
140                {
141                        socket_info->out_queue = owqueue_new
142                        (
143                                out_queue_usable_size,
144                                out_queue_packet_mode,
145                                out_queue_packet_max,
146                                out_queue_packet_info_size
147                        ) ;
148                        if (socket_info->out_queue == NULL)
149                        {
150                                if (in_queue_usable_size > 0)
151                                {
152                                        owqueue_free (socket_info->in_queue) ;
153                                }
154                                free (socket_info) ;
155                                return NULL ;
156                        }
157                        owqueue_callback_set (socket_info->out_queue, (owsl_socket_type_info_get (type))->on_queue_event, socket_info) ;
158                }
159                else
160                {
161                        socket_info->out_queue = NULL ;
162                }
163                if (pthread_mutex_init (& socket_info->listening_mutex, NULL))
164                {
165                        if (out_queue_usable_size > 0)
166                        {
167                                owqueue_free (socket_info->out_queue) ;
168                        }
169                        if (in_queue_usable_size > 0)
170                        {
171                                owqueue_free (socket_info->in_queue) ;
172                        }
173                        free (socket_info) ;
174                        return NULL ;
175                }
176                socket_info->listening = 0 ;
177                socket_info->connected = 0 ;
178                socket_info->error = 0 ;
179                socket_info->callback_function = NULL ;
180                socket_info->callback_user_data = NULL ;
181                memset (& socket_info->bound_address, 0, sizeof (socket_info->bound_address)) ;
182                ((struct sockaddr *) (& socket_info->bound_address))->sa_family = AF_MAX ;
183                socket_info->name = NULL ;
184        }
185        return socket_info ;
186}
187
188int
189owsl_socket_info_free
190(
191        OWSLSocketInfo * socket
192)
193{
194        int return_code = 0 ;
195
196        return_code |= pthread_mutex_destroy (& socket->listening_mutex) ;
197        if (socket->out_queue != NULL)
198        {
199                return_code |= owqueue_free (socket->out_queue) ;
200        }
201        if (socket->in_queue != NULL)
202        {
203                return_code |= owqueue_free (socket->in_queue) ;
204        }
205        if (socket->name != NULL)
206        {
207                free (socket->name) ;
208        }
209
210        free (socket) ;
211
212        return return_code ;
213}
214
215OWSLSocketInfo *
216owsl_socket_info_get
217(
218        OWSLSocket socket
219)
220{
221        if (socket <= 0 || socket > OWSL_SOCKET_MAX)
222        {
223                return NULL ;
224        }
225        return owsl_socket_array [socket - 1] ;
226}
227
228int
229owsl_socket_listen_disable
230(
231        OWSLSocketInfo * socket
232)
233{
234        if (pthread_mutex_lock (& socket->listening_mutex))
235        {
236                return -1 ;
237        }
238
239        if (socket->listening == 0)
240        {
241                socket->listening = -1 ;
242        }
243        else if (socket->listening == 1)
244        {
245                pthread_mutex_unlock (& socket->listening_mutex) ;
246                return -1 ;
247        }
248
249        if (pthread_mutex_unlock (& socket->listening_mutex))
250        {
251                return -1 ;
252        }
253
254        return 0 ;
255}
256
257int
258owsl_socket_listen_activate
259(
260        OWSLSocketInfo * socket
261)
262{
263        if (pthread_mutex_lock (& socket->listening_mutex))
264        {
265                return -1 ;
266        }
267
268        if (socket->listening == 0)
269        {
270                socket->listening = 1 ;
271        }
272        else if (socket->listening == -1)
273        {
274                pthread_mutex_unlock (& socket->listening_mutex) ;
275                return -1 ;
276        }
277
278        if (pthread_mutex_unlock (& socket->listening_mutex))
279        {
280                return -1 ;
281        }
282
283        return 0 ;
284}
285
286int
287owsl_socket_is_readable
288(
289        OWSLSocketInfo * socket
290)
291{
292        return
293        (
294                (
295                        socket->type_info->mode == OWSL_MODE_DATAGRAM
296                        ||
297                        socket->connected > 0
298                        ||
299                        socket->listening > 0
300                )
301                &&
302                (
303                        socket->in_queue == NULL
304                        ||
305                        ! owqueue_is_empty (socket->in_queue)
306                )
307                &&
308                (
309                        socket->type_info->is_readable == NULL
310                        ||
311                        socket->type_info->is_readable (socket)
312                )
313        ) ;
314}
315
316int
317owsl_socket_is_writable
318(
319        OWSLSocketInfo * socket
320)
321{
322        return
323        (
324                (
325                        socket->type_info->mode == OWSL_MODE_DATAGRAM
326                        ||
327                        socket->connected > 0
328                )
329                &&
330                (
331                        socket->out_queue == NULL
332                        ||
333                        ! owqueue_is_full (socket->out_queue)
334                )
335                &&
336                (
337                        socket->type_info->is_writable == NULL
338                        ||
339                        socket->type_info->is_writable (socket)
340                )
341        ) ;
342}
343
344int
345owsl_socket_has_error
346(
347        OWSLSocketInfo * socket
348)
349{
350        return
351        (
352                socket->error != 0
353                ||
354                (
355                        socket->type_info->has_error != NULL
356                        &&
357                        socket->type_info->has_error (socket)
358                )
359        ) ;
360}
Note: See TracBrowser for help on using the repository browser.