diff options
author | mannol <eniz_vukovic@hotmail.com> | 2015-02-16 23:30:20 +0100 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2015-02-16 23:30:20 +0100 |
commit | 7329f3b3d461a8f7738fa4b13a2dffc8d6a5b5f5 (patch) | |
tree | 97b852c024eee0ae7b4da32a54636e4d5b035fff | |
parent | 8c245affb1f7dac2baab263ad0c4e19314073d71 (diff) |
Fixed header protectors and cleaning up the msi
-rw-r--r-- | toxav/codec.h | 6 | ||||
-rw-r--r-- | toxav/msi.c | 861 | ||||
-rw-r--r-- | toxav/msi.h | 89 | ||||
-rw-r--r-- | toxav/rtp.h | 6 | ||||
-rw-r--r-- | toxav/toxav.c | 14 | ||||
-rw-r--r-- | toxav/toxav.h | 8 |
6 files changed, 379 insertions, 605 deletions
diff --git a/toxav/codec.h b/toxav/codec.h index de5a6cd1..02a3b1b4 100644 --- a/toxav/codec.h +++ b/toxav/codec.h | |||
@@ -21,8 +21,8 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef _CODEC_H_ | 24 | #ifndef CODEC_H |
25 | #define _CODEC_H_ | 25 | #define CODEC_H |
26 | 26 | ||
27 | #include "toxav.h" | 27 | #include "toxav.h" |
28 | #include "rtp.h" | 28 | #include "rtp.h" |
@@ -186,4 +186,4 @@ void cs_disable_audio_receiving(CSSession* cs); | |||
186 | 186 | ||
187 | /* Internal. Called from rtp_handle_message */ | 187 | /* Internal. Called from rtp_handle_message */ |
188 | void queue_message(RTPSession *session, RTPMessage *msg); | 188 | void queue_message(RTPSession *session, RTPMessage *msg); |
189 | #endif /* _CODEC_H_ */ | 189 | #endif /* CODEC_H */ |
diff --git a/toxav/msi.c b/toxav/msi.c index 706e21d7..e78c57fe 100644 --- a/toxav/msi.c +++ b/toxav/msi.c | |||
@@ -51,7 +51,7 @@ | |||
51 | typedef enum { | 51 | typedef enum { |
52 | IDRequest = 1, | 52 | IDRequest = 1, |
53 | IDResponse, | 53 | IDResponse, |
54 | IDReason, | 54 | IDError, |
55 | IDCapabilities, | 55 | IDCapabilities, |
56 | 56 | ||
57 | } MSIHeaderID; | 57 | } MSIHeaderID; |
@@ -67,7 +67,6 @@ typedef enum { | |||
67 | typedef enum { | 67 | typedef enum { |
68 | requ_invite, | 68 | requ_invite, |
69 | requ_start, | 69 | requ_start, |
70 | requ_cancel, | ||
71 | requ_reject, | 70 | requ_reject, |
72 | requ_end, | 71 | requ_end, |
73 | } MSIRequest; | 72 | } MSIRequest; |
@@ -75,21 +74,9 @@ typedef enum { | |||
75 | typedef enum { | 74 | typedef enum { |
76 | resp_ringing, | 75 | resp_ringing, |
77 | resp_starting, | 76 | resp_starting, |
78 | resp_ending, | ||
79 | resp_error, | 77 | resp_error, |
80 | } MSIResponse; | 78 | } MSIResponse; |
81 | 79 | ||
82 | typedef enum { | ||
83 | res_undisclosed, | ||
84 | } MSIReason; | ||
85 | |||
86 | typedef enum { | ||
87 | cap_saudio, /* sending audio */ | ||
88 | cap_svideo, /* sending video */ | ||
89 | cap_raudio, /* receiving audio */ | ||
90 | cap_rvideo, /* receiving video */ | ||
91 | } MSICapabilities; | ||
92 | |||
93 | #define GENERIC_HEADER(header, val_type) \ | 80 | #define GENERIC_HEADER(header, val_type) \ |
94 | typedef struct { \ | 81 | typedef struct { \ |
95 | val_type value; \ | 82 | val_type value; \ |
@@ -99,23 +86,23 @@ _Bool exists; \ | |||
99 | 86 | ||
100 | GENERIC_HEADER ( Request, MSIRequest ) | 87 | GENERIC_HEADER ( Request, MSIRequest ) |
101 | GENERIC_HEADER ( Response, MSIResponse ) | 88 | GENERIC_HEADER ( Response, MSIResponse ) |
102 | GENERIC_HEADER ( Reason, MSIReason ) | 89 | GENERIC_HEADER ( Error, MSIError ) |
103 | GENERIC_HEADER ( Capabilities, MSICapabilities ) | 90 | GENERIC_HEADER ( Capabilities, uint8_t ) |
104 | 91 | ||
105 | 92 | ||
106 | typedef struct { | 93 | typedef struct { |
107 | MSIHeaderRequest request; | 94 | MSIHeaderRequest request; |
108 | MSIHeaderResponse response; | 95 | MSIHeaderResponse response; |
109 | MSIHeaderReason reason; | 96 | MSIHeaderError error; |
110 | MSIHeaderCapabilities capabilities; | 97 | MSIHeaderCapabilities capabilities; |
111 | } MSIMessage; | 98 | } MSIMessage; |
112 | 99 | ||
113 | 100 | ||
114 | static void invoke_callback(MSISession *s, int32_t c, MSICallbackID i) | 101 | static void invoke_callback(MSICall* c, MSICallbackID i) |
115 | { | 102 | { |
116 | if ( s->callbacks[i] ) { | 103 | if ( c->session->callbacks[i] ) { |
117 | LOGGER_DEBUG("Invoking callback function: %d", i); | 104 | LOGGER_DEBUG("Invoking callback function: %d", i); |
118 | s->callbacks[i] ( s->agent_handler, c ); | 105 | c->session->callbacks[i] ( c->session->agent_handler, c ); |
119 | } | 106 | } |
120 | } | 107 | } |
121 | 108 | ||
@@ -149,22 +136,15 @@ static MSIMessage *msi_new_message ( MSIMessageType type, const uint8_t type_val | |||
149 | */ | 136 | */ |
150 | static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length ) | 137 | static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length ) |
151 | { | 138 | { |
152 | #define PARSE_HEADER(bytes, header, constraint, enum_high_limit) do {\ | 139 | |
153 | if ((constraint -= 3) < 1) { \ | 140 | #define CHECK_SIZE(bytes, constraint, size) \ |
154 | LOGGER_ERROR("Read over length!"); \ | 141 | if ((constraint -= 3) < 1) { LOGGER_ERROR("Read over length!"); return -1; } \ |
155 | return -1; \ | 142 | if ( bytes[1] != size ) { LOGGER_ERROR("Invalid data size!"); return -1; } |
156 | } \ | 143 | |
157 | \ | 144 | #define CHECK_ENUM_HIGH(bytes, enum_high) \ |
158 | if ( bytes[1] != 1 ) { \ | 145 | if ( bytes[2] > enum_high ) { LOGGER_ERROR("Failed enum high limit!"); return -1; } |
159 | LOGGER_ERROR("Invalid data size!"); \ | 146 | |
160 | return -1; \ | 147 | #define SET_VALUES(bytes, header) do { \ |
161 | } \ | ||
162 | \ | ||
163 | if ( bytes[2] > enum_high_limit ) { \ | ||
164 | LOGGER_ERROR("Failed enum high limit!"); \ | ||
165 | return -1; \ | ||
166 | } \ | ||
167 | \ | ||
168 | header.value = bytes[2]; \ | 148 | header.value = bytes[2]; \ |
169 | header.exists = 1; \ | 149 | header.exists = 1; \ |
170 | bytes += 3; \ | 150 | bytes += 3; \ |
@@ -176,7 +156,7 @@ static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t lengt | |||
176 | return -1; | 156 | return -1; |
177 | } | 157 | } |
178 | 158 | ||
179 | if ( data[length - 1] ) { /* End byte must have value 0 */ | 159 | if ( length == 0 || data[length - 1] ) { /* End byte must have value 0 */ |
180 | LOGGER_ERROR("Invalid end byte"); | 160 | LOGGER_ERROR("Invalid end byte"); |
181 | return -1; | 161 | return -1; |
182 | } | 162 | } |
@@ -187,20 +167,27 @@ static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t lengt | |||
187 | while ( *it ) {/* until end byte is hit */ | 167 | while ( *it ) {/* until end byte is hit */ |
188 | switch (*it) { | 168 | switch (*it) { |
189 | case IDRequest: | 169 | case IDRequest: |
190 | PARSE_HEADER(it, msg->request, size_constraint, requ_end); | 170 | CHECK_SIZE(it, size_constraint, 1); |
171 | CHECK_ENUM_HIGH(it, requ_end); | ||
172 | SET_VALUES(it, msg->request); | ||
191 | break; | 173 | break; |
192 | 174 | ||
193 | case IDResponse: | 175 | case IDResponse: |
194 | PARSE_HEADER(it, msg->response, size_constraint, resp_error); | 176 | CHECK_SIZE(it, size_constraint, 1); |
177 | CHECK_ENUM_HIGH(it, resp_error); | ||
178 | SET_VALUES(it, msg->response); | ||
195 | it += 3; | 179 | it += 3; |
196 | break; | 180 | break; |
197 | 181 | ||
198 | case IDReason: | 182 | case IDError: |
199 | PARSE_HEADER(it, msg->reason, size_constraint, res_undisclosed); | 183 | CHECK_SIZE(it, size_constraint, 1); |
184 | CHECK_ENUM_HIGH(it, msi_ErrUndisclosed); | ||
185 | SET_VALUES(it, msg->error); | ||
200 | break; | 186 | break; |
201 | 187 | ||
202 | case IDCapabilities: | 188 | case IDCapabilities: |
203 | PARSE_HEADER(it, msg->capabilities, size_constraint, requ_end); | 189 | CHECK_SIZE(it, size_constraint, 1); |
190 | SET_VALUES(it, msg->capabilities); | ||
204 | break; | 191 | break; |
205 | 192 | ||
206 | default: | 193 | default: |
@@ -212,7 +199,9 @@ static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t lengt | |||
212 | 199 | ||
213 | return 0; | 200 | return 0; |
214 | 201 | ||
215 | #undef PARSE_HEADER | 202 | #undef CHECK_SIZE |
203 | #undef CHECK_ENUM_HIGH | ||
204 | #undef SET_VALUES | ||
216 | } | 205 | } |
217 | 206 | ||
218 | /** | 207 | /** |
@@ -299,8 +288,8 @@ static uint16_t parse_out ( MSIMessage *msg, uint8_t *dest ) | |||
299 | it = prepare_header(IDResponse, it, &cast, 1, &size); | 288 | it = prepare_header(IDResponse, it, &cast, 1, &size); |
300 | } | 289 | } |
301 | 290 | ||
302 | if (msg->reason.exists) { | 291 | if (msg->error.exists) { |
303 | it = prepare_header(IDReason, it, &msg->reason.value, sizeof(msg->reason.value), &size); | 292 | it = prepare_header(IDError, it, &msg->error.value, sizeof(msg->error.value), &size); |
304 | } | 293 | } |
305 | 294 | ||
306 | if (msg->capabilities.exists) { | 295 | if (msg->capabilities.exists) { |
@@ -340,22 +329,22 @@ static int send_reponse ( MSICall *call, MSIResponse response, uint32_t to ) | |||
340 | return ret; | 329 | return ret; |
341 | } | 330 | } |
342 | 331 | ||
343 | static int send_error ( MSICall *call, MSIReason reason, uint32_t to ) | 332 | static int send_error ( MSICall *call, MSIError error, uint32_t to ) |
344 | { | 333 | { |
345 | if (!call) { | 334 | if (!call) { |
346 | LOGGER_WARNING("Cannot handle error on 'null' call"); | 335 | LOGGER_WARNING("Cannot handle error on 'null' call"); |
347 | return -1; | 336 | return -1; |
348 | } | 337 | } |
349 | 338 | ||
350 | LOGGER_DEBUG("Sending error: %d on call: %d", reason, call->call_idx); | 339 | LOGGER_DEBUG("Sending error: %d on call: %d", error, call->call_idx); |
351 | 340 | ||
352 | MSIMessage *msg_error = msi_new_message ( type_response, resp_error ); | 341 | MSIMessage *msg_error = msi_new_message ( type_response, resp_error ); |
353 | 342 | ||
354 | if (!msg_error) | 343 | if (!msg_error) |
355 | return -1; | 344 | return -1; |
356 | 345 | ||
357 | msg_error->reason.exists = 1; | 346 | msg_error->error.exists = 1; |
358 | msg_error->reason.value = reason; | 347 | msg_error->error.value = error; |
359 | 348 | ||
360 | send_message ( call, msg_error, to ); | 349 | send_message ( call, msg_error, to ); |
361 | free ( msg_error ); | 350 | free ( msg_error ); |
@@ -364,53 +353,113 @@ static int send_error ( MSICall *call, MSIReason reason, uint32_t to ) | |||
364 | } | 353 | } |
365 | 354 | ||
366 | 355 | ||
367 | 356 | static MSICall *get_call ( MSISession *session, uint32_t friend_id ) | |
368 | static MSICall *init_call ( MSISession *session, int peers, int ringing_timeout ) | ||
369 | { | 357 | { |
358 | if (session->calls == NULL || session->calls_tail < friend_id) | ||
359 | return NULL; | ||
370 | 360 | ||
361 | return session->calls[friend_id]; | ||
371 | } | 362 | } |
372 | 363 | ||
373 | static int terminate_call ( MSISession *session, MSICall *call ) | 364 | static MSICall *new_call ( MSISession *session, uint32_t friend_id ) |
374 | { | 365 | { |
375 | if ( !call ) { | 366 | MSICall *rc = calloc(sizeof(MSICall), 1); |
376 | LOGGER_WARNING("Tried to terminate non-existing call!"); | 367 | |
377 | return -1; | 368 | if (rc == NULL) |
369 | return NULL; | ||
370 | |||
371 | rc->friend_id = friend_id; | ||
372 | |||
373 | if (session->calls == NULL) { /* Creating */ | ||
374 | session->calls = calloc (sizeof(MSICall*), friend_id + 1); | ||
375 | |||
376 | if (session->calls == NULL) { | ||
377 | free(rc); | ||
378 | return NULL; | ||
379 | } | ||
380 | |||
381 | session->calls_tail = session->calls_head = friend_id; | ||
382 | |||
383 | } else if (session->calls_tail < friend_id) { /* Appending */ | ||
384 | void* tmp = realloc(session->calls, sizeof(MSICall*) * friend_id + 1); | ||
385 | |||
386 | if (tmp == NULL) { | ||
387 | free(rc); | ||
388 | return NULL; | ||
389 | } | ||
390 | |||
391 | session->calls = tmp; | ||
392 | |||
393 | /* Set fields in between to null */ | ||
394 | int32_t i = session->calls_tail; | ||
395 | for (; i < friend_id; i ++) | ||
396 | session->calls[i] = NULL; | ||
397 | |||
398 | rc->prev = session->calls[session->calls_tail]; | ||
399 | session->calls[session->calls_tail]->next = rc; | ||
400 | |||
401 | session->calls_tail = friend_id; | ||
402 | |||
403 | } else if (session->calls_head > friend_id) { /* Inserting at front */ | ||
404 | rc->next = session->calls[session->calls_head]; | ||
405 | session->calls[session->calls_head]->prev = rc; | ||
406 | session->calls_head = friend_id; | ||
378 | } | 407 | } |
408 | |||
409 | session->calls[friend_id] = rc; | ||
410 | return rc; | ||
411 | } | ||
379 | 412 | ||
380 | session->calls[call->call_idx] = NULL; | 413 | static void kill_call ( MSICall *call ) |
381 | 414 | { | |
382 | LOGGER_DEBUG("Terminated call id: %d", call->call_idx); | 415 | if ( call == NULL ) |
416 | return; | ||
417 | |||
418 | |||
419 | MSISession* session = call->session; | ||
420 | |||
421 | MSICall* prev = call->prev; | ||
422 | MSICall* next = call->next; | ||
423 | |||
424 | if (prev) | ||
425 | prev->next = next; | ||
426 | else if (next) | ||
427 | session->calls_head = next->friend_id; | ||
428 | else goto CLEAR; | ||
429 | |||
430 | if (next) | ||
431 | next->prev = prev; | ||
432 | else if (prev) | ||
433 | session->calls_tail = prev->friend_id; | ||
434 | else goto CLEAR; | ||
435 | |||
436 | session->calls[call->friend_id] = NULL; | ||
437 | free(call); | ||
438 | return; | ||
439 | |||
440 | CLEAR: | ||
441 | session->calls_head = session->calls_tail = 0; | ||
442 | free(session->calls); | ||
443 | session->calls = NULL; | ||
444 | free(call); | ||
445 | } | ||
383 | 446 | ||
384 | free ( call->csettings_peer ); | ||
385 | free ( call->peers ); | ||
386 | free ( call ); | ||
387 | 447 | ||
388 | return 0; | ||
389 | } | ||
390 | 448 | ||
391 | static void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8_t status, void *session_p) | 449 | static void handle_remote_connection_change(Messenger *messenger, int friend_id, uint8_t status, void *session_p) |
392 | { | 450 | { |
393 | (void)messenger; | 451 | (void)messenger; |
394 | MSISession *session = session_p; | 452 | MSISession *session = session_p; |
395 | 453 | ||
396 | switch ( status ) { | 454 | switch ( status ) { |
397 | case 0: { /* Went offline */ | 455 | case 0: { /* Went offline */ |
398 | int32_t j = 0; | 456 | MSICall* call = get_call(session, friend_id); |
399 | 457 | ||
400 | for ( ; j < session->max_calls; j ++ ) { | 458 | if (call == NULL) |
401 | 459 | return; | |
402 | if ( !session->calls[j] ) continue; | 460 | |
403 | 461 | invoke_callback(call, msi_OnPeerTimeout); | |
404 | uint16_t i = 0; | 462 | kill_call(call); |
405 | |||
406 | for ( ; i < session->calls[j]->peer_count; i ++ ) | ||
407 | if ( session->calls[j]->peers[i] == (uint32_t)friend_num ) { | ||
408 | invoke_callback(session, j, msi_OnPeerTimeout); | ||
409 | terminate_call(session, session->calls[j]); | ||
410 | LOGGER_DEBUG("Remote: %d timed out!", friend_num); | ||
411 | return; /* TODO: On group calls change behaviour */ | ||
412 | } | ||
413 | } | ||
414 | } | 463 | } |
415 | break; | 464 | break; |
416 | 465 | ||
@@ -419,247 +468,177 @@ static void handle_remote_connection_change(Messenger *messenger, int friend_num | |||
419 | } | 468 | } |
420 | } | 469 | } |
421 | 470 | ||
422 | /********** Request handlers **********/ | ||
423 | static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *msg ) | ||
424 | { | ||
425 | LOGGER_DEBUG("Session: %p Handling 'invite' on call: %d", session, call ? call->call_idx : -1); | ||
426 | |||
427 | |||
428 | if (!msg->csettings.exists) {/**/ | ||
429 | LOGGER_WARNING("Peer sent invalid codec settings!"); | ||
430 | send_error ( session, call, error_no_callid, msg->friend_id ); | ||
431 | return 0; | ||
432 | } | ||
433 | 471 | ||
434 | if ( call ) { | ||
435 | if ( call->peers[0] == (uint32_t)msg->friend_id ) { | ||
436 | if (call->state == msi_CallRequesting) { | ||
437 | /* The glare case. A calls B when at the same time | ||
438 | * B calls A. Who has advantage is set bey calculating | ||
439 | * 'bigger' Call id and then that call id is being used in | ||
440 | * future. User with 'bigger' Call id has the advantage | ||
441 | * as in he will wait the response from the other. | ||
442 | */ | ||
443 | LOGGER_DEBUG("Glare case; Peer: %d", call->peers[0]); | ||
444 | |||
445 | if ( call_id_bigger (call->id, msg->callid.value) == 1 ) { /* Peer has advantage */ | ||
446 | |||
447 | /* Terminate call; peer will timeout(call) if call initialization fails */ | ||
448 | terminate_call(session, call); | ||
449 | |||
450 | call = init_call ( session, 1, 0 ); | ||
451 | |||
452 | if ( !call ) { | ||
453 | LOGGER_ERROR("Starting call"); | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | } else { | ||
458 | return 0; /* Wait for ringing from peer */ | ||
459 | } | ||
460 | } else if (call->state == msi_CallActive) { | ||
461 | /* Request for media change; call callback and send starting response */ | ||
462 | if (flush_peer_csettings(call, msg, 0) != 0) { /**/ | ||
463 | LOGGER_WARNING("Peer sent invalid csetting!"); | ||
464 | send_error ( session, call, error_no_callid, msg->friend_id ); | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | LOGGER_DEBUG("Set new call type: %s", call->csettings_peer[0].call_type == msi_TypeAudio ? "audio" : "video"); | ||
469 | send_reponse(session, call, resp_starting, msg->friend_id); | ||
470 | invoke_callback(session, call->call_idx, msi_OnPeerCSChange); | ||
471 | return 1; | ||
472 | } | ||
473 | } else { | ||
474 | send_error ( session, call, error_busy, msg->friend_id ); /* TODO: Ugh*/ | ||
475 | terminate_call(session, call); | ||
476 | return 0; | ||
477 | } | ||
478 | } else { | ||
479 | call = init_call ( session, 1, 0 ); | ||
480 | 472 | ||
481 | if ( !call ) { | 473 | /********** Request handlers **********/ |
482 | LOGGER_ERROR("Starting call"); | 474 | static int handle_recv_invite ( MSICall *call, MSIMessage *msg ) |
483 | return 0; | 475 | { |
484 | } | 476 | if ( call == NULL ) { |
477 | LOGGER_WARNING("Session: %p Handling 'invite' on no call"); | ||
478 | return -1; | ||
485 | } | 479 | } |
480 | |||
481 | MSISession* session = call->session; | ||
482 | |||
483 | LOGGER_DEBUG("Session: %p Handling 'invite' friend: %d", call->session, call->friend_id); | ||
486 | 484 | ||
487 | if ( !msg->callid.exists ) { | 485 | |
488 | send_error ( session, call, error_no_callid, msg->friend_id ); | 486 | if ( call->state == msi_CallRequesting ) { |
489 | terminate_call(session, call); | 487 | /* The rare glare case. |
488 | * Send starting and wait for starting by the other side. | ||
489 | * The peer will do the same. | ||
490 | * When you receive starting from peer send started. | ||
491 | * Don't notice the app until the start is received. | ||
492 | */ | ||
493 | |||
494 | LOGGER_DEBUG("Glare detected!"); | ||
495 | |||
496 | MSIMessage *msg_starting = msi_new_message ( type_response, resp_starting ); | ||
497 | |||
498 | call->capabilities &= msg->capabilities; | ||
499 | |||
500 | msg_starting->capabilities.value = call->capabilities; | ||
501 | msg_starting->capabilities.exists = 1; | ||
502 | |||
503 | send_message ( call, msg_starting, call->friend_id ); | ||
504 | free ( msg_starting ); | ||
505 | |||
490 | return 0; | 506 | return 0; |
491 | } | 507 | } |
492 | 508 | ||
493 | memcpy ( call->id, msg->callid.value, sizeof(msg->callid.value) ); | 509 | call->capabilities = msg->capabilities; |
494 | call->state = msi_CallRequested; | 510 | call->state = msi_CallRequested; |
511 | |||
512 | send_reponse(call, resp_ringing, call->friend_id); | ||
513 | invoke_callback(call, msi_OnInvite); | ||
495 | 514 | ||
496 | add_peer( call, msg->friend_id); | 515 | return 0; |
497 | flush_peer_csettings ( call, msg, 0 ); | ||
498 | send_reponse(session, call, resp_ringing, msg->friend_id); | ||
499 | invoke_callback(session, call->call_idx, msi_OnInvite); | ||
500 | |||
501 | return 1; | ||
502 | } | 516 | } |
503 | 517 | ||
504 | static int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg ) | 518 | static int handle_recv_start ( MSICall *call, MSIMessage *msg ) |
505 | { | 519 | { |
506 | if ( !call ) { | 520 | if ( call == NULL ) { |
507 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); | 521 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); |
508 | return 0; | 522 | return -1; |
509 | } | 523 | } |
510 | 524 | ||
525 | if ( call->state != msi_CallRequested || call->state != msi_CallRequesting ) { | ||
526 | LOGGER_WARNING("Session: %p Invalid call state on 'start'"); | ||
527 | /* TODO send error */ | ||
528 | return -1; | ||
529 | } | ||
530 | |||
511 | (void)msg; | 531 | (void)msg; |
512 | 532 | ||
513 | LOGGER_DEBUG("Session: %p Handling 'start' on call: %d, friend id: %d", session, call->call_idx, msg->friend_id ); | 533 | LOGGER_DEBUG("Session: %p Handling 'start', friend id: %d", call->session, call->friend_id ); |
514 | 534 | ||
515 | call->state = msi_CallActive; | 535 | call->state = msi_CallActive; |
516 | invoke_callback(session, call->call_idx, msi_OnStart); | 536 | invoke_callback(call, msi_OnStart); |
517 | return 1; | 537 | |
518 | } | 538 | return 0; |
519 | |||
520 | static int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg ) | ||
521 | { | ||
522 | if ( !call ) { | ||
523 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); | ||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | LOGGER_DEBUG("Session: %p Handling 'reject' on call: %u", session, call->call_idx); | ||
528 | |||
529 | invoke_callback(session, call->call_idx, msi_OnReject); | ||
530 | |||
531 | send_reponse(session, call, resp_ending, msg->friend_id); | ||
532 | terminate_call(session, call); | ||
533 | |||
534 | return 1; | ||
535 | } | 539 | } |
536 | 540 | ||
537 | static int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg ) | 541 | static int handle_recv_reject ( MSICall *call, MSIMessage *msg ) |
538 | { | 542 | { |
539 | if ( !call ) { | 543 | if ( call == NULL ) { |
540 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); | 544 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); |
541 | return 0; | 545 | return -1; |
542 | } | 546 | } |
543 | 547 | ||
544 | (void)msg; | 548 | (void)msg; |
549 | |||
550 | if ( call->state != msi_CallRequesting ) { | ||
551 | LOGGER_WARNING("Session: %p Invalid call state on 'reject'"); | ||
552 | /* TODO send error */ | ||
553 | return -1; | ||
554 | } | ||
555 | |||
556 | LOGGER_DEBUG("Session: %p Handling 'reject', friend id: %u", call->session, call->friend_id); | ||
545 | 557 | ||
546 | LOGGER_DEBUG("Session: %p Handling 'cancel' on call: %u", session, call->call_idx); | 558 | invoke_callback(call, msi_OnReject); |
547 | 559 | kill_call(call); | |
548 | invoke_callback(session, call->call_idx, msi_OnCancel); | ||
549 | terminate_call ( session, call ); | ||
550 | 560 | ||
551 | return 1; | 561 | return 0; |
552 | } | 562 | } |
553 | 563 | ||
554 | static int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg ) | 564 | static int handle_recv_end ( MSICall *call, MSIMessage *msg ) |
555 | { | 565 | { |
556 | if ( !call ) { | 566 | (void)msg; |
567 | |||
568 | if ( call == NULL ) { | ||
557 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); | 569 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); |
558 | return 0; | 570 | return -1; |
559 | } | 571 | } |
560 | 572 | ||
561 | LOGGER_DEBUG("Session: %p Handling 'end' on call: %d", session, call->call_idx); | 573 | LOGGER_DEBUG("Session: %p Handling 'end', friend id: %d", call->session, call->friend_id); |
562 | 574 | ||
563 | invoke_callback(session, call->call_idx, msi_OnEnd); | 575 | invoke_callback(call, msi_OnEnd); |
564 | send_reponse(session, call, resp_ending, msg->friend_id); | 576 | kill_call ( call ); |
565 | terminate_call ( session, call ); | ||
566 | 577 | ||
567 | return 1; | 578 | return 0; |
568 | } | 579 | } |
569 | 580 | ||
570 | /********** Response handlers **********/ | 581 | /********** Response handlers **********/ |
571 | static int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg ) | 582 | static int handle_recv_ringing ( MSICall *call, MSIMessage *msg ) |
572 | { | 583 | { |
573 | if ( !call ) { | 584 | if ( call == NULL ) { |
574 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); | 585 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); |
575 | return 0; | 586 | return -1; |
576 | } | 587 | } |
577 | 588 | ||
578 | (void)msg; | 589 | (void)msg; |
579 | 590 | ||
580 | if ( call->ringing_timer_id ) { | 591 | if ( call->state != msi_CallRequesting ) { |
581 | LOGGER_WARNING("Call already ringing"); | 592 | LOGGER_WARNING("Session: %p Invalid call state on 'ringing'"); |
582 | return 0; | 593 | /* TODO send error */ |
594 | return -1; | ||
583 | } | 595 | } |
584 | 596 | ||
585 | LOGGER_DEBUG("Session: %p Handling 'ringing' on call: %d", session, call->call_idx ); | 597 | LOGGER_DEBUG("Session: %p Handling 'ringing' friend id: %d", call->session, call->friend_id ); |
586 | 598 | ||
587 | call->ringing_timer_id = timer_alloc | 599 | invoke_callback(call, msi_OnRinging); |
588 | ( session, handle_timeout, call->call_idx, call->ringing_tout_ms ); | 600 | return 0; |
589 | invoke_callback(session, call->call_idx, msi_OnRinging); | ||
590 | return 1; | ||
591 | } | 601 | } |
592 | static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg ) | 602 | static int handle_recv_starting ( MSICall *call, MSIMessage *msg ) |
593 | { | 603 | { |
594 | if ( !call ) { | 604 | if ( call == NULL ) { |
595 | LOGGER_WARNING("Session: %p Handling 'starting' on non-existing call"); | 605 | LOGGER_WARNING("Session: %p Handling 'starting' on non-existing call"); |
596 | return 0; | 606 | return 0; |
597 | } | 607 | } |
598 | 608 | ||
599 | if ( call->state == msi_CallActive ) { /* Change media */ | 609 | if ( call->state != msi_CallRequested || call->state != msi_CallRequesting ) { |
600 | 610 | LOGGER_WARNING("Session: %p Invalid call state on 'starting'"); | |
601 | LOGGER_DEBUG("Session: %p Changing media on call: %d", session, call->call_idx ); | 611 | /* TODO send error */ |
602 | 612 | return -1; | |
603 | invoke_callback(session, call->call_idx, msi_OnSelfCSChange); | ||
604 | |||
605 | } else if ( call->state == msi_CallRequesting ) { | ||
606 | LOGGER_DEBUG("Session: %p Handling 'starting' on call: %d", session, call->call_idx ); | ||
607 | |||
608 | call->state = msi_CallActive; | ||
609 | |||
610 | MSIMessage *msg_start = msi_new_message ( type_request, requ_start ); | ||
611 | send_message ( session, call, msg_start, msg->friend_id ); | ||
612 | free ( msg_start ); | ||
613 | |||
614 | |||
615 | flush_peer_csettings ( call, msg, 0 ); | ||
616 | |||
617 | /* This is here in case of glare */ | ||
618 | timer_release(session->timer_handler, call->ringing_timer_id); | ||
619 | invoke_callback(session, call->call_idx, msi_OnStart); | ||
620 | } else { | ||
621 | LOGGER_ERROR("Invalid call state"); | ||
622 | terminate_call(session, call ); | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | return 1; | ||
627 | } | ||
628 | static int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg ) | ||
629 | { | ||
630 | if ( !call ) { | ||
631 | LOGGER_WARNING("Session: %p Handling 'start' on no call"); | ||
632 | return 0; | ||
633 | } | 613 | } |
634 | 614 | ||
635 | (void)msg; | 615 | MSIMessage *msg_start = msi_new_message ( type_request, requ_start ); |
636 | 616 | send_message ( call, msg_start, call->friend_id ); | |
637 | LOGGER_DEBUG("Session: %p Handling 'ending' on call: %d", session, call->call_idx ); | 617 | free ( msg_start ); |
638 | 618 | ||
639 | invoke_callback(session, call->call_idx, msi_OnEnd); | 619 | if (call->state == msi_CallRequesting) { |
640 | terminate_call ( session, call ); | 620 | call->state = msi_CallActive; |
641 | 621 | invoke_callback(call, msi_OnStart); | |
642 | return 1; | 622 | } |
623 | |||
624 | /* Otherwise it's a glare case so don't start until 'start' is recved */ | ||
625 | |||
626 | return 0; | ||
643 | } | 627 | } |
644 | static int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *msg ) | 628 | static int handle_recv_error ( MSICall *call, MSIMessage *msg ) |
645 | { | 629 | { |
646 | if ( !call ) { | 630 | if ( call == NULL ) { |
647 | LOGGER_WARNING("Handling 'error' on non-existing call!"); | 631 | LOGGER_WARNING("Handling 'error' on non-existing call!"); |
648 | return -1; | 632 | return -1; |
649 | } | 633 | } |
650 | 634 | ||
651 | LOGGER_DEBUG("Session: %p Handling 'error' on call: %d", session, call->call_idx ); | 635 | LOGGER_DEBUG("Session: %p Handling 'error' friend id: %d", call->session, call->friend_id ); |
652 | 636 | ||
653 | invoke_callback(session, call->call_idx, msi_OnEnd); | 637 | invoke_callback(call, msi_OnError); |
654 | 638 | ||
655 | /* Handle error accordingly */ | 639 | /* TODO Handle error accordingly */ |
656 | if ( msg->reason.exists ) { | ||
657 | /* TODO */ | ||
658 | } | ||
659 | |||
660 | terminate_call ( session, call ); | ||
661 | 640 | ||
662 | return 1; | 641 | return -1; |
663 | } | 642 | } |
664 | 643 | ||
665 | /** | 644 | /** |
@@ -694,20 +673,16 @@ static int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *m | |||
694 | * | 673 | * |
695 | * | 674 | * |
696 | */ | 675 | */ |
697 | static void msi_handle_packet ( Messenger *messenger, int source, const uint8_t *data, uint16_t length, void *object ) | 676 | static void msi_handle_packet ( Messenger *messenger, int friend_id, const uint8_t *data, uint16_t length, void *object ) |
698 | { | 677 | { |
699 | LOGGER_DEBUG("Got msi message"); | 678 | LOGGER_DEBUG("Got msi message"); |
679 | |||
700 | /* Unused */ | 680 | /* Unused */ |
701 | (void)messenger; | 681 | (void)messenger; |
702 | 682 | ||
703 | MSISession *session = object; | 683 | MSISession *session = object; |
704 | MSIMessage *msg; | 684 | MSIMessage *msg; |
705 | 685 | ||
706 | if ( !length ) { | ||
707 | LOGGER_WARNING("Length param negative"); | ||
708 | return; | ||
709 | } | ||
710 | |||
711 | msg = parse_in ( data, length ); | 686 | msg = parse_in ( data, length ); |
712 | 687 | ||
713 | if ( !msg ) { | 688 | if ( !msg ) { |
@@ -716,64 +691,69 @@ static void msi_handle_packet ( Messenger *messenger, int source, const uint8_t | |||
716 | } else { | 691 | } else { |
717 | LOGGER_DEBUG("Successfully parsed message"); | 692 | LOGGER_DEBUG("Successfully parsed message"); |
718 | } | 693 | } |
719 | 694 | ||
720 | pthread_mutex_lock(session->mutex); | 695 | pthread_mutex_lock(session->mutex); |
721 | 696 | ||
722 | /* Find what call */ | 697 | MSICall *call = get_call(session, friend_id); |
723 | MSICall *call = NULL; | 698 | |
699 | if (call == NULL) { | ||
700 | if (msg->request != requ_invite) { | ||
701 | /* TODO send error */ | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | call = new_call(session, friend_id); | ||
706 | if (call == NULL) { | ||
707 | /* TODO send error */ | ||
708 | return; | ||
709 | } | ||
710 | } | ||
711 | |||
724 | 712 | ||
725 | /* Now handle message */ | 713 | /* Now handle message */ |
726 | 714 | int rc = 0; | |
727 | if ( msg->request.exists ) { /* Handle request */ | 715 | if ( msg->request.exists ) { /* Handle request */ |
728 | |||
729 | switch (msg->request.value) { | 716 | switch (msg->request.value) { |
730 | case requ_invite: | 717 | case requ_invite: |
731 | handle_recv_invite ( session, call, msg ); | 718 | rc = handle_recv_invite ( call, msg ); |
732 | break; | 719 | break; |
733 | 720 | ||
734 | case requ_start: | 721 | case requ_start: |
735 | handle_recv_start ( session, call, msg ); | 722 | rc = handle_recv_start ( call, msg ); |
736 | break; | ||
737 | |||
738 | case requ_cancel: | ||
739 | handle_recv_cancel ( session, call, msg ); | ||
740 | break; | 723 | break; |
741 | 724 | ||
742 | case requ_reject: | 725 | case requ_reject: |
743 | handle_recv_reject ( session, call, msg ); | 726 | rc = handle_recv_reject ( call, msg ); |
744 | break; | 727 | break; |
745 | 728 | ||
746 | case requ_end: | 729 | case requ_end: |
747 | handle_recv_end ( session, call, msg ); | 730 | rc = handle_recv_end ( call, msg ); |
748 | break; | 731 | break; |
749 | } | 732 | } |
750 | |||
751 | } else if ( msg->response.exists ) { /* Handle response */ | 733 | } else if ( msg->response.exists ) { /* Handle response */ |
752 | |||
753 | switch (msg->response.value) { | 734 | switch (msg->response.value) { |
754 | case resp_ringing: | 735 | case resp_ringing: |
755 | handle_recv_ringing ( session, call, msg ); | 736 | rc = handle_recv_ringing ( call, msg ); |
756 | break; | 737 | break; |
757 | 738 | ||
758 | case resp_starting: | 739 | case resp_starting: |
759 | handle_recv_starting ( session, call, msg ); | 740 | rc = handle_recv_starting ( call, msg ); |
760 | break; | ||
761 | |||
762 | case resp_ending: | ||
763 | handle_recv_ending ( session, call, msg ); | ||
764 | break; | 741 | break; |
765 | 742 | ||
766 | case resp_error: | 743 | case resp_error: |
767 | handle_recv_error ( session, call, msg ); | 744 | rc = handle_recv_error ( call, msg ); |
768 | break; | 745 | break; |
769 | } | 746 | } |
770 | |||
771 | } else { | 747 | } else { |
772 | LOGGER_WARNING("Invalid message: no resp nor requ headers"); | 748 | LOGGER_WARNING("Invalid message: no resp nor requ headers"); |
749 | /* TODO send error */ | ||
750 | rc = -1; | ||
773 | } | 751 | } |
774 | 752 | ||
753 | if (rc == -1) | ||
754 | kill_call(call); | ||
755 | |||
775 | free ( msg ); | 756 | free ( msg ); |
776 | |||
777 | pthread_mutex_unlock(session->mutex); | 757 | pthread_mutex_unlock(session->mutex); |
778 | } | 758 | } |
779 | 759 | ||
@@ -792,7 +772,6 @@ MSISession *msi_new ( Messenger *messenger ) | |||
792 | return NULL; | 772 | return NULL; |
793 | } | 773 | } |
794 | 774 | ||
795 | |||
796 | MSISession *retu = calloc ( sizeof ( MSISession ), 1 ); | 775 | MSISession *retu = calloc ( sizeof ( MSISession ), 1 ); |
797 | 776 | ||
798 | if (retu == NULL) { | 777 | if (retu == NULL) { |
@@ -802,7 +781,8 @@ MSISession *msi_new ( Messenger *messenger ) | |||
802 | 781 | ||
803 | if (create_recursive_mutex(retu->mutex) != 0) { | 782 | if (create_recursive_mutex(retu->mutex) != 0) { |
804 | LOGGER_ERROR("Failed to init mutex! Program might misbehave"); | 783 | LOGGER_ERROR("Failed to init mutex! Program might misbehave"); |
805 | goto error; | 784 | free(retu); |
785 | return NULL; | ||
806 | } | 786 | } |
807 | 787 | ||
808 | retu->messenger_handle = messenger; | 788 | retu->messenger_handle = messenger; |
@@ -814,17 +794,6 @@ MSISession *msi_new ( Messenger *messenger ) | |||
814 | 794 | ||
815 | LOGGER_DEBUG("New msi session: %p ", retu); | 795 | LOGGER_DEBUG("New msi session: %p ", retu); |
816 | return retu; | 796 | return retu; |
817 | |||
818 | error: | ||
819 | |||
820 | if (retu->timer_handler) { | ||
821 | free(((TimerHandler *)retu->timer_handler)->timers); | ||
822 | free(retu->timer_handler); | ||
823 | } | ||
824 | |||
825 | free(retu->calls); | ||
826 | free(retu); | ||
827 | return NULL; | ||
828 | } | 797 | } |
829 | 798 | ||
830 | int msi_kill ( MSISession *session ) | 799 | int msi_kill ( MSISession *session ) |
@@ -837,19 +806,18 @@ int msi_kill ( MSISession *session ) | |||
837 | m_callback_msi_packet((struct Messenger *) session->messenger_handle, NULL, NULL); | 806 | m_callback_msi_packet((struct Messenger *) session->messenger_handle, NULL, NULL); |
838 | pthread_mutex_lock(session->mutex); | 807 | pthread_mutex_lock(session->mutex); |
839 | 808 | ||
840 | /* Cancel active calls */ | 809 | if (session->calls) { |
841 | int32_t idx = 0; | 810 | MSIMessage *msg_end = msi_new_message ( type_request, requ_end ); |
842 | 811 | ||
843 | for (; idx < session->max_calls; idx ++) if ( session->calls[idx] ) { | 812 | MSICall* it = get_call(session, session->calls_head); |
844 | /* Cancel all? */ | 813 | for (; it; it = it->next) { |
845 | uint16_t _it = 0; | 814 | send_message(it, msg_end, it->friend_id); |
846 | /*for ( ; _it < session->calls[idx]->peer_count; _it++ ) | 815 | kill_call(it); |
847 | * FIXME: will not work on multiple peers, must cancel call for all peers | ||
848 | */ | ||
849 | msi_cancel ( session, idx, session->calls[idx]->peers [_it], "MSI session terminated!" ); | ||
850 | } | 816 | } |
851 | 817 | ||
852 | free ( session->calls ); | 818 | free(msg_end); |
819 | } | ||
820 | |||
853 | pthread_mutex_unlock(session->mutex); | 821 | pthread_mutex_unlock(session->mutex); |
854 | pthread_mutex_destroy(session->mutex); | 822 | pthread_mutex_destroy(session->mutex); |
855 | 823 | ||
@@ -858,247 +826,92 @@ int msi_kill ( MSISession *session ) | |||
858 | return 0; | 826 | return 0; |
859 | } | 827 | } |
860 | 828 | ||
861 | int msi_invite ( MSISession *session, | 829 | int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_t capabilities ) |
862 | int32_t *call_index, | ||
863 | const MSICSettings *csettings, | ||
864 | uint32_t rngsec, | ||
865 | uint32_t friend_id ) | ||
866 | { | 830 | { |
867 | pthread_mutex_lock(session->mutex); | ||
868 | |||
869 | LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_id); | 831 | LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_id); |
870 | 832 | ||
871 | 833 | if (get_call(session, friend_id) != NULL) { | |
872 | int i = 0; | 834 | LOGGER_ERROR("Already in a call"); |
873 | 835 | return -1; | |
874 | for (; i < session->max_calls; i ++) | ||
875 | if (session->calls[i] && session->calls[i]->peers[0] == friend_id) { | ||
876 | LOGGER_ERROR("Already in a call with friend %d", friend_id); | ||
877 | pthread_mutex_unlock(session->mutex); | ||
878 | return msi_ErrorAlreadyInCallWithPeer; | ||
879 | } | ||
880 | |||
881 | |||
882 | MSICall *call = init_call ( session, 1, rngsec ); /* Just one peer for now */ | ||
883 | |||
884 | if ( !call ) { | ||
885 | pthread_mutex_unlock(session->mutex); | ||
886 | LOGGER_ERROR("Cannot handle more calls"); | ||
887 | return msi_ErrorReachedCallLimit; | ||
888 | } | 836 | } |
837 | |||
838 | *call = new_call ( session, friend_id ); | ||
889 | 839 | ||
890 | *call_index = call->call_idx; | 840 | if ( *call == NULL ) |
891 | 841 | return -1; | |
892 | t_randomstr ( call->id, sizeof(call->id) ); | 842 | |
893 | 843 | *call->capabilities = capabilities; | |
894 | add_peer ( call, friend_id ); | 844 | |
895 | |||
896 | call->csettings_local = *csettings; | ||
897 | |||
898 | MSIMessage *msg_invite = msi_new_message ( type_request, requ_invite ); | 845 | MSIMessage *msg_invite = msi_new_message ( type_request, requ_invite ); |
899 | 846 | ||
900 | msi_msg_set_csettings(msg_invite, csettings); | 847 | msg_invite->capabilities.value = capabilities; |
901 | send_message ( session, call, msg_invite, friend_id ); | 848 | msg_invite->capabilities.exists = 1; |
849 | |||
850 | send_message ( *call, msg_invite, friend_id ); | ||
902 | free( msg_invite ); | 851 | free( msg_invite ); |
903 | 852 | ||
904 | call->state = msi_CallRequesting; | 853 | *call->state = msi_CallRequesting; |
905 | 854 | ||
906 | call->request_timer_id = timer_alloc ( session, handle_timeout, call->call_idx, m_deftout ); | ||
907 | |||
908 | LOGGER_DEBUG("Invite sent"); | 855 | LOGGER_DEBUG("Invite sent"); |
909 | |||
910 | pthread_mutex_unlock(session->mutex); | ||
911 | |||
912 | return 0; | 856 | return 0; |
913 | } | 857 | } |
914 | 858 | ||
915 | int msi_hangup ( MSISession *session, int32_t call_index ) | 859 | int msi_hangup ( MSICall* call ) |
916 | { | 860 | { |
917 | pthread_mutex_lock(session->mutex); | ||
918 | LOGGER_DEBUG("Session: %p Hanging up call: %u", session, call_index); | 861 | LOGGER_DEBUG("Session: %p Hanging up call: %u", session, call_index); |
919 | 862 | ||
920 | if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { | ||
921 | LOGGER_ERROR("Invalid call index!"); | ||
922 | pthread_mutex_unlock(session->mutex); | ||
923 | return msi_ErrorNoCall; | ||
924 | } | ||
925 | |||
926 | if ( session->calls[call_index]->state != msi_CallActive ) { | ||
927 | LOGGER_ERROR("Call is not active!"); | ||
928 | pthread_mutex_unlock(session->mutex); | ||
929 | return msi_ErrorInvalidState; | ||
930 | } | ||
931 | |||
932 | MSIMessage *msg_end = msi_new_message ( type_request, requ_end ); | 863 | MSIMessage *msg_end = msi_new_message ( type_request, requ_end ); |
933 | 864 | send_message ( call, msg_end, call->friend_id ); | |
934 | /* hangup for each peer */ | ||
935 | int it = 0; | ||
936 | |||
937 | for ( ; it < session->calls[call_index]->peer_count; it ++ ) | ||
938 | send_message ( session, session->calls[call_index], msg_end, session->calls[call_index]->peers[it] ); | ||
939 | |||
940 | session->calls[call_index]->state = msi_CallOver; | ||
941 | |||
942 | free ( msg_end ); | 865 | free ( msg_end ); |
943 | 866 | ||
944 | session->calls[call_index]->request_timer_id = | 867 | kill_call(call); |
945 | timer_alloc ( session, handle_timeout, call_index, m_deftout ); | ||
946 | |||
947 | pthread_mutex_unlock(session->mutex); | ||
948 | return 0; | 868 | return 0; |
949 | } | 869 | } |
950 | 870 | ||
951 | int msi_answer ( MSISession *session, int32_t call_index, const MSICSettings *csettings ) | 871 | int msi_answer ( MSICall* call, uint8_t capabilities ) |
952 | { | 872 | { |
953 | pthread_mutex_lock(session->mutex); | ||
954 | LOGGER_DEBUG("Session: %p Answering call: %u", session, call_index); | 873 | LOGGER_DEBUG("Session: %p Answering call: %u", session, call_index); |
955 | 874 | ||
956 | if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { | 875 | if ( call->state != msi_CallRequested ) { |
957 | LOGGER_ERROR("Invalid call index!"); | ||
958 | pthread_mutex_unlock(session->mutex); | ||
959 | return msi_ErrorNoCall; | ||
960 | } | ||
961 | |||
962 | if ( session->calls[call_index]->state != msi_CallRequested ) { | ||
963 | LOGGER_ERROR("Call is in invalid state!"); | 876 | LOGGER_ERROR("Call is in invalid state!"); |
964 | pthread_mutex_unlock(session->mutex); | 877 | return -1; |
965 | return msi_ErrorInvalidState; | ||
966 | } | 878 | } |
967 | 879 | ||
880 | call->capabilities = capabilities; | ||
881 | |||
968 | MSIMessage *msg_starting = msi_new_message ( type_response, resp_starting ); | 882 | MSIMessage *msg_starting = msi_new_message ( type_response, resp_starting ); |
969 | 883 | ||
970 | session->calls[call_index]->csettings_local = *csettings; | 884 | msg_starting->capabilities.value = capabilities; |
971 | 885 | msg_starting->capabilities.exists = 1; | |
972 | msi_msg_set_csettings(msg_starting, csettings); | 886 | |
973 | 887 | send_message ( call, msg_starting, call->friend_id ); | |
974 | send_message ( session, session->calls[call_index], msg_starting, session->calls[call_index]->peers[0] ); | ||
975 | free ( msg_starting ); | 888 | free ( msg_starting ); |
976 | 889 | ||
977 | session->calls[call_index]->state = msi_CallActive; | ||
978 | |||
979 | pthread_mutex_unlock(session->mutex); | ||
980 | return 0; | 890 | return 0; |
981 | } | 891 | } |
982 | 892 | ||
983 | int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const char *reason ) | 893 | int msi_reject ( MSICall* call ) |
984 | { | 894 | { |
985 | pthread_mutex_lock(session->mutex); | ||
986 | LOGGER_DEBUG("Session: %p Canceling call: %u; reason: %s", session, call_index, reason ? reason : "Unknown"); | ||
987 | |||
988 | if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { | ||
989 | LOGGER_ERROR("Invalid call index!"); | ||
990 | pthread_mutex_unlock(session->mutex); | ||
991 | return msi_ErrorNoCall; | ||
992 | } | ||
993 | |||
994 | if ( session->calls[call_index]->state != msi_CallRequesting ) { | ||
995 | LOGGER_ERROR("Call is in invalid state!"); | ||
996 | pthread_mutex_unlock(session->mutex); | ||
997 | return msi_ErrorInvalidState; | ||
998 | } | ||
999 | |||
1000 | MSIMessage *msg_cancel = msi_new_message ( type_request, requ_cancel ); | ||
1001 | |||
1002 | /* FIXME */ | ||
1003 | #if 0 | ||
1004 | |||
1005 | if ( reason && strlen(reason) < sizeof(MSIReasonStrType) ) { | ||
1006 | MSIReasonStrType reason_cast; | ||
1007 | memset(reason_cast, '\0', sizeof(MSIReasonStrType)); | ||
1008 | memcpy(reason_cast, reason, strlen(reason)); | ||
1009 | msi_msg_set_reason(msg_cancel, reason_cast); | ||
1010 | } | ||
1011 | |||
1012 | #else | ||
1013 | (void)reason; | ||
1014 | |||
1015 | #endif | ||
1016 | |||
1017 | send_message ( session, session->calls[call_index], msg_cancel, peer ); | ||
1018 | free ( msg_cancel ); | ||
1019 | |||
1020 | terminate_call ( session, session->calls[call_index] ); | ||
1021 | pthread_mutex_unlock(session->mutex); | ||
1022 | |||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | int msi_reject ( MSISession *session, int32_t call_index, const char *reason ) | ||
1027 | { | ||
1028 | pthread_mutex_lock(session->mutex); | ||
1029 | LOGGER_DEBUG("Session: %p Rejecting call: %u; reason: %s", session, call_index, reason ? reason : "Unknown"); | 895 | LOGGER_DEBUG("Session: %p Rejecting call: %u; reason: %s", session, call_index, reason ? reason : "Unknown"); |
1030 | 896 | ||
1031 | if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { | 897 | if ( call->state != msi_CallRequested ) { |
1032 | LOGGER_ERROR("Invalid call index!"); | ||
1033 | pthread_mutex_unlock(session->mutex); | ||
1034 | return msi_ErrorNoCall; | ||
1035 | } | ||
1036 | |||
1037 | if ( session->calls[call_index]->state != msi_CallRequested ) { | ||
1038 | LOGGER_ERROR("Call is in invalid state!"); | 898 | LOGGER_ERROR("Call is in invalid state!"); |
1039 | pthread_mutex_unlock(session->mutex); | ||
1040 | return msi_ErrorInvalidState; | 899 | return msi_ErrorInvalidState; |
1041 | } | 900 | } |
1042 | 901 | ||
1043 | MSIMessage *msg_reject = msi_new_message ( type_request, requ_reject ); | 902 | MSIMessage *msg_reject = msi_new_message ( type_request, requ_reject ); |
1044 | 903 | send_message ( call, msg_reject, call->friend_id ); | |
1045 | /* FIXME */ | ||
1046 | #if 0 | ||
1047 | |||
1048 | if ( reason && strlen(reason) < sizeof(MSIReasonStrType) ) { | ||
1049 | MSIReasonStrType reason_cast; | ||
1050 | memset(reason_cast, '\0', sizeof(MSIReasonStrType)); | ||
1051 | memcpy(reason_cast, reason, strlen(reason)); | ||
1052 | msi_msg_set_reason(msg_reject, reason_cast); | ||
1053 | } | ||
1054 | |||
1055 | #else | ||
1056 | (void)reason; | ||
1057 | |||
1058 | #endif | ||
1059 | |||
1060 | send_message ( session, session->calls[call_index], msg_reject, | ||
1061 | session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] ); | ||
1062 | free ( msg_reject ); | 904 | free ( msg_reject ); |
1063 | 905 | ||
1064 | session->calls[call_index]->state = msi_CallOver; | ||
1065 | session->calls[call_index]->request_timer_id = | ||
1066 | timer_alloc ( session, handle_timeout, call_index, m_deftout ); | ||
1067 | |||
1068 | pthread_mutex_unlock(session->mutex); | ||
1069 | return 0; | 906 | return 0; |
1070 | } | 907 | } |
1071 | 908 | ||
1072 | int msi_stopcall ( MSISession *session, int32_t call_index ) | 909 | int msi_change_csettings( MSICall* call, uint8_t capabilities ) |
1073 | { | ||
1074 | pthread_mutex_lock(session->mutex); | ||
1075 | LOGGER_DEBUG("Session: %p Stopping call index: %u", session, call_index); | ||
1076 | |||
1077 | if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { | ||
1078 | pthread_mutex_unlock(session->mutex); | ||
1079 | return msi_ErrorNoCall; | ||
1080 | } | ||
1081 | |||
1082 | /* just terminate it */ | ||
1083 | |||
1084 | terminate_call ( session, session->calls[call_index] ); | ||
1085 | |||
1086 | pthread_mutex_unlock(session->mutex); | ||
1087 | return 0; | ||
1088 | } | ||
1089 | |||
1090 | int msi_change_csettings(MSISession *session, int32_t call_index, const MSICSettings *csettings) | ||
1091 | { | 910 | { |
1092 | pthread_mutex_lock(session->mutex); | 911 | pthread_mutex_lock(session->mutex); |
1093 | 912 | ||
1094 | LOGGER_DEBUG("Changing media on call: %d", call_index); | 913 | LOGGER_DEBUG("Changing media on call: %d", call_index); |
1095 | 914 | ||
1096 | if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { | ||
1097 | LOGGER_ERROR("Invalid call index!"); | ||
1098 | pthread_mutex_unlock(session->mutex); | ||
1099 | return msi_ErrorNoCall; | ||
1100 | } | ||
1101 | |||
1102 | MSICall *call = session->calls[call_index]; | 915 | MSICall *call = session->calls[call_index]; |
1103 | 916 | ||
1104 | if ( call->state != msi_CallActive ) { | 917 | if ( call->state != msi_CallActive ) { |
@@ -1136,26 +949,4 @@ int msi_change_csettings(MSISession *session, int32_t call_index, const MSICSett | |||
1136 | pthread_mutex_unlock(session->mutex); | 949 | pthread_mutex_unlock(session->mutex); |
1137 | 950 | ||
1138 | return 0; | 951 | return 0; |
1139 | } | 952 | } \ No newline at end of file |
1140 | |||
1141 | void msi_do(MSISession *session) | ||
1142 | { | ||
1143 | pthread_mutex_lock(session->mutex); | ||
1144 | |||
1145 | TimerHandler *timer = session->timer_handler; | ||
1146 | |||
1147 | uint64_t time = current_time_monotonic(); | ||
1148 | |||
1149 | while ( timer->timers[0] && timer->timers[0]->timeout < time ) { | ||
1150 | LOGGER_DEBUG("Executing timer assigned at: %d", timer->timers[0]->timeout); | ||
1151 | |||
1152 | int id = timer->timers[0]->id; | ||
1153 | timer->timers[0]->func(timer->timers[0]); | ||
1154 | |||
1155 | /* In case function has released timer */ | ||
1156 | if (timer->timers[0] && timer->timers[0]->id == id) | ||
1157 | timer_release(timer, id); | ||
1158 | } | ||
1159 | |||
1160 | pthread_mutex_unlock(session->mutex); | ||
1161 | } | ||
diff --git a/toxav/msi.h b/toxav/msi.h index c71c69dd..8fa309c3 100644 --- a/toxav/msi.h +++ b/toxav/msi.h | |||
@@ -19,8 +19,8 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #ifndef __TOXMSI | 22 | #ifndef MSI_H |
23 | #define __TOXMSI | 23 | #define MSI_H |
24 | 24 | ||
25 | #include <inttypes.h> | 25 | #include <inttypes.h> |
26 | #include <pthread.h> | 26 | #include <pthread.h> |
@@ -40,6 +40,23 @@ typedef enum { | |||
40 | msi_TypeVideo | 40 | msi_TypeVideo |
41 | } MSICallType; | 41 | } MSICallType; |
42 | 42 | ||
43 | /** | ||
44 | * Error codes. | ||
45 | */ | ||
46 | typedef enum { | ||
47 | msi_ErrUndisclosed, | ||
48 | } MSIError; | ||
49 | |||
50 | /** | ||
51 | * Supported capabilities | ||
52 | */ | ||
53 | typedef enum { | ||
54 | msi_CapSAudio = 1, /* sending audio */ | ||
55 | msi_CapSVideo = 2, /* sending video */ | ||
56 | msi_CapRAudio = 4, /* receiving audio */ | ||
57 | msi_CapRVideo = 8, /* receiving video */ | ||
58 | } MSICapabilities; | ||
59 | |||
43 | 60 | ||
44 | /** | 61 | /** |
45 | * Call state identifiers. | 62 | * Call state identifiers. |
@@ -71,25 +88,15 @@ typedef struct { | |||
71 | } MSICSettings; | 88 | } MSICSettings; |
72 | 89 | ||
73 | /** | 90 | /** |
74 | * Active capabilities masks | ||
75 | */ | ||
76 | typedef enum { | ||
77 | msi_SendingAudio = 1, | ||
78 | msi_SendingVideo = 2, | ||
79 | msi_RecvingAudio = 4, | ||
80 | msi_RecvingVideo = 8, | ||
81 | } MSICapMask; | ||
82 | |||
83 | /** | ||
84 | * Callbacks ids that handle the states | 91 | * Callbacks ids that handle the states |
85 | */ | 92 | */ |
86 | typedef enum { | 93 | typedef enum { |
87 | msi_OnInvite, /* Incoming call */ | 94 | msi_OnInvite, /* Incoming call */ |
88 | msi_OnRinging, /* When peer is ready to accept/reject the call */ | 95 | msi_OnRinging, /* When peer is ready to accept/reject the call */ |
89 | msi_OnStart, /* Call (RTP transmission) started */ | 96 | msi_OnStart, /* Call (RTP transmission) started */ |
90 | msi_OnCancel, /* The side that initiated call canceled invite */ | ||
91 | msi_OnReject, /* The side that was invited rejected the call */ | 97 | msi_OnReject, /* The side that was invited rejected the call */ |
92 | msi_OnEnd, /* Call that was active ended */ | 98 | msi_OnEnd, /* Call that was active ended */ |
99 | msi_OnError, /* Call that was active ended */ | ||
93 | msi_OnRequestTimeout, /* When the requested action didn't get response in specified time */ | 100 | msi_OnRequestTimeout, /* When the requested action didn't get response in specified time */ |
94 | msi_OnPeerTimeout, /* Peer timed out; stop the call */ | 101 | msi_OnPeerTimeout, /* Peer timed out; stop the call */ |
95 | msi_OnPeerCSChange, /* Peer requested Csettings change */ | 102 | msi_OnPeerCSChange, /* Peer requested Csettings change */ |
@@ -107,25 +114,30 @@ typedef enum { | |||
107 | } MSIError; | 114 | } MSIError; |
108 | 115 | ||
109 | /** | 116 | /** |
110 | * The call struct. | 117 | * The call struct. Please do not modify outside msi.c |
111 | */ | 118 | */ |
112 | typedef struct { | 119 | typedef struct MSICall_s { |
113 | struct MSISession_s *session; /* Session pointer */ | 120 | struct MSISession_s *session; /* Session pointer */ |
114 | 121 | ||
115 | MSICallState state; | 122 | MSICallState state; |
116 | uint8_t caps; /* Active capabilities */ | 123 | uint8_t capabilities; /* Active capabilities */ |
117 | 124 | ||
118 | uint32_t friend_id; /* Index of this call in MSISession */ | 125 | uint32_t friend_id; /* Index of this call in MSISession */ |
126 | |||
127 | struct MSICall_s* next; | ||
128 | struct MSICall_s* prev; | ||
119 | } MSICall; | 129 | } MSICall; |
120 | 130 | ||
121 | 131 | ||
122 | /** | 132 | /** |
123 | * Control session struct | 133 | * Control session struct. Please do not modify outside msi.c |
124 | */ | 134 | */ |
125 | typedef struct MSISession_s { | 135 | typedef struct MSISession_s { |
126 | /* Call handlers */ | 136 | /* Call handlers */ |
127 | MSICall **calls; | 137 | MSICall **calls; |
128 | 138 | uint32_t calls_tail; | |
139 | uint32_t calls_head; | ||
140 | |||
129 | void *agent_handler; | 141 | void *agent_handler; |
130 | Messenger *messenger_handle; | 142 | Messenger *messenger_handle; |
131 | 143 | ||
@@ -139,7 +151,7 @@ typedef struct MSISession_s { | |||
139 | MSISession *msi_new ( Messenger *messenger, int32_t max_calls ); | 151 | MSISession *msi_new ( Messenger *messenger, int32_t max_calls ); |
140 | 152 | ||
141 | /** | 153 | /** |
142 | * Terminate control session. | 154 | * Terminate control session. NOTE: all calls will be freed |
143 | */ | 155 | */ |
144 | int msi_kill ( MSISession *session ); | 156 | int msi_kill ( MSISession *session ); |
145 | 157 | ||
@@ -151,45 +163,26 @@ void msi_register_callback(MSISession *session, MSICallbackType callback, MSICal | |||
151 | /** | 163 | /** |
152 | * Send invite request to friend_id. | 164 | * Send invite request to friend_id. |
153 | */ | 165 | */ |
154 | int msi_invite ( MSISession *session, | 166 | int msi_invite ( MSISession* session, MSICall** call, uint32_t friend_id, uint8_t capabilities ); |
155 | int32_t *call_index, | ||
156 | const MSICSettings *csettings, | ||
157 | uint32_t rngsec, | ||
158 | uint32_t friend_id ); | ||
159 | |||
160 | /** | ||
161 | * Hangup active call. | ||
162 | */ | ||
163 | int msi_hangup ( MSISession *session, int32_t call_index ); | ||
164 | |||
165 | /** | ||
166 | * Answer active call request. | ||
167 | */ | ||
168 | int msi_answer ( MSISession *session, int32_t call_index, const MSICSettings *csettings ); | ||
169 | |||
170 | /** | ||
171 | * Cancel request. | ||
172 | */ | ||
173 | int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const char *reason ); | ||
174 | 167 | ||
175 | /** | 168 | /** |
176 | * Reject incoming call. | 169 | * Hangup call. NOTE: 'call' will be freed |
177 | */ | 170 | */ |
178 | int msi_reject ( MSISession *session, int32_t call_index, const char *reason ); | 171 | int msi_hangup ( MSICall* call ); |
179 | 172 | ||
180 | /** | 173 | /** |
181 | * Terminate the call. | 174 | * Answer call request. |
182 | */ | 175 | */ |
183 | int msi_stopcall ( MSISession *session, int32_t call_index ); | 176 | int msi_answer ( MSICall* call, uint8_t capabilities ); |
184 | 177 | ||
185 | /** | 178 | /** |
186 | * Change codec settings of the current call. | 179 | * Reject incoming call. NOTE: 'call' will be freed |
187 | */ | 180 | */ |
188 | int msi_change_csettings ( MSISession *session, int32_t call_index, const MSICSettings *csettings ); | 181 | int msi_reject ( MSICall* call ); |
189 | 182 | ||
190 | /** | 183 | /** |
191 | * Main msi loop | 184 | * Change capabilities of the call. |
192 | */ | 185 | */ |
193 | void msi_do( MSISession *session ); | 186 | int msi_change_capabilities ( MSICall* call, uint8_t capabilities ); |
194 | 187 | ||
195 | #endif /* __TOXMSI */ | 188 | #endif /* MSI_H */ |
diff --git a/toxav/rtp.h b/toxav/rtp.h index 03b44719..b1888f6c 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h | |||
@@ -19,8 +19,8 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #ifndef __TOXRTP | 22 | #ifndef RTP_H |
23 | #define __TOXRTP | 23 | #define RTP_H |
24 | 24 | ||
25 | #define RTP_VERSION 2 | 25 | #define RTP_VERSION 2 |
26 | #include <inttypes.h> | 26 | #include <inttypes.h> |
@@ -130,4 +130,4 @@ void rtp_free_msg ( RTPSession *session, RTPMessage *msg ); | |||
130 | 130 | ||
131 | 131 | ||
132 | 132 | ||
133 | #endif /* __TOXRTP */ | 133 | #endif /* RTP_H */ |
diff --git a/toxav/toxav.c b/toxav/toxav.c index b594cc29..72f99576 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -83,7 +83,6 @@ struct toxAV | |||
83 | void i_toxav_msi_callback_invite(void* toxav_inst, int32_t call_idx, void *data); | 83 | void i_toxav_msi_callback_invite(void* toxav_inst, int32_t call_idx, void *data); |
84 | void i_toxav_msi_callback_ringing(void* toxav_inst, int32_t call_idx, void *data); | 84 | void i_toxav_msi_callback_ringing(void* toxav_inst, int32_t call_idx, void *data); |
85 | void i_toxav_msi_callback_start(void* toxav_inst, int32_t call_idx, void *data); | 85 | void i_toxav_msi_callback_start(void* toxav_inst, int32_t call_idx, void *data); |
86 | void i_toxav_msi_callback_cancel(void* toxav_inst, int32_t call_idx, void *data); | ||
87 | void i_toxav_msi_callback_reject(void* toxav_inst, int32_t call_idx, void *data); | 86 | void i_toxav_msi_callback_reject(void* toxav_inst, int32_t call_idx, void *data); |
88 | void i_toxav_msi_callback_end(void* toxav_inst, int32_t call_idx, void *data); | 87 | void i_toxav_msi_callback_end(void* toxav_inst, int32_t call_idx, void *data); |
89 | void i_toxav_msi_callback_request_to(void* toxav_inst, int32_t call_idx, void *data); /* TODO remove */ | 88 | void i_toxav_msi_callback_request_to(void* toxav_inst, int32_t call_idx, void *data); /* TODO remove */ |
@@ -138,7 +137,6 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error) | |||
138 | msi_register_callback(av->msi, i_toxav_msi_callback_invite, msi_OnInvite, NULL); | 137 | msi_register_callback(av->msi, i_toxav_msi_callback_invite, msi_OnInvite, NULL); |
139 | msi_register_callback(av->msi, i_toxav_msi_callback_ringing, msi_OnRinging, NULL); | 138 | msi_register_callback(av->msi, i_toxav_msi_callback_ringing, msi_OnRinging, NULL); |
140 | msi_register_callback(av->msi, i_toxav_msi_callback_start, msi_OnStart, NULL); | 139 | msi_register_callback(av->msi, i_toxav_msi_callback_start, msi_OnStart, NULL); |
141 | msi_register_callback(av->msi, i_toxav_msi_callback_cancel, msi_OnCancel, NULL); | ||
142 | msi_register_callback(av->msi, i_toxav_msi_callback_reject, msi_OnReject, NULL); | 140 | msi_register_callback(av->msi, i_toxav_msi_callback_reject, msi_OnReject, NULL); |
143 | msi_register_callback(av->msi, i_toxav_msi_callback_end, msi_OnEnd, NULL); | 141 | msi_register_callback(av->msi, i_toxav_msi_callback_end, msi_OnEnd, NULL); |
144 | msi_register_callback(av->msi, i_toxav_msi_callback_request_to, msi_OnRequestTimeout, NULL); | 142 | msi_register_callback(av->msi, i_toxav_msi_callback_request_to, msi_OnRequestTimeout, NULL); |
@@ -588,17 +586,6 @@ void i_toxav_msi_callback_start(void* toxav_inst, int32_t call_idx, void* data) | |||
588 | toxav->scb.first(toxav, call->friend_number, state, toxav->scb.second); | 586 | toxav->scb.first(toxav, call->friend_number, state, toxav->scb.second); |
589 | } | 587 | } |
590 | 588 | ||
591 | void i_toxav_msi_callback_cancel(void* toxav_inst, int32_t call_idx, void* data) | ||
592 | { | ||
593 | ToxAV* toxav = toxav_inst; | ||
594 | |||
595 | i_toxav_remove_call(toxav, toxav->msi->calls[call_idx]->peers[0]); | ||
596 | |||
597 | if (toxav->scb.first) | ||
598 | toxav->scb.first(toxav, toxav->msi->calls[call_idx]->peers[0], | ||
599 | TOXAV_CALL_STATE_END, toxav->scb.second); | ||
600 | } | ||
601 | |||
602 | void i_toxav_msi_callback_reject(void* toxav_inst, int32_t call_idx, void* data) | 589 | void i_toxav_msi_callback_reject(void* toxav_inst, int32_t call_idx, void* data) |
603 | { | 590 | { |
604 | ToxAV* toxav = toxav_inst; | 591 | ToxAV* toxav = toxav_inst; |
@@ -918,7 +905,6 @@ void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number) | |||
918 | 905 | ||
919 | if (!call->active) { | 906 | if (!call->active) { |
920 | pthread_mutex_unlock(call->mutex_control); | 907 | pthread_mutex_unlock(call->mutex_control); |
921 | LOGGER_WARNING("Action on inactive call: %d", call->call_idx); | ||
922 | return; | 908 | return; |
923 | } | 909 | } |
924 | 910 | ||
diff --git a/toxav/toxav.h b/toxav/toxav.h index 69654f97..04ad3cd0 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h | |||
@@ -1,4 +1,6 @@ | |||
1 | #pragma once | 1 | #ifndef TOXAV_H |
2 | #define TOXAV_H | ||
3 | |||
2 | #include <stdbool.h> | 4 | #include <stdbool.h> |
3 | #include <stddef.h> | 5 | #include <stddef.h> |
4 | #include <stdint.h> | 6 | #include <stdint.h> |
@@ -480,4 +482,6 @@ typedef void toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, | |||
480 | /** | 482 | /** |
481 | * Set the callback for the `receive_audio_frame` event. Pass NULL to unset. | 483 | * Set the callback for the `receive_audio_frame` event. Pass NULL to unset. |
482 | */ | 484 | */ |
483 | void toxav_callback_receive_audio_frame(ToxAV *av, toxav_receive_audio_frame_cb *function, void *user_data); \ No newline at end of file | 485 | void toxav_callback_receive_audio_frame(ToxAV *av, toxav_receive_audio_frame_cb *function, void *user_data); |
486 | |||
487 | #endif /* TOXAV_H */ \ No newline at end of file | ||