summaryrefslogtreecommitdiff
path: root/toxav/msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/msi.c')
-rw-r--r--toxav/msi.c300
1 files changed, 174 insertions, 126 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
61typedef enum { 61typedef enum {
62 TypeRequest, 62 TypeRequest,
63 TypeResponse, 63 TypeResponse,
64 64
65} MSIMessageType; 65} MSIMessageType;
66 66
67typedef enum { 67typedef 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
76typedef enum { 76typedef 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
117inline__ void invoke_callback(MSISession* session, int32_t call_index, MSICallbackID id) 117inline__ 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 */
136static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length ) 136static 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
347void msi_msg_set_calltype ( MSIMessage* msg, const MSICallType value ) 359void 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
354void msi_msg_set_reason ( MSIMessage* msg, const MSIReasonStrType value ) 367void 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
361void msi_msg_set_callid ( MSIMessage* msg, const MSICallIDType value ) 375void 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 */
665static inline__ const uint8_t* stringify_error ( MSICallError error_code ) 680static 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 */
740static int flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id ) 755static 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}
1238static int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg ) 1253static 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 */
1721int msi_change_type(MSISession* session, int32_t call_index, MSICallType call_type) 1768int 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