Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjlib / src / pj / sock_select_symbian.cpp
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/array.h>
22 #include <pj/assert.h>
23 #include <pj/os.h>
24 #include "os_symbian.h"
25
26  
27 struct symbian_fd_set
28 {
29     unsigned     count;
30     CPjSocket   *sock[PJ_IOQUEUE_MAX_HANDLES];
31 };
32
33
34 PJ_DEF(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp)
35 {
36     symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
37     fds->count = 0;
38 }
39
40
41 PJ_DEF(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp)
42 {
43     symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
44
45     PJ_ASSERT_ON_FAIL(fds->count < PJ_IOQUEUE_MAX_HANDLES, return);
46     fds->sock[fds->count++] = (CPjSocket*)fd;
47 }
48
49
50 PJ_DEF(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp)
51 {
52     symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
53     unsigned i;
54     
55     for (i=0; i<fds->count; ++i) {
56         if (fds->sock[i] == (CPjSocket*)fd) {
57             pj_array_erase(fds->sock, sizeof(fds->sock[0]), fds->count, i);
58             --fds->count;
59             return;
60         }
61     }
62 }
63
64
65 PJ_DEF(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp)
66 {
67     symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
68     unsigned i;
69     
70     for (i=0; i<fds->count; ++i) {
71         if (fds->sock[i] == (CPjSocket*)fd) {
72             return PJ_TRUE;
73         }
74     }
75
76     return PJ_FALSE;
77 }
78
79 PJ_DEF(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp)
80 {
81     symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
82     return fds->count;
83 }
84
85
86 PJ_DEF(int) pj_sock_select( int n, 
87                             pj_fd_set_t *readfds, 
88                             pj_fd_set_t *writefds,
89                             pj_fd_set_t *exceptfds, 
90                             const pj_time_val *timeout)
91 {
92     CPjTimeoutTimer *pjTimer;
93     unsigned i;
94
95     PJ_UNUSED_ARG(n);
96     PJ_UNUSED_ARG(writefds);
97     PJ_UNUSED_ARG(exceptfds);
98
99     if (timeout) {
100         pjTimer = PjSymbianOS::Instance()->SelectTimeoutTimer();
101         pjTimer->StartTimer(timeout->sec*1000 + timeout->msec);
102
103     } else {
104         pjTimer = NULL;
105     }
106
107     /* Scan for readable sockets */
108
109     if (readfds) {
110         symbian_fd_set *fds = (symbian_fd_set *)readfds;
111
112         do {
113             /* Scan sockets for readily available data */
114             for (i=0; i<fds->count; ++i) {
115                 CPjSocket *pjsock = fds->sock[i];
116
117                 if (pjsock->Reader()) {
118                     if (pjsock->Reader()->HasData() && !pjsock->Reader()->IsActive()) {
119
120                         /* Found socket with data ready */
121                         PJ_FD_ZERO(readfds);
122                         PJ_FD_SET((pj_sock_t)pjsock, readfds);
123
124                         /* Cancel timer, if any */
125                         if (pjTimer) {
126                             pjTimer->Cancel();
127                         }
128
129                         /* Clear writable and exception fd_set */
130                         if (writefds)
131                             PJ_FD_ZERO(writefds);
132                         if (exceptfds)
133                             PJ_FD_ZERO(exceptfds);
134
135                         return 1;
136
137                     } else if (!pjsock->Reader()->IsActive())
138                         pjsock->Reader()->StartRecvFrom();
139
140                 } else {
141                     pjsock->CreateReader();
142                     pjsock->Reader()->StartRecvFrom();
143                 }
144             }
145
146             PjSymbianOS::Instance()->WaitForActiveObjects();
147
148         } while (pjTimer==NULL || !pjTimer->HasTimedOut());
149     }
150
151
152     /* Timeout */
153
154     if (readfds)
155         PJ_FD_ZERO(readfds);
156     if (writefds)
157         PJ_FD_ZERO(writefds);
158     if (exceptfds)
159         PJ_FD_ZERO(exceptfds);
160
161     return 0;
162 }
163