summaryrefslogtreecommitdiff
path: root/toxmsi/toxmsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxmsi/toxmsi.c')
-rw-r--r--toxmsi/toxmsi.c835
1 files changed, 0 insertions, 835 deletions
diff --git a/toxmsi/toxmsi.c b/toxmsi/toxmsi.c
deleted file mode 100644
index 38af28fb..00000000
--- a/toxmsi/toxmsi.c
+++ /dev/null
@@ -1,835 +0,0 @@
1
2#ifdef HAVE_CONFIG_H
3#include "config.h"
4#endif /* HAVE_CONFIG_H */
5
6#define _BSD_SOURCE
7
8#include "toxmsi.h"
9#include "toxmsi_event.h"
10#include "toxmsi_message.h"
11#include "../toxrtp/toxrtp_helper.h"
12#include "../toxcore/network.h"
13
14#include <assert.h>
15#include <unistd.h>
16#include <string.h>
17
18#define same(x, y) strcmp((const char*) x, (const char*) y) == 0
19
20typedef enum {
21 error_deadcall = 1, /* has call id but it's from old call */
22 error_id_mismatch, /* non-existing call */
23
24 error_no_callid, /* not having call id */
25 error_no_call, /* no call in session */
26
27 error_busy
28} msi_error_t; /* Error codes */
29
30static inline const uint8_t *stringify_error(msi_error_t _error_code)
31{
32 static const uint8_t* strings[] =
33 {
34 (uint8_t*)"",
35 (uint8_t*)"Using dead call",
36 (uint8_t*)"Call id not set to any call",
37 (uint8_t*)"Call id not available",
38 (uint8_t*)"No active call in session",
39 (uint8_t*)"Callee busy"
40 };
41
42 return strings[_error_code];
43}
44
45static inline const uint8_t *stringify_error_code(msi_error_t _error_code)
46{
47 static const uint8_t* strings[] =
48 {
49 (uint8_t*)"",
50 (uint8_t*)"1",
51 (uint8_t*)"2",
52 (uint8_t*)"3",
53 (uint8_t*)"4",
54 (uint8_t*)"5"
55 };
56
57 return strings[_error_code];
58}
59
60/* ******************* */
61/* --------- GLOBAL FUNCTIONS USED BY THIS FILE --------- */
62
63/* CALLBACKS */
64/*int (*msi_send_message_callback) ( int, uint8_t*, uint32_t ) = NULL;*/
65int ( *msi_send_message_callback ) ( void* _core_handler, tox_IP_Port, uint8_t*, uint32_t ) = NULL;
66int ( *msi_recv_message_callback ) ( tox_IP_Port*, uint8_t*, uint32_t* ) = NULL;
67
68MCBTYPE ( *msi_recv_invite_callback ) ( MCBARGS ) = NULL;
69MCBTYPE ( *msi_start_call_callback ) ( MCBARGS ) = NULL;
70MCBTYPE ( *msi_reject_call_callback ) ( MCBARGS ) = NULL;
71MCBTYPE ( *msi_cancel_call_callback ) ( MCBARGS ) = NULL;
72MCBTYPE ( *msi_end_call_callback ) ( MCBARGS ) = NULL;
73
74MCBTYPE ( *msi_ringing_callback ) ( MCBARGS ) = NULL;
75MCBTYPE ( *msi_starting_callback ) ( MCBARGS ) = NULL;
76MCBTYPE ( *msi_ending_callback ) ( MCBARGS ) = NULL;
77MCBTYPE ( *msi_error_callback ) ( MCBARGS ) = NULL;
78
79MCBTYPE ( *msi_timeout_callback ) ( MCBARGS ) = NULL;
80/* End of CALLBACKS */
81
82/*------------------------*/
83/*------------------------*/
84/*------------------------*/
85/*------------------------*/
86/*------------------------*/
87/*------------------------*/
88/*------------------------*/
89/*------------------------*/
90/*------------------------*/
91/*------------------------*/
92/*------------------------*/
93/*------------------------*/
94
95/* REGISTER CALLBACKS */
96/*void msi_register_callback_send(int (*callback) ( int, uint8_t*, uint32_t ) )*/
97void msi_register_callback_send ( int ( *callback ) ( void* _core_handler, tox_IP_Port, uint8_t*, uint32_t ) )
98{
99 msi_send_message_callback = callback;
100}
101
102void msi_register_callback_recv ( int ( *callback ) ( tox_IP_Port*, uint8_t*, uint32_t* ) )
103{
104 msi_recv_message_callback = callback;
105}
106
107/* Function to be called when received invite.
108 * This callback is all about what you do with it.
109 * Everything else is done internally.
110 */
111void msi_register_callback_recv_invite ( MCALLBACK )
112{
113 msi_recv_invite_callback = callback;
114}
115
116/* Function to be called when the call is started
117 * This callback is all about what you do with it.
118 * Everything else is done internally.
119 */
120void msi_register_callback_call_started ( MCALLBACK )
121{
122 msi_start_call_callback = callback;
123}
124
125/* Function to be called when call is rejected
126 * This callback is all about what you do with it.
127 * Everything else is done internally.
128 */
129void msi_register_callback_call_rejected ( MCALLBACK )
130{
131 msi_reject_call_callback = callback;
132}
133
134/* Function to be called when call is canceled
135 * This callback is all about what you do with it.
136 * Everything else is done internally.
137 */
138void msi_register_callback_call_canceled ( MCALLBACK )
139{
140 msi_cancel_call_callback = callback;
141}
142
143void msi_register_callback_call_ended ( MCALLBACK )
144{
145 msi_end_call_callback = callback;
146}
147
148
149/* Functions to be called when gotten x response */
150
151void msi_register_callback_recv_ringing ( MCALLBACK )
152{
153 msi_ringing_callback = callback;
154}
155void msi_register_callback_recv_starting ( MCALLBACK )
156{
157 msi_starting_callback = callback;
158}
159void msi_register_callback_recv_ending ( MCALLBACK )
160{
161 msi_ending_callback = callback;
162}
163
164void msi_register_callback_recv_error ( MCALLBACK )
165{
166 msi_error_callback = callback;
167}
168
169/* Timeout */
170void msi_register_callback_requ_timeout ( MCALLBACK )
171{
172 msi_timeout_callback = callback;
173}
174/* END REGISTERING */
175
176/*------------------------*/
177/*------------------------*/
178/*------------------------*/
179/*------------------------*/
180/*------------------------*/
181/*------------------------*/
182/*------------------------*/
183/*------------------------*/
184/*------------------------*/
185/*------------------------*/
186/*------------------------*/
187/*------------------------*/
188
189/* Function for receiving and parsing a message that will be used internally */
190
191msi_msg_t* receive_message ( msi_session_t* _session )
192{
193 assert(_session);
194
195
196 msi_msg_t* _retu = _session->_oldest_msg;
197
198 pthread_mutex_lock ( &_session->_mutex );
199
200 if ( _retu )
201 _session->_oldest_msg = _retu->_next;
202
203 if ( !_session->_oldest_msg )
204 _session->_last_msg = NULL;
205
206 pthread_mutex_unlock ( &_session->_mutex );
207
208 return _retu;
209}
210
211void msi_store_msg ( msi_session_t* _session, msi_msg_t* _msg )
212{
213 assert(_session);
214 assert(_msg);
215
216 pthread_mutex_lock ( &_session->_mutex );
217
218 if ( _session->_last_msg ) {
219 _session->_last_msg->_next = _msg;
220 _session->_last_msg = _msg;
221 } else {
222 _session->_last_msg = _session->_oldest_msg = _msg;
223 }
224
225 pthread_mutex_unlock ( &_session->_mutex );
226}
227
228int msi_send_msg ( msi_session_t* _session, msi_msg_t* _msg )
229{
230 int _status;
231
232 if ( !_session->_call ) /* Which should never happen */
233 return FAILURE;
234
235 msi_msg_set_call_id ( _msg, _session->_call->_id );
236
237 uint8_t _msg_string_final [MSI_MAXMSG_SIZE];
238 t_memset ( _msg_string_final, '\0', MSI_MAXMSG_SIZE );
239
240 _msg_string_final[0] = 69;
241
242 uint8_t* _msg_string = msi_msg_to_string ( _msg );
243
244 size_t _lenght = t_memlen ( _msg_string );
245
246 memcpy ( _msg_string_final + 1, _msg_string, _lenght );
247
248 _lenght += 1;
249
250 _status = ( *msi_send_message_callback ) ( _session->_core_handler, _session->_friend_id, _msg_string_final, _lenght );
251
252 free ( _msg_string );
253
254 return _status;
255}
256
257/* Random stuff */
258void flush_peer_type ( msi_session_t* _session, msi_msg_t* _msg, int _peer_id )
259{
260 if ( _msg->_call_type ) {
261 if ( strcmp ( ( const char* ) _msg->_call_type->_header_value, CT_AUDIO_HEADER_VALUE ) == 0 ) {
262 _session->_call->_type_peer[_peer_id] = type_audio;
263
264 } else if ( strcmp ( ( const char* ) _msg->_call_type->_header_value, CT_VIDEO_HEADER_VALUE ) == 0 ) {
265 _session->_call->_type_peer[_peer_id] = type_video;
266 } else {} /* Error */
267 } else {} /* Error */
268}
269
270int has_call_error ( msi_session_t* _session, msi_msg_t* _msg )
271{
272 msi_msg_t* _msg_error = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _error ) );
273
274 if ( !_msg->_call_id ) {
275 msi_msg_set_reason(_msg_error, stringify_error_code(error_no_callid) );
276
277 } else if ( !_session->_call ) {
278 msi_msg_set_reason(_msg_error, stringify_error_code(error_no_call) );
279
280 } else if ( strcmp((const char*)_session->_call->_id, (const char*)_msg->_call_id->_header_value ) != 0 ) {
281 msi_msg_set_reason(_msg_error, stringify_error_code(error_id_mismatch) );
282 }
283
284 if ( _msg_error->_reason ) {
285 msi_send_msg ( _session, _msg_error );
286 msi_free_msg ( _msg_error );
287 return SUCCESS;
288 }
289
290 msi_free_msg ( _msg_error );
291 return FAILURE;
292}
293
294/* --------- END OF GLOBAL FUNCTIONS USED BY THIS FILE --------- */
295
296/*------------------------*/
297/*------------------------*/
298/*------------------------*/
299/*------------------------*/
300/*------------------------*/
301/*------------------------*/
302/*------------------------*/
303/*------------------------*/
304/*------------------------*/
305/*------------------------*/
306/*------------------------*/
307/*------------------------*/
308
309msi_session_t* msi_init_session ( void* _core_handler, const uint8_t* _user_agent )
310{
311 assert(_core_handler);
312 assert(_user_agent);
313
314 msi_session_t* _session = calloc ( sizeof ( msi_session_t ), 1 );
315 assert(_session);
316
317 _session->_oldest_msg = _session->_last_msg = NULL;
318 _session->_core_handler = _core_handler;
319
320 _session->_user_agent = t_strallcpy ( _user_agent );
321 _session->_agent_handler = NULL;
322
323 _session->_key = 0;
324 _session->_call = NULL;
325
326 _session->_frequ = 10000; /* default value? */
327 _session->_call_timeout = 30000; /* default value? */
328
329 /* Use the same frequency */
330 _session->_event_handler = init_event_poll ( _session->_frequ );
331
332 pthread_mutex_init ( &_session->_mutex, NULL );
333
334 return _session;
335}
336
337int msi_terminate_session ( msi_session_t* _session )
338{
339 assert(_session);
340
341 int _status = 0;
342
343 terminate_event_poll ( _session->_event_handler );
344 free ( _session );
345 /* TODO: terminate the rest of the session */
346
347 pthread_mutex_destroy ( &_session->_mutex );
348
349 return _status;
350}
351
352msi_call_t* msi_init_call ( msi_session_t* _session, int _peers, uint32_t _timeoutms )
353{
354 assert(_session);
355 assert(_peers);
356
357 msi_call_t* _call = calloc ( sizeof ( msi_call_t ), 1 );
358 _call->_type_peer = calloc ( sizeof ( call_type ), _peers );
359
360 assert(_call);
361 assert(_call->_type_peer);
362
363 _call->_participants = _peers;
364 _call->_key = _session->_key;
365 _call->_timeoutst = _timeoutms;
366 _call->_outgoing_timer_id = 0;
367
368 return _call;
369}
370
371int msi_terminate_call ( msi_session_t* _session )
372{
373 assert(_session);
374
375 if ( _session->_call->_type_peer )
376 free ( _session->_call->_type_peer );
377
378 cancel_timer_event(_session->_event_handler, _session->_call->_outgoing_timer_id);
379
380 free ( _session->_call );
381
382 _session->_call = NULL;
383
384 return SUCCESS;
385}
386/*------------------------*/
387/*------------------------*/
388/*------------------------*/
389/*------------------------*/
390/*------------------------*/
391/*------------------------*/
392/*------------------------*/
393/*------------------------*/
394/*------------------------*/
395/*------------------------*/
396/*------------------------*/
397/*------------------------*/
398
399/* STATE HANDLERS */
400
401/* REQUESTS */
402int msi_handle_recv_invite ( msi_session_t* _session, msi_msg_t* _msg )
403{
404 assert(_session);
405
406 if ( _session->_call ) {
407 msi_msg_t* _msg_error = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _error ) );
408 msi_msg_set_reason(_msg_error, stringify_error_code(error_busy));
409 msi_send_msg(_session, _msg_error);
410 msi_free_msg(_msg_error);
411
412 return 0;
413 }
414 if ( !_msg->_call_id ) {
415 msi_msg_t* _msg_error = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _error ) );
416 msi_msg_set_reason(_msg_error, stringify_error_code(error_no_callid));
417 msi_send_msg(_session, _msg_error);
418 msi_free_msg(_msg_error);
419 return 0;
420 }
421
422 _session->_call = msi_init_call ( _session, 1, _session->_call_timeout );
423 t_memcpy(_session->_call->_id, _msg->_call_id->_header_value, _CALL_ID_LEN);
424 _session->_call->_state = call_starting;
425
426 flush_peer_type ( _session, _msg, 0 );
427
428 msi_msg_t* _msg_ringing = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _ringing ) );
429 msi_send_msg ( _session, _msg_ringing );
430 msi_free_msg ( _msg_ringing );
431
432 throw_event ( _session->_event_handler, msi_recv_invite_callback, _session );
433 return 1;
434}
435int msi_handle_recv_start ( msi_session_t* _session, msi_msg_t* _msg )
436{
437 assert(_session);
438
439 if ( has_call_error(_session, _msg) == 0 )
440 return 0;
441
442 _session->_call->_state = call_active;
443
444 flush_peer_type ( _session, _msg, 0 );
445
446 throw_event ( _session->_event_handler, msi_start_call_callback, _session );
447 return 1;
448}
449int msi_handle_recv_reject ( msi_session_t* _session, msi_msg_t* _msg )
450{
451 assert(_session);
452
453 if ( has_call_error(_session, _msg) == 0 )
454 return 0;
455
456 msi_msg_t* _msg_end = msi_msg_new ( TYPE_REQUEST, stringify_request ( _end ) );
457 msi_send_msg ( _session, _msg_end );
458 msi_free_msg ( _msg_end );
459
460 throw_event ( _session->_event_handler, msi_reject_call_callback, _session );
461
462 return 1;
463}
464int msi_handle_recv_cancel ( msi_session_t* _session, msi_msg_t* _msg )
465{
466 assert(_session);
467
468 if ( has_call_error(_session, _msg) == 0 )
469 return 0;
470
471 msi_msg_t* _msg_ending = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _ending ) );
472 msi_send_msg ( _session, _msg_ending );
473 msi_free_msg ( _msg_ending );
474
475 msi_terminate_call ( _session );
476
477 throw_event ( _session->_event_handler, msi_cancel_call_callback, _session );
478
479 return 1;
480}
481int msi_handle_recv_end ( msi_session_t* _session, msi_msg_t* _msg )
482{
483 assert(_session);
484
485 if ( has_call_error(_session, _msg) == 0 )
486 return 0;
487
488 msi_msg_t* _msg_ending = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _ending ) );
489 msi_send_msg ( _session, _msg_ending );
490 msi_free_msg ( _msg_ending );
491
492 msi_terminate_call ( _session );
493
494 throw_event ( _session->_event_handler, msi_end_call_callback, _session );
495
496 return 1;
497}
498/*--------*/
499
500/* RESPONSES */
501int msi_handle_recv_ringing ( msi_session_t* _session, msi_msg_t* _msg )
502{
503 assert(_session);
504
505 if ( has_call_error(_session, _msg) == 0 )
506 return 0;
507
508 throw_event ( _session->_event_handler, msi_ringing_callback, _session );
509
510 return 1;
511}
512int msi_handle_recv_starting ( msi_session_t* _session, msi_msg_t* _msg )
513{
514 assert(_session);
515
516 if ( has_call_error(_session, _msg) == 0 )
517 return 0;
518
519 _session->_call->_state = call_active;
520
521 msi_msg_t* _msg_start = msi_msg_new ( TYPE_REQUEST, stringify_request ( _start ) );
522 msi_send_msg ( _session, _msg_start );
523 msi_free_msg ( _msg_start );
524
525 flush_peer_type ( _session, _msg, 0 );
526
527 throw_event ( _session->_event_handler, msi_starting_callback, _session );
528 cancel_timer_event(_session->_event_handler, _session->_call->_outgoing_timer_id);
529 _session->_call->_outgoing_timer_id = 0;
530
531 return 1;
532}
533int msi_handle_recv_ending ( msi_session_t* _session, msi_msg_t* _msg )
534{
535 assert(_session);
536
537 if ( has_call_error(_session, _msg) == 0 )
538 return 0;
539
540 msi_terminate_call ( _session );
541 throw_event ( _session->_event_handler, msi_ending_callback, _session );
542
543 return 1;
544}
545int msi_handle_recv_error ( msi_session_t* _session, msi_msg_t* _msg )
546{
547 assert(_session);
548 assert(_session->_call);
549
550 /* Handle error accordingly */
551 if ( _msg->_reason ) {
552 _session->_last_error_id = atoi((const char*)_msg->_reason->_header_value);
553 _session->_last_error_str = stringify_error(_session->_last_error_id);
554 }
555
556 msi_terminate_call(_session);
557
558 throw_event ( _session->_event_handler, msi_error_callback, _session );
559
560 return 1;
561}
562/* ------------------ */
563
564MCBTYPE msi_handle_timeout (void* _arg)
565{
566 msi_session_t* _session = _arg;
567 msi_terminate_call(_session);
568
569 (*msi_timeout_callback) (_arg);
570 (*msi_ending_callback) (_arg);
571
572}
573
574/*------------------------*/
575/*------------------------*/
576/*------------------------*/
577/*------------------------*/
578/*------------------------*/
579/*------------------------*/
580/*------------------------*/
581/*------------------------*/
582/*------------------------*/
583/*------------------------*/
584/*------------------------*/
585/*------------------------*/
586
587int msi_invite ( msi_session_t* _session, call_type _call_type, uint32_t _timeoutms )
588{
589 assert(_session);
590
591 if ( !msi_send_message_callback )
592 return 0;
593
594 msi_msg_t* _msg_invite = msi_msg_new ( TYPE_REQUEST, stringify_request ( _invite ) );
595
596 _session->_call = msi_init_call ( _session, 1, _timeoutms ); /* Just one for now */
597 msi_genterate_call_id(_session->_call->_id, _CALL_ID_LEN);
598 _session->_call->_type_local = _call_type;
599 /* Do whatever with message */
600
601 if ( _call_type == type_audio ) {
602 msi_msg_set_call_type ( _msg_invite, ( const uint8_t* ) CT_AUDIO_HEADER_VALUE );
603 } else {
604 msi_msg_set_call_type ( _msg_invite, ( const uint8_t* ) CT_VIDEO_HEADER_VALUE );
605 }
606
607 msi_send_msg ( _session, _msg_invite );
608 msi_free_msg ( _msg_invite );
609
610 _session->_call->_state = call_inviting;
611
612 _session->_call->_outgoing_timer_id = throw_timer_event(_session->_event_handler, msi_handle_timeout, _session, _timeoutms );
613
614 return 1;
615}
616int msi_hangup ( msi_session_t* _session )
617{
618 assert(_session);
619
620 if ( !_session->_call || ( !msi_send_message_callback && _session->_call->_state != call_active ) )
621 return 0;
622
623 msi_msg_t* _msg_ending = msi_msg_new ( TYPE_REQUEST, stringify_request ( _end ) );
624 msi_send_msg ( _session, _msg_ending );
625 msi_free_msg ( _msg_ending );
626
627 return 1;
628}
629
630
631int msi_answer ( msi_session_t* _session, call_type _call_type )
632{
633 assert(_session);
634
635 if ( !msi_send_message_callback || !_session->_call )
636 return 0;
637
638 msi_msg_t* _msg_starting = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _starting ) );
639 _session->_call->_type_local = _call_type;
640
641 if ( _call_type == type_audio ) {
642 msi_msg_set_call_type ( _msg_starting, ( const uint8_t* ) CT_AUDIO_HEADER_VALUE );
643 } else {
644 msi_msg_set_call_type ( _msg_starting, ( const uint8_t* ) CT_VIDEO_HEADER_VALUE );
645 }
646
647 msi_send_msg ( _session, _msg_starting );
648 msi_free_msg ( _msg_starting );
649
650 _session->_call->_state = call_active;
651 return 1;
652}
653int msi_cancel ( msi_session_t* _session )
654{
655 assert(_session);
656
657 if ( !_session->_call || !msi_send_message_callback )
658 return 0;
659
660 msi_msg_t* _msg_cancel = msi_msg_new ( TYPE_REQUEST, stringify_request ( _cancel ) );
661 msi_send_msg ( _session, _msg_cancel );
662 msi_free_msg ( _msg_cancel );
663
664
665
666 return 1;
667}
668int msi_reject ( msi_session_t* _session )
669{
670 assert(_session);
671
672 if ( !_session->_call || !msi_send_message_callback )
673 return 0;
674
675 msi_msg_t* _msg_reject = msi_msg_new ( TYPE_REQUEST, stringify_request ( _reject ) );
676 msi_send_msg ( _session, _msg_reject );
677 msi_free_msg ( _msg_reject );
678
679 return 1;
680}
681
682/*------------------------*/
683/*------------------------*/
684/*------------------------*/
685/*------------------------*/
686/*------------------------*/
687/*------------------------*/
688/*------------------------*/
689/*------------------------*/
690/*------------------------*/
691/*------------------------*/
692/*------------------------*/
693/*------------------------*/
694
695/* OUR MAIN POOL FUNCTION */
696/*
697 * Forks it self to other thread and then handles the session initiation.
698 *
699 * BASIC call flow:
700 *
701 * ALICE BOB
702 * | invite --> |
703 * | |
704 * | <-- ringing |
705 * | |
706 * | <-- starting |
707 * | |
708 * | start --> |
709 * | |
710 * | <-- MEDIA TRANS --> |
711 * | |
712 * | end --> |
713 * | |
714 * | <-- ending |
715 *
716 * Alice calls Bob by sending invite packet.
717 * Bob recvs the packet and sends an ringing packet;
718 * which notifies Alice that her invite is acknowledged.
719 * Ringing screen shown on both sides.
720 * Bob accepts the invite for a call by sending starting packet.
721 * Alice recvs the starting packet and sends the started packet to
722 * inform Bob that she recved the starting packet.
723 * Now the media transmission is established ( i.e. RTP transmission ).
724 * Alice hangs up and sends end packet.
725 * Bob recves the end packet and sends ending packet
726 * as the acknowledgement that the call is ending.
727 *
728 *
729 */
730
731
732/*
733 * Needs a bit more work on the protocol
734 */
735void* msi_poll_stack ( void* _session_p )
736{
737 msi_session_t* _session = ( msi_session_t* ) _session_p;
738 msi_msg_t* _msg = NULL;
739
740 uint32_t* _frequ = &_session->_frequ;
741 while ( _session ) {
742
743 /* At this point it's already parsed */
744 _msg = receive_message ( _session );
745
746 if ( _msg ) {
747
748 if ( _msg->_request ) { /* Handle request */
749
750 const uint8_t* _request_value = _msg->_request->_header_value;
751
752 if ( same ( _request_value, stringify_request ( _invite ) ) ) {
753 msi_handle_recv_invite ( _session, _msg );
754
755 } else if ( same ( _request_value, stringify_request ( _start ) ) ) {
756 msi_handle_recv_start ( _session, _msg );
757
758 } else if ( same ( _request_value, stringify_request ( _cancel ) ) ) {
759 msi_handle_recv_cancel ( _session, _msg );
760
761 } else if ( same ( _request_value, stringify_request ( _reject ) ) ) {
762 msi_handle_recv_reject ( _session, _msg );
763
764 } else if ( same ( _request_value, stringify_request ( _end ) ) ) {
765 msi_handle_recv_end ( _session, _msg );
766 }
767
768 } else if ( _msg->_response ) { /* Handle response */
769
770 const uint8_t* _response_value = _msg->_response->_header_value;
771
772 if ( same ( _response_value, stringify_response ( _ringing ) ) ) {
773 msi_handle_recv_ringing ( _session, _msg );
774
775 } else if ( same ( _response_value, stringify_response ( _starting ) ) ) {
776 msi_handle_recv_starting ( _session, _msg );
777
778 } else if ( same ( _response_value, stringify_response ( _ending ) ) ) {
779 msi_handle_recv_ending ( _session, _msg );
780
781 } else if ( same ( _response_value, stringify_response ( _error ) ) ) {
782 msi_handle_recv_error ( _session, _msg );
783 }
784
785 }
786
787 msi_free_msg ( _msg );
788
789 }
790 usleep ( *_frequ );
791 }
792
793 return NULL;
794}
795
796/*------------------------*/
797/*------------------------*/
798/*------------------------*/
799/*------------------------*/
800/*------------------------*/
801/*------------------------*/
802/*------------------------*/
803/*------------------------*/
804/*------------------------*/
805/*------------------------*/
806/*------------------------*/
807/*------------------------*/
808
809/* Easy way to start the poll */
810
811pthread_t msi_start_main_loop ( msi_session_t* _session, uint32_t _frequms )
812{
813 assert(_session);
814
815 int _status;
816 pthread_t _thread_id;
817
818
819 _session->_frequ = _frequms * 1000;
820
821 _status = pthread_create ( &_thread_id, NULL, msi_poll_stack, _session );
822
823 if ( _status < 0 ) {
824 printf ( "Error while starting main loop: %d, %s\n", errno, strerror ( errno ) );
825 return _status;
826 }
827
828 _status = pthread_detach ( _thread_id );
829
830 if ( _status < 0 ) {
831 printf ( "Error while starting main loop: %d, %s\n", errno, strerror ( errno ) );
832 }
833
834 return _thread_id;
835}