1 /*
2 eXosip - This is the eXtended osip library.
3 Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com
4
5 eXosip 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 eXosip 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 In addition, as a special exception, the copyright holders give
20 permission to link the code of portions of this program with the
21 OpenSSL library under certain conditions as described in each
22 individual source file, and distribute linked combinations
23 including the two.
24 You must obey the GNU General Public License in all respects
25 for all of the code used other than OpenSSL. If you modify
26 file(s) with this exception, you may extend this exception to your
27 version of the file(s), but you are not obligated to do so. If you
28 do not wish to do so, delete this exception statement from your
29 version. If you delete this exception statement from all source
30 files in the program, then also delete it here.
31 */
32
33 #include "eXosip2.h"
34 #include <eXosip2/eXosip.h>
35 #include <osip2/osip_condv.h>
36
37 static int _eXosip_event_fill_messages(eXosip_event_t *je, osip_transaction_t *tr);
38
_eXosip_event_fill_messages(eXosip_event_t * je,osip_transaction_t * tr)39 static int _eXosip_event_fill_messages(eXosip_event_t *je, osip_transaction_t *tr) {
40 int i;
41
42 if (tr != NULL && tr->orig_request != NULL) {
43 i = osip_message_clone(tr->orig_request, &je->request);
44
45 if (i != 0) {
46 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] failed to clone request for event\n"));
47 }
48 }
49
50 if (tr != NULL && tr->last_response != NULL) {
51 i = osip_message_clone(tr->last_response, &je->response);
52
53 if (i != 0) {
54 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] failed to clone response for event\n"));
55 }
56 }
57
58 if (tr != NULL && tr->ack != NULL) {
59 i = osip_message_clone(tr->ack, &je->ack);
60
61 if (i != 0) {
62 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] failed to clone ACK for event\n"));
63 }
64 }
65
66 return OSIP_SUCCESS;
67 }
68
_eXosip_event_init_for_call(int type,eXosip_call_t * jc,eXosip_dialog_t * jd,osip_transaction_t * tr)69 eXosip_event_t *_eXosip_event_init_for_call(int type, eXosip_call_t *jc, eXosip_dialog_t *jd, osip_transaction_t *tr) {
70 eXosip_event_t *je;
71
72 if (jc == NULL)
73 return NULL;
74
75 _eXosip_event_init(&je, type);
76
77 if (je == NULL)
78 return NULL;
79
80 je->cid = jc->c_id;
81
82 if (jd != NULL)
83 je->did = jd->d_id;
84
85 if (tr != NULL)
86 je->tid = tr->transactionid;
87
88 je->external_reference = jc->external_reference;
89
90 _eXosip_event_fill_messages(je, tr);
91 return je;
92 }
93
94 #ifndef MINISIZE
95
_eXosip_event_init_for_subscription(int type,eXosip_subscribe_t * js,eXosip_dialog_t * jd,osip_transaction_t * tr)96 eXosip_event_t *_eXosip_event_init_for_subscription(int type, eXosip_subscribe_t *js, eXosip_dialog_t *jd, osip_transaction_t *tr) {
97 eXosip_event_t *je;
98
99 if (js == NULL)
100 return NULL;
101
102 _eXosip_event_init(&je, type);
103
104 if (je == NULL)
105 return NULL;
106
107 je->sid = js->s_id;
108
109 if (jd != NULL)
110 je->did = jd->d_id;
111
112 if (tr != NULL)
113 je->tid = tr->transactionid;
114
115 je->ss_status = js->s_ss_status;
116 je->ss_reason = js->s_ss_reason;
117
118 /* je->external_reference = js->external_reference; */
119
120 _eXosip_event_fill_messages(je, tr);
121
122 return je;
123 }
124
_eXosip_event_init_for_notify(int type,eXosip_notify_t * jn,eXosip_dialog_t * jd,osip_transaction_t * tr)125 eXosip_event_t *_eXosip_event_init_for_notify(int type, eXosip_notify_t *jn, eXosip_dialog_t *jd, osip_transaction_t *tr) {
126 eXosip_event_t *je;
127
128 if (jn == NULL)
129 return NULL;
130
131 _eXosip_event_init(&je, type);
132
133 if (je == NULL)
134 return NULL;
135
136 je->nid = jn->n_id;
137
138 if (jd != NULL)
139 je->did = jd->d_id;
140
141 if (tr != NULL)
142 je->tid = tr->transactionid;
143
144 je->ss_status = jn->n_ss_status;
145 je->ss_reason = jn->n_ss_reason;
146
147 /*je->external_reference = jc->external_reference; */
148
149 _eXosip_event_fill_messages(je, tr);
150
151 return je;
152 }
153
154 #endif
155
_eXosip_event_init_for_reg(int type,eXosip_reg_t * jr,osip_transaction_t * tr)156 eXosip_event_t *_eXosip_event_init_for_reg(int type, eXosip_reg_t *jr, osip_transaction_t *tr) {
157 eXosip_event_t *je;
158
159 if (jr == NULL)
160 return NULL;
161
162 _eXosip_event_init(&je, type);
163
164 if (je == NULL)
165 return NULL;
166
167 je->rid = jr->r_id;
168
169 _eXosip_event_fill_messages(je, tr);
170 return je;
171 }
172
_eXosip_event_init_for_message(int type,osip_transaction_t * tr)173 eXosip_event_t *_eXosip_event_init_for_message(int type, osip_transaction_t *tr) {
174 eXosip_event_t *je;
175
176 _eXosip_event_init(&je, type);
177
178 if (je == NULL)
179 return NULL;
180
181 if (tr != NULL)
182 je->tid = tr->transactionid;
183
184 _eXosip_event_fill_messages(je, tr);
185
186 return je;
187 }
188
_eXosip_event_init(eXosip_event_t ** je,int type)189 int _eXosip_event_init(eXosip_event_t **je, int type) {
190 *je = (eXosip_event_t *) osip_malloc(sizeof(eXosip_event_t));
191
192 if (*je == NULL)
193 return OSIP_NOMEM;
194
195 memset(*je, 0, sizeof(eXosip_event_t));
196 (*je)->type = type;
197
198 #if !defined(_WIN32_WCE)
199
200 if (type == EXOSIP_CALL_NOANSWER) {
201 sprintf((*je)->textinfo, "No answer for this Call!");
202
203 } else if (type == EXOSIP_CALL_PROCEEDING) {
204 sprintf((*je)->textinfo, "Call is being processed!");
205
206 } else if (type == EXOSIP_CALL_RINGING) {
207 sprintf((*je)->textinfo, "Remote phone is ringing!");
208
209 } else if (type == EXOSIP_CALL_ANSWERED) {
210 sprintf((*je)->textinfo, "Remote phone has answered!");
211
212 } else if (type == EXOSIP_CALL_REDIRECTED) {
213 sprintf((*je)->textinfo, "Call is redirected!");
214
215 } else if (type == EXOSIP_CALL_REQUESTFAILURE) {
216 sprintf((*je)->textinfo, "4xx received for Call!");
217
218 } else if (type == EXOSIP_CALL_SERVERFAILURE) {
219 sprintf((*je)->textinfo, "5xx received for Call!");
220
221 } else if (type == EXOSIP_CALL_GLOBALFAILURE) {
222 sprintf((*je)->textinfo, "6xx received for Call!");
223
224 } else if (type == EXOSIP_CALL_INVITE) {
225 sprintf((*je)->textinfo, "New call received!");
226
227 } else if (type == EXOSIP_CALL_ACK) {
228 sprintf((*je)->textinfo, "ACK received!");
229
230 } else if (type == EXOSIP_CALL_CANCELLED) {
231 sprintf((*je)->textinfo, "Call has been cancelled!");
232
233 } else if (type == EXOSIP_CALL_REINVITE) {
234 sprintf((*je)->textinfo, "INVITE within call received!");
235
236 } else if (type == EXOSIP_CALL_CLOSED) {
237 sprintf((*je)->textinfo, "Bye Received!");
238
239 } else if (type == EXOSIP_CALL_RELEASED) {
240 sprintf((*je)->textinfo, "Call Context is released!");
241
242 } else if (type == EXOSIP_REGISTRATION_SUCCESS) {
243 sprintf((*je)->textinfo, "User is successfully registred!");
244
245 } else if (type == EXOSIP_REGISTRATION_FAILURE) {
246 sprintf((*je)->textinfo, "Registration failed!");
247
248 } else if (type == EXOSIP_CALL_MESSAGE_NEW) {
249 sprintf((*je)->textinfo, "New request received!");
250
251 } else if (type == EXOSIP_CALL_MESSAGE_PROCEEDING) {
252 sprintf((*je)->textinfo, "request is being processed!");
253
254 } else if (type == EXOSIP_CALL_MESSAGE_ANSWERED) {
255 sprintf((*je)->textinfo, "2xx received for request!");
256
257 } else if (type == EXOSIP_CALL_MESSAGE_REDIRECTED) {
258 sprintf((*je)->textinfo, "3xx received for request!");
259
260 } else if (type == EXOSIP_CALL_MESSAGE_REQUESTFAILURE) {
261 sprintf((*je)->textinfo, "4xx received for request!");
262
263 } else if (type == EXOSIP_CALL_MESSAGE_SERVERFAILURE) {
264 sprintf((*je)->textinfo, "5xx received for request!");
265
266 } else if (type == EXOSIP_CALL_MESSAGE_GLOBALFAILURE) {
267 sprintf((*je)->textinfo, "5xx received for request!");
268
269 } else if (type == EXOSIP_MESSAGE_NEW) {
270 sprintf((*je)->textinfo, "New request outside call received!");
271
272 } else if (type == EXOSIP_MESSAGE_PROCEEDING) {
273 sprintf((*je)->textinfo, "request outside call is being processed!");
274
275 } else if (type == EXOSIP_MESSAGE_ANSWERED) {
276 sprintf((*je)->textinfo, "2xx received for request outside call!");
277
278 } else if (type == EXOSIP_MESSAGE_REDIRECTED) {
279 sprintf((*je)->textinfo, "3xx received for request outside call!");
280
281 } else if (type == EXOSIP_MESSAGE_REQUESTFAILURE) {
282 sprintf((*je)->textinfo, "4xx received for request outside call!");
283
284 } else if (type == EXOSIP_MESSAGE_SERVERFAILURE) {
285 sprintf((*je)->textinfo, "5xx received for request outside call!");
286
287 } else if (type == EXOSIP_MESSAGE_GLOBALFAILURE) {
288 sprintf((*je)->textinfo, "5xx received for request outside call!");
289
290 } else if (type == EXOSIP_SUBSCRIPTION_NOANSWER) {
291 sprintf((*je)->textinfo, "No answer for this SUBSCRIBE!");
292
293 } else if (type == EXOSIP_SUBSCRIPTION_PROCEEDING) {
294 sprintf((*je)->textinfo, "SUBSCRIBE is being processed!");
295
296 } else if (type == EXOSIP_SUBSCRIPTION_ANSWERED) {
297 sprintf((*je)->textinfo, "2xx received for SUBSCRIBE!");
298
299 } else if (type == EXOSIP_SUBSCRIPTION_REDIRECTED) {
300 sprintf((*je)->textinfo, "3xx received for SUBSCRIBE!");
301
302 } else if (type == EXOSIP_SUBSCRIPTION_REQUESTFAILURE) {
303 sprintf((*je)->textinfo, "4xx received for SUBSCRIBE!");
304
305 } else if (type == EXOSIP_SUBSCRIPTION_SERVERFAILURE) {
306 sprintf((*je)->textinfo, "5xx received for SUBSCRIBE!");
307
308 } else if (type == EXOSIP_SUBSCRIPTION_GLOBALFAILURE) {
309 sprintf((*je)->textinfo, "5xx received for SUBSCRIBE!");
310
311 } else if (type == EXOSIP_SUBSCRIPTION_NOTIFY) {
312 sprintf((*je)->textinfo, "NOTIFY request for subscription!");
313
314 } else if (type == EXOSIP_IN_SUBSCRIPTION_NEW) {
315 sprintf((*je)->textinfo, "New incoming SUBSCRIBE!");
316
317 } else {
318 (*je)->textinfo[0] = '\0';
319 }
320
321 #endif
322 return OSIP_SUCCESS;
323 }
324
eXosip_event_free(eXosip_event_t * je)325 void eXosip_event_free(eXosip_event_t *je) {
326 if (je == NULL)
327 return;
328
329 if (je->request != NULL)
330 osip_message_free(je->request);
331
332 if (je->response != NULL)
333 osip_message_free(je->response);
334
335 if (je->ack != NULL)
336 osip_message_free(je->ack);
337
338 osip_free(je);
339 }
340
_eXosip_report_event(struct eXosip_t * excontext,eXosip_event_t * je)341 void _eXosip_report_event(struct eXosip_t *excontext, eXosip_event_t *je) {
342 if (je != NULL) {
343 _eXosip_event_add(excontext, je);
344 }
345 }
346
_eXosip_report_call_event(struct eXosip_t * excontext,int evt,eXosip_call_t * jc,eXosip_dialog_t * jd,osip_transaction_t * tr)347 void _eXosip_report_call_event(struct eXosip_t *excontext, int evt, eXosip_call_t *jc, eXosip_dialog_t *jd, osip_transaction_t *tr) {
348 eXosip_event_t *je;
349
350 je = _eXosip_event_init_for_call(evt, jc, jd, tr);
351 _eXosip_report_event(excontext, je);
352 }
353
_eXosip_event_add(struct eXosip_t * excontext,eXosip_event_t * je)354 int _eXosip_event_add(struct eXosip_t *excontext, eXosip_event_t *je) {
355 int i = osip_fifo_add(excontext->j_events, (void *) je);
356
357 #ifndef OSIP_MONOTHREAD
358 #if !defined(_WIN32_WCE)
359 osip_cond_signal((struct osip_cond *) excontext->j_cond);
360 #endif
361 #endif
362
363 eXosip_wakeup_event(excontext);
364 return i;
365 }
366
367 #ifdef OSIP_MONOTHREAD
368
eXosip_event_wait(struct eXosip_t * excontext,int tv_s,int tv_ms)369 eXosip_event_t *eXosip_event_wait(struct eXosip_t *excontext, int tv_s, int tv_ms) {
370 eXosip_event_t *je = NULL;
371
372 je = (eXosip_event_t *) osip_fifo_tryget(excontext->j_events);
373
374 if (je != NULL)
375 return je;
376
377 eXosip_lock(excontext);
378 _eXosip_retransmit_lost200ok(excontext);
379 eXosip_unlock(excontext);
380
381 return NULL;
382 }
383
384 #else
385
386 #ifdef HAVE_SYS_EPOLL_H
387
eXosip_event_wait_epoll(struct eXosip_t * excontext,int tv_s,int tv_ms)388 static eXosip_event_t *eXosip_event_wait_epoll(struct eXosip_t *excontext, int tv_s, int tv_ms) {
389 eXosip_event_t *je = NULL;
390 struct epoll_event ep_array;
391
392 int nfds;
393
394 eXosip_lock(excontext);
395 _eXosip_retransmit_lost200ok(excontext);
396 eXosip_unlock(excontext);
397
398 if (tv_s == 0 && tv_ms == 0)
399 return NULL;
400
401 nfds = epoll_wait(excontext->epfdctl, &ep_array, 1, tv_s * 1000 + tv_ms);
402
403 if (nfds <= 0)
404 return OSIP_SUCCESS;
405
406 if (excontext->j_stop_ua)
407 return NULL;
408
409 if (nfds > 0) {
410 char buf[500];
411
412 jpipe_read(excontext->j_socketctl_event, buf, 499);
413 }
414
415 je = (eXosip_event_t *) osip_fifo_tryget(excontext->j_events);
416
417 if (je != NULL)
418 return je;
419
420 return je;
421 }
422
423 #endif
424
eXosip_event_wait(struct eXosip_t * excontext,int tv_s,int tv_ms)425 eXosip_event_t *eXosip_event_wait(struct eXosip_t *excontext, int tv_s, int tv_ms) {
426 eXosip_event_t *je = NULL;
427
428 fd_set fdset;
429 struct timeval tv;
430 int max, i;
431
432 if (excontext == NULL) {
433 return NULL;
434 }
435
436 je = (eXosip_event_t *) osip_fifo_tryget(excontext->j_events);
437
438 if (je != NULL)
439 return je;
440
441 #ifdef HAVE_SYS_EPOLL_H
442
443 if (excontext->poll_method == EXOSIP_USE_EPOLL_LT) {
444 return eXosip_event_wait_epoll(excontext, tv_s, tv_ms);
445 }
446
447 #endif
448
449 FD_ZERO(&fdset);
450 eXFD_SET(jpipe_get_read_descr(excontext->j_socketctl_event), &fdset);
451 max = jpipe_get_read_descr(excontext->j_socketctl_event);
452
453 tv.tv_sec = 0;
454 tv.tv_usec = 0;
455 i = select(max + 1, &fdset, NULL, NULL, &tv);
456
457 if (FD_ISSET(jpipe_get_read_descr(excontext->j_socketctl_event), &fdset)) {
458 char buf[500];
459
460 jpipe_read(excontext->j_socketctl_event, buf, 499);
461 }
462
463 eXosip_lock(excontext);
464 _eXosip_retransmit_lost200ok(excontext);
465 eXosip_unlock(excontext);
466
467 FD_ZERO(&fdset);
468 eXFD_SET(jpipe_get_read_descr(excontext->j_socketctl_event), &fdset);
469 tv.tv_sec = tv_s;
470 tv.tv_usec = tv_ms * 1000;
471
472 if (tv_s == 0 && tv_ms == 0)
473 return NULL;
474
475 i = select(max + 1, &fdset, NULL, NULL, &tv);
476
477 if (i <= 0)
478 return OSIP_SUCCESS;
479
480 if (excontext->j_stop_ua)
481 return NULL;
482
483 if (FD_ISSET(jpipe_get_read_descr(excontext->j_socketctl_event), &fdset)) {
484 char buf[500];
485
486 jpipe_read(excontext->j_socketctl_event, buf, 499);
487 }
488
489 je = (eXosip_event_t *) osip_fifo_tryget(excontext->j_events);
490
491 if (je != NULL)
492 return je;
493
494 return je;
495 }
496
eXosip_event_geteventsocket(struct eXosip_t * excontext)497 int eXosip_event_geteventsocket(struct eXosip_t *excontext) {
498 return jpipe_get_read_descr(excontext->j_socketctl_event);
499 }
500
501 #ifdef HAVE_SYS_EPOLL_H
502
eXosip_event_get_epoll(struct eXosip_t * excontext)503 static eXosip_event_t *eXosip_event_get_epoll(struct eXosip_t *excontext) {
504 struct epoll_event ep_array;
505
506 int nfds = epoll_wait(excontext->epfdctl, &ep_array, 1, 0);
507
508 if (nfds > 0) {
509 char buf[500];
510
511 jpipe_read(excontext->j_socketctl_event, buf, 499);
512 }
513
514 return (eXosip_event_t *) osip_fifo_get(excontext->j_events);
515 }
516
517 #endif
518
eXosip_event_get(struct eXosip_t * excontext)519 eXosip_event_t *eXosip_event_get(struct eXosip_t *excontext) {
520 fd_set fdset;
521 struct timeval tv;
522 int max;
523
524 #ifdef HAVE_SYS_EPOLL_H
525
526 if (excontext->poll_method == EXOSIP_USE_EPOLL_LT) {
527 return eXosip_event_get_epoll(excontext);
528 }
529
530 #endif
531
532 FD_ZERO(&fdset);
533 eXFD_SET(jpipe_get_read_descr(excontext->j_socketctl_event), &fdset);
534 max = jpipe_get_read_descr(excontext->j_socketctl_event);
535
536 tv.tv_sec = 0;
537 tv.tv_usec = 0;
538 select(max + 1, &fdset, NULL, NULL, &tv);
539
540 if (FD_ISSET(jpipe_get_read_descr(excontext->j_socketctl_event), &fdset)) {
541 char buf[500];
542
543 jpipe_read(excontext->j_socketctl_event, buf, 499);
544 }
545
546 return (eXosip_event_t *) osip_fifo_get(excontext->j_events);
547 }
548
549 #endif
550