Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjlib / src / pj / sock_select.c
1 /* $Id$ */
2 /* 
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19  */
20 #include <pj/sock_select.h>
21 #include <pj/compat/socket.h>
22 #include <pj/os.h>
23 #include <pj/assert.h>
24 #include <pj/errno.h>
25
26 #if defined(PJ_HAS_STRING_H) && PJ_HAS_STRING_H!=0
27 #   include <string.h>
28 #endif
29
30 #if defined(PJ_HAS_SYS_TIME_H) && PJ_HAS_SYS_TIME_H!=0
31 #   include <sys/time.h>
32 #endif
33
34 #ifdef _MSC_VER
35 #   pragma warning(disable: 4018)    // Signed/unsigned mismatch in FD_*
36 #   pragma warning(disable: 4389)    // Signed/unsigned mismatch in FD_*
37 #endif
38
39 #define PART_FDSET(ps)          ((fd_set*)&ps->data[1])
40 #define PART_FDSET_OR_NULL(ps)  (ps ? PART_FDSET(ps) : NULL)
41 #define PART_COUNT(ps)          (ps->data[0])
42
43 PJ_DEF(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp)
44 {
45     PJ_CHECK_STACK();
46     pj_assert(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set));
47
48     FD_ZERO(PART_FDSET(fdsetp));
49     PART_COUNT(fdsetp) = 0;
50 }
51
52
53 PJ_DEF(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp)
54 {
55     PJ_CHECK_STACK();
56     pj_assert(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set));
57
58     if (!PJ_FD_ISSET(fd, fdsetp))
59         ++PART_COUNT(fdsetp);
60     FD_SET(fd, PART_FDSET(fdsetp));
61 }
62
63
64 PJ_DEF(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp)
65 {
66     PJ_CHECK_STACK();
67     pj_assert(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set));
68
69     if (PJ_FD_ISSET(fd, fdsetp))
70         --PART_COUNT(fdsetp);
71     FD_CLR(fd, PART_FDSET(fdsetp));
72 }
73
74
75 PJ_DEF(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp)
76 {
77     PJ_CHECK_STACK();
78     PJ_ASSERT_RETURN(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set),
79                      0);
80
81     return FD_ISSET(fd, PART_FDSET(fdsetp));
82 }
83
84 PJ_DEF(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp)
85 {
86     return PART_COUNT(fdsetp);
87 }
88
89 PJ_DEF(int) pj_sock_select( int n, 
90                             pj_fd_set_t *readfds, 
91                             pj_fd_set_t *writefds,
92                             pj_fd_set_t *exceptfds, 
93                             const pj_time_val *timeout)
94 {
95     struct timeval os_timeout, *p_os_timeout;
96
97     PJ_CHECK_STACK();
98
99     PJ_ASSERT_RETURN(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set),
100                      PJ_EBUG);
101
102     if (timeout) {
103         os_timeout.tv_sec = timeout->sec;
104         os_timeout.tv_usec = timeout->msec * 1000;
105         p_os_timeout = &os_timeout;
106     } else {
107         p_os_timeout = NULL;
108     }
109
110     return select(n, PART_FDSET_OR_NULL(readfds), PART_FDSET_OR_NULL(writefds),
111                   PART_FDSET_OR_NULL(exceptfds), p_os_timeout);
112 }
113