summaryrefslogtreecommitdiff
path: root/toxav/msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/msi.c')
-rw-r--r--toxav/msi.c198
1 files changed, 106 insertions, 92 deletions
diff --git a/toxav/msi.c b/toxav/msi.c
index a80c4b30..497af13b 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -112,10 +112,10 @@ typedef struct _MSIMessage {
112 112
113static void invoke_callback(MSISession *s, int32_t c, MSICallbackID i) 113static void invoke_callback(MSISession *s, int32_t c, MSICallbackID i)
114{ 114{
115 if ( s->callbacks[i].function ) { 115 if ( s->callbacks[i].first ) {
116 LOGGER_DEBUG("Invoking callback function: %d", i); 116 LOGGER_DEBUG("Invoking callback function: %d", i);
117 117
118 s->callbacks[i].function( s->agent_handler, c, s->callbacks[i].data ); 118 s->callbacks[i].first( s->agent_handler, c, s->callbacks[i].second );
119 } 119 }
120} 120}
121 121
@@ -791,7 +791,7 @@ static void handle_remote_connection_change(Messenger *messenger, int friend_num
791 791
792 for ( ; i < session->calls[j]->peer_count; i ++ ) 792 for ( ; i < session->calls[j]->peer_count; i ++ )
793 if ( session->calls[j]->peers[i] == (uint32_t)friend_num ) { 793 if ( session->calls[j]->peers[i] == (uint32_t)friend_num ) {
794 invoke_callback(session, j, MSI_OnPeerTimeout); 794 invoke_callback(session, j, msi_OnPeerTimeout);
795 terminate_call(session, session->calls[j]); 795 terminate_call(session, session->calls[j]);
796 LOGGER_DEBUG("Remote: %d timed out!", friend_num); 796 LOGGER_DEBUG("Remote: %d timed out!", friend_num);
797 return; /* TODO: On group calls change behaviour */ 797 return; /* TODO: On group calls change behaviour */
@@ -820,7 +820,7 @@ static void handle_timeout ( Timer *timer )
820 if (call) { 820 if (call) {
821 LOGGER_DEBUG("[Call: %d] Request timed out!", call->call_idx); 821 LOGGER_DEBUG("[Call: %d] Request timed out!", call->call_idx);
822 822
823 invoke_callback(timer->session, timer->call_idx, MSI_OnRequestTimeout); 823 invoke_callback(timer->session, timer->call_idx, msi_OnRequestTimeout);
824 msi_cancel(timer->session, timer->call_idx, call->peers [0], "Request timed out"); 824 msi_cancel(timer->session, timer->call_idx, call->peers [0], "Request timed out");
825 } 825 }
826} 826}
@@ -840,7 +840,7 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *
840 840
841 if ( call ) { 841 if ( call ) {
842 if ( call->peers[0] == (uint32_t)msg->friend_id ) { 842 if ( call->peers[0] == (uint32_t)msg->friend_id ) {
843 if (call->state == call_inviting) { 843 if (call->state == msi_CallInviting) {
844 /* The glare case. A calls B when at the same time 844 /* The glare case. A calls B when at the same time
845 * B calls A. Who has advantage is set bey calculating 845 * B calls A. Who has advantage is set bey calculating
846 * 'bigger' Call id and then that call id is being used in 846 * 'bigger' Call id and then that call id is being used in
@@ -864,7 +864,7 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *
864 } else { 864 } else {
865 return 0; /* Wait for ringing from peer */ 865 return 0; /* Wait for ringing from peer */
866 } 866 }
867 } else if (call->state == call_active) { 867 } else if (call->state == msi_CallActive) {
868 /* Request for media change; call callback and send starting response */ 868 /* Request for media change; call callback and send starting response */
869 if (flush_peer_csettings(call, msg, 0) != 0) { /**/ 869 if (flush_peer_csettings(call, msg, 0) != 0) { /**/
870 LOGGER_WARNING("Peer sent invalid csetting!"); 870 LOGGER_WARNING("Peer sent invalid csetting!");
@@ -872,9 +872,9 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *
872 return 0; 872 return 0;
873 } 873 }
874 874
875 LOGGER_DEBUG("Set new call type: %s", call->csettings_peer[0].call_type == type_audio ? "audio" : "video"); 875 LOGGER_DEBUG("Set new call type: %s", call->csettings_peer[0].call_type == msi_TypeAudio ? "audio" : "video");
876 send_reponse(session, call, starting, msg->friend_id); 876 send_reponse(session, call, starting, msg->friend_id);
877 invoke_callback(session, call->call_idx, MSI_OnPeerCSChange); 877 invoke_callback(session, call->call_idx, msi_OnPeerCSChange);
878 return 1; 878 return 1;
879 } 879 }
880 } else { 880 } else {
@@ -898,12 +898,12 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *
898 } 898 }
899 899
900 memcpy ( call->id, msg->callid.value, sizeof(msg->callid.value) ); 900 memcpy ( call->id, msg->callid.value, sizeof(msg->callid.value) );
901 call->state = call_starting; 901 call->state = msi_CallStarting;
902 902
903 add_peer( call, msg->friend_id); 903 add_peer( call, msg->friend_id);
904 flush_peer_csettings ( call, msg, 0 ); 904 flush_peer_csettings ( call, msg, 0 );
905 send_reponse(session, call, ringing, msg->friend_id); 905 send_reponse(session, call, ringing, msg->friend_id);
906 invoke_callback(session, call->call_idx, MSI_OnInvite); 906 invoke_callback(session, call->call_idx, msi_OnInvite);
907 907
908 return 1; 908 return 1;
909} 909}
@@ -919,8 +919,8 @@ static int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *m
919 919
920 LOGGER_DEBUG("Session: %p Handling 'start' on call: %d, friend id: %d", session, call->call_idx, msg->friend_id ); 920 LOGGER_DEBUG("Session: %p Handling 'start' on call: %d, friend id: %d", session, call->call_idx, msg->friend_id );
921 921
922 call->state = call_active; 922 call->state = msi_CallActive;
923 invoke_callback(session, call->call_idx, MSI_OnStart); 923 invoke_callback(session, call->call_idx, msi_OnStart);
924 return 1; 924 return 1;
925} 925}
926 926
@@ -933,7 +933,7 @@ static int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *
933 933
934 LOGGER_DEBUG("Session: %p Handling 'reject' on call: %u", session, call->call_idx); 934 LOGGER_DEBUG("Session: %p Handling 'reject' on call: %u", session, call->call_idx);
935 935
936 invoke_callback(session, call->call_idx, MSI_OnReject); 936 invoke_callback(session, call->call_idx, msi_OnReject);
937 937
938 send_reponse(session, call, ending, msg->friend_id); 938 send_reponse(session, call, ending, msg->friend_id);
939 terminate_call(session, call); 939 terminate_call(session, call);
@@ -952,7 +952,7 @@ static int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *
952 952
953 LOGGER_DEBUG("Session: %p Handling 'cancel' on call: %u", session, call->call_idx); 953 LOGGER_DEBUG("Session: %p Handling 'cancel' on call: %u", session, call->call_idx);
954 954
955 invoke_callback(session, call->call_idx, MSI_OnCancel); 955 invoke_callback(session, call->call_idx, msi_OnCancel);
956 terminate_call ( session, call ); 956 terminate_call ( session, call );
957 957
958 return 1; 958 return 1;
@@ -967,7 +967,7 @@ static int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg
967 967
968 LOGGER_DEBUG("Session: %p Handling 'end' on call: %d", session, call->call_idx); 968 LOGGER_DEBUG("Session: %p Handling 'end' on call: %d", session, call->call_idx);
969 969
970 invoke_callback(session, call->call_idx, MSI_OnEnd); 970 invoke_callback(session, call->call_idx, msi_OnEnd);
971 send_reponse(session, call, ending, msg->friend_id); 971 send_reponse(session, call, ending, msg->friend_id);
972 terminate_call ( session, call ); 972 terminate_call ( session, call );
973 973
@@ -993,7 +993,7 @@ static int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage
993 993
994 call->ringing_timer_id = timer_alloc 994 call->ringing_timer_id = timer_alloc
995 ( session, handle_timeout, call->call_idx, call->ringing_tout_ms ); 995 ( session, handle_timeout, call->call_idx, call->ringing_tout_ms );
996 invoke_callback(session, call->call_idx, MSI_OnRinging); 996 invoke_callback(session, call->call_idx, msi_OnRinging);
997 return 1; 997 return 1;
998} 998}
999static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg ) 999static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg )
@@ -1003,16 +1003,16 @@ static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage
1003 return 0; 1003 return 0;
1004 } 1004 }
1005 1005
1006 if ( call->state == call_active ) { /* Change media */ 1006 if ( call->state == msi_CallActive ) { /* Change media */
1007 1007
1008 LOGGER_DEBUG("Session: %p Changing media on call: %d", session, call->call_idx ); 1008 LOGGER_DEBUG("Session: %p Changing media on call: %d", session, call->call_idx );
1009 1009
1010 invoke_callback(session, call->call_idx, MSI_OnSelfCSChange); 1010 invoke_callback(session, call->call_idx, msi_OnSelfCSChange);
1011 1011
1012 } else if ( call->state == call_inviting ) { 1012 } else if ( call->state == msi_CallInviting ) {
1013 LOGGER_DEBUG("Session: %p Handling 'starting' on call: %d", session, call->call_idx ); 1013 LOGGER_DEBUG("Session: %p Handling 'starting' on call: %d", session, call->call_idx );
1014 1014
1015 call->state = call_active; 1015 call->state = msi_CallActive;
1016 1016
1017 MSIMessage *msg_start = msi_new_message ( TypeRequest, start ); 1017 MSIMessage *msg_start = msi_new_message ( TypeRequest, start );
1018 send_message ( session, call, msg_start, msg->friend_id ); 1018 send_message ( session, call, msg_start, msg->friend_id );
@@ -1023,7 +1023,7 @@ static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage
1023 1023
1024 /* This is here in case of glare */ 1024 /* This is here in case of glare */
1025 timer_release(session->timer_handler, call->ringing_timer_id); 1025 timer_release(session->timer_handler, call->ringing_timer_id);
1026 invoke_callback(session, call->call_idx, MSI_OnStart); 1026 invoke_callback(session, call->call_idx, msi_OnStart);
1027 } else { 1027 } else {
1028 LOGGER_ERROR("Invalid call state"); 1028 LOGGER_ERROR("Invalid call state");
1029 terminate_call(session, call ); 1029 terminate_call(session, call );
@@ -1043,14 +1043,13 @@ static int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *
1043 1043
1044 LOGGER_DEBUG("Session: %p Handling 'ending' on call: %d", session, call->call_idx ); 1044 LOGGER_DEBUG("Session: %p Handling 'ending' on call: %d", session, call->call_idx );
1045 1045
1046 invoke_callback(session, call->call_idx, MSI_OnEnd); 1046 invoke_callback(session, call->call_idx, msi_OnEnd);
1047 terminate_call ( session, call ); 1047 terminate_call ( session, call );
1048 1048
1049 return 1; 1049 return 1;
1050} 1050}
1051static int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *msg ) 1051static int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *msg )
1052{ 1052{
1053
1054 if ( !call ) { 1053 if ( !call ) {
1055 LOGGER_WARNING("Handling 'error' on non-existing call!"); 1054 LOGGER_WARNING("Handling 'error' on non-existing call!");
1056 return -1; 1055 return -1;
@@ -1058,7 +1057,7 @@ static int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *m
1058 1057
1059 LOGGER_DEBUG("Session: %p Handling 'error' on call: %d", session, call->call_idx ); 1058 LOGGER_DEBUG("Session: %p Handling 'error' on call: %d", session, call->call_idx );
1060 1059
1061 invoke_callback(session, call->call_idx, MSI_OnEnd); 1060 invoke_callback(session, call->call_idx, msi_OnEnd);
1062 1061
1063 /* Handle error accordingly */ 1062 /* Handle error accordingly */
1064 if ( msg->reason.exists ) { 1063 if ( msg->reason.exists ) {
@@ -1127,7 +1126,7 @@ static void msi_handle_packet ( Messenger *messenger, int source, const uint8_t
1127 1126
1128 msg->friend_id = source; 1127 msg->friend_id = source;
1129 1128
1130 pthread_mutex_lock(&session->mutex); 1129 pthread_mutex_lock(session->mutex);
1131 1130
1132 /* Find what call */ 1131 /* Find what call */
1133 MSICall *call = msg->callid.exists ? find_call(session, msg->callid.value ) : NULL; 1132 MSICall *call = msg->callid.exists ? find_call(session, msg->callid.value ) : NULL;
@@ -1187,7 +1186,7 @@ static void msi_handle_packet ( Messenger *messenger, int source, const uint8_t
1187 1186
1188 free ( msg ); 1187 free ( msg );
1189 1188
1190 pthread_mutex_unlock(&session->mutex); 1189 pthread_mutex_unlock(session->mutex);
1191} 1190}
1192 1191
1193 1192
@@ -1195,8 +1194,8 @@ static void msi_handle_packet ( Messenger *messenger, int source, const uint8_t
1195/********** User functions **********/ 1194/********** User functions **********/
1196void msi_register_callback ( MSISession *session, MSICallbackType callback, MSICallbackID id, void *userdata ) 1195void msi_register_callback ( MSISession *session, MSICallbackType callback, MSICallbackID id, void *userdata )
1197{ 1196{
1198 session->callbacks[id].function = callback; 1197 session->callbacks[id].first = callback;
1199 session->callbacks[id].data = userdata; 1198 session->callbacks[id].second = userdata;
1200} 1199}
1201 1200
1202 1201
@@ -1224,17 +1223,6 @@ MSISession *msi_new ( Messenger *messenger, int32_t max_calls )
1224 goto error; 1223 goto error;
1225 } 1224 }
1226 1225
1227 pthread_mutexattr_t attr;
1228
1229 if (pthread_mutexattr_init(&attr) != 0 ||
1230 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0 ||
1231 pthread_mutex_init(&retu->mutex, &attr) != 0 ) {
1232 LOGGER_ERROR("Failed to init mutex! Program might misbehave!");
1233
1234 goto error;
1235 }
1236
1237
1238 retu->timer_handler = calloc(1, sizeof(TimerHandler)); 1226 retu->timer_handler = calloc(1, sizeof(TimerHandler));
1239 1227
1240 if (retu->timer_handler == NULL) { 1228 if (retu->timer_handler == NULL) {
@@ -1250,6 +1238,11 @@ MSISession *msi_new ( Messenger *messenger, int32_t max_calls )
1250 goto error; 1238 goto error;
1251 } 1239 }
1252 1240
1241 if (create_recursive_mutex(retu->mutex) != 0) {
1242 LOGGER_ERROR("Failed to init mutex! Program might misbehave");
1243 goto error;
1244 }
1245
1253 retu->messenger_handle = messenger; 1246 retu->messenger_handle = messenger;
1254 retu->agent_handler = NULL; 1247 retu->agent_handler = NULL;
1255 retu->max_calls = max_calls; 1248 retu->max_calls = max_calls;
@@ -1265,7 +1258,12 @@ MSISession *msi_new ( Messenger *messenger, int32_t max_calls )
1265 return retu; 1258 return retu;
1266 1259
1267error: 1260error:
1268 free(retu->timer_handler); 1261
1262 if (retu->timer_handler) {
1263 free(((TimerHandler *)retu->timer_handler)->timers);
1264 free(retu->timer_handler);
1265 }
1266
1269 free(retu->calls); 1267 free(retu->calls);
1270 free(retu); 1268 free(retu);
1271 return NULL; 1269 return NULL;
@@ -1279,13 +1277,10 @@ int msi_kill ( MSISession *session )
1279 return -1; 1277 return -1;
1280 } 1278 }
1281 1279
1282 pthread_mutex_lock(&session->mutex);
1283 m_callback_msi_packet((struct Messenger *) session->messenger_handle, NULL, NULL); 1280 m_callback_msi_packet((struct Messenger *) session->messenger_handle, NULL, NULL);
1284 pthread_mutex_unlock(&session->mutex); 1281 pthread_mutex_lock(session->mutex);
1285 1282
1286 int _status = 0; 1283 /* Cancel active calls */
1287
1288 /* If have calls, cancel them */
1289 int32_t idx = 0; 1284 int32_t idx = 0;
1290 1285
1291 for (; idx < session->max_calls; idx ++) if ( session->calls[idx] ) { 1286 for (; idx < session->max_calls; idx ++) if ( session->calls[idx] ) {
@@ -1297,12 +1292,13 @@ int msi_kill ( MSISession *session )
1297 msi_cancel ( session, idx, session->calls[idx]->peers [_it], "MSI session terminated!" ); 1292 msi_cancel ( session, idx, session->calls[idx]->peers [_it], "MSI session terminated!" );
1298 } 1293 }
1299 1294
1300 pthread_mutex_destroy(&session->mutex); 1295 free ( session->calls );
1296 pthread_mutex_unlock(session->mutex);
1297 pthread_mutex_destroy(session->mutex);
1301 1298
1302 LOGGER_DEBUG("Terminated session: %p", session); 1299 LOGGER_DEBUG("Terminated session: %p", session);
1303 free ( session->calls );
1304 free ( session ); 1300 free ( session );
1305 return _status; 1301 return 0;
1306} 1302}
1307 1303
1308int msi_invite ( MSISession *session, 1304int msi_invite ( MSISession *session,
@@ -1311,7 +1307,7 @@ int msi_invite ( MSISession *session,
1311 uint32_t rngsec, 1307 uint32_t rngsec,
1312 uint32_t friend_id ) 1308 uint32_t friend_id )
1313{ 1309{
1314 pthread_mutex_lock(&session->mutex); 1310 pthread_mutex_lock(session->mutex);
1315 1311
1316 LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_id); 1312 LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_id);
1317 1313
@@ -1321,17 +1317,17 @@ int msi_invite ( MSISession *session,
1321 for (; i < session->max_calls; i ++) 1317 for (; i < session->max_calls; i ++)
1322 if (session->calls[i] && session->calls[i]->peers[0] == friend_id) { 1318 if (session->calls[i] && session->calls[i]->peers[0] == friend_id) {
1323 LOGGER_ERROR("Already in a call with friend %d", friend_id); 1319 LOGGER_ERROR("Already in a call with friend %d", friend_id);
1324 pthread_mutex_unlock(&session->mutex); 1320 pthread_mutex_unlock(session->mutex);
1325 return -1; 1321 return msi_ErrorAlreadyInCallWithPeer;
1326 } 1322 }
1327 1323
1328 1324
1329 MSICall *call = init_call ( session, 1, rngsec ); /* Just one peer for now */ 1325 MSICall *call = init_call ( session, 1, rngsec ); /* Just one peer for now */
1330 1326
1331 if ( !call ) { 1327 if ( !call ) {
1332 pthread_mutex_unlock(&session->mutex); 1328 pthread_mutex_unlock(session->mutex);
1333 LOGGER_ERROR("Cannot handle more calls"); 1329 LOGGER_ERROR("Cannot handle more calls");
1334 return -1; 1330 return msi_ErrorReachedCallLimit;
1335 } 1331 }
1336 1332
1337 *call_index = call->call_idx; 1333 *call_index = call->call_idx;
@@ -1348,32 +1344,32 @@ int msi_invite ( MSISession *session,
1348 send_message ( session, call, msg_invite, friend_id ); 1344 send_message ( session, call, msg_invite, friend_id );
1349 free( msg_invite ); 1345 free( msg_invite );
1350 1346
1351 call->state = call_inviting; 1347 call->state = msi_CallInviting;
1352 1348
1353 call->request_timer_id = timer_alloc ( session, handle_timeout, call->call_idx, m_deftout ); 1349 call->request_timer_id = timer_alloc ( session, handle_timeout, call->call_idx, m_deftout );
1354 1350
1355 LOGGER_DEBUG("Invite sent"); 1351 LOGGER_DEBUG("Invite sent");
1356 1352
1357 pthread_mutex_unlock(&session->mutex); 1353 pthread_mutex_unlock(session->mutex);
1358 1354
1359 return 0; 1355 return 0;
1360} 1356}
1361 1357
1362int msi_hangup ( MSISession *session, int32_t call_index ) 1358int msi_hangup ( MSISession *session, int32_t call_index )
1363{ 1359{
1364 pthread_mutex_lock(&session->mutex); 1360 pthread_mutex_lock(session->mutex);
1365 LOGGER_DEBUG("Session: %p Hanging up call: %u", session, call_index); 1361 LOGGER_DEBUG("Session: %p Hanging up call: %u", session, call_index);
1366 1362
1367 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { 1363 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) {
1368 LOGGER_ERROR("Invalid call index!"); 1364 LOGGER_ERROR("Invalid call index!");
1369 pthread_mutex_unlock(&session->mutex); 1365 pthread_mutex_unlock(session->mutex);
1370 return -1; 1366 return msi_ErrorNoCall;
1371 } 1367 }
1372 1368
1373 if ( session->calls[call_index]->state != call_active ) { 1369 if ( session->calls[call_index]->state != msi_CallActive ) {
1374 LOGGER_ERROR("No call with such index or call is not active!"); 1370 LOGGER_ERROR("Call is not active!");
1375 pthread_mutex_unlock(&session->mutex); 1371 pthread_mutex_unlock(session->mutex);
1376 return -1; 1372 return msi_ErrorInvalidState;
1377 } 1373 }
1378 1374
1379 MSIMessage *msg_end = msi_new_message ( TypeRequest, end ); 1375 MSIMessage *msg_end = msi_new_message ( TypeRequest, end );
@@ -1384,26 +1380,32 @@ int msi_hangup ( MSISession *session, int32_t call_index )
1384 for ( ; it < session->calls[call_index]->peer_count; it ++ ) 1380 for ( ; it < session->calls[call_index]->peer_count; it ++ )
1385 send_message ( session, session->calls[call_index], msg_end, session->calls[call_index]->peers[it] ); 1381 send_message ( session, session->calls[call_index], msg_end, session->calls[call_index]->peers[it] );
1386 1382
1387 session->calls[call_index]->state = call_hanged_up; 1383 session->calls[call_index]->state = msi_CallOver;
1388 1384
1389 free ( msg_end ); 1385 free ( msg_end );
1390 1386
1391 session->calls[call_index]->request_timer_id = 1387 session->calls[call_index]->request_timer_id =
1392 timer_alloc ( session, handle_timeout, call_index, m_deftout ); 1388 timer_alloc ( session, handle_timeout, call_index, m_deftout );
1393 1389
1394 pthread_mutex_unlock(&session->mutex); 1390 pthread_mutex_unlock(session->mutex);
1395 return 0; 1391 return 0;
1396} 1392}
1397 1393
1398int msi_answer ( MSISession *session, int32_t call_index, const MSICSettings *csettings ) 1394int msi_answer ( MSISession *session, int32_t call_index, const MSICSettings *csettings )
1399{ 1395{
1400 pthread_mutex_lock(&session->mutex); 1396 pthread_mutex_lock(session->mutex);
1401 LOGGER_DEBUG("Session: %p Answering call: %u", session, call_index); 1397 LOGGER_DEBUG("Session: %p Answering call: %u", session, call_index);
1402 1398
1403 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { 1399 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) {
1404 LOGGER_ERROR("Invalid call index!"); 1400 LOGGER_ERROR("Invalid call index!");
1405 pthread_mutex_unlock(&session->mutex); 1401 pthread_mutex_unlock(session->mutex);
1406 return -1; 1402 return msi_ErrorNoCall;
1403 }
1404
1405 if ( session->calls[call_index]->state != msi_CallStarting ) {
1406 LOGGER_ERROR("Call is in invalid state!");
1407 pthread_mutex_unlock(session->mutex);
1408 return msi_ErrorInvalidState;
1407 } 1409 }
1408 1410
1409 MSIMessage *msg_starting = msi_new_message ( TypeResponse, starting ); 1411 MSIMessage *msg_starting = msi_new_message ( TypeResponse, starting );
@@ -1415,21 +1417,27 @@ int msi_answer ( MSISession *session, int32_t call_index, const MSICSettings *cs
1415 send_message ( session, session->calls[call_index], msg_starting, session->calls[call_index]->peers[0] ); 1417 send_message ( session, session->calls[call_index], msg_starting, session->calls[call_index]->peers[0] );
1416 free ( msg_starting ); 1418 free ( msg_starting );
1417 1419
1418 session->calls[call_index]->state = call_active; 1420 session->calls[call_index]->state = msi_CallActive;
1419 1421
1420 pthread_mutex_unlock(&session->mutex); 1422 pthread_mutex_unlock(session->mutex);
1421 return 0; 1423 return 0;
1422} 1424}
1423 1425
1424int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const char *reason ) 1426int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const char *reason )
1425{ 1427{
1426 pthread_mutex_lock(&session->mutex); 1428 pthread_mutex_lock(session->mutex);
1427 LOGGER_DEBUG("Session: %p Canceling call: %u; reason: %s", session, call_index, reason ? reason : "Unknown"); 1429 LOGGER_DEBUG("Session: %p Canceling call: %u; reason: %s", session, call_index, reason ? reason : "Unknown");
1428 1430
1429 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { 1431 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) {
1430 LOGGER_ERROR("Invalid call index!"); 1432 LOGGER_ERROR("Invalid call index!");
1431 pthread_mutex_unlock(&session->mutex); 1433 pthread_mutex_unlock(session->mutex);
1432 return -1; 1434 return msi_ErrorNoCall;
1435 }
1436
1437 if ( session->calls[call_index]->state != msi_CallInviting ) {
1438 LOGGER_ERROR("Call is in invalid state!");
1439 pthread_mutex_unlock(session->mutex);
1440 return msi_ErrorInvalidState;
1433 } 1441 }
1434 1442
1435 MSIMessage *msg_cancel = msi_new_message ( TypeRequest, cancel ); 1443 MSIMessage *msg_cancel = msi_new_message ( TypeRequest, cancel );
@@ -1453,20 +1461,26 @@ int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const c
1453 free ( msg_cancel ); 1461 free ( msg_cancel );
1454 1462
1455 terminate_call ( session, session->calls[call_index] ); 1463 terminate_call ( session, session->calls[call_index] );
1456 pthread_mutex_unlock(&session->mutex); 1464 pthread_mutex_unlock(session->mutex);
1457 1465
1458 return 0; 1466 return 0;
1459} 1467}
1460 1468
1461int msi_reject ( MSISession *session, int32_t call_index, const char *reason ) 1469int msi_reject ( MSISession *session, int32_t call_index, const char *reason )
1462{ 1470{
1463 pthread_mutex_lock(&session->mutex); 1471 pthread_mutex_lock(session->mutex);
1464 LOGGER_DEBUG("Session: %p Rejecting call: %u; reason: %s", session, call_index, reason ? reason : "Unknown"); 1472 LOGGER_DEBUG("Session: %p Rejecting call: %u; reason: %s", session, call_index, reason ? reason : "Unknown");
1465 1473
1466 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { 1474 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) {
1467 LOGGER_ERROR("Invalid call index!"); 1475 LOGGER_ERROR("Invalid call index!");
1468 pthread_mutex_unlock(&session->mutex); 1476 pthread_mutex_unlock(session->mutex);
1469 return -1; 1477 return msi_ErrorNoCall;
1478 }
1479
1480 if ( session->calls[call_index]->state != msi_CallStarting ) {
1481 LOGGER_ERROR("Call is in invalid state!");
1482 pthread_mutex_unlock(session->mutex);
1483 return msi_ErrorInvalidState;
1470 } 1484 }
1471 1485
1472 MSIMessage *msg_reject = msi_new_message ( TypeRequest, reject ); 1486 MSIMessage *msg_reject = msi_new_message ( TypeRequest, reject );
@@ -1490,50 +1504,50 @@ int msi_reject ( MSISession *session, int32_t call_index, const char *reason )
1490 session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] ); 1504 session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] );
1491 free ( msg_reject ); 1505 free ( msg_reject );
1492 1506
1493 session->calls[call_index]->state = call_hanged_up; 1507 session->calls[call_index]->state = msi_CallOver;
1494 session->calls[call_index]->request_timer_id = 1508 session->calls[call_index]->request_timer_id =
1495 timer_alloc ( session, handle_timeout, call_index, m_deftout ); 1509 timer_alloc ( session, handle_timeout, call_index, m_deftout );
1496 1510
1497 pthread_mutex_unlock(&session->mutex); 1511 pthread_mutex_unlock(session->mutex);
1498 return 0; 1512 return 0;
1499} 1513}
1500 1514
1501int msi_stopcall ( MSISession *session, int32_t call_index ) 1515int msi_stopcall ( MSISession *session, int32_t call_index )
1502{ 1516{
1503 pthread_mutex_lock(&session->mutex); 1517 pthread_mutex_lock(session->mutex);
1504 LOGGER_DEBUG("Session: %p Stopping call index: %u", session, call_index); 1518 LOGGER_DEBUG("Session: %p Stopping call index: %u", session, call_index);
1505 1519
1506 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { 1520 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) {
1507 pthread_mutex_unlock(&session->mutex); 1521 pthread_mutex_unlock(session->mutex);
1508 return -1; 1522 return msi_ErrorNoCall;
1509 } 1523 }
1510 1524
1511 /* just terminate it */ 1525 /* just terminate it */
1512 1526
1513 terminate_call ( session, session->calls[call_index] ); 1527 terminate_call ( session, session->calls[call_index] );
1514 1528
1515 pthread_mutex_unlock(&session->mutex); 1529 pthread_mutex_unlock(session->mutex);
1516 return 0; 1530 return 0;
1517} 1531}
1518 1532
1519int msi_change_csettings(MSISession *session, int32_t call_index, const MSICSettings *csettings) 1533int msi_change_csettings(MSISession *session, int32_t call_index, const MSICSettings *csettings)
1520{ 1534{
1521 pthread_mutex_lock(&session->mutex); 1535 pthread_mutex_lock(session->mutex);
1522 1536
1523 LOGGER_DEBUG("Changing media on call: %d", call_index); 1537 LOGGER_DEBUG("Changing media on call: %d", call_index);
1524 1538
1525 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) { 1539 if ( call_index < 0 || call_index >= session->max_calls || !session->calls[call_index] ) {
1526 LOGGER_ERROR("Invalid call index!"); 1540 LOGGER_ERROR("Invalid call index!");
1527 pthread_mutex_unlock(&session->mutex); 1541 pthread_mutex_unlock(session->mutex);
1528 return -1; 1542 return msi_ErrorNoCall;
1529 } 1543 }
1530 1544
1531 MSICall *call = session->calls[call_index]; 1545 MSICall *call = session->calls[call_index];
1532 1546
1533 if ( call->state != call_active ) { 1547 if ( call->state != msi_CallActive ) {
1534 LOGGER_ERROR("Call is not active!"); 1548 LOGGER_ERROR("Call is not active!");
1535 pthread_mutex_unlock(&session->mutex); 1549 pthread_mutex_unlock(session->mutex);
1536 return -1; 1550 return msi_ErrorInvalidState;
1537 } 1551 }
1538 1552
1539 MSICSettings *local = &call->csettings_local; 1553 MSICSettings *local = &call->csettings_local;
@@ -1548,7 +1562,7 @@ int msi_change_csettings(MSISession *session, int32_t call_index, const MSICSett
1548 local->audio_sample_rate == csettings->audio_sample_rate && 1562 local->audio_sample_rate == csettings->audio_sample_rate &&
1549 local->audio_channels == csettings->audio_channels ) { 1563 local->audio_channels == csettings->audio_channels ) {
1550 LOGGER_ERROR("Call is already set accordingly!"); 1564 LOGGER_ERROR("Call is already set accordingly!");
1551 pthread_mutex_unlock(&session->mutex); 1565 pthread_mutex_unlock(session->mutex);
1552 return -1; 1566 return -1;
1553 } 1567 }
1554 1568
@@ -1562,14 +1576,14 @@ int msi_change_csettings(MSISession *session, int32_t call_index, const MSICSett
1562 1576
1563 LOGGER_DEBUG("Request for media change sent"); 1577 LOGGER_DEBUG("Request for media change sent");
1564 1578
1565 pthread_mutex_unlock(&session->mutex); 1579 pthread_mutex_unlock(session->mutex);
1566 1580
1567 return 0; 1581 return 0;
1568} 1582}
1569 1583
1570void msi_do(MSISession *session) 1584void msi_do(MSISession *session)
1571{ 1585{
1572 pthread_mutex_lock(&session->mutex); 1586 pthread_mutex_lock(session->mutex);
1573 1587
1574 TimerHandler *timer = session->timer_handler; 1588 TimerHandler *timer = session->timer_handler;
1575 1589
@@ -1586,5 +1600,5 @@ void msi_do(MSISession *session)
1586 timer_release(timer, id); 1600 timer_release(timer, id);
1587 } 1601 }
1588 1602
1589 pthread_mutex_unlock(&session->mutex); 1603 pthread_mutex_unlock(session->mutex);
1590} 1604}