hfp_ag.c (484fb8b62904abf203ed92992f6bb23a540308e7) hfp_ag.c (a5bdcda89a13d85a2d6e095a87c45c0fca9a01a2)
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 970 unchanged lines hidden (view full) ---

979 linked_list_iterator_init(&it, hfp_get_connections());
980 while (linked_list_iterator_has_next(&it)){
981 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
982 if (connection->call_state == call_state) return connection;
983 }
984 return NULL;
985}
986
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 970 unchanged lines hidden (view full) ---

979 linked_list_iterator_init(&it, hfp_get_connections());
980 while (linked_list_iterator_has_next(&it)){
981 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
982 if (connection->call_state == call_state) return connection;
983 }
984 return NULL;
985}
986
987static void hfp_ag_send_response_and_hold_state(void){
987static void hfp_ag_send_response_and_hold_state(hfp_response_and_hold_state_t state){
988 linked_list_iterator_t it;
989 linked_list_iterator_init(&it, hfp_get_connections());
990 while (linked_list_iterator_has_next(&it)){
991 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
988 linked_list_iterator_t it;
989 linked_list_iterator_init(&it, hfp_get_connections());
990 while (linked_list_iterator_has_next(&it)){
991 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
992 connection->send_response_and_hold_status = 1;
992 connection->send_response_and_hold_status = state + 1;
993 }
994}
995
996static int call_setup_state_machine(hfp_connection_t * connection){
997 int indicator_index;
998 switch (connection->call_state){
999 case HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING:
1000 if (connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED) return 0;

--- 86 unchanged lines hidden (view full) ---

1087 case HFP_AG_HELD_CALL_JOINED_BY_AG:
1088 switch (hfp_ag_call_state){
1089 case HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT:
1090 switch (hfp_ag_callheld_state){
1091 case HFP_CALLHELD_STATUS_CALL_ON_HOLD_OR_SWAPPED:
1092 printf("AG: joining held call with active call\n");
1093 hfp_ag_set_callheld_state(HFP_CALLHELD_STATUS_NO_CALLS_HELD);
1094 hfp_ag_transfer_callheld_state();
993 }
994}
995
996static int call_setup_state_machine(hfp_connection_t * connection){
997 int indicator_index;
998 switch (connection->call_state){
999 case HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING:
1000 if (connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED) return 0;

--- 86 unchanged lines hidden (view full) ---

1087 case HFP_AG_HELD_CALL_JOINED_BY_AG:
1088 switch (hfp_ag_call_state){
1089 case HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT:
1090 switch (hfp_ag_callheld_state){
1091 case HFP_CALLHELD_STATUS_CALL_ON_HOLD_OR_SWAPPED:
1092 printf("AG: joining held call with active call\n");
1093 hfp_ag_set_callheld_state(HFP_CALLHELD_STATUS_NO_CALLS_HELD);
1094 hfp_ag_transfer_callheld_state();
1095 hfp_emit_event(hfp_callback, HFP_SUBEVENT_CONFERENCE_CALL, 0);
1095 break;
1096 default:
1097 break;
1098 }
1099 break;
1100 default:
1101 break;
1102 }

--- 25 unchanged lines hidden (view full) ---

1128 // clear CLIP
1129 clip_type = 0;
1130 switch (hfp_ag_call_state){
1131 case HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS:
1132 switch (hfp_ag_callsetup_state){
1133 case HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS:
1134 hfp_ag_response_and_hold_active = 1;
1135 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD;
1096 break;
1097 default:
1098 break;
1099 }
1100 break;
1101 default:
1102 break;
1103 }

--- 25 unchanged lines hidden (view full) ---

1129 // clear CLIP
1130 clip_type = 0;
1131 switch (hfp_ag_call_state){
1132 case HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS:
1133 switch (hfp_ag_callsetup_state){
1134 case HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS:
1135 hfp_ag_response_and_hold_active = 1;
1136 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD;
1136 hfp_ag_send_response_and_hold_state();
1137 hfp_ag_send_response_and_hold_state(hfp_ag_response_and_hold_state);
1137 // as with regualr call
1138 hfp_ag_set_call_state(HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT);
1139 hfp_ag_set_callsetup_state(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS);
1140 hfp_ag_ag_accept_call();
1141 printf("AG response and hold - hold by AG\n");
1142 break;
1143 default:
1144 break;

--- 8 unchanged lines hidden (view full) ---

1153 // clear CLIP
1154 clip_type = 0;
1155 switch (hfp_ag_call_state){
1156 case HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS:
1157 switch (hfp_ag_callsetup_state){
1158 case HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS:
1159 hfp_ag_response_and_hold_active = 1;
1160 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD;
1138 // as with regualr call
1139 hfp_ag_set_call_state(HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT);
1140 hfp_ag_set_callsetup_state(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS);
1141 hfp_ag_ag_accept_call();
1142 printf("AG response and hold - hold by AG\n");
1143 break;
1144 default:
1145 break;

--- 8 unchanged lines hidden (view full) ---

1154 // clear CLIP
1155 clip_type = 0;
1156 switch (hfp_ag_call_state){
1157 case HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS:
1158 switch (hfp_ag_callsetup_state){
1159 case HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS:
1160 hfp_ag_response_and_hold_active = 1;
1161 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD;
1161 hfp_ag_send_response_and_hold_state();
1162 hfp_ag_send_response_and_hold_state(hfp_ag_response_and_hold_state);
1162 // as with regualr call
1163 hfp_ag_set_call_state(HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT);
1164 hfp_ag_set_callsetup_state(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS);
1165 hfp_ag_hf_accept_call(connection);
1166 printf("AG response and hold - hold by HF\n");
1167 break;
1168 default:
1169 break;
1170 }
1171 break;
1172 default:
1173 break;
1174 }
1175 break;
1176
1177 case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_AG:
1178 case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_HF:
1179 if (!hfp_ag_response_and_hold_active) break;
1180 if (hfp_ag_response_and_hold_state != HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD) break;
1163 // as with regualr call
1164 hfp_ag_set_call_state(HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT);
1165 hfp_ag_set_callsetup_state(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS);
1166 hfp_ag_hf_accept_call(connection);
1167 printf("AG response and hold - hold by HF\n");
1168 break;
1169 default:
1170 break;
1171 }
1172 break;
1173 default:
1174 break;
1175 }
1176 break;
1177
1178 case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_AG:
1179 case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_HF:
1180 if (!hfp_ag_response_and_hold_active) break;
1181 if (hfp_ag_response_and_hold_state != HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD) break;
1182 hfp_ag_response_and_hold_active = 0;
1181 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_HELD_INCOMING_ACCEPTED;
1183 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_HELD_INCOMING_ACCEPTED;
1182 hfp_ag_send_response_and_hold_state();
1184 hfp_ag_send_response_and_hold_state(hfp_ag_response_and_hold_state);
1183 printf("Held Call accepted and active\n");
1184 break;
1185
1186 case HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_AG:
1187 case HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_HF:
1188 if (!hfp_ag_response_and_hold_active) break;
1189 if (hfp_ag_response_and_hold_state != HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD) break;
1185 printf("Held Call accepted and active\n");
1186 break;
1187
1188 case HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_AG:
1189 case HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_HF:
1190 if (!hfp_ag_response_and_hold_active) break;
1191 if (hfp_ag_response_and_hold_state != HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD) break;
1192 hfp_ag_response_and_hold_active = 0;
1190 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_HELD_INCOMING_REJECTED;
1193 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_HELD_INCOMING_REJECTED;
1191 hfp_ag_send_response_and_hold_state();
1194 hfp_ag_send_response_and_hold_state(hfp_ag_response_and_hold_state);
1192 // from terminate by ag
1193 hfp_ag_set_call_state(HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS);
1194 hfp_ag_trigger_terminate_call();
1195 break;
1196
1197 case HFP_AG_TERMINATE_CALL_BY_HF:
1198 // clear CLIP
1199 clip_type = 0;

--- 67 unchanged lines hidden (view full) ---

1267 break;
1268 }
1269 hfp_ag_set_callsetup_state(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS);
1270 hfp_ag_transfer_callsetup_state();
1271 break;
1272 case HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT:
1273 if (hfp_ag_response_and_hold_active) {
1274 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_HELD_INCOMING_REJECTED;
1195 // from terminate by ag
1196 hfp_ag_set_call_state(HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS);
1197 hfp_ag_trigger_terminate_call();
1198 break;
1199
1200 case HFP_AG_TERMINATE_CALL_BY_HF:
1201 // clear CLIP
1202 clip_type = 0;

--- 67 unchanged lines hidden (view full) ---

1270 break;
1271 }
1272 hfp_ag_set_callsetup_state(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS);
1273 hfp_ag_transfer_callsetup_state();
1274 break;
1275 case HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT:
1276 if (hfp_ag_response_and_hold_active) {
1277 hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_HELD_INCOMING_REJECTED;
1275 hfp_ag_send_response_and_hold_state();
1278 hfp_ag_send_response_and_hold_state(hfp_ag_response_and_hold_state);
1276 }
1277 hfp_ag_set_callsetup_state(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS);
1278 hfp_ag_set_call_state(HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS);
1279 hfp_ag_trigger_terminate_call();
1280 printf("AG notify call dropped\n");
1281 break;
1282 default:
1283 break;

--- 106 unchanged lines hidden (view full) ---

1390 context->send_error = 0;
1391 context->command = HFP_CMD_NONE;
1392 hfp_ag_error(context->rfcomm_cid);
1393 return;
1394 }
1395
1396 // note: before update AG indicators and ok_pending
1397 if (context->send_response_and_hold_status){
1279 }
1280 hfp_ag_set_callsetup_state(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS);
1281 hfp_ag_set_call_state(HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS);
1282 hfp_ag_trigger_terminate_call();
1283 printf("AG notify call dropped\n");
1284 break;
1285 default:
1286 break;

--- 106 unchanged lines hidden (view full) ---

1393 context->send_error = 0;
1394 context->command = HFP_CMD_NONE;
1395 hfp_ag_error(context->rfcomm_cid);
1396 return;
1397 }
1398
1399 // note: before update AG indicators and ok_pending
1400 if (context->send_response_and_hold_status){
1401 int status = context->send_response_and_hold_status - 1;
1398 context->send_response_and_hold_status = 0;
1402 context->send_response_and_hold_status = 0;
1399 hfp_ag_set_response_and_hold(context->rfcomm_cid, hfp_ag_response_and_hold_state);
1403 hfp_ag_set_response_and_hold(context->rfcomm_cid, status);
1400 return;
1401 }
1402
1404 return;
1405 }
1406
1403 if (context->send_response_and_hold_active){
1404 context->send_response_and_hold_active = 0;
1405 hfp_ag_set_response_and_hold(context->rfcomm_cid, 0);
1406 return;
1407 }
1408
1409 if (context->ok_pending){
1410 context->ok_pending = 0;
1411 context->command = HFP_CMD_NONE;
1412 hfp_ag_ok(context->rfcomm_cid);
1413 return;
1414 }
1415
1416 // update AG indicators

--- 112 unchanged lines hidden (view full) ---

1529 for (pos = 0; pos < size ; pos++){
1530 hfp_parse(context, packet[pos], 0);
1531 }
1532 hfp_generic_status_indicator_t * indicator;
1533 int value;
1534 switch(context->command){
1535 case HFP_CMD_RESPONSE_AND_HOLD_QUERY:
1536 if (hfp_ag_response_and_hold_active){
1407 if (context->ok_pending){
1408 context->ok_pending = 0;
1409 context->command = HFP_CMD_NONE;
1410 hfp_ag_ok(context->rfcomm_cid);
1411 return;
1412 }
1413
1414 // update AG indicators

--- 112 unchanged lines hidden (view full) ---

1527 for (pos = 0; pos < size ; pos++){
1528 hfp_parse(context, packet[pos], 0);
1529 }
1530 hfp_generic_status_indicator_t * indicator;
1531 int value;
1532 switch(context->command){
1533 case HFP_CMD_RESPONSE_AND_HOLD_QUERY:
1534 if (hfp_ag_response_and_hold_active){
1537 context->send_response_and_hold_active = 1;
1535 context->send_response_and_hold_status = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD + 1;
1538 }
1539 context->ok_pending = 1;
1540 break;
1541 case HFP_CMD_RESPONSE_AND_HOLD_COMMAND:
1542 value = atoi((char *)&context->line_buffer[0]);
1543 printf("HF Response and Hold: %u\n", value);
1544 switch(value){
1545 case HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD:

--- 543 unchanged lines hidden ---
1536 }
1537 context->ok_pending = 1;
1538 break;
1539 case HFP_CMD_RESPONSE_AND_HOLD_COMMAND:
1540 value = atoi((char *)&context->line_buffer[0]);
1541 printf("HF Response and Hold: %u\n", value);
1542 switch(value){
1543 case HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD:

--- 543 unchanged lines hidden ---