diff options
Diffstat (limited to 'toxav')
-rw-r--r-- | toxav/msi.c | 300 | ||||
-rw-r--r-- | toxav/msi.h | 8 | ||||
-rw-r--r-- | toxav/toxav.c | 13 | ||||
-rw-r--r-- | toxav/toxav.h | 2 |
4 files changed, 186 insertions, 137 deletions
diff --git a/toxav/msi.c b/toxav/msi.c index 7dc12d4d..b300ca75 100644 --- a/toxav/msi.c +++ b/toxav/msi.c | |||
@@ -55,13 +55,13 @@ typedef enum { | |||
55 | IDReason, | 55 | IDReason, |
56 | IDCallType, | 56 | IDCallType, |
57 | IDCallId, | 57 | IDCallId, |
58 | 58 | ||
59 | } MSIHeaderID; | 59 | } MSIHeaderID; |
60 | 60 | ||
61 | typedef enum { | 61 | typedef enum { |
62 | TypeRequest, | 62 | TypeRequest, |
63 | TypeResponse, | 63 | TypeResponse, |
64 | 64 | ||
65 | } MSIMessageType; | 65 | } MSIMessageType; |
66 | 66 | ||
67 | typedef enum { | 67 | typedef enum { |
@@ -70,7 +70,7 @@ typedef enum { | |||
70 | cancel, | 70 | cancel, |
71 | reject, | 71 | reject, |
72 | end, | 72 | end, |
73 | 73 | ||
74 | } MSIRequest; | 74 | } MSIRequest; |
75 | 75 | ||
76 | typedef enum { | 76 | typedef enum { |
@@ -78,7 +78,7 @@ typedef enum { | |||
78 | starting, | 78 | starting, |
79 | ending, | 79 | ending, |
80 | error | 80 | error |
81 | 81 | ||
82 | } MSIResponse; | 82 | } MSIResponse; |
83 | 83 | ||
84 | 84 | ||
@@ -114,7 +114,7 @@ typedef struct _MSIMessage { | |||
114 | } MSIMessage; | 114 | } MSIMessage; |
115 | 115 | ||
116 | 116 | ||
117 | inline__ void invoke_callback(MSISession* session, int32_t call_index, MSICallbackID id) | 117 | inline__ void invoke_callback(MSISession *session, int32_t call_index, MSICallbackID id) |
118 | { | 118 | { |
119 | if ( session->callbacks[id].function ) { | 119 | if ( session->callbacks[id].function ) { |
120 | LOGGER_DEBUG("Invoking callback function: %d", id); | 120 | LOGGER_DEBUG("Invoking callback function: %d", id); |
@@ -135,63 +135,73 @@ inline__ void invoke_callback(MSISession* session, int32_t call_index, MSICallba | |||
135 | */ | 135 | */ |
136 | static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length ) | 136 | static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length ) |
137 | { | 137 | { |
138 | 138 | ||
139 | #define FAIL_CONSTRAINT(constraint, wanted) if ((constraint -= wanted) < 1) { LOGGER_ERROR("Read over length!"); return -1; } | 139 | #define FAIL_CONSTRAINT(constraint, wanted) if ((constraint -= wanted) < 1) { LOGGER_ERROR("Read over length!"); return -1; } |
140 | #define FAIL_SIZE(byte, valid) if ( byte != valid ) { LOGGER_ERROR("Invalid data size!"); return -1; } | 140 | #define FAIL_SIZE(byte, valid) if ( byte != valid ) { LOGGER_ERROR("Invalid data size!"); return -1; } |
141 | #define FAIL_LIMITS(byte, low, high) if ( byte < low || byte > high ) { LOGGER_ERROR("Invalid data!"); return -1; } | 141 | #define FAIL_LIMITS(byte, low, high) if ( byte < low || byte > high ) { LOGGER_ERROR("Invalid data!"); return -1; } |
142 | 142 | ||
143 | if ( msg == NULL ) { | 143 | if ( msg == NULL ) { |
144 | LOGGER_ERROR("Could not parse message: no storage!"); | 144 | LOGGER_ERROR("Could not parse message: no storage!"); |
145 | return -1; | 145 | return -1; |
146 | } | 146 | } |
147 | 147 | ||
148 | if ( data[length - 1] ) { /* End byte must have value 0 */ | 148 | if ( data[length - 1] ) { /* End byte must have value 0 */ |
149 | LOGGER_ERROR("Invalid end byte"); | 149 | LOGGER_ERROR("Invalid end byte"); |
150 | return -1; | 150 | return -1; |
151 | } | 151 | } |
152 | 152 | ||
153 | const uint8_t *it = data; | 153 | const uint8_t *it = data; |
154 | int size_constraint = length; | 154 | int size_constraint = length; |
155 | 155 | ||
156 | while ( *it ) {/* until end byte is hit */ | 156 | while ( *it ) {/* until end byte is hit */ |
157 | switch (*it) { | 157 | switch (*it) { |
158 | case IDRequest: | 158 | case IDRequest: |
159 | FAIL_CONSTRAINT(size_constraint, 3); | 159 | FAIL_CONSTRAINT(size_constraint, 3); |
160 | FAIL_SIZE(it[1], 1); | 160 | FAIL_SIZE(it[1], 1); |
161 | FAIL_LIMITS(it[2], invite, end); | 161 | FAIL_LIMITS(it[2], invite, end); |
162 | msg->request.value = it[2]; it += 3; | 162 | msg->request.value = it[2]; |
163 | msg->request.exists = 1; | 163 | it += 3; |
164 | break; | 164 | msg->request.exists = 1; |
165 | case IDResponse: | 165 | break; |
166 | FAIL_CONSTRAINT(size_constraint, 3); | 166 | |
167 | FAIL_SIZE(it[1], 1); | 167 | case IDResponse: |
168 | FAIL_LIMITS(it[2], ringing, error); | 168 | FAIL_CONSTRAINT(size_constraint, 3); |
169 | msg->response.value = it[2]; it += 3; | 169 | FAIL_SIZE(it[1], 1); |
170 | msg->response.exists = 1; | 170 | FAIL_LIMITS(it[2], ringing, error); |
171 | break; | 171 | msg->response.value = it[2]; |
172 | case IDCallType: | 172 | it += 3; |
173 | FAIL_CONSTRAINT(size_constraint, 3); | 173 | msg->response.exists = 1; |
174 | FAIL_SIZE(it[1], 1); | 174 | break; |
175 | FAIL_LIMITS(it[2], type_audio, type_video); | 175 | |
176 | msg->calltype.value = it[2]; it += 3; | 176 | case IDCallType: |
177 | msg->calltype.exists = 1; | 177 | FAIL_CONSTRAINT(size_constraint, 3); |
178 | break; | 178 | FAIL_SIZE(it[1], 1); |
179 | case IDCallId: | 179 | FAIL_LIMITS(it[2], type_audio, type_video); |
180 | FAIL_CONSTRAINT(size_constraint, sizeof(MSICallIDType) + 2); | 180 | msg->calltype.value = it[2]; |
181 | FAIL_SIZE(it[1], sizeof(MSICallIDType)); | 181 | it += 3; |
182 | memcpy(msg->callid.value, it + 2, sizeof(MSICallIDType)); it += sizeof(MSICallIDType) + 2; | 182 | msg->calltype.exists = 1; |
183 | msg->callid.exists = 1; | 183 | break; |
184 | break; | 184 | |
185 | case IDReason: | 185 | case IDCallId: |
186 | FAIL_CONSTRAINT(size_constraint, sizeof(MSIReasonStrType) + 2); | 186 | FAIL_CONSTRAINT(size_constraint, sizeof(MSICallIDType) + 2); |
187 | FAIL_SIZE(it[1], sizeof(MSIReasonStrType)); | 187 | FAIL_SIZE(it[1], sizeof(MSICallIDType)); |
188 | memcpy(msg->reason.value, it + 2, sizeof(MSIReasonStrType)); it += sizeof(MSIReasonStrType) + 2; | 188 | memcpy(msg->callid.value, it + 2, sizeof(MSICallIDType)); |
189 | msg->reason.exists = 1; | 189 | it += sizeof(MSICallIDType) + 2; |
190 | break; | 190 | msg->callid.exists = 1; |
191 | default: | 191 | break; |
192 | LOGGER_ERROR("Invalid id byte"); | 192 | |
193 | return -1; | 193 | case IDReason: |
194 | break; | 194 | FAIL_CONSTRAINT(size_constraint, sizeof(MSIReasonStrType) + 2); |
195 | FAIL_SIZE(it[1], sizeof(MSIReasonStrType)); | ||
196 | memcpy(msg->reason.value, it + 2, sizeof(MSIReasonStrType)); | ||
197 | it += sizeof(MSIReasonStrType) + 2; | ||
198 | msg->reason.exists = 1; | ||
199 | break; | ||
200 | |||
201 | default: | ||
202 | LOGGER_ERROR("Invalid id byte"); | ||
203 | return -1; | ||
204 | break; | ||
195 | } | 205 | } |
196 | } | 206 | } |
197 | 207 | ||
@@ -214,7 +224,7 @@ MSIMessage *msi_new_message ( MSIMessageType type, const uint8_t type_value ) | |||
214 | LOGGER_WARNING("Allocation failed! Program might misbehave!"); | 224 | LOGGER_WARNING("Allocation failed! Program might misbehave!"); |
215 | return NULL; | 225 | return NULL; |
216 | } | 226 | } |
217 | 227 | ||
218 | if ( type == TypeRequest ) { | 228 | if ( type == TypeRequest ) { |
219 | retu->request.exists = 1; | 229 | retu->request.exists = 1; |
220 | retu->request.value = type_value; | 230 | retu->request.value = type_value; |
@@ -281,13 +291,15 @@ uint8_t *format_output ( uint8_t *dest, MSIHeaderID id, const void *value, uint8 | |||
281 | return NULL; | 291 | return NULL; |
282 | } | 292 | } |
283 | 293 | ||
284 | *dest = id; dest ++; | 294 | *dest = id; |
285 | *dest = value_len; dest ++; | 295 | dest ++; |
286 | 296 | *dest = value_len; | |
297 | dest ++; | ||
298 | |||
287 | memcpy(dest, value, value_len); | 299 | memcpy(dest, value, value_len); |
288 | 300 | ||
289 | *length += (2 + value_len); | 301 | *length += (2 + value_len); |
290 | 302 | ||
291 | return dest + value_len; /* Set to next position ready to be written */ | 303 | return dest + value_len; /* Set to next position ready to be written */ |
292 | } | 304 | } |
293 | 305 | ||
@@ -313,30 +325,30 @@ uint16_t parse_send ( MSIMessage *msg, uint8_t *dest ) | |||
313 | 325 | ||
314 | uint8_t *it = dest; | 326 | uint8_t *it = dest; |
315 | uint16_t size = 0; | 327 | uint16_t size = 0; |
316 | 328 | ||
317 | if (msg->request.exists) { | 329 | if (msg->request.exists) { |
318 | uint8_t cast = msg->request.value; | 330 | uint8_t cast = msg->request.value; |
319 | it = format_output(it, IDRequest, &cast, 1, &size); | 331 | it = format_output(it, IDRequest, &cast, 1, &size); |
320 | } | 332 | } |
321 | 333 | ||
322 | if (msg->response.exists) { | 334 | if (msg->response.exists) { |
323 | uint8_t cast = msg->response.value; | 335 | uint8_t cast = msg->response.value; |
324 | it = format_output(it, IDResponse, &cast, 1, &size); | 336 | it = format_output(it, IDResponse, &cast, 1, &size); |
325 | } | 337 | } |
326 | 338 | ||
327 | if (msg->calltype.exists) { | 339 | if (msg->calltype.exists) { |
328 | uint8_t cast = msg->calltype.value; | 340 | uint8_t cast = msg->calltype.value; |
329 | it = format_output(it, IDCallType, &cast, 1, &size); | 341 | it = format_output(it, IDCallType, &cast, 1, &size); |
330 | } | 342 | } |
331 | 343 | ||
332 | if (msg->callid.exists) { | 344 | if (msg->callid.exists) { |
333 | it = format_output(it, IDCallId, &msg->callid.value, sizeof(msg->callid.value), &size); | 345 | it = format_output(it, IDCallId, &msg->callid.value, sizeof(msg->callid.value), &size); |
334 | } | 346 | } |
335 | 347 | ||
336 | if (msg->reason.exists) { | 348 | if (msg->reason.exists) { |
337 | it = format_output(it, IDReason, &msg->reason.value, sizeof(msg->reason.value), &size); | 349 | it = format_output(it, IDReason, &msg->reason.value, sizeof(msg->reason.value), &size); |
338 | } | 350 | } |
339 | 351 | ||
340 | *it = 0; | 352 | *it = 0; |
341 | size ++; | 353 | size ++; |
342 | 354 | ||
@@ -344,24 +356,27 @@ uint16_t parse_send ( MSIMessage *msg, uint8_t *dest ) | |||
344 | } | 356 | } |
345 | 357 | ||
346 | 358 | ||
347 | void msi_msg_set_calltype ( MSIMessage* msg, const MSICallType value ) | 359 | void msi_msg_set_calltype ( MSIMessage *msg, const MSICallType value ) |
348 | { | 360 | { |
349 | if ( !msg ) return; | 361 | if ( !msg ) return; |
350 | msg->calltype.exists = 1; | 362 | |
351 | msg->calltype.value = value; | 363 | msg->calltype.exists = 1; |
364 | msg->calltype.value = value; | ||
352 | } | 365 | } |
353 | 366 | ||
354 | void msi_msg_set_reason ( MSIMessage* msg, const MSIReasonStrType value ) | 367 | void msi_msg_set_reason ( MSIMessage *msg, const MSIReasonStrType value ) |
355 | { | 368 | { |
356 | if ( !msg ) return; | 369 | if ( !msg ) return; |
370 | |||
357 | msg->reason.exists = 1; | 371 | msg->reason.exists = 1; |
358 | memcpy(msg->reason.value, value, sizeof(MSIReasonStrType)); | 372 | memcpy(msg->reason.value, value, sizeof(MSIReasonStrType)); |
359 | } | 373 | } |
360 | 374 | ||
361 | void msi_msg_set_callid ( MSIMessage* msg, const MSICallIDType value ) | 375 | void msi_msg_set_callid ( MSIMessage *msg, const MSICallIDType value ) |
362 | { | 376 | { |
363 | if ( !msg ) return; | 377 | if ( !msg ) return; |
364 | msg->callid.exists = 1; | 378 | |
379 | msg->callid.exists = 1; | ||
365 | memcpy(msg->callid.value, value, sizeof(MSICallIDType)); | 380 | memcpy(msg->callid.value, value, sizeof(MSICallIDType)); |
366 | } | 381 | } |
367 | 382 | ||
@@ -528,7 +543,7 @@ static void *timer_poll( void *arg ) | |||
528 | args->arg2 = handler->timers[0]->func_arg2; | 543 | args->arg2 = handler->timers[0]->func_arg2; |
529 | 544 | ||
530 | if ( 0 != pthread_create(&tid, NULL, handler->timers[0]->func, args) || | 545 | if ( 0 != pthread_create(&tid, NULL, handler->timers[0]->func, args) || |
531 | 0 != pthread_detach(tid) ) { | 546 | 0 != pthread_detach(tid) ) { |
532 | LOGGER_ERROR("Failed to execute timer at: %d!", handler->timers[0]->timeout); | 547 | LOGGER_ERROR("Failed to execute timer at: %d!", handler->timers[0]->timeout); |
533 | free(args); | 548 | free(args); |
534 | } else { | 549 | } else { |
@@ -662,9 +677,9 @@ typedef enum { | |||
662 | * @param error_code The code. | 677 | * @param error_code The code. |
663 | * @return const uint8_t* The string. | 678 | * @return const uint8_t* The string. |
664 | */ | 679 | */ |
665 | static inline__ const uint8_t* stringify_error ( MSICallError error_code ) | 680 | static inline__ const uint8_t *stringify_error ( MSICallError error_code ) |
666 | { | 681 | { |
667 | static const uint8_t* strings[] = { | 682 | static const uint8_t *strings[] = { |
668 | ( uint8_t *) "", | 683 | ( uint8_t *) "", |
669 | ( uint8_t *) "Using dead call", | 684 | ( uint8_t *) "Using dead call", |
670 | ( uint8_t *) "Call id not set to any call", | 685 | ( uint8_t *) "Call id not set to any call", |
@@ -739,7 +754,7 @@ static int call_id_bigger( const uint8_t *first, const uint8_t *second) | |||
739 | */ | 754 | */ |
740 | static int flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id ) | 755 | static int flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id ) |
741 | { | 756 | { |
742 | if ( msg->calltype.exists ) { | 757 | if ( msg->calltype.exists ) { |
743 | call->type_peer[peer_id] = msg->calltype.value; | 758 | call->type_peer[peer_id] = msg->calltype.value; |
744 | return 0; | 759 | return 0; |
745 | } | 760 | } |
@@ -995,10 +1010,10 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage * | |||
995 | LOGGER_DEBUG("Session: %p Handling 'invite' on call: %d", session, call ? call->call_idx : -1); | 1010 | LOGGER_DEBUG("Session: %p Handling 'invite' on call: %d", session, call ? call->call_idx : -1); |
996 | 1011 | ||
997 | pthread_mutex_lock(&session->mutex); | 1012 | pthread_mutex_lock(&session->mutex); |
998 | 1013 | ||
999 | if (!msg->calltype.exists) {/**/ | 1014 | if (!msg->calltype.exists) {/**/ |
1000 | LOGGER_WARNING("Peer sent invalid call type!"); | 1015 | LOGGER_WARNING("Peer sent invalid call type!"); |
1001 | send_error ( session, call, error_no_callid, msg->friend_id ); | 1016 | send_error ( session, call, error_no_callid, msg->friend_id ); |
1002 | pthread_mutex_unlock(&session->mutex); | 1017 | pthread_mutex_unlock(&session->mutex); |
1003 | return 0; | 1018 | return 0; |
1004 | } | 1019 | } |
@@ -1013,7 +1028,7 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage * | |||
1013 | * as in he will wait the response from the other. | 1028 | * as in he will wait the response from the other. |
1014 | */ | 1029 | */ |
1015 | LOGGER_DEBUG("Glare case; Peer: %d", call->peers[0]); | 1030 | LOGGER_DEBUG("Glare case; Peer: %d", call->peers[0]); |
1016 | 1031 | ||
1017 | if ( call_id_bigger (call->id, msg->callid.value) == 1 ) { /* Peer has advantage */ | 1032 | if ( call_id_bigger (call->id, msg->callid.value) == 1 ) { /* Peer has advantage */ |
1018 | 1033 | ||
1019 | /* Terminate call; peer will timeout(call) if call initialization fails */ | 1034 | /* Terminate call; peer will timeout(call) if call initialization fails */ |
@@ -1035,11 +1050,11 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage * | |||
1035 | /* Request for media change; call callback and send starting response */ | 1050 | /* Request for media change; call callback and send starting response */ |
1036 | if (flush_peer_type(call, msg, 0) != 0) { /**/ | 1051 | if (flush_peer_type(call, msg, 0) != 0) { /**/ |
1037 | LOGGER_WARNING("Peer sent invalid call type!"); | 1052 | LOGGER_WARNING("Peer sent invalid call type!"); |
1038 | send_error ( session, call, error_no_callid, msg->friend_id ); | 1053 | send_error ( session, call, error_no_callid, msg->friend_id ); |
1039 | pthread_mutex_unlock(&session->mutex); | 1054 | pthread_mutex_unlock(&session->mutex); |
1040 | return 0; | 1055 | return 0; |
1041 | } | 1056 | } |
1042 | 1057 | ||
1043 | LOGGER_DEBUG("Set new call type: %s", call->type_peer[0] == type_audio ? "audio" : "video"); | 1058 | LOGGER_DEBUG("Set new call type: %s", call->type_peer[0] == type_audio ? "audio" : "video"); |
1044 | send_reponse(session, call, starting, msg->friend_id); | 1059 | send_reponse(session, call, starting, msg->friend_id); |
1045 | pthread_mutex_unlock(&session->mutex); | 1060 | pthread_mutex_unlock(&session->mutex); |
@@ -1114,7 +1129,7 @@ static int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage * | |||
1114 | LOGGER_DEBUG("Session: %p Handling 'reject' on call: %s", session, call->call_idx); | 1129 | LOGGER_DEBUG("Session: %p Handling 'reject' on call: %s", session, call->call_idx); |
1115 | 1130 | ||
1116 | invoke_callback(session, call->call_idx, MSI_OnReject); | 1131 | invoke_callback(session, call->call_idx, MSI_OnReject); |
1117 | 1132 | ||
1118 | pthread_mutex_lock(&session->mutex); | 1133 | pthread_mutex_lock(&session->mutex); |
1119 | 1134 | ||
1120 | send_reponse(session, call, ending, msg->friend_id); | 1135 | send_reponse(session, call, ending, msg->friend_id); |
@@ -1137,11 +1152,11 @@ static int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage * | |||
1137 | invoke_callback(session, call->call_idx, MSI_OnCancel); | 1152 | invoke_callback(session, call->call_idx, MSI_OnCancel); |
1138 | 1153 | ||
1139 | pthread_mutex_lock(&session->mutex); | 1154 | pthread_mutex_lock(&session->mutex); |
1140 | 1155 | ||
1141 | terminate_call ( session, call ); | 1156 | terminate_call ( session, call ); |
1142 | 1157 | ||
1143 | pthread_mutex_unlock(&session->mutex); | 1158 | pthread_mutex_unlock(&session->mutex); |
1144 | 1159 | ||
1145 | return 1; | 1160 | return 1; |
1146 | } | 1161 | } |
1147 | 1162 | ||
@@ -1159,7 +1174,7 @@ static int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg | |||
1159 | 1174 | ||
1160 | send_reponse(session, call, ending, msg->friend_id); | 1175 | send_reponse(session, call, ending, msg->friend_id); |
1161 | terminate_call ( session, call ); | 1176 | terminate_call ( session, call ); |
1162 | 1177 | ||
1163 | pthread_mutex_unlock(&session->mutex); | 1178 | pthread_mutex_unlock(&session->mutex); |
1164 | 1179 | ||
1165 | 1180 | ||
@@ -1202,12 +1217,12 @@ static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage | |||
1202 | pthread_mutex_lock(&session->mutex); | 1217 | pthread_mutex_lock(&session->mutex); |
1203 | 1218 | ||
1204 | if ( call->state == call_active ) { /* Change media */ | 1219 | if ( call->state == call_active ) { /* Change media */ |
1205 | 1220 | ||
1206 | LOGGER_DEBUG("Session: %p Changing media on call: %d", session, call->call_idx ); | 1221 | LOGGER_DEBUG("Session: %p Changing media on call: %d", session, call->call_idx ); |
1207 | pthread_mutex_unlock(&session->mutex); | 1222 | pthread_mutex_unlock(&session->mutex); |
1208 | 1223 | ||
1209 | invoke_callback(session, call->call_idx, MSI_OnMediaChange); | 1224 | invoke_callback(session, call->call_idx, MSI_OnMediaChange); |
1210 | 1225 | ||
1211 | } else if ( call->state == call_inviting ) { | 1226 | } else if ( call->state == call_inviting ) { |
1212 | LOGGER_DEBUG("Session: %p Handling 'starting' on call: %d", session, call->call_idx ); | 1227 | LOGGER_DEBUG("Session: %p Handling 'starting' on call: %d", session, call->call_idx ); |
1213 | 1228 | ||
@@ -1217,22 +1232,22 @@ static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage | |||
1217 | send_message ( session, call, msg_start, msg->friend_id ); | 1232 | send_message ( session, call, msg_start, msg->friend_id ); |
1218 | free ( msg_start ); | 1233 | free ( msg_start ); |
1219 | 1234 | ||
1220 | 1235 | ||
1221 | flush_peer_type ( call, msg, 0 ); | 1236 | flush_peer_type ( call, msg, 0 ); |
1222 | 1237 | ||
1223 | /* This is here in case of glare */ | 1238 | /* This is here in case of glare */ |
1224 | timer_release ( session->timer_handler, call->ringing_timer_id, 1 ); | 1239 | timer_release ( session->timer_handler, call->ringing_timer_id, 1 ); |
1225 | 1240 | ||
1226 | pthread_mutex_unlock(&session->mutex); | 1241 | pthread_mutex_unlock(&session->mutex); |
1227 | 1242 | ||
1228 | invoke_callback(session, call->call_idx, MSI_OnStarting); | 1243 | invoke_callback(session, call->call_idx, MSI_OnStarting); |
1229 | } else { | 1244 | } else { |
1230 | LOGGER_ERROR("Invalid call state"); | 1245 | LOGGER_ERROR("Invalid call state"); |
1231 | terminate_call(session, call ); | 1246 | terminate_call(session, call ); |
1232 | pthread_mutex_unlock(&session->mutex); | 1247 | pthread_mutex_unlock(&session->mutex); |
1233 | return 0; | 1248 | return 0; |
1234 | } | 1249 | } |
1235 | 1250 | ||
1236 | return 1; | 1251 | return 1; |
1237 | } | 1252 | } |
1238 | static int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg ) | 1253 | static int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg ) |
@@ -1265,15 +1280,16 @@ static int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *m | |||
1265 | LOGGER_DEBUG("Session: %p Handling 'error' on call: %d", session, call->call_idx ); | 1280 | LOGGER_DEBUG("Session: %p Handling 'error' on call: %d", session, call->call_idx ); |
1266 | 1281 | ||
1267 | invoke_callback(session, call->call_idx, MSI_OnEnding); | 1282 | invoke_callback(session, call->call_idx, MSI_OnEnding); |
1268 | 1283 | ||
1269 | pthread_mutex_lock(&session->mutex); | 1284 | pthread_mutex_lock(&session->mutex); |
1285 | |||
1270 | /* Handle error accordingly */ | 1286 | /* Handle error accordingly */ |
1271 | if ( msg->reason.exists ) { | 1287 | if ( msg->reason.exists ) { |
1272 | /* TODO */ | 1288 | /* TODO */ |
1273 | } | 1289 | } |
1274 | 1290 | ||
1275 | terminate_call ( session, call ); | 1291 | terminate_call ( session, call ); |
1276 | 1292 | ||
1277 | pthread_mutex_unlock(&session->mutex); | 1293 | pthread_mutex_unlock(&session->mutex); |
1278 | 1294 | ||
1279 | return 1; | 1295 | return 1; |
@@ -1344,27 +1360,52 @@ static void msi_handle_packet ( Messenger *messenger, int source, const uint8_t | |||
1344 | /* Now handle message */ | 1360 | /* Now handle message */ |
1345 | 1361 | ||
1346 | if ( msg->request.exists ) { /* Handle request */ | 1362 | if ( msg->request.exists ) { /* Handle request */ |
1347 | 1363 | ||
1348 | switch(msg->request.value) { | 1364 | switch (msg->request.value) { |
1349 | case invite: handle_recv_invite ( session, call, msg ); break; | 1365 | case invite: |
1350 | case start: handle_recv_start ( session, call, msg ); break; | 1366 | handle_recv_invite ( session, call, msg ); |
1351 | case cancel: handle_recv_cancel ( session, call, msg ); break; | 1367 | break; |
1352 | case reject: handle_recv_reject ( session, call, msg ); break; | 1368 | |
1353 | case end: handle_recv_end ( session, call, msg ); break; | 1369 | case start: |
1370 | handle_recv_start ( session, call, msg ); | ||
1371 | break; | ||
1372 | |||
1373 | case cancel: | ||
1374 | handle_recv_cancel ( session, call, msg ); | ||
1375 | break; | ||
1376 | |||
1377 | case reject: | ||
1378 | handle_recv_reject ( session, call, msg ); | ||
1379 | break; | ||
1380 | |||
1381 | case end: | ||
1382 | handle_recv_end ( session, call, msg ); | ||
1383 | break; | ||
1354 | } | 1384 | } |
1355 | 1385 | ||
1356 | } else if ( msg->response.exists ) { /* Handle response */ | 1386 | } else if ( msg->response.exists ) { /* Handle response */ |
1357 | 1387 | ||
1358 | /* Got response so cancel timer */ | 1388 | /* Got response so cancel timer */ |
1359 | if ( call ) timer_release ( session->timer_handler, call->request_timer_id, 1 ); | 1389 | if ( call ) timer_release ( session->timer_handler, call->request_timer_id, 1 ); |
1360 | 1390 | ||
1361 | switch(msg->response.value) { | 1391 | switch (msg->response.value) { |
1362 | case ringing: handle_recv_ringing ( session, call, msg ); break; | 1392 | case ringing: |
1363 | case starting: handle_recv_starting ( session, call, msg ); break; | 1393 | handle_recv_ringing ( session, call, msg ); |
1364 | case ending: handle_recv_ending ( session, call, msg ); break; | 1394 | break; |
1365 | case error: handle_recv_error ( session, call, msg ); break; | 1395 | |
1396 | case starting: | ||
1397 | handle_recv_starting ( session, call, msg ); | ||
1398 | break; | ||
1399 | |||
1400 | case ending: | ||
1401 | handle_recv_ending ( session, call, msg ); | ||
1402 | break; | ||
1403 | |||
1404 | case error: | ||
1405 | handle_recv_error ( session, call, msg ); | ||
1406 | break; | ||
1366 | } | 1407 | } |
1367 | 1408 | ||
1368 | } else { | 1409 | } else { |
1369 | LOGGER_WARNING("Invalid message: no resp nor requ headers"); | 1410 | LOGGER_WARNING("Invalid message: no resp nor requ headers"); |
1370 | } | 1411 | } |
@@ -1431,7 +1472,7 @@ MSISession *msi_init_session ( Messenger *messenger, int32_t max_calls ) | |||
1431 | 1472 | ||
1432 | retu->frequ = 10000; /* default value? */ | 1473 | retu->frequ = 10000; /* default value? */ |
1433 | retu->call_timeout = 30000; /* default value? */ | 1474 | retu->call_timeout = 30000; /* default value? */ |
1434 | 1475 | ||
1435 | 1476 | ||
1436 | m_callback_msi_packet(messenger, msi_handle_packet, retu ); | 1477 | m_callback_msi_packet(messenger, msi_handle_packet, retu ); |
1437 | 1478 | ||
@@ -1503,14 +1544,15 @@ int msi_invite ( MSISession *session, int32_t *call_index, MSICallType call_type | |||
1503 | 1544 | ||
1504 | 1545 | ||
1505 | int i = 0; | 1546 | int i = 0; |
1506 | for (; i < session->max_calls; i ++) | 1547 | |
1548 | for (; i < session->max_calls; i ++) | ||
1507 | if (session->calls[i] && session->calls[i]->peers[0] == friend_id) { | 1549 | if (session->calls[i] && session->calls[i]->peers[0] == friend_id) { |
1508 | LOGGER_ERROR("Already in a call with friend %d", friend_id); | 1550 | LOGGER_ERROR("Already in a call with friend %d", friend_id); |
1509 | pthread_mutex_unlock(&session->mutex); | 1551 | pthread_mutex_unlock(&session->mutex); |
1510 | return -1; | 1552 | return -1; |
1511 | } | 1553 | } |
1512 | 1554 | ||
1513 | 1555 | ||
1514 | MSICall *call = init_call ( session, 1, rngsec ); /* Just one peer for now */ | 1556 | MSICall *call = init_call ( session, 1, rngsec ); /* Just one peer for now */ |
1515 | 1557 | ||
1516 | if ( !call ) { | 1558 | if ( !call ) { |
@@ -1575,6 +1617,7 @@ int msi_hangup ( MSISession *session, int32_t call_index ) | |||
1575 | 1617 | ||
1576 | /* hangup for each peer */ | 1618 | /* hangup for each peer */ |
1577 | int it = 0; | 1619 | int it = 0; |
1620 | |||
1578 | for ( ; it < session->calls[call_index]->peer_count; it ++ ) | 1621 | for ( ; it < session->calls[call_index]->peer_count; it ++ ) |
1579 | send_message ( session, session->calls[call_index], msg_end, session->calls[call_index]->peers[it] ); | 1622 | send_message ( session, session->calls[call_index], msg_end, session->calls[call_index]->peers[it] ); |
1580 | 1623 | ||
@@ -1618,7 +1661,7 @@ int msi_answer ( MSISession *session, int32_t call_index, MSICallType call_type | |||
1618 | free ( msg_starting ); | 1661 | free ( msg_starting ); |
1619 | 1662 | ||
1620 | session->calls[call_index]->state = call_active; | 1663 | session->calls[call_index]->state = call_active; |
1621 | 1664 | ||
1622 | pthread_mutex_unlock(&session->mutex); | 1665 | pthread_mutex_unlock(&session->mutex); |
1623 | return 0; | 1666 | return 0; |
1624 | } | 1667 | } |
@@ -1646,13 +1689,15 @@ int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const c | |||
1646 | MSIMessage *msg_cancel = msi_new_message ( TypeRequest, cancel ); | 1689 | MSIMessage *msg_cancel = msi_new_message ( TypeRequest, cancel ); |
1647 | 1690 | ||
1648 | /* FIXME */ | 1691 | /* FIXME */ |
1649 | #if 0 | 1692 | #if 0 |
1693 | |||
1650 | if ( reason && strlen(reason) < sizeof(MSIReasonStrType) ) { | 1694 | if ( reason && strlen(reason) < sizeof(MSIReasonStrType) ) { |
1651 | MSIReasonStrType reason_cast; | 1695 | MSIReasonStrType reason_cast; |
1652 | memset(reason_cast, '\0', sizeof(MSIReasonStrType)); | 1696 | memset(reason_cast, '\0', sizeof(MSIReasonStrType)); |
1653 | memcpy(reason_cast, reason, strlen(reason)); | 1697 | memcpy(reason_cast, reason, strlen(reason)); |
1654 | msi_msg_set_reason(msg_cancel, reason_cast); | 1698 | msi_msg_set_reason(msg_cancel, reason_cast); |
1655 | } | 1699 | } |
1700 | |||
1656 | #endif | 1701 | #endif |
1657 | 1702 | ||
1658 | send_message ( session, session->calls[call_index], msg_cancel, peer ); | 1703 | send_message ( session, session->calls[call_index], msg_cancel, peer ); |
@@ -1687,12 +1732,14 @@ int msi_reject ( MSISession *session, int32_t call_index, const char *reason ) | |||
1687 | 1732 | ||
1688 | /* FIXME */ | 1733 | /* FIXME */ |
1689 | #if 0 | 1734 | #if 0 |
1735 | |||
1690 | if ( reason && strlen(reason) < sizeof(MSIReasonStrType) ) { | 1736 | if ( reason && strlen(reason) < sizeof(MSIReasonStrType) ) { |
1691 | MSIReasonStrType reason_cast; | 1737 | MSIReasonStrType reason_cast; |
1692 | memset(reason_cast, '\0', sizeof(MSIReasonStrType)); | 1738 | memset(reason_cast, '\0', sizeof(MSIReasonStrType)); |
1693 | memcpy(reason_cast, reason, strlen(reason)); | 1739 | memcpy(reason_cast, reason, strlen(reason)); |
1694 | msi_msg_set_reason(msg_reject, reason_cast); | 1740 | msi_msg_set_reason(msg_reject, reason_cast); |
1695 | } | 1741 | } |
1742 | |||
1696 | #endif | 1743 | #endif |
1697 | 1744 | ||
1698 | send_message ( session, session->calls[call_index], msg_reject, | 1745 | send_message ( session, session->calls[call_index], msg_reject, |
@@ -1718,43 +1765,44 @@ int msi_reject ( MSISession *session, int32_t call_index, const char *reason ) | |||
1718 | * @param friend_id The friend. | 1765 | * @param friend_id The friend. |
1719 | * @return int | 1766 | * @return int |
1720 | */ | 1767 | */ |
1721 | int msi_change_type(MSISession* session, int32_t call_index, MSICallType call_type) | 1768 | int msi_change_type(MSISession *session, int32_t call_index, MSICallType call_type) |
1722 | { | 1769 | { |
1723 | pthread_mutex_lock(&session->mutex); | 1770 | pthread_mutex_lock(&session->mutex); |
1724 | 1771 | ||
1725 | LOGGER_DEBUG("Changing media on call: %d", call_index); | 1772 | LOGGER_DEBUG("Changing media on call: %d", call_index); |
1726 | 1773 | ||
1727 | if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { | 1774 | if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { |
1728 | LOGGER_ERROR("Invalid call index!"); | 1775 | LOGGER_ERROR("Invalid call index!"); |
1729 | pthread_mutex_unlock(&session->mutex); | 1776 | pthread_mutex_unlock(&session->mutex); |
1730 | return -1; | 1777 | return -1; |
1731 | } | 1778 | } |
1732 | 1779 | ||
1733 | MSICall *call = session->calls[call_index]; | 1780 | MSICall *call = session->calls[call_index]; |
1781 | |||
1734 | if ( call->state != call_active ) { | 1782 | if ( call->state != call_active ) { |
1735 | LOGGER_ERROR("Call is not active!"); | 1783 | LOGGER_ERROR("Call is not active!"); |
1736 | pthread_mutex_unlock(&session->mutex); | 1784 | pthread_mutex_unlock(&session->mutex); |
1737 | return -1; | 1785 | return -1; |
1738 | } | 1786 | } |
1739 | 1787 | ||
1740 | if ( call->type_local == call_type ) { | 1788 | if ( call->type_local == call_type ) { |
1741 | LOGGER_ERROR("Call is already set to the requested type!"); | 1789 | LOGGER_ERROR("Call is already set to the requested type!"); |
1742 | pthread_mutex_unlock(&session->mutex); | 1790 | pthread_mutex_unlock(&session->mutex); |
1743 | return -1; | 1791 | return -1; |
1744 | } | 1792 | } |
1745 | 1793 | ||
1746 | call->type_local = call_type; | 1794 | call->type_local = call_type; |
1747 | 1795 | ||
1748 | MSIMessage *msg_invite = msi_new_message ( TypeRequest, invite ); | 1796 | MSIMessage *msg_invite = msi_new_message ( TypeRequest, invite ); |
1749 | 1797 | ||
1750 | msi_msg_set_calltype ( msg_invite, call_type ); | 1798 | msi_msg_set_calltype ( msg_invite, call_type ); |
1751 | send_message ( session, call, msg_invite, call->peers[0] ); | 1799 | send_message ( session, call, msg_invite, call->peers[0] ); |
1752 | free ( msg_invite ); | 1800 | free ( msg_invite ); |
1753 | 1801 | ||
1754 | LOGGER_DEBUG("Request for media change sent"); | 1802 | LOGGER_DEBUG("Request for media change sent"); |
1755 | 1803 | ||
1756 | pthread_mutex_unlock(&session->mutex); | 1804 | pthread_mutex_unlock(&session->mutex); |
1757 | 1805 | ||
1758 | return 0; | 1806 | return 0; |
1759 | } | 1807 | } |
1760 | 1808 | ||
diff --git a/toxav/msi.h b/toxav/msi.h index 4f73e58b..b99b2de8 100644 --- a/toxav/msi.h +++ b/toxav/msi.h | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | typedef uint8_t MSICallIDType[12]; | 30 | typedef uint8_t MSICallIDType[12]; |
31 | typedef uint8_t MSIReasonStrType[255]; | 31 | typedef uint8_t MSIReasonStrType[255]; |
32 | typedef void ( *MSICallbackType ) ( void* agent, int32_t call_idx, void *arg ); | 32 | typedef void ( *MSICallbackType ) ( void *agent, int32_t call_idx, void *arg ); |
33 | 33 | ||
34 | 34 | ||
35 | /** | 35 | /** |
@@ -65,12 +65,12 @@ typedef enum { | |||
65 | MSI_OnCancel, | 65 | MSI_OnCancel, |
66 | MSI_OnReject, | 66 | MSI_OnReject, |
67 | MSI_OnEnd, | 67 | MSI_OnEnd, |
68 | 68 | ||
69 | /* Responses */ | 69 | /* Responses */ |
70 | MSI_OnRinging, | 70 | MSI_OnRinging, |
71 | MSI_OnStarting, | 71 | MSI_OnStarting, |
72 | MSI_OnEnding, | 72 | MSI_OnEnding, |
73 | 73 | ||
74 | /* Protocol */ | 74 | /* Protocol */ |
75 | MSI_OnRequestTimeout, | 75 | MSI_OnRequestTimeout, |
76 | MSI_OnPeerTimeout, | 76 | MSI_OnPeerTimeout, |
@@ -123,7 +123,7 @@ typedef struct _MSISession { | |||
123 | MSICall **calls; | 123 | MSICall **calls; |
124 | int32_t max_calls; | 124 | int32_t max_calls; |
125 | 125 | ||
126 | void *agent_handler; | 126 | void *agent_handler; |
127 | Messenger *messenger_handle; | 127 | Messenger *messenger_handle; |
128 | 128 | ||
129 | uint32_t frequ; | 129 | uint32_t frequ; |
diff --git a/toxav/toxav.c b/toxav/toxav.c index 0e9ef4c4..ebe32fe4 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -167,7 +167,7 @@ void toxav_kill ( ToxAv *av ) | |||
167 | * @param id One of the ToxAvCallbackID values | 167 | * @param id One of the ToxAvCallbackID values |
168 | * @return void | 168 | * @return void |
169 | */ | 169 | */ |
170 | void toxav_register_callstate_callback ( ToxAv* av, ToxAVCallback callback, ToxAvCallbackID id, void* userdata ) | 170 | void toxav_register_callstate_callback ( ToxAv *av, ToxAVCallback callback, ToxAvCallbackID id, void *userdata ) |
171 | { | 171 | { |
172 | msi_register_callback(av->msi_session, (MSICallbackType)callback, (MSICallbackID) id, userdata); | 172 | msi_register_callback(av->msi_session, (MSICallbackType)callback, (MSICallbackID) id, userdata); |
173 | } | 173 | } |
@@ -307,12 +307,12 @@ int toxav_cancel ( ToxAv *av, int32_t call_index, int peer_id, const char *reaso | |||
307 | * @retval 0 Success. | 307 | * @retval 0 Success. |
308 | * @retval ToxAvError On error. | 308 | * @retval ToxAvError On error. |
309 | */ | 309 | */ |
310 | int toxav_change_type(ToxAv* av, int32_t call_index, ToxAvCallType call_type) | 310 | int toxav_change_type(ToxAv *av, int32_t call_index, ToxAvCallType call_type) |
311 | { | 311 | { |
312 | if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) { | 312 | if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) { |
313 | return ErrorNoCall; | 313 | return ErrorNoCall; |
314 | } | 314 | } |
315 | 315 | ||
316 | return msi_change_type(av->msi_session, call_index, call_type); | 316 | return msi_change_type(av->msi_session, call_index, call_type); |
317 | } | 317 | } |
318 | 318 | ||
@@ -777,7 +777,7 @@ void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg) | |||
777 | CallSpecific *call = &av->calls[call_index]; | 777 | CallSpecific *call = &av->calls[call_index]; |
778 | 778 | ||
779 | if (!call->call_active) return; | 779 | if (!call->call_active) return; |
780 | 780 | ||
781 | if (_session->payload_type == type_audio % 128) { | 781 | if (_session->payload_type == type_audio % 128) { |
782 | queue(call->j_buf, _msg); | 782 | queue(call->j_buf, _msg); |
783 | 783 | ||
@@ -800,7 +800,7 @@ void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg) | |||
800 | 800 | ||
801 | if ( av->audio_callback ) | 801 | if ( av->audio_callback ) |
802 | av->audio_callback(av, call_index, dest, frame_size); | 802 | av->audio_callback(av, call_index, dest, frame_size); |
803 | else | 803 | else |
804 | LOGGER_WARNING("Audio packet dropped due to missing callback!"); | 804 | LOGGER_WARNING("Audio packet dropped due to missing callback!"); |
805 | } | 805 | } |
806 | } else { | 806 | } else { |
@@ -847,7 +847,8 @@ void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg) | |||
847 | LOGGER_DEBUG("Limit: %u\n", call->frame_limit); | 847 | LOGGER_DEBUG("Limit: %u\n", call->frame_limit); |
848 | } | 848 | } |
849 | 849 | ||
850 | end:; | 850 | end: |
851 | ; | ||
851 | vpx_codec_iter_t iter = NULL; | 852 | vpx_codec_iter_t iter = NULL; |
852 | vpx_image_t *img; | 853 | vpx_image_t *img; |
853 | img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); | 854 | img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); |
diff --git a/toxav/toxav.h b/toxav/toxav.h index 6df9d300..8dda26cf 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h | |||
@@ -31,7 +31,7 @@ extern "C" { | |||
31 | /* vpx_image_t */ | 31 | /* vpx_image_t */ |
32 | #include <vpx/vpx_image.h> | 32 | #include <vpx/vpx_image.h> |
33 | 33 | ||
34 | typedef void ( *ToxAVCallback ) ( void* agent, int32_t call_idx, void *arg ); | 34 | typedef void ( *ToxAVCallback ) ( void *agent, int32_t call_idx, void *arg ); |
35 | typedef struct _ToxAv ToxAv; | 35 | typedef struct _ToxAv ToxAv; |
36 | 36 | ||
37 | #ifndef __TOX_DEFINED__ | 37 | #ifndef __TOX_DEFINED__ |