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