From ccb2e1df97bed0abc2c630a8dbd096c8e7946061 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Thu, 11 Feb 2016 13:59:00 +0100 Subject: [PATCH 01/26] gsm: cleanup --- src/hfp_gsm_model.c | 20 +++++++++++++++----- src/hfp_gsm_model.h | 1 + 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 2f907a2e1..6a96c2c6c 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -73,6 +73,15 @@ static char last_dialed_number[HFP_GSM_MAX_CALL_NUMBER_SIZE]; static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t type, const char * number); +static void set_call_status_none(int index_in_table){ + gsm_calls[index_in_table].status = CALL_NONE; + gsm_calls[index_in_table].used_slot = 0; +} + +static int is_call_status_none(int index_in_table){ + return gsm_calls[index_in_table].status == CALL_NONE; +} + void hfp_gsm_init(void){ callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; clip_type = 0; @@ -81,7 +90,7 @@ void hfp_gsm_init(void){ memset(gsm_calls, 0, sizeof(gsm_calls)); int i; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - gsm_calls[i].status = CALL_NONE; + set_call_status_none(i); } } @@ -163,8 +172,8 @@ static void delete_call(int delete_index_in_table){ gsm_calls[i].index--; } } - - gsm_calls[delete_index_in_table].status = CALL_NONE; + set_call_status_none(delete_index_in_table); + gsm_calls[delete_index_in_table].clip_type = 0; gsm_calls[delete_index_in_table].index = 0; gsm_calls[delete_index_in_table].clip_number[0] = '\0'; @@ -456,7 +465,8 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_USER_BUSY: // Held or waiting call gets active, callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; - gsm_calls[initiated_call_index].status = CALL_NONE; + set_call_status_none(initiated_call_index); + gsm_calls[held_call_index].status = CALL_ACTIVE; break; @@ -503,7 +513,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_ADD_HELD_CALL: if (hfp_gsm_callheld_status() != HFP_CALLHELD_STATUS_NO_CALLS_HELD){ for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (gsm_calls[i].status != CALL_NONE){ + if (!is_call_status_none(i)){ gsm_calls[i].status = CALL_ACTIVE; gsm_calls[i].mpty = HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL; } diff --git a/src/hfp_gsm_model.h b/src/hfp_gsm_model.h index e76f10ae3..c085123a3 100644 --- a/src/hfp_gsm_model.h +++ b/src/hfp_gsm_model.h @@ -65,6 +65,7 @@ typedef enum{ typedef struct { // TODO: use enhanced_status instead of status + uint8_t used_slot; hfp_gsm_call_status_t status; hfp_enhanced_call_dir_t direction; hfp_enhanced_call_status_t enhanced_status; From 79d3c2ada78bfa23bc47212c37f94bc911799473 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Thu, 11 Feb 2016 14:41:37 +0100 Subject: [PATCH 02/26] hfp gsm cleanup --- src/hfp.h | 4 +- src/hfp_gsm_model.c | 91 +++++++++++++++++++++++++++------------------ src/hfp_gsm_model.h | 2 +- 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/hfp.h b/src/hfp.h index 94c13f2a8..dffba6544 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -381,7 +381,9 @@ typedef enum{ HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING, HFP_ENHANCED_CALL_STATUS_INCOMING, HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING, - HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD + HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD, + // used only internally + HFP_ENHANCED_CALL_STATUS_NONE } hfp_enhanced_call_status_t; typedef enum{ diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 6a96c2c6c..08e600e7c 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -73,15 +73,15 @@ static char last_dialed_number[HFP_GSM_MAX_CALL_NUMBER_SIZE]; static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t type, const char * number); -static void set_call_status_none(int index_in_table){ - gsm_calls[index_in_table].status = CALL_NONE; - gsm_calls[index_in_table].used_slot = 0; +static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ + gsm_calls[index_in_table].status = status; } -static int is_call_status_none(int index_in_table){ - return gsm_calls[index_in_table].status == CALL_NONE; +static int get_call_status(int index_in_table){ + return gsm_calls[index_in_table].status; } + void hfp_gsm_init(void){ callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; clip_type = 0; @@ -90,14 +90,30 @@ void hfp_gsm_init(void){ memset(gsm_calls, 0, sizeof(gsm_calls)); int i; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - set_call_status_none(i); + set_call_status(i, CALL_NONE); } } +static int get_number_calls_with_enhanced_status(hfp_enhanced_call_status_t status){ + int i, count = 0; + for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ + if (gsm_calls[i].enhanced_status == status) count++; + } + return count; +} + +static int get_call_index_with_enhanced_status(hfp_enhanced_call_status_t status){ + int i ; + for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ + if (gsm_calls[i].enhanced_status == status) return i; + } + return -1; +} + static int get_number_calls_with_status(hfp_gsm_call_status_t status){ int i, count = 0; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (gsm_calls[i].status == status) count++; + if (get_call_status(i) == status) count++; } return count; } @@ -105,7 +121,7 @@ static int get_number_calls_with_status(hfp_gsm_call_status_t status){ static int get_call_index_with_status(hfp_gsm_call_status_t status){ int i ; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (gsm_calls[i].status == status) return i; + if (get_call_status(i) == status) return i; } return -1; } @@ -172,7 +188,7 @@ static void delete_call(int delete_index_in_table){ gsm_calls[i].index--; } } - set_call_status_none(delete_index_in_table); + set_call_status(delete_index_in_table, CALL_NONE); gsm_calls[delete_index_in_table].clip_type = 0; gsm_calls[delete_index_in_table].index = 0; @@ -185,7 +201,7 @@ static void create_call(hfp_enhanced_call_dir_t direction){ int next_free_slot = get_next_free_slot(); gsm_calls[next_free_slot].direction = direction; gsm_calls[next_free_slot].index = next_call_index(); - gsm_calls[next_free_slot].status = CALL_INITIATED; + set_call_status(next_free_slot, CALL_INITIATED); gsm_calls[next_free_slot].clip_type = 0; gsm_calls[next_free_slot].clip_number[0] = '\0'; gsm_calls[next_free_slot].mpty = HFP_ENHANCED_CALL_MPTY_NOT_A_CONFERENCE_CALL; @@ -214,12 +230,11 @@ hfp_gsm_call_t * hfp_gsm_call(int call_index){ if (call->index != call_index) continue; - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; - - if (call->status == CALL_ACTIVE) call->enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; - if (call->status == CALL_HELD) call->enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; - - if (call->status == CALL_INITIATED){ + if (call->status == CALL_ACTIVE){ + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; + } else if (call->status == CALL_HELD) { + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; + } else if (call->status == CALL_INITIATED){ if (call->direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; @@ -231,6 +246,8 @@ hfp_gsm_call_t * hfp_gsm_call(int call_index){ } call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; } + } else { + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; } return call; } @@ -348,7 +365,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_OUTGOING_CALL_ACCEPTED: if (current_call_index != -1){ - gsm_calls[current_call_index].status = CALL_HELD; + set_call_status(current_call_index, CALL_HELD); } callsetup_status = HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_DIALING_STATE; break; @@ -362,7 +379,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty break; case HFP_AG_OUTGOING_CALL_ESTABLISHED: callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; - gsm_calls[initiated_call_index].status = CALL_ACTIVE; + set_call_status(initiated_call_index, CALL_ACTIVE); break; case HFP_AG_INCOMING_CALL: @@ -376,9 +393,9 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; if (hfp_gsm_call_status() == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - gsm_calls[current_call_index].status = CALL_HELD; + set_call_status(current_call_index, CALL_HELD); } - gsm_calls[initiated_call_index].status = CALL_ACTIVE; + set_call_status(initiated_call_index, CALL_ACTIVE); break; case HFP_AG_HELD_CALL_JOINED_BY_AG: @@ -386,14 +403,14 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty // TODO: is following condition correct? Can we join incoming call before it is answered? if (callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ - gsm_calls[initiated_call_index].status = CALL_ACTIVE; + set_call_status(initiated_call_index, CALL_ACTIVE); callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; } else if (hfp_gsm_callheld_status() == HFP_CALLHELD_STATUS_CALL_ON_HOLD_OR_SWAPPED) { - gsm_calls[held_call_index].status = CALL_ACTIVE; + set_call_status(held_call_index, CALL_ACTIVE); } for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (gsm_calls[i].status == CALL_ACTIVE){ + if (get_call_status(i) == CALL_ACTIVE){ gsm_calls[i].mpty = HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL; } } @@ -403,7 +420,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) break; if (hfp_gsm_call_status() != HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS) break; callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; - gsm_calls[initiated_call_index].status = CALL_ACTIVE; + set_call_status(initiated_call_index, CALL_ACTIVE); break; case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_INCOMING_CALL_BY_AG: @@ -411,13 +428,13 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) break; if (hfp_gsm_call_status() != HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS) break; callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; - gsm_calls[initiated_call_index].status = CALL_RESPONSE_HOLD; + set_call_status(initiated_call_index, CALL_RESPONSE_HOLD); break; case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_AG: case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_HF: if (!hfp_gsm_response_held_active()) break; - gsm_calls[get_response_held_call_index()].status = CALL_ACTIVE; + set_call_status(get_response_held_call_index(), CALL_ACTIVE); break; case HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_AG: @@ -465,9 +482,9 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_USER_BUSY: // Held or waiting call gets active, callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; - set_call_status_none(initiated_call_index); + set_call_status(initiated_call_index, CALL_NONE); - gsm_calls[held_call_index].status = CALL_ACTIVE; + set_call_status(held_call_index, CALL_ACTIVE); break; case HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL: @@ -480,16 +497,16 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty } } else { for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (gsm_calls[i].status == CALL_ACTIVE){ + if (get_call_status(i) == CALL_ACTIVE){ delete_call(i); } } } if (callsetup_status != HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS){ - gsm_calls[initiated_call_index].status = CALL_ACTIVE; + set_call_status(initiated_call_index, CALL_ACTIVE); } else { - gsm_calls[held_call_index].status = CALL_ACTIVE; + set_call_status(held_call_index, CALL_ACTIVE); } callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; @@ -497,15 +514,15 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL: for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (gsm_calls[i].status == CALL_ACTIVE && gsm_calls[i].index != index){ - gsm_calls[i].status = CALL_HELD; + if (get_call_status(i) == CALL_ACTIVE && gsm_calls[i].index != index){ + set_call_status(i, CALL_HELD); } } if (callsetup_status != HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS){ - gsm_calls[initiated_call_index].status = CALL_ACTIVE; + set_call_status(initiated_call_index, CALL_ACTIVE); } else { - gsm_calls[held_call_index].status = CALL_ACTIVE; + set_call_status(held_call_index, CALL_ACTIVE); } callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; break; @@ -513,8 +530,8 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_ADD_HELD_CALL: if (hfp_gsm_callheld_status() != HFP_CALLHELD_STATUS_NO_CALLS_HELD){ for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (!is_call_status_none(i)){ - gsm_calls[i].status = CALL_ACTIVE; + if (get_call_status(i) != CALL_NONE){ + set_call_status(i, CALL_ACTIVE); gsm_calls[i].mpty = HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL; } } diff --git a/src/hfp_gsm_model.h b/src/hfp_gsm_model.h index c085123a3..f7ececa31 100644 --- a/src/hfp_gsm_model.h +++ b/src/hfp_gsm_model.h @@ -65,7 +65,7 @@ typedef enum{ typedef struct { // TODO: use enhanced_status instead of status - uint8_t used_slot; + //uint8_t used_slot; hfp_gsm_call_status_t status; hfp_enhanced_call_dir_t direction; hfp_enhanced_call_status_t enhanced_status; From 915fbfcbc0133cc09b9c50cb0c80ce265363853b Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Thu, 11 Feb 2016 16:44:16 +0100 Subject: [PATCH 03/26] hfp gsm cleanup --- src/hfp.h | 4 +-- src/hfp_gsm_model.c | 84 ++++++++++++++++++++++++--------------------- src/hfp_gsm_model.h | 3 +- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/src/hfp.h b/src/hfp.h index dffba6544..94c13f2a8 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -381,9 +381,7 @@ typedef enum{ HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING, HFP_ENHANCED_CALL_STATUS_INCOMING, HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING, - HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD, - // used only internally - HFP_ENHANCED_CALL_STATUS_NONE + HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD } hfp_enhanced_call_status_t; typedef enum{ diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 08e600e7c..ac6b0d5c2 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -75,12 +75,17 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ gsm_calls[index_in_table].status = status; + gsm_calls[index_in_table].used_slot = 1; } static int get_call_status(int index_in_table){ return gsm_calls[index_in_table].status; } +static void free_call_slot(int index_in_table){ + gsm_calls[index_in_table].used_slot = 0; + gsm_calls[index_in_table].status = CALL_NONE; +} void hfp_gsm_init(void){ callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; @@ -90,26 +95,10 @@ void hfp_gsm_init(void){ memset(gsm_calls, 0, sizeof(gsm_calls)); int i; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - set_call_status(i, CALL_NONE); + free_call_slot(i); } } -static int get_number_calls_with_enhanced_status(hfp_enhanced_call_status_t status){ - int i, count = 0; - for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (gsm_calls[i].enhanced_status == status) count++; - } - return count; -} - -static int get_call_index_with_enhanced_status(hfp_enhanced_call_status_t status){ - int i ; - for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (gsm_calls[i].enhanced_status == status) return i; - } - return -1; -} - static int get_number_calls_with_status(hfp_gsm_call_status_t status){ int i, count = 0; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ @@ -127,7 +116,11 @@ static int get_call_index_with_status(hfp_gsm_call_status_t status){ } static inline int get_next_free_slot(void){ - return get_call_index_with_status(CALL_NONE); + int i ; + for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ + if (!gsm_calls[i].used_slot) return i; + } + return -1; } static inline int get_active_call_index(void){ @@ -147,7 +140,11 @@ static inline int get_response_held_call_index(void){ } static inline int get_number_none_calls(void){ - return get_number_calls_with_status(CALL_NONE); + int i, count = 0; + for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ + if (!gsm_calls[i].used_slot) count++; + } + return count; } static inline int get_number_active_calls(void){ @@ -188,7 +185,7 @@ static void delete_call(int delete_index_in_table){ gsm_calls[i].index--; } } - set_call_status(delete_index_in_table, CALL_NONE); + free_call_slot(delete_index_in_table); gsm_calls[delete_index_in_table].clip_type = 0; gsm_calls[delete_index_in_table].index = 0; @@ -230,24 +227,33 @@ hfp_gsm_call_t * hfp_gsm_call(int call_index){ if (call->index != call_index) continue; - if (call->status == CALL_ACTIVE){ - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; - } else if (call->status == CALL_HELD) { - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; - } else if (call->status == CALL_INITIATED){ - if (call->direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ - if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; + switch (call->status){ + case CALL_ACTIVE: + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; + break; + case CALL_HELD: + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; + break; + case CALL_INITIATED: + if (call->direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ + if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; + } + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING; + } else { + if (get_number_active_calls() > 0){ + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; + } + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; } - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING; - } else { - if (get_number_active_calls() > 0){ - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; - } - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; - } - } else { - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; + break; + case CALL_RESPONSE_HOLD: + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; + break; + default: + log_error("no call status"); + break; + } return call; } @@ -482,8 +488,8 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_USER_BUSY: // Held or waiting call gets active, callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; - set_call_status(initiated_call_index, CALL_NONE); - + // set_call_status(initiated_call_index, CALL_NONE); + free_call_slot(initiated_call_index); set_call_status(held_call_index, CALL_ACTIVE); break; diff --git a/src/hfp_gsm_model.h b/src/hfp_gsm_model.h index f7ececa31..4ca5f3a7a 100644 --- a/src/hfp_gsm_model.h +++ b/src/hfp_gsm_model.h @@ -65,7 +65,8 @@ typedef enum{ typedef struct { // TODO: use enhanced_status instead of status - //uint8_t used_slot; + uint8_t initiated; + uint8_t used_slot; hfp_gsm_call_status_t status; hfp_enhanced_call_dir_t direction; hfp_enhanced_call_status_t enhanced_status; From 19d39eec25a2c7ef69e181a4fdbeea537e7e38fb Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Thu, 11 Feb 2016 16:45:57 +0100 Subject: [PATCH 04/26] hfp gsm cleanup --- src/hfp_gsm_model.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index ac6b0d5c2..4f170d5fc 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -488,7 +488,6 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_USER_BUSY: // Held or waiting call gets active, callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; - // set_call_status(initiated_call_index, CALL_NONE); free_call_slot(initiated_call_index); set_call_status(held_call_index, CALL_ACTIVE); break; @@ -536,7 +535,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_ADD_HELD_CALL: if (hfp_gsm_callheld_status() != HFP_CALLHELD_STATUS_NO_CALLS_HELD){ for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (get_call_status(i) != CALL_NONE){ + if (gsm_calls[i].used_slot){ set_call_status(i, CALL_ACTIVE); gsm_calls[i].mpty = HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL; } From a70c22075539cef93e0e225e6c94ec1f70b0ccde Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Thu, 11 Feb 2016 16:51:24 +0100 Subject: [PATCH 05/26] hfp gsm cleanup --- src/hfp_gsm_model.c | 2 +- src/hfp_gsm_model.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 4f170d5fc..305f7e445 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -79,12 +79,12 @@ static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ } static int get_call_status(int index_in_table){ + if (!gsm_calls[index_in_table].used_slot) return -1; return gsm_calls[index_in_table].status; } static void free_call_slot(int index_in_table){ gsm_calls[index_in_table].used_slot = 0; - gsm_calls[index_in_table].status = CALL_NONE; } void hfp_gsm_init(void){ diff --git a/src/hfp_gsm_model.h b/src/hfp_gsm_model.h index 4ca5f3a7a..c81c4b2ca 100644 --- a/src/hfp_gsm_model.h +++ b/src/hfp_gsm_model.h @@ -56,7 +56,6 @@ extern "C" { /* API_START */ typedef enum{ - CALL_NONE, CALL_INITIATED, CALL_RESPONSE_HOLD, CALL_ACTIVE, From bacea99514b852e0bf8f5936c14d02fc4b6f85f4 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 11:38:45 +0100 Subject: [PATCH 06/26] hfp gsm: set active and hold enhanced states on state change --- src/hfp_gsm_model.c | 39 ++++++++++++++++++++++++++++++--------- src/hfp_gsm_model.h | 13 ++++++++++--- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 305f7e445..ce401908a 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -74,10 +74,40 @@ static char last_dialed_number[HFP_GSM_MAX_CALL_NUMBER_SIZE]; static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t type, const char * number); static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ + switch (status){ + case CALL_RESPONSE_HOLD: + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; + break; + case CALL_ACTIVE: + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; + break; + case CALL_HELD: + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; + break; + default: + break; + } gsm_calls[index_in_table].status = status; gsm_calls[index_in_table].used_slot = 1; } +static int get_call_status_for_enhanced_status(hfp_enhanced_call_status_t enhanced_status){ + switch(enhanced_status){ + case HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING: + case HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING: + case HFP_ENHANCED_CALL_STATUS_INCOMING: + case HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING: + return CALL_INITIATED; + case HFP_ENHANCED_CALL_STATUS_ACTIVE: + return CALL_ACTIVE; + case HFP_ENHANCED_CALL_STATUS_HELD: + return CALL_HELD; + case HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD: + return CALL_RESPONSE_HOLD; + } +} + + static int get_call_status(int index_in_table){ if (!gsm_calls[index_in_table].used_slot) return -1; return gsm_calls[index_in_table].status; @@ -228,12 +258,6 @@ hfp_gsm_call_t * hfp_gsm_call(int call_index){ if (call->index != call_index) continue; switch (call->status){ - case CALL_ACTIVE: - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; - break; - case CALL_HELD: - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; - break; case CALL_INITIATED: if (call->direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ @@ -247,9 +271,6 @@ hfp_gsm_call_t * hfp_gsm_call(int call_index){ call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; } break; - case CALL_RESPONSE_HOLD: - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; - break; default: log_error("no call status"); break; diff --git a/src/hfp_gsm_model.h b/src/hfp_gsm_model.h index c81c4b2ca..af5e6f27a 100644 --- a/src/hfp_gsm_model.h +++ b/src/hfp_gsm_model.h @@ -57,18 +57,25 @@ extern "C" { typedef enum{ CALL_INITIATED, + + // CALL_ENHANCED_CALL_STATUS_OUTGOING_DIALING, + // CALL_ENHANCED_CALL_STATUS_OUTGOING_ALERTING, + // CALL_ENHANCED_CALL_STATUS_INCOMING, + // CALL_ENHANCED_CALL_STATUS_INCOMING_WAITING, + CALL_RESPONSE_HOLD, CALL_ACTIVE, CALL_HELD } hfp_gsm_call_status_t; typedef struct { - // TODO: use enhanced_status instead of status - uint8_t initiated; uint8_t used_slot; + + // TODO: use enhanced_status instead of status hfp_gsm_call_status_t status; - hfp_enhanced_call_dir_t direction; hfp_enhanced_call_status_t enhanced_status; + + hfp_enhanced_call_dir_t direction; hfp_enhanced_call_mode_t mode; hfp_enhanced_call_mpty_t mpty; // TODO: sort on drop call, so that index corresponds to table index From 17d2322f1c6a2d9ca7c26771d5236d9e8a36a4e6 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 11:42:19 +0100 Subject: [PATCH 07/26] hfp gsm: set incoming enhanced states on state change --- src/hfp_gsm_model.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index ce401908a..8d0ec0fed 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -84,6 +84,14 @@ static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ case CALL_HELD: gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; break; + case CALL_INITIATED: + if (gsm_calls[index_in_table].direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ + if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; + } + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING; + } + break; default: break; } @@ -259,12 +267,7 @@ hfp_gsm_call_t * hfp_gsm_call(int call_index){ switch (call->status){ case CALL_INITIATED: - if (call->direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ - if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; - } - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING; - } else { + if (call->direction == HFP_ENHANCED_CALL_DIR_INCOMING){ if (get_number_active_calls() > 0){ call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; } From 74ac0b603138f9e93a1a3ce2ea79499f25792b2a Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 11:57:09 +0100 Subject: [PATCH 08/26] hfp gsm: setter for callsetup status --- src/hfp_gsm_model.c | 74 +++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 8d0ec0fed..0792018d8 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -72,6 +72,11 @@ static char clip_number[HFP_GSM_MAX_CALL_NUMBER_SIZE]; static char last_dialed_number[HFP_GSM_MAX_CALL_NUMBER_SIZE]; static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t type, const char * number); +static inline int get_number_active_calls(void); + +static void set_callsetup_status(hfp_callsetup_status_t status){ + callsetup_status = status; +} static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ switch (status){ @@ -85,13 +90,16 @@ static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; break; case CALL_INITIATED: - if (gsm_calls[index_in_table].direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ - if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ - gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; - } - gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING; - } - break; + if (gsm_calls[index_in_table].direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING; + } else { + if (get_number_active_calls() > 0){ + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; + } else { + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; + } + } + break; default: break; } @@ -126,7 +134,7 @@ static void free_call_slot(int index_in_table){ } void hfp_gsm_init(void){ - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); clip_type = 0; memset(clip_number, 0, sizeof(clip_number)); memset(last_dialed_number, 0, sizeof(last_dialed_number)); @@ -267,12 +275,18 @@ hfp_gsm_call_t * hfp_gsm_call(int call_index){ switch (call->status){ case CALL_INITIATED: - if (call->direction == HFP_ENHANCED_CALL_DIR_INCOMING){ - if (get_number_active_calls() > 0){ - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; - } - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; - } + if (call->direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ + if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ + call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; + } + } + // } else { + // if (get_number_active_calls() > 0){ + // call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; + // } else { + // call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; + // } + // } break; default: log_error("no call status"); @@ -390,14 +404,14 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty if (current_call_index != -1){ delete_call(current_call_index); } - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); break; case HFP_AG_OUTGOING_CALL_ACCEPTED: if (current_call_index != -1){ set_call_status(current_call_index, CALL_HELD); } - callsetup_status = HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_DIALING_STATE; + set_callsetup_status(HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_DIALING_STATE); break; case HFP_AG_OUTGOING_CALL_RINGING: @@ -405,22 +419,22 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty log_error("gsm: no active call"); return; } - callsetup_status = HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE; + set_callsetup_status(HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE); break; case HFP_AG_OUTGOING_CALL_ESTABLISHED: - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); set_call_status(initiated_call_index, CALL_ACTIVE); break; case HFP_AG_INCOMING_CALL: if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS) break; - callsetup_status = HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS); create_call(HFP_ENHANCED_CALL_DIR_INCOMING); break; case HFP_AG_INCOMING_CALL_ACCEPTED_BY_AG: if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) break; - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); if (hfp_gsm_call_status() == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ set_call_status(current_call_index, CALL_HELD); @@ -434,7 +448,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty // TODO: is following condition correct? Can we join incoming call before it is answered? if (callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ set_call_status(initiated_call_index, CALL_ACTIVE); - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); } else if (hfp_gsm_callheld_status() == HFP_CALLHELD_STATUS_CALL_ON_HOLD_OR_SWAPPED) { set_call_status(held_call_index, CALL_ACTIVE); } @@ -449,7 +463,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_INCOMING_CALL_ACCEPTED_BY_HF: if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) break; if (hfp_gsm_call_status() != HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS) break; - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); set_call_status(initiated_call_index, CALL_ACTIVE); break; @@ -457,7 +471,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_INCOMING_CALL_BY_HF: if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) break; if (hfp_gsm_call_status() != HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS) break; - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); set_call_status(initiated_call_index, CALL_RESPONSE_HOLD); break; @@ -477,7 +491,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_TERMINATE_CALL_BY_HF: switch (hfp_gsm_call_status()){ case HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS: - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); break; case HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT: delete_call(current_call_index); @@ -489,10 +503,10 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty switch (hfp_gsm_call_status()){ case HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS: if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) break; - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); break; case HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT: - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); delete_call(current_call_index); break; default: @@ -501,7 +515,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty break; case HFP_AG_CALL_DROPPED: - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); if (hfp_gsm_call_status() != HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT) break; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ @@ -511,7 +525,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_USER_BUSY: // Held or waiting call gets active, - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); free_call_slot(initiated_call_index); set_call_status(held_call_index, CALL_ACTIVE); break; @@ -538,7 +552,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty set_call_status(held_call_index, CALL_ACTIVE); } - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); break; case HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL: @@ -553,7 +567,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty } else { set_call_status(held_call_index, CALL_ACTIVE); } - callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; + set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); break; case HFP_AG_CALL_HOLD_ADD_HELD_CALL: From 65bb457efa3d5ed918a33e9185f15e8a01b0e6c8 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 12:12:22 +0100 Subject: [PATCH 09/26] hfp gsm: remove status field from hfp_gsm_call_t, use enhanced_status instead --- src/hfp_gsm_model.c | 40 ++++++++++++++++------------------------ src/hfp_gsm_model.h | 17 ----------------- 2 files changed, 16 insertions(+), 41 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 0792018d8..c55fbc7b1 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -64,6 +64,13 @@ #define HFP_GSM_MAX_NR_CALLS 3 #define HFP_GSM_MAX_CALL_NUMBER_SIZE 25 +typedef enum{ + CALL_INITIATED, + CALL_RESPONSE_HOLD, + CALL_ACTIVE, + CALL_HELD +} hfp_gsm_call_status_t; + static hfp_gsm_call_t gsm_calls[HFP_GSM_MAX_NR_CALLS]; static hfp_callsetup_status_t callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; @@ -76,6 +83,14 @@ static inline int get_number_active_calls(void); static void set_callsetup_status(hfp_callsetup_status_t status){ callsetup_status = status; + if (callsetup_status != HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE) return; + + int i ; + for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ + if (gsm_calls[i].direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ + gsm_calls[i].enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; + } + } } static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ @@ -103,7 +118,6 @@ static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ default: break; } - gsm_calls[index_in_table].status = status; gsm_calls[index_in_table].used_slot = 1; } @@ -126,7 +140,7 @@ static int get_call_status_for_enhanced_status(hfp_enhanced_call_status_t enhanc static int get_call_status(int index_in_table){ if (!gsm_calls[index_in_table].used_slot) return -1; - return gsm_calls[index_in_table].status; + return get_call_status_for_enhanced_status(gsm_calls[index_in_table].enhanced_status); } static void free_call_slot(int index_in_table){ @@ -270,29 +284,7 @@ hfp_gsm_call_t * hfp_gsm_call(int call_index){ for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ hfp_gsm_call_t * call = &gsm_calls[i]; - if (call->index != call_index) continue; - - switch (call->status){ - case CALL_INITIATED: - if (call->direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ - if (callsetup_status == HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE){ - call->enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING; - } - } - // } else { - // if (get_number_active_calls() > 0){ - // call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; - // } else { - // call->enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; - // } - // } - break; - default: - log_error("no call status"); - break; - - } return call; } return NULL; diff --git a/src/hfp_gsm_model.h b/src/hfp_gsm_model.h index af5e6f27a..ad1cc8176 100644 --- a/src/hfp_gsm_model.h +++ b/src/hfp_gsm_model.h @@ -54,25 +54,8 @@ extern "C" { #endif /* API_START */ - -typedef enum{ - CALL_INITIATED, - - // CALL_ENHANCED_CALL_STATUS_OUTGOING_DIALING, - // CALL_ENHANCED_CALL_STATUS_OUTGOING_ALERTING, - // CALL_ENHANCED_CALL_STATUS_INCOMING, - // CALL_ENHANCED_CALL_STATUS_INCOMING_WAITING, - - CALL_RESPONSE_HOLD, - CALL_ACTIVE, - CALL_HELD -} hfp_gsm_call_status_t; - typedef struct { uint8_t used_slot; - - // TODO: use enhanced_status instead of status - hfp_gsm_call_status_t status; hfp_enhanced_call_status_t enhanced_status; hfp_enhanced_call_dir_t direction; From fe1a8d500e95a3e1b81fe426240cb46a8fd68298 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 12:32:44 +0100 Subject: [PATCH 10/26] hfp gsm: use set_enhanced_call_status_active --- src/hfp_gsm_model.c | 48 +++++++++++++++++++++++++++++++++------------ src/hfp_gsm_model.h | 1 - 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index c55fbc7b1..07471ad14 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -93,6 +93,30 @@ static void set_callsetup_status(hfp_callsetup_status_t status){ } } +static inline void set_enhanced_call_status_active(int index_in_table){ + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; +} + +static inline void set_enhanced_call_status_held(int index_in_table){ + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; +} + +static inline void set_enhanced_call_status_response_hold(int index_in_table){ + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; +} + +static inline void set_enhanced_call_status_initiated(int index_in_table){ + if (gsm_calls[index_in_table].direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING; + } else { + if (get_number_active_calls() > 0){ + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; + } else { + gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; + } + } +} + static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ switch (status){ case CALL_RESPONSE_HOLD: @@ -415,7 +439,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty break; case HFP_AG_OUTGOING_CALL_ESTABLISHED: set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); - set_call_status(initiated_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(initiated_call_index); break; case HFP_AG_INCOMING_CALL: @@ -431,7 +455,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty if (hfp_gsm_call_status() == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ set_call_status(current_call_index, CALL_HELD); } - set_call_status(initiated_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(initiated_call_index); break; case HFP_AG_HELD_CALL_JOINED_BY_AG: @@ -439,10 +463,10 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty // TODO: is following condition correct? Can we join incoming call before it is answered? if (callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ - set_call_status(initiated_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(initiated_call_index); set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); } else if (hfp_gsm_callheld_status() == HFP_CALLHELD_STATUS_CALL_ON_HOLD_OR_SWAPPED) { - set_call_status(held_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(held_call_index); } for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ @@ -456,7 +480,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) break; if (hfp_gsm_call_status() != HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS) break; set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); - set_call_status(initiated_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(initiated_call_index); break; case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_INCOMING_CALL_BY_AG: @@ -470,7 +494,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_AG: case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_HF: if (!hfp_gsm_response_held_active()) break; - set_call_status(get_response_held_call_index(), CALL_ACTIVE); + set_enhanced_call_status_active(get_response_held_call_index()); break; case HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_AG: @@ -519,7 +543,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty // Held or waiting call gets active, set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); free_call_slot(initiated_call_index); - set_call_status(held_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(held_call_index); break; case HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL: @@ -539,9 +563,9 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty } if (callsetup_status != HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS){ - set_call_status(initiated_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(initiated_call_index); } else { - set_call_status(held_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(held_call_index); } set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); @@ -555,9 +579,9 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty } if (callsetup_status != HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS){ - set_call_status(initiated_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(initiated_call_index); } else { - set_call_status(held_call_index, CALL_ACTIVE); + set_enhanced_call_status_active(held_call_index); } set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); break; @@ -566,7 +590,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty if (hfp_gsm_callheld_status() != HFP_CALLHELD_STATUS_NO_CALLS_HELD){ for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ if (gsm_calls[i].used_slot){ - set_call_status(i, CALL_ACTIVE); + set_enhanced_call_status_active(i); gsm_calls[i].mpty = HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL; } } diff --git a/src/hfp_gsm_model.h b/src/hfp_gsm_model.h index ad1cc8176..f66d67831 100644 --- a/src/hfp_gsm_model.h +++ b/src/hfp_gsm_model.h @@ -57,7 +57,6 @@ extern "C" { typedef struct { uint8_t used_slot; hfp_enhanced_call_status_t enhanced_status; - hfp_enhanced_call_dir_t direction; hfp_enhanced_call_mode_t mode; hfp_enhanced_call_mpty_t mpty; From e5db645c869adcf3c6769ae31f801e0485162557 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 13:23:48 +0100 Subject: [PATCH 11/26] hfp gsm: use set_enhanced_call_status_held --- src/hfp_gsm_model.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 07471ad14..e53583a19 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -425,7 +425,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_OUTGOING_CALL_ACCEPTED: if (current_call_index != -1){ - set_call_status(current_call_index, CALL_HELD); + set_enhanced_call_status_held(current_call_index); } set_callsetup_status(HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_DIALING_STATE); break; @@ -453,7 +453,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); if (hfp_gsm_call_status() == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - set_call_status(current_call_index, CALL_HELD); + set_enhanced_call_status_held(current_call_index); } set_enhanced_call_status_active(initiated_call_index); break; @@ -574,7 +574,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL: for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ if (get_call_status(i) == CALL_ACTIVE && gsm_calls[i].index != index){ - set_call_status(i, CALL_HELD); + set_enhanced_call_status_held(i); } } From 0436e65c89e917c57ba919cf37b7d0a3c6fe0dde Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 13:24:40 +0100 Subject: [PATCH 12/26] hfp gsm: use set_enhanced_call_status_response_hold --- src/hfp_gsm_model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index e53583a19..6866f69ae 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -488,7 +488,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty if (hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) break; if (hfp_gsm_call_status() != HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS) break; set_callsetup_status(HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS); - set_call_status(initiated_call_index, CALL_RESPONSE_HOLD); + set_enhanced_call_status_response_hold(initiated_call_index); break; case HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_AG: From 9dce5e79b77b572ece5febeb2bf7f3ecf9470af4 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 13:26:47 +0100 Subject: [PATCH 13/26] hfp gsm: use set_enhanced_call_status_INITIATED --- src/hfp_gsm_model.c | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 6866f69ae..0f99cf3b9 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -95,14 +95,17 @@ static void set_callsetup_status(hfp_callsetup_status_t status){ static inline void set_enhanced_call_status_active(int index_in_table){ gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; + gsm_calls[index_in_table].used_slot = 1; } static inline void set_enhanced_call_status_held(int index_in_table){ gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; + gsm_calls[index_in_table].used_slot = 1; } static inline void set_enhanced_call_status_response_hold(int index_in_table){ gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; + gsm_calls[index_in_table].used_slot = 1; } static inline void set_enhanced_call_status_initiated(int index_in_table){ @@ -115,33 +118,6 @@ static inline void set_enhanced_call_status_initiated(int index_in_table){ gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; } } -} - -static void set_call_status(int index_in_table, hfp_gsm_call_status_t status){ - switch (status){ - case CALL_RESPONSE_HOLD: - gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; - break; - case CALL_ACTIVE: - gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_ACTIVE; - break; - case CALL_HELD: - gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_HELD; - break; - case CALL_INITIATED: - if (gsm_calls[index_in_table].direction == HFP_ENHANCED_CALL_DIR_OUTGOING){ - gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING; - } else { - if (get_number_active_calls() > 0){ - gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING; - } else { - gsm_calls[index_in_table].enhanced_status = HFP_ENHANCED_CALL_STATUS_INCOMING; - } - } - break; - default: - break; - } gsm_calls[index_in_table].used_slot = 1; } @@ -282,7 +258,7 @@ static void create_call(hfp_enhanced_call_dir_t direction){ int next_free_slot = get_next_free_slot(); gsm_calls[next_free_slot].direction = direction; gsm_calls[next_free_slot].index = next_call_index(); - set_call_status(next_free_slot, CALL_INITIATED); + set_enhanced_call_status_initiated(next_free_slot); gsm_calls[next_free_slot].clip_type = 0; gsm_calls[next_free_slot].clip_number[0] = '\0'; gsm_calls[next_free_slot].mpty = HFP_ENHANCED_CALL_MPTY_NOT_A_CONFERENCE_CALL; From 49170286cad8daf6f45677fdc64f64c9db3abc9f Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 13:57:44 +0100 Subject: [PATCH 14/26] hfp gsm: introduced enhanced status functions --- src/hfp_gsm_model.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 0f99cf3b9..2c7eba4bb 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -121,6 +121,30 @@ static inline void set_enhanced_call_status_initiated(int index_in_table){ gsm_calls[index_in_table].used_slot = 1; } +static inline int is_enhanced_call_status_active(int index_in_table){ + return gsm_calls[index_in_table].enhanced_status == HFP_ENHANCED_CALL_STATUS_ACTIVE; +} + +static inline int is_enhanced_call_status_held(int index_in_table){ + return gsm_calls[index_in_table].enhanced_status == HFP_ENHANCED_CALL_STATUS_HELD; +} + +static inline int is_enhanced_call_status_response_hold(int index_in_table){ + return gsm_calls[index_in_table].enhanced_status == HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; +} + +static inline int is_enhanced_call_status_initiated(int index_in_table){ + switch (gsm_calls[index_in_table].enhanced_status){ + case HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING: + case HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING: + case HFP_ENHANCED_CALL_STATUS_INCOMING: + case HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING: + return 1; + default: + return 0; + } +} + static int get_call_status_for_enhanced_status(hfp_enhanced_call_status_t enhanced_status){ switch(enhanced_status){ case HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING: @@ -137,6 +161,10 @@ static int get_call_status_for_enhanced_status(hfp_enhanced_call_status_t enhanc } } +static int get_enhanced_call_status(int index_in_table){ + if (!gsm_calls[index_in_table].used_slot) return -1; + return gsm_calls[index_in_table].enhanced_status; +} static int get_call_status(int index_in_table){ if (!gsm_calls[index_in_table].used_slot) return -1; @@ -175,6 +203,14 @@ static int get_call_index_with_status(hfp_gsm_call_status_t status){ return -1; } +static int get_enhanced_call_index_with_status(hfp_enhanced_call_status_t enhanced_status){ + int i ; + for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ + if (get_enhanced_call_status(i) == enhanced_status) return i; + } + return -1; +} + static inline int get_next_free_slot(void){ int i ; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ From 0195afd67a2b89a17e02548cdc06d3eb6c301f8f Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 14:26:17 +0100 Subject: [PATCH 15/26] hfp gsm: remove status enum --- src/hfp_gsm_model.c | 80 ++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 56 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 2c7eba4bb..66828820e 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -64,13 +64,6 @@ #define HFP_GSM_MAX_NR_CALLS 3 #define HFP_GSM_MAX_CALL_NUMBER_SIZE 25 -typedef enum{ - CALL_INITIATED, - CALL_RESPONSE_HOLD, - CALL_ACTIVE, - CALL_HELD -} hfp_gsm_call_status_t; - static hfp_gsm_call_t gsm_calls[HFP_GSM_MAX_NR_CALLS]; static hfp_callsetup_status_t callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; @@ -121,20 +114,25 @@ static inline void set_enhanced_call_status_initiated(int index_in_table){ gsm_calls[index_in_table].used_slot = 1; } +static int get_enhanced_call_status(int index_in_table){ + if (!gsm_calls[index_in_table].used_slot) return -1; + return gsm_calls[index_in_table].enhanced_status; +} + static inline int is_enhanced_call_status_active(int index_in_table){ - return gsm_calls[index_in_table].enhanced_status == HFP_ENHANCED_CALL_STATUS_ACTIVE; + return get_enhanced_call_status(index_in_table) == HFP_ENHANCED_CALL_STATUS_ACTIVE; } static inline int is_enhanced_call_status_held(int index_in_table){ - return gsm_calls[index_in_table].enhanced_status == HFP_ENHANCED_CALL_STATUS_HELD; + return get_enhanced_call_status(index_in_table) == HFP_ENHANCED_CALL_STATUS_HELD; } static inline int is_enhanced_call_status_response_hold(int index_in_table){ - return gsm_calls[index_in_table].enhanced_status == HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; + return get_enhanced_call_status(index_in_table) == HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; } static inline int is_enhanced_call_status_initiated(int index_in_table){ - switch (gsm_calls[index_in_table].enhanced_status){ + switch (get_enhanced_call_status(index_in_table)){ case HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING: case HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING: case HFP_ENHANCED_CALL_STATUS_INCOMING: @@ -145,32 +143,6 @@ static inline int is_enhanced_call_status_initiated(int index_in_table){ } } -static int get_call_status_for_enhanced_status(hfp_enhanced_call_status_t enhanced_status){ - switch(enhanced_status){ - case HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING: - case HFP_ENHANCED_CALL_STATUS_OUTGOING_ALERTING: - case HFP_ENHANCED_CALL_STATUS_INCOMING: - case HFP_ENHANCED_CALL_STATUS_INCOMING_WAITING: - return CALL_INITIATED; - case HFP_ENHANCED_CALL_STATUS_ACTIVE: - return CALL_ACTIVE; - case HFP_ENHANCED_CALL_STATUS_HELD: - return CALL_HELD; - case HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD: - return CALL_RESPONSE_HOLD; - } -} - -static int get_enhanced_call_status(int index_in_table){ - if (!gsm_calls[index_in_table].used_slot) return -1; - return gsm_calls[index_in_table].enhanced_status; -} - -static int get_call_status(int index_in_table){ - if (!gsm_calls[index_in_table].used_slot) return -1; - return get_call_status_for_enhanced_status(gsm_calls[index_in_table].enhanced_status); -} - static void free_call_slot(int index_in_table){ gsm_calls[index_in_table].used_slot = 0; } @@ -187,26 +159,26 @@ void hfp_gsm_init(void){ } } -static int get_number_calls_with_status(hfp_gsm_call_status_t status){ +static int get_number_calls_with_enhanced_status(hfp_enhanced_call_status_t enhanced_status){ int i, count = 0; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (get_call_status(i) == status) count++; + if (get_enhanced_call_status(i) == enhanced_status) count++; } return count; } -static int get_call_index_with_status(hfp_gsm_call_status_t status){ +static int get_call_index_with_enhanced_status(hfp_enhanced_call_status_t enhanced_status){ int i ; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (get_call_status(i) == status) return i; + if (get_enhanced_call_status(i) == enhanced_status) return i; } return -1; } -static int get_enhanced_call_index_with_status(hfp_enhanced_call_status_t enhanced_status){ +static inline int get_initiated_call_index(void){ int i ; for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (get_enhanced_call_status(i) == enhanced_status) return i; + if (is_enhanced_call_status_initiated(i)) return i; } return -1; } @@ -220,19 +192,15 @@ static inline int get_next_free_slot(void){ } static inline int get_active_call_index(void){ - return get_call_index_with_status(CALL_ACTIVE); -} - -static inline int get_initiated_call_index(void){ - return get_call_index_with_status(CALL_INITIATED); + return get_call_index_with_enhanced_status(HFP_ENHANCED_CALL_STATUS_ACTIVE); } static inline int get_held_call_index(void){ - return get_call_index_with_status(CALL_HELD); + return get_call_index_with_enhanced_status(HFP_ENHANCED_CALL_STATUS_HELD); } static inline int get_response_held_call_index(void){ - return get_call_index_with_status(CALL_RESPONSE_HOLD); + return get_call_index_with_enhanced_status(HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD); } static inline int get_number_none_calls(void){ @@ -244,15 +212,15 @@ static inline int get_number_none_calls(void){ } static inline int get_number_active_calls(void){ - return get_number_calls_with_status(CALL_ACTIVE); + return get_number_calls_with_enhanced_status(HFP_ENHANCED_CALL_STATUS_ACTIVE); } static inline int get_number_held_calls(void){ - return get_number_calls_with_status(CALL_HELD); + return get_number_calls_with_enhanced_status(HFP_ENHANCED_CALL_STATUS_HELD); } static inline int get_number_response_held_calls(void){ - return get_number_calls_with_status(CALL_RESPONSE_HOLD); + return get_number_calls_with_enhanced_status(HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD); } static int next_call_index(void){ @@ -482,7 +450,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty } for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (get_call_status(i) == CALL_ACTIVE){ + if (is_enhanced_call_status_active(i)){ gsm_calls[i].mpty = HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL; } } @@ -568,7 +536,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty } } else { for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (get_call_status(i) == CALL_ACTIVE){ + if (is_enhanced_call_status_active(i)){ delete_call(i); } } @@ -585,7 +553,7 @@ static void hfp_gsm_handler(hfp_ag_call_event_t event, uint8_t index, uint8_t ty case HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL: for (i = 0; i < HFP_GSM_MAX_NR_CALLS; i++){ - if (get_call_status(i) == CALL_ACTIVE && gsm_calls[i].index != index){ + if (is_enhanced_call_status_active(i) && gsm_calls[i].index != index){ set_enhanced_call_status_held(i); } } From 9188a3b7e0065e4f881c710beeaa6841984e5460 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 14:28:08 +0100 Subject: [PATCH 16/26] hfp gsm: remove unsed functions --- src/hfp_gsm_model.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/hfp_gsm_model.c b/src/hfp_gsm_model.c index 66828820e..11699a553 100644 --- a/src/hfp_gsm_model.c +++ b/src/hfp_gsm_model.c @@ -123,14 +123,6 @@ static inline int is_enhanced_call_status_active(int index_in_table){ return get_enhanced_call_status(index_in_table) == HFP_ENHANCED_CALL_STATUS_ACTIVE; } -static inline int is_enhanced_call_status_held(int index_in_table){ - return get_enhanced_call_status(index_in_table) == HFP_ENHANCED_CALL_STATUS_HELD; -} - -static inline int is_enhanced_call_status_response_hold(int index_in_table){ - return get_enhanced_call_status(index_in_table) == HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD; -} - static inline int is_enhanced_call_status_initiated(int index_in_table){ switch (get_enhanced_call_status(index_in_table)){ case HFP_ENHANCED_CALL_STATUS_OUTGOING_DIALING: From 793a2762379e1a3c58803a30a667f2ed4717df8a Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 12 Feb 2016 14:53:40 +0100 Subject: [PATCH 17/26] hfp_ag: code review --- src/hsp_ag.c | 65 ++++++++++++++++------------------------------------ src/hsp_ag.h | 21 +++++++++++------ 2 files changed, 34 insertions(+), 52 deletions(-) diff --git a/src/hsp_ag.c b/src/hsp_ag.c index 961f705a2..fbe24d502 100644 --- a/src/hsp_ag.c +++ b/src/hsp_ag.c @@ -37,7 +37,7 @@ // ***************************************************************************** // -// Minimal setup for HSP Audio Gateway (!! UNDER DEVELOPMENT !!) +// HSP Audio Gateway // // ***************************************************************************** @@ -60,8 +60,6 @@ #include "debug.h" #include "hsp_ag.h" -#define RFCOMM_SERVER_CHANNEL 1 - #define HSP_HS_BUTTON_PRESS "AT+CKPD=200" #define HSP_HS_AT_CKPD "AT+CKPD\r\n" #define HSP_AG_OK "\r\nOK\r\n" @@ -84,8 +82,6 @@ static uint16_t sco_handle = 0; static uint16_t rfcomm_handle = 0; static timer_source_t hs_timeout; -// static uint8_t connection_state = 0; - static int ag_microphone_gain = -1; static int ag_speaker_gain = -1; static uint8_t ag_ring = 0; @@ -221,14 +217,13 @@ static int hsp_ag_send_str_over_rfcomm(uint16_t cid, char * command){ if (!rfcomm_can_send_packet_now(cid)) return 1; int err = rfcomm_send_internal(cid, (uint8_t*) command, strlen(command)); if (err){ - printf("rfcomm_send_internal -> error 0X%02x", err); + log_error("rfcomm_send_internal -> error 0X%02x", err); return err; } - printf("Send string: \"%s\"\n", command); return err; } -void hsp_ag_support_custom_commands(int enable){ +void hsp_ag_enable_custom_commands(int enable){ ag_support_custom_commands = enable; } @@ -298,7 +293,7 @@ void hsp_ag_disconnect(void){ void hsp_ag_set_microphone_gain(uint8_t gain){ if (gain < 0 || gain >15) { - printf("Gain must be in interval [0..15], it is given %d\n", gain); + log_error("Gain must be in interval [0..15], it is given %d", gain); return; } ag_microphone_gain = gain; @@ -308,7 +303,7 @@ void hsp_ag_set_microphone_gain(uint8_t gain){ // AG +VGS=5 [0..15] ; HS AT+VGM=6 | AG OK void hsp_ag_set_speaker_gain(uint8_t gain){ if (gain < 0 || gain >15) { - printf("Gain must be in interval [0..15], it is given %d\n", gain); + log_error("Gain must be in interval [0..15], it is given %d", gain); return; } ag_speaker_gain = gain; @@ -368,7 +363,7 @@ static void hsp_run(void){ switch (hsp_state){ case HSP_SDP_QUERY_RFCOMM_CHANNEL: hsp_state = HSP_W4_SDP_QUERY_COMPLETE; - printf("Start SDP query %s, 0x%02x\n", bd_addr_to_str(remote), SDP_HSP); + log_info("Start SDP query %s, 0x%02x", bd_addr_to_str(remote), SDP_HSP); sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_HSP); break; @@ -444,7 +439,7 @@ static void hsp_run(void){ static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ - // printf("packet_handler type %u, packet[0] %x\n", packet_type, packet[0]); + // log_info("packet_handler type %u, packet[0] %x", packet_type, packet[0]); if (packet_type == RFCOMM_DATA_PACKET){ while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){ size--; @@ -452,7 +447,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha } if (strncmp((char *)packet, HSP_HS_BUTTON_PRESS, strlen(HSP_HS_BUTTON_PRESS)) == 0){ - printf("Received button press %s\n", HSP_HS_BUTTON_PRESS); + log_info("Received button press %s", HSP_HS_BUTTON_PRESS); ag_num_button_press_received++; ag_send_ok = 1; if (hsp_state == HSP_ACTIVE && ag_num_button_press_received >=2){ @@ -490,19 +485,6 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha uint16_t handle; switch (event) { - case BTSTACK_EVENT_STATE: - // BTstack activated, get started - if (packet[2] == HCI_STATE_WORKING){ - printf("BTstack activated, get started .\n"); - } - break; - - case HCI_EVENT_PIN_CODE_REQUEST: - // inform about pin code request - printf("Pin code request - using '0000'\n\r"); - bt_flip_addr(event_addr, &packet[2]); - hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000"); - break; case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{ int index = 2; uint8_t status = packet[index++]; @@ -527,14 +509,14 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha } switch (link_type){ case 0x00: - printf("SCO Connection established. \n"); + log_info("SCO Connection established."); if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval); if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval); if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length); if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length); break; case 0x02: - printf("eSCO Connection established. \n"); + log_info("eSCO Connection established."); break; default: log_error("(e)SCO reserved link_type 0x%2x", link_type); @@ -560,18 +542,17 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha bt_flip_addr(event_addr, &packet[2]); rfcomm_cid = READ_BT_16(packet, 9); - printf("RFCOMM channel %u requested for %s\n", packet[8], bd_addr_to_str(event_addr)); + log_info("RFCOMM channel %u requested for %s", packet[8], bd_addr_to_str(event_addr)); rfcomm_accept_connection_internal(rfcomm_cid); hsp_state = HSP_W4_RFCOMM_CONNECTED; - break; case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE: - printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x\n", packet_type, packet[0]); + log_info("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x", packet_type, packet[0]); // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16) if (packet[2]) { - printf("RFCOMM channel open failed, status %u\n", packet[2]); + log_info("RFCOMM channel open failed, status %u§", packet[2]); hsp_ag_reset_state(); emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, packet[2]); } else { @@ -579,7 +560,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha rfcomm_handle = READ_BT_16(packet, 9); rfcomm_cid = READ_BT_16(packet, 12); mtu = READ_BT_16(packet, 14); - printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u, state %d\n", rfcomm_cid, mtu, hsp_state); + log_info("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u, state %d", rfcomm_cid, mtu, hsp_state); switch (hsp_state){ case HSP_W4_RFCOMM_CONNECTED: @@ -590,7 +571,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha hsp_state = HSP_W2_DISCONNECT_RFCOMM; break; default: - printf("no valid state\n"); + log_error("no valid state"); break; } } @@ -600,22 +581,16 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha break; case HCI_EVENT_DISCONNECTION_COMPLETE: - if (hsp_state != HSP_W4_SCO_DISCONNECTED){ - log_info("received gap disconnect in wrong hsp state"); - } handle = READ_BT_16(packet,3); if (handle == sco_handle){ - printf("SCO disconnected, w2 disconnect RFCOMM\n"); + log_info("SCO disconnected, w2 disconnect RFCOMM"); sco_handle = 0; hsp_state = HSP_W2_DISCONNECT_RFCOMM; break; } break; case RFCOMM_EVENT_CHANNEL_CLOSED: - if (hsp_state != HSP_W4_RFCOMM_DISCONNECTED){ - log_info("received RFCOMM disconnect in wrong hsp state"); - } - printf("RFCOMM channel closed\n"); + log_info("RFCOMM channel closed"); hsp_ag_reset_state(); emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0); break; @@ -633,19 +608,19 @@ static void handle_query_rfcomm_event(sdp_query_event_t * event, void * context) case SDP_QUERY_RFCOMM_SERVICE: ve = (sdp_query_rfcomm_service_event_t*) event; channel_nr = ve->channel_nr; - printf("** Service name: '%s', RFCOMM port %u\n", ve->service_name, channel_nr); + log_info("** Service name: '%s', RFCOMM port %u", ve->service_name, channel_nr); break; case SDP_QUERY_COMPLETE: ce = (sdp_query_complete_event_t*) event; if (channel_nr > 0){ hsp_state = HSP_W4_RFCOMM_CONNECTED; - printf("RFCOMM create channel. state %d\n", HSP_W4_RFCOMM_CONNECTED); + log_info("RFCOMM create channel. state %d", HSP_W4_RFCOMM_CONNECTED); rfcomm_create_channel_internal(NULL, remote, channel_nr); break; } hsp_ag_reset_state(); - printf("Service not found, status %u.\n", ce->status); + log_info("Service not found, status %u.", ce->status); if (ce->status){ emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, ce->status); } else { diff --git a/src/hsp_ag.h b/src/hsp_ag.h index 03764290b..7c9646021 100644 --- a/src/hsp_ag.h +++ b/src/hsp_ag.h @@ -37,7 +37,7 @@ // ***************************************************************************** // -// HSP Audio Gateway (!! UNDER DEVELOPMENT !!) +// HSP Audio Gateway // // ***************************************************************************** @@ -53,27 +53,34 @@ extern "C" { #endif typedef void (*hsp_ag_callback_t)(uint8_t * event, uint16_t event_size); -// Register callback (packet handler) for hsp audio gateway -void hsp_ag_register_packet_handler(hsp_ag_callback_t callback); -void hsp_ag_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name); void hsp_ag_init(uint8_t rfcomm_channel_nr); + +void hsp_ag_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name); + +// Register callback (packet handler) for hsp audio gateway +void hsp_ag_register_packet_handler(hsp_ag_callback_t callback); + void hsp_ag_connect(bd_addr_t bd_addr); + void hsp_ag_disconnect(void); // +VGM=[0..15] void hsp_ag_set_microphone_gain(uint8_t gain); + // +VGS=[0..15] void hsp_ag_set_speaker_gain(uint8_t gain); void hsp_ag_start_ringing(void); + void hsp_ag_stop_ringing(void); -void hsp_ag_support_custom_commands(int enable); - -// When support custom commands is enabled, AG will send HSP_SUBEVENT_HS_COMMAND. +// When support custom commands is enabled, AG will emit HSP_SUBEVENT_HS_COMMAND. // On occurance of this event, client's packet handler must send the result back // by calling hsp_ag_send_result function. + +void hsp_ag_enable_custom_commands(int enable); + int hsp_ag_send_result(char * result); #if defined __cplusplus From 294b9a8299761c1e0f7c0cc94489034a8624eabe Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 12 Feb 2016 14:57:38 +0100 Subject: [PATCH 18/26] hsp_hs: code review --- src/hsp_hs.c | 17 +++-------------- src/hsp_hs.h | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/hsp_hs.c b/src/hsp_hs.c index af11eba12..778b62e48 100644 --- a/src/hsp_hs.c +++ b/src/hsp_hs.c @@ -37,7 +37,7 @@ // ***************************************************************************** // -// Minimal setup for HSP Headset (!! UNDER DEVELOPMENT !!) +// HSP Headset // // ***************************************************************************** @@ -155,13 +155,10 @@ static int hsp_hs_send_str_over_rfcomm(uint16_t cid, const char * command){ return err; } -void hsp_hs_support_custom_indications(int enable){ +void hsp_hs_enable_custom_indications(int enable){ hs_support_custom_indications = enable; } -// When support custom commands is enabled, AG will send HSP_SUBEVENT_HS_COMMAND. -// On occurance of this event, client's packet handler must send the result back -// by calling hsp_hs_send_result function. int hsp_hs_send_result(char * result){ if (!hs_support_custom_indications) return 1; return hsp_hs_send_str_over_rfcomm(rfcomm_cid, result); @@ -547,10 +544,6 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha break; case HCI_EVENT_DISCONNECTION_COMPLETE: - printf("HCI_EVENT_DISCONNECTION_COMPLETE \n"); - // if (hsp_state != HSP_W4_SCO_DISCONNECTED){ - // printf("received gap disconnect in wrong hsp state\n"); - // } handle = READ_BT_16(packet,3); if (handle == sco_handle){ sco_handle = 0; @@ -560,10 +553,6 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha } break; case RFCOMM_EVENT_CHANNEL_CLOSED: - printf("RFCOMM_EVENT_CHANNEL_CLOSED\n"); - // if (hsp_state != HSP_W4_RFCOMM_DISCONNECTED){ - // printf("received RFCOMM disconnect in wrong hsp state\n"); - // } printf("RFCOMM channel closed\n"); hsp_hs_reset_state(); emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0); @@ -600,7 +589,7 @@ static void handle_query_rfcomm_event(sdp_query_event_t * event, void * context) } } -void hsp_hs_press_button(void){ +void hsp_hs_send_button_press(void){ hs_send_button_press = 1; hsp_run(); } diff --git a/src/hsp_hs.h b/src/hsp_hs.h index c21d155da..07e0085b7 100644 --- a/src/hsp_hs.h +++ b/src/hsp_hs.h @@ -37,7 +37,7 @@ // ***************************************************************************** // -// HSP Headset (!! UNDER DEVELOPMENT !!) +// HSP Headset // // ***************************************************************************** @@ -53,26 +53,32 @@ extern "C" { #endif typedef void (*hsp_hs_callback_t)(uint8_t * event, uint16_t event_size); -// Register callback (packet handler) for hsp headset -void hsp_hs_register_packet_handler(hsp_hs_callback_t callback); -void hsp_hs_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t have_remote_audio_control); void hsp_hs_init(uint8_t rfcomm_channel_nr); + +void hsp_hs_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t have_remote_audio_control); + +// Register callback (packet handler) for hsp headset +void hsp_hs_register_packet_handler(hsp_hs_callback_t callback); + void hsp_hs_connect(bd_addr_t bd_addr); + void hsp_hs_disconnect(bd_addr_t bd_addr); // AT+VGM=[0..15] void hsp_hs_set_microphone_gain(uint8_t gain); + // AT+VGS=[0..15] void hsp_hs_set_speaker_gain(uint8_t gain); -void hsp_hs_support_custom_indications(int enable); +void hsp_hs_send_button_press(void); -void hsp_hs_press_button(void); - -// When support custom commands is enabled, AG will send HSP_SUBEVENT_AG_INDICATION. +// When support custom indications is enabled, HS will send HSP_SUBEVENT_HS_INDICATION. // On occurance of this event, client's packet handler must send the result back // by calling hsp_hs_send_result function. + +void hsp_hs_enable_custom_indications(int enable); + int hsp_hs_send_result(char * indication); #if defined __cplusplus From bd23fc3eafa33aea6d8bff71a441ea7c93c46515 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 12 Feb 2016 15:36:11 +0100 Subject: [PATCH 19/26] hfp_ag: API review --- example/embedded/hsp_hs_test.c | 2 +- src/hfp_ag.c | 14 +- src/hfp_ag.h | 249 ++++++++++++++------------------- src/hfp_hf.h | 19 ++- src/hsp_ag.c | 2 +- src/hsp_ag.h | 6 +- src/hsp_hs.c | 2 +- src/hsp_hs.h | 2 +- test/pts/hsp_ag_test.c | 2 +- test/pts/hsp_hs_test.c | 2 +- 10 files changed, 137 insertions(+), 163 deletions(-) diff --git a/example/embedded/hsp_hs_test.c b/example/embedded/hsp_hs_test.c index 1cf61bb22..b8f372978 100644 --- a/example/embedded/hsp_hs_test.c +++ b/example/embedded/hsp_hs_test.c @@ -239,7 +239,7 @@ int btstack_main(int argc, const char * argv[]){ sdp_init(); memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer)); - hsp_hs_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_hs_service_name, 0); + hsp_hs_create_sdp_record((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_hs_service_name, 0); sdp_register_service_internal(NULL, (uint8_t *)hsp_service_buffer); diff --git a/src/hfp_ag.c b/src/hfp_ag.c index 5c16a6320..a5f4c84a5 100644 --- a/src/hfp_ag.c +++ b/src/hfp_ag.c @@ -37,7 +37,7 @@ // ***************************************************************************** // -// Minimal setup for HFP Audio Gateway (AG) unit (!! UNDER DEVELOPMENT !!) +// HFP Audio Gateway (AG) unit // // ***************************************************************************** @@ -51,16 +51,16 @@ #include #include -#include "hci.h" #include "btstack_memory.h" -#include "hci_dump.h" -#include "l2cap.h" -#include "sdp_query_rfcomm.h" -#include "sdp.h" #include "debug.h" +#include "hci.h" +#include "hci_dump.h" #include "hfp.h" -#include "hfp_gsm_model.h" #include "hfp_ag.h" +#include "hfp_gsm_model.h" +#include "l2cap.h" +#include "sdp.h" +#include "sdp_query_rfcomm.h" static const char default_hfp_ag_service_name[] = "Voice gateway"; diff --git a/src/hfp_ag.h b/src/hfp_ag.h index 6df0ba6cd..b14982de9 100644 --- a/src/hfp_ag.h +++ b/src/hfp_ag.h @@ -37,7 +37,7 @@ // ***************************************************************************** // -// Minimal setup for HFP Audio Gateway (AG) unit (!! UNDER DEVELOPMENT !!) +// HFP Audio Gateway (AG) unit // // ***************************************************************************** @@ -46,9 +46,7 @@ #define btstack_hfp_ag_h #include "hci.h" -#include "sdp_query_rfcomm.h" #include "hfp.h" -#include "hfp_gsm_model.h" #if defined __cplusplus extern "C" { @@ -80,6 +78,14 @@ void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, */ void hfp_ag_register_packet_handler(hfp_callback_t callback); +/** + * @brief Enable in-band ring tone + */ +void hfp_ag_set_use_in_band_ring_tone(int use_in_band_ring_tone); + + +// actions used by local device / user + /** * @brief Establish RFCOMM connection, and perform service level connection agreement: * - exchange of supported features @@ -93,72 +99,10 @@ void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr); /** * @brief Release the RFCOMM channel and the audio connection between the HF and the AG. - * TODO: trigger release of the audio connection + * TODO: trigger release of the audio connection ?? */ void hfp_ag_release_service_level_connection(bd_addr_t bd_addr); -/** - * @brief Report Extended Audio Gateway Error result codes in the AG. - * Whenever there is an error relating to the functionality of the AG as a - * result of AT command, the AG shall send +CME ERROR: - * - +CME ERROR: 0 - AG failure - * - +CME ERROR: 1 - no connection to phone - * - +CME ERROR: 3 - operation not allowed - * - +CME ERROR: 4 - operation not supported - * - +CME ERROR: 5 - PH-SIM PIN required - * - +CME ERROR: 10 - SIM not inserted - * - +CME ERROR: 11 - SIM PIN required - * - +CME ERROR: 12 - SIM PUK required - * - +CME ERROR: 13 - SIM failure - * - +CME ERROR: 14 - SIM busy - * - +CME ERROR: 16 - incorrect password - * - +CME ERROR: 17 - SIM PIN2 required - * - +CME ERROR: 18 - SIM PUK2 required - * - +CME ERROR: 20 - memory full - * - +CME ERROR: 21 - invalid index - * - +CME ERROR: 23 - memory failure - * - +CME ERROR: 24 - text string too long - * - +CME ERROR: 25 - invalid characters in text string - * - +CME ERROR: 26 - dial string too long - * - +CME ERROR: 27 - invalid characters in dial string - * - +CME ERROR: 30 - no network service - * - +CME ERROR: 31 - network Timeout. - * - +CME ERROR: 32 - network not allowed – Emergency calls only - */ -void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error); - -/** - * @brief Report the change in AG's call status. - * Call status: - * - 0 = No calls (held or active) - * - 1 = Call is present (active or held) - */ -void hfp_ag_transfer_call_status(bd_addr_t bd_addr, hfp_call_status_t status); - -/** - * @brief Report the change in AG's call setup status. - * Call setup status: - * - 0 = No call setup in progress - * - 1 = Incoming call setup in progress - * - 2 = Outgoing call setup in dialing state - * - 3 = Outgoing call setup in alerting state - */ -void hfp_ag_transfer_callsetup_status(bd_addr_t bd_addr, hfp_callsetup_status_t status); - -/** - * @brief Report the change in AG's held call status. - * Held call status: - * - 0 = No calls held - * - 1 = Call is placed on hold or active/held calls are swapped - * - 2 = Call on hold, no active calls - */ -void hfp_ag_transfer_callheld_status(bd_addr_t bd_addr, hfp_callheld_status_t status); - -/** - * @brief - */ -void hfp_ag_negotiate_codecs(bd_addr_t bd_addr); - /** * @brief */ @@ -169,11 +113,76 @@ void hfp_ag_establish_audio_connection(bd_addr_t bd_addr); */ void hfp_ag_release_audio_connection(bd_addr_t bd_addr); +/** + * @brief + */ +void hfp_ag_answer_incoming_call(void); /** - * @brief Enable in-band ring tone + * @brief */ -void hfp_ag_set_use_in_band_ring_tone(int use_in_band_ring_tone); +void hfp_ag_join_held_call(void); + +/** + * @brief + */ +void hfp_ag_terminate_call(void); + +/* + * @brief + */ +void hfp_ag_hold_incoming_call(void); + +/* + * @brief + */ +void hfp_ag_accept_held_incoming_call(void); + +/* + * @brief + */ +void hfp_ag_reject_held_incoming_call(void); + +/* + * @brief + */ +void hfp_ag_set_microphone_gain(bd_addr_t bd_addr, int gain); + +/* + * @brief + */ +void hfp_ag_set_speaker_gain(bd_addr_t bd_addr, int gain); + +/* + * @brief + */ +void hfp_ag_set_battery_level(int level); + +/* + * @brief + */ +void hfp_ag_clear_last_dialed_number(void); + + +// Voice Recognition + +/* + * @brief + */ +void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate); + +/* + * @brief + */ +void hfp_ag_send_phone_number_for_voice_tag(bd_addr_t bd_addr, const char * number); + +/* + * @brief + */ +void hfp_ag_reject_phone_number_for_voice_tag(bd_addr_t bd_addr); + + +// Cellular Actions /** * @brief @@ -209,22 +218,6 @@ void hfp_ag_outgoing_call_established(void); * @brief */ void hfp_ag_call_dropped(void); - -/** - * @brief - */ -void hfp_ag_answer_incoming_call(void); - -/** - * @brief - */ -void hfp_ag_join_held_call(void); - -/** - * @brief - */ -void hfp_ag_terminate_call(void); - /* * @brief */ @@ -240,75 +233,49 @@ void hfp_ag_set_signal_strength(int strength); */ void hfp_ag_set_roaming_status(int status); -/* - * @brief - */ -void hfp_ag_set_battery_level(int level); - - -/* - * @brief - */ -void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate); - -/* - * @brief - */ -void hfp_ag_set_microphone_gain(bd_addr_t bd_addr, int gain); - -/* - * @brief - */ -void hfp_ag_set_speaker_gain(bd_addr_t bd_addr, int gain); - -/* - * @brief - */ -void hfp_ag_send_phone_number_for_voice_tag(bd_addr_t bd_addr, const char * number); - -/* - * @brief - */ -void hfp_ag_reject_phone_number_for_voice_tag(bd_addr_t bd_addr); - -/* - * @brief - */ -void hfp_ag_send_dtmf_code_done(bd_addr_t bd_addr); - /* * @brief */ void hfp_ag_set_subcriber_number_information(hfp_phone_number_t * numbers, int numbers_count); /* - * @brief + * @brief Called by cellular unit after a DTMF code was transmitted, so that the next one can be emitted */ +void hfp_ag_send_dtmf_code_done(bd_addr_t bd_addr); -void hfp_ag_send_current_call_status(bd_addr_t bd_addr, int idx); - -/* - * @brief +/** + * @brief Report Extended Audio Gateway Error result codes in the AG. + * Whenever there is an error relating to the functionality of the AG as a + * result of AT command, the AG shall send +CME ERROR: + * - +CME ERROR: 0 - AG failure + * - +CME ERROR: 1 - no connection to phone + * - +CME ERROR: 3 - operation not allowed + * - +CME ERROR: 4 - operation not supported + * - +CME ERROR: 5 - PH-SIM PIN required + * - +CME ERROR: 10 - SIM not inserted + * - +CME ERROR: 11 - SIM PIN required + * - +CME ERROR: 12 - SIM PUK required + * - +CME ERROR: 13 - SIM failure + * - +CME ERROR: 14 - SIM busy + * - +CME ERROR: 16 - incorrect password + * - +CME ERROR: 17 - SIM PIN2 required + * - +CME ERROR: 18 - SIM PUK2 required + * - +CME ERROR: 20 - memory full + * - +CME ERROR: 21 - invalid index + * - +CME ERROR: 23 - memory failure + * - +CME ERROR: 24 - text string too long + * - +CME ERROR: 25 - invalid characters in text string + * - +CME ERROR: 26 - dial string too long + * - +CME ERROR: 27 - invalid characters in dial string + * - +CME ERROR: 30 - no network service + * - +CME ERROR: 31 - network Timeout. + * - +CME ERROR: 32 - network not allowed – Emergency calls only */ -void hfp_ag_hold_incoming_call(void); - -/* - * @brief - */ -void hfp_ag_accept_held_incoming_call(void); - -/* - * @brief - */ -void hfp_ag_reject_held_incoming_call(void); - -/* - * @brief - */ -void hfp_ag_clear_last_dialed_number(void); +void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error); /* API_END */ + #if defined __cplusplus } #endif diff --git a/src/hfp_hf.h b/src/hfp_hf.h index 5e764e50f..a9393c06d 100644 --- a/src/hfp_hf.h +++ b/src/hfp_hf.h @@ -37,13 +37,13 @@ // ***************************************************************************** // -// Minimal setup for HFP Hands-Free (HF) unit (!! UNDER DEVELOPMENT !!) +// HFP Hands-Free (HF) unit // // ***************************************************************************** -#ifndef btstack_hfp_hf_h -#define btstack_hfp_hf_h +#ifndef __BTSTACK_HFP_HF_H +#define __BTSTACK_HFP_HF_H #include "hci.h" #include "sdp_query_rfcomm.h" @@ -55,7 +55,6 @@ extern "C" { /* API_START */ - /** * @brief Create HFP Hands-Free (HF) SDP service record. */ @@ -66,8 +65,11 @@ void hfp_hf_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const ch * TODO: move optional params into setters */ void hfp_hf_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint16_t * indicators, int indicators_nr, uint32_t indicators_status); + void hfp_hf_set_codecs(uint8_t * codecs, int codecs_nr); +void hfp_hf_set_supported_features(uint32_t supported_features); + /** * @brief Register callback for the HFP Hands-Free (HF) client. */ @@ -83,7 +85,6 @@ void hfp_hf_register_packet_handler(hfp_callback_t callback); * - retrieve which HF indicators are enabled on the AG, if possible */ void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr); -void hfp_hf_set_supported_features(uint32_t supported_features); /** * @brief Release the RFCOMM channel and the audio connection between the HF and the AG. @@ -95,6 +96,7 @@ void hfp_hf_release_service_level_connection(bd_addr_t bd_addr); * @brief Deactivate/reactivate status update for all indicators in the AG. */ void hfp_hf_enable_status_update_for_all_ag_indicators(bd_addr_t bd_addr); + void hfp_hf_disable_status_update_for_all_ag_indicators(bd_addr_t bd_addr); /** @@ -106,6 +108,8 @@ void hfp_hf_set_status_update_for_individual_ag_indicators(bd_addr_t bd_addr, ui /** * @brief Find out the name of the currently selected Network operator by AG. * The name is restricted to max 16 characters. + * + * TODO: what is the result of this? */ void hfp_hf_query_operator_selection(bd_addr_t bd_addr); @@ -196,7 +200,8 @@ void hfp_hf_terminate_call(bd_addr_t bd_addr); void hfp_hf_dial_number(bd_addr_t bd_addr, char * number); /** - * @brief + * @brief + * TODO: use int for number instead of string? */ void hfp_hf_dial_memory(bd_addr_t bd_addr, char * number); @@ -317,4 +322,4 @@ void hfp_hf_set_hf_indicator(bd_addr_t addr, int assigned_number, int value); } #endif -#endif \ No newline at end of file +#endif // __BTSTACK_HFP_HF_H \ No newline at end of file diff --git a/src/hsp_ag.c b/src/hsp_ag.c index fbe24d502..128c13eaf 100644 --- a/src/hsp_ag.c +++ b/src/hsp_ag.c @@ -146,7 +146,7 @@ static void emit_event_audio_connected(uint8_t status, uint16_t handle){ (*hsp_hs_callback)(event, sizeof(event)); } -void hsp_ag_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name){ +void hsp_ag_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name){ uint8_t* attribute; de_create_sequence(service); diff --git a/src/hsp_ag.h b/src/hsp_ag.h index 7c9646021..9f72d68a9 100644 --- a/src/hsp_ag.h +++ b/src/hsp_ag.h @@ -54,9 +54,11 @@ extern "C" { typedef void (*hsp_ag_callback_t)(uint8_t * event, uint16_t event_size); -void hsp_ag_init(uint8_t rfcomm_channel_nr); -void hsp_ag_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name); +void hsp_ag_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name); + + +void hsp_ag_init(uint8_t rfcomm_channel_nr); // Register callback (packet handler) for hsp audio gateway void hsp_ag_register_packet_handler(hsp_ag_callback_t callback); diff --git a/src/hsp_hs.c b/src/hsp_hs.c index 778b62e48..f55cc27c6 100644 --- a/src/hsp_hs.c +++ b/src/hsp_hs.c @@ -165,7 +165,7 @@ int hsp_hs_send_result(char * result){ } -void hsp_hs_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t have_remote_audio_control){ +void hsp_hs_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t have_remote_audio_control){ uint8_t* attribute; de_create_sequence(service); diff --git a/src/hsp_hs.h b/src/hsp_hs.h index 07e0085b7..4f54ac892 100644 --- a/src/hsp_hs.h +++ b/src/hsp_hs.h @@ -56,7 +56,7 @@ typedef void (*hsp_hs_callback_t)(uint8_t * event, uint16_t event_size); void hsp_hs_init(uint8_t rfcomm_channel_nr); -void hsp_hs_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t have_remote_audio_control); +void hsp_hs_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t have_remote_audio_control); // Register callback (packet handler) for hsp headset void hsp_hs_register_packet_handler(hsp_hs_callback_t callback); diff --git a/test/pts/hsp_ag_test.c b/test/pts/hsp_ag_test.c index b7964b015..d9ea3f03a 100644 --- a/test/pts/hsp_ag_test.c +++ b/test/pts/hsp_ag_test.c @@ -186,7 +186,7 @@ int btstack_main(int argc, const char * argv[]); int btstack_main(int argc, const char * argv[]){ // init SDP, create record for SPP and register with SDP memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer)); - hsp_ag_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_ag_service_name); + hsp_ag_create_sdp_record((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_ag_service_name); hsp_ag_init(rfcomm_channel_nr); hsp_ag_register_packet_handler(packet_handler); diff --git a/test/pts/hsp_hs_test.c b/test/pts/hsp_hs_test.c index a52de2809..d25f8d019 100644 --- a/test/pts/hsp_hs_test.c +++ b/test/pts/hsp_hs_test.c @@ -317,7 +317,7 @@ int btstack_main(int argc, const char * argv[]){ hci_register_sco_packet_handler(&sco_packet_handler); memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer)); - hsp_hs_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_hs_service_name, 0); + hsp_hs_create_sdp_record((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_hs_service_name, 0); hsp_hs_init(rfcomm_channel_nr); hsp_hs_register_packet_handler(packet_handler); From e33e86d340c4e0eb6f77d703db138bf5da985838 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 15:44:43 +0100 Subject: [PATCH 20/26] fix compile --- src/hsp_ag.c | 4 ++-- test/pts/hsp_hs_test.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hsp_ag.c b/src/hsp_ag.c index 128c13eaf..ec0169f2c 100644 --- a/src/hsp_ag.c +++ b/src/hsp_ag.c @@ -136,14 +136,14 @@ static void emit_event(uint8_t event_subtype, uint8_t value){ } static void emit_event_audio_connected(uint8_t status, uint16_t handle){ - if (!hsp_hs_callback) return; + if (!hsp_ag_callback) return; uint8_t event[6]; event[0] = HCI_EVENT_HSP_META; event[1] = sizeof(event) - 2; event[2] = HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE; event[3] = status; bt_store_16(event, 4, handle); - (*hsp_hs_callback)(event, sizeof(event)); + (*hsp_ag_callback)(event, sizeof(event)); } void hsp_ag_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name){ diff --git a/test/pts/hsp_hs_test.c b/test/pts/hsp_hs_test.c index d25f8d019..7fe04ffd6 100644 --- a/test/pts/hsp_hs_test.c +++ b/test/pts/hsp_hs_test.c @@ -203,7 +203,7 @@ static int stdin_process(struct data_source *ds){ break; case 'b': printf("Press user button\n"); - hsp_hs_press_button(); + hsp_hs_send_button_press(); break; default: show_usage(); From d4d01b595dbc7dbb842983252928e2b610bb864c Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Feb 2016 17:25:06 +0100 Subject: [PATCH 21/26] hsp hs api docu --- src/hsp_hs.c | 2 +- src/hsp_hs.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/hsp_hs.c b/src/hsp_hs.c index f55cc27c6..2a6883d12 100644 --- a/src/hsp_hs.c +++ b/src/hsp_hs.c @@ -159,7 +159,7 @@ void hsp_hs_enable_custom_indications(int enable){ hs_support_custom_indications = enable; } -int hsp_hs_send_result(char * result){ +int hsp_hs_send_result(const char * result){ if (!hs_support_custom_indications) return 1; return hsp_hs_send_str_over_rfcomm(rfcomm_cid, result); } diff --git a/src/hsp_hs.h b/src/hsp_hs.h index 4f54ac892..914fa400c 100644 --- a/src/hsp_hs.h +++ b/src/hsp_hs.h @@ -52,34 +52,94 @@ extern "C" { #endif +/* API_START */ + +/** + * @brief Packet handler for HSP Headset (HS) events. The HSP HS event has type HCI_EVENT_HSP_META with following subtypes: + * - HSP_SUBEVENT_ERROR + * - HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE + * - HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE + * - HSP_SUBEVENT_RING + * - HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED + * - HSP_SUBEVENT_SPEAKER_GAIN_CHANGED + * - HSP_SUBEVENT_AG_INDICATION + */ typedef void (*hsp_hs_callback_t)(uint8_t * event, uint16_t event_size); +/** + * @brief Set up HSP HS + * @param rfcomm_channel_nr + */ void hsp_hs_init(uint8_t rfcomm_channel_nr); +/** + * @brief Create HSP Headset (HS) SDP service record. have_remote_audio_control? + */ void hsp_hs_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t have_remote_audio_control); -// Register callback (packet handler) for hsp headset +/** + * @brief Register packet handler to receive HSP HS events. + */ void hsp_hs_register_packet_handler(hsp_hs_callback_t callback); +/** + * @brief Connect to HSP Audio Gateway + * + * Perform SDP query for an RFCOMM service on a remote device, + * and establish an RFCOMM connection if such service is found. The reception of the + * HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE or + * HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE event + * indicate if the connection is successfully established or not. + */ void hsp_hs_connect(bd_addr_t bd_addr); +/** + * @brief Disconnect from HSP Audio Gateway + * + * Releases the RFCOMM channel. + */ void hsp_hs_disconnect(bd_addr_t bd_addr); -// AT+VGM=[0..15] +/** + * @brief Set microphone gain. + * + * The new gain value will be confirmed by the HSP Audio Gateway. + * A HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED event will be received. + * @param gain - valid range: [0,15] + */ void hsp_hs_set_microphone_gain(uint8_t gain); -// AT+VGS=[0..15] +/** + * @brief Set speaker gain. + * + * The new gain value will be confirmed by the HSP Audio Gateway. + * A HSP_SUBEVENT_SPEAKER_GAIN_CHANGED event will be received. + * @param gain - valid range: [0,15] + */ void hsp_hs_set_speaker_gain(uint8_t gain); +/** + * @brief Send button press action. + */ void hsp_hs_send_button_press(void); -// When support custom indications is enabled, HS will send HSP_SUBEVENT_HS_INDICATION. -// On occurance of this event, client's packet handler must send the result back -// by calling hsp_hs_send_result function. - +/** + * @brief Enable custom indications + * + * Custom indications are disable by default. + * When enabled, custom indications are received via the HSP_SUBEVENT_AG_INDICATION. + */ void hsp_hs_enable_custom_indications(int enable); -int hsp_hs_send_result(char * indication); +/** + * @brief Send answer to custom command + * + * On HSP_SUBEVENT_AG_INDICATION, the client needs to respond + * with this function with the result to the custom indication + */ +int hsp_hs_send_result(const char * indication); + +/* API_END */ #if defined __cplusplus } From 25ad7c220c101bfc12c3a4773fae29d6ae9b4d26 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 15 Feb 2016 14:07:37 +0100 Subject: [PATCH 22/26] libusb: use & operator for function pointers --- platforms/posix/src/hci_transport_h2_libusb.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/platforms/posix/src/hci_transport_h2_libusb.c b/platforms/posix/src/hci_transport_h2_libusb.c index 5a117004e..8bd8b0834 100644 --- a/platforms/posix/src/hci_transport_h2_libusb.c +++ b/platforms/posix/src/hci_transport_h2_libusb.c @@ -256,7 +256,7 @@ static int usb_send_sco_packet(uint8_t *packet, int size){ // setup transfer struct libusb_transfer * sco_transfer = sco_ring_transfers[tranfer_index]; - libusb_fill_iso_transfer(sco_transfer, handle, sco_out_addr, data, size, NUM_ISO_PACKETS, async_callback, NULL, 0); + libusb_fill_iso_transfer(sco_transfer, handle, sco_out_addr, data, size, NUM_ISO_PACKETS, &async_callback, NULL, 0); libusb_set_iso_packet_lengths(sco_transfer, ISO_PACKET_SIZE); r = libusb_submit_transfer(sco_transfer); if (r < 0) { @@ -769,7 +769,7 @@ static int usb_open(void *transport_config){ } // configure sco_in handlers libusb_fill_iso_transfer(sco_in_transfer[c], handle, sco_in_addr, - hci_sco_in_buffer[c], SCO_PACKET_SIZE, NUM_ISO_PACKETS, async_callback, NULL, 0); + hci_sco_in_buffer[c], SCO_PACKET_SIZE, NUM_ISO_PACKETS, &async_callback, NULL, 0); libusb_set_iso_packet_lengths(sco_in_transfer[c], ISO_PACKET_SIZE); r = libusb_submit_transfer(sco_in_transfer[c]); log_info("Submit iso transfer res = %d", r); @@ -789,7 +789,7 @@ static int usb_open(void *transport_config){ for (c = 0 ; c < ASYNC_BUFFERS ; c++) { // configure event_in handlers libusb_fill_interrupt_transfer(event_in_transfer[c], handle, event_in_addr, - hci_event_in_buffer[c], HCI_ACL_BUFFER_SIZE, async_callback, NULL, 0) ; + hci_event_in_buffer[c], HCI_ACL_BUFFER_SIZE, &async_callback, NULL, 0) ; r = libusb_submit_transfer(event_in_transfer[c]); if (r) { log_error("Error submitting interrupt transfer %d", r); @@ -799,7 +799,7 @@ static int usb_open(void *transport_config){ // configure acl_in handlers libusb_fill_bulk_transfer(acl_in_transfer[c], handle, acl_in_addr, - hci_acl_in_buffer[c] + HCI_INCOMING_PRE_BUFFER_SIZE, HCI_ACL_BUFFER_SIZE, async_callback, NULL, 0) ; + hci_acl_in_buffer[c] + HCI_INCOMING_PRE_BUFFER_SIZE, HCI_ACL_BUFFER_SIZE, &async_callback, NULL, 0) ; r = libusb_submit_transfer(acl_in_transfer[c]); if (r) { log_error("Error submitting bulk in transfer %d", r); @@ -926,7 +926,7 @@ static int usb_send_cmd_packet(uint8_t *packet, int size){ // prepare transfer int completed = 0; - libusb_fill_control_transfer(command_out_transfer, handle, hci_cmd_buffer, async_callback, &completed, 0); + libusb_fill_control_transfer(command_out_transfer, handle, hci_cmd_buffer, &async_callback, &completed, 0); command_out_transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; // update stata before submitting transfer @@ -953,8 +953,7 @@ static int usb_send_acl_packet(uint8_t *packet, int size){ // prepare transfer int completed = 0; - libusb_fill_bulk_transfer(acl_out_transfer, handle, acl_out_addr, packet, size, - async_callback, &completed, 0); + libusb_fill_bulk_transfer(acl_out_transfer, handle, acl_out_addr, packet, size, &async_callback, &completed, 0); acl_out_transfer->type = LIBUSB_TRANSFER_TYPE_BULK; // update stata before submitting transfer From b2faedc9fab1c1a0afaadefb3b47290c98f32edd Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 15 Feb 2016 14:29:20 +0100 Subject: [PATCH 23/26] libusb: fix compile on win32 --- platforms/posix/src/hci_transport_h2_libusb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platforms/posix/src/hci_transport_h2_libusb.c b/platforms/posix/src/hci_transport_h2_libusb.c index 8bd8b0834..b743ca1ab 100644 --- a/platforms/posix/src/hci_transport_h2_libusb.c +++ b/platforms/posix/src/hci_transport_h2_libusb.c @@ -211,8 +211,9 @@ static void queue_transfer(struct libusb_transfer *transfer){ temp->user_data = transfer; } -static void async_callback(struct libusb_transfer *transfer) -{ +// LIBUSB_CALL is needed on WIN32 (and resolveds to nothing on other platforms) +static void LIBUSB_CALL async_callback(struct libusb_transfer *transfer) { + if (libusb_state != LIB_USB_TRANSFERS_ALLOCATED) return; int r; // log_info("begin async_callback endpoint %x, status %x, actual length %u", transfer->endpoint, transfer->status, transfer->actual_length ); From c9b5173dc5e4ec48971a7d7aeee60a606c0ed554 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 15 Feb 2016 21:01:31 +0100 Subject: [PATCH 24/26] libubs: fix compile without SCO --- platforms/posix/src/hci_transport_h2_libusb.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/platforms/posix/src/hci_transport_h2_libusb.c b/platforms/posix/src/hci_transport_h2_libusb.c index b743ca1ab..0a9c28ca0 100644 --- a/platforms/posix/src/hci_transport_h2_libusb.c +++ b/platforms/posix/src/hci_transport_h2_libusb.c @@ -179,17 +179,21 @@ static int acl_out_addr; static int sco_in_addr; static int sco_out_addr; - +#ifdef HAVE_SCO static void sco_ring_init(void){ sco_ring_write = 0; sco_ring_transfers_active = 0; } +#endif static int sco_ring_have_space(void){ +#ifdef HAVE_SCO return sco_ring_transfers_active < SCO_RING_BUFFER_COUNT; +#else + return 0; +#endif } - // static void queue_transfer(struct libusb_transfer *transfer){ @@ -283,6 +287,7 @@ static int usb_send_sco_packet(uint8_t *packet, int size){ return 0; } +#ifdef HAVE_SCO static void sco_state_machine_init(void){ sco_state = H2_W4_SCO_HEADER; sco_read_pos = 0; @@ -318,6 +323,7 @@ static void handle_isochronous_data(uint8_t * buffer, uint16_t size){ } } } +#endif static void handle_completed_transfer(struct libusb_transfer *transfer){ @@ -332,6 +338,7 @@ static void handle_completed_transfer(struct libusb_transfer *transfer){ packet_handler(HCI_ACL_DATA_PACKET, transfer-> buffer, transfer->actual_length); resubmit = 1; } else if (transfer->endpoint == sco_in_addr) { +#ifdef HAVE_SCO // log_info("handle_completed_transfer for SCO IN! num packets %u", transfer->NUM_ISO_PACKETS); int i; for (i = 0; i < transfer->num_iso_packets; i++) { @@ -347,6 +354,7 @@ static void handle_completed_transfer(struct libusb_transfer *transfer){ handle_isochronous_data(data, pack->actual_length); } resubmit = 1; +#endif } else if (transfer->endpoint == 0){ // log_info("command done, size %u", transfer->actual_length); usb_command_active = 0; @@ -356,6 +364,7 @@ static void handle_completed_transfer(struct libusb_transfer *transfer){ usb_acl_out_active = 0; signal_done = 1; } else if (transfer->endpoint == sco_out_addr){ +#ifdef HAVE_SCO log_info("sco out done, {{ %u/%u (%x)}, { %u/%u (%x)}, { %u/%u (%x)}}", transfer->iso_packet_desc[0].actual_length, transfer->iso_packet_desc[0].length, transfer->iso_packet_desc[0].status, transfer->iso_packet_desc[1].actual_length, transfer->iso_packet_desc[1].length, transfer->iso_packet_desc[1].status, @@ -367,6 +376,7 @@ static void handle_completed_transfer(struct libusb_transfer *transfer){ // decrease tab sco_ring_transfers_active--; // log_info("H2: sco out complete, num active num active %u", sco_ring_transfers_active); +#endif } else { log_info("usb_process_ds endpoint unknown %x", transfer->endpoint); } @@ -634,8 +644,10 @@ static int prepare_device(libusb_device_handle * aHandle){ static int usb_open(void *transport_config){ int r; +#ifdef HAVE_SCO sco_state_machine_init(); sco_ring_init(); +#endif handle_packet = NULL; // default endpoint addresses From e50ca9fbb85287b970cfeefed3a21492fca7eddf Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 15 Feb 2016 21:07:35 +0100 Subject: [PATCH 25/26] examples: delete .exe on make clean --- example/embedded/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/embedded/Makefile.inc b/example/embedded/Makefile.inc index 28fb766c6..3a78804df 100644 --- a/example/embedded/Makefile.inc +++ b/example/embedded/Makefile.inc @@ -173,7 +173,7 @@ hsp_hs_test: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} hsp_hs.o hsp_hs_test.c clean: rm -f ${EXAMPLES} - rm -f *.o *.out *.hex + rm -f *.o *.out *.hex *.exe rm -f ${BTSTACK_ROOT}/include/btstack/version.h rm -f ancs_client.h profile.h spp_and_le_counter.h rm -rf *.dSYM From 042a40aaa542a4ed1e1a3c588d42d70bb5a1cd00 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 15 Feb 2016 21:49:39 +0100 Subject: [PATCH 26/26] libusb: #error with HAVE_SCO on Win32 --- platforms/posix/src/hci_transport_h2_libusb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platforms/posix/src/hci_transport_h2_libusb.c b/platforms/posix/src/hci_transport_h2_libusb.c index 0a9c28ca0..1d5091039 100644 --- a/platforms/posix/src/hci_transport_h2_libusb.c +++ b/platforms/posix/src/hci_transport_h2_libusb.c @@ -138,6 +138,10 @@ static struct libusb_transfer *acl_in_transfer[ASYNC_BUFFERS]; #ifdef HAVE_SCO +#ifdef _WIN32 +#error "SCO not working on Win32 (Windows 8, libusb 1.0.19, Zadic WinUSB), please uncomment HAVE_SCO in btstack-config.h for now" +#endif + // incoming SCO static H2_SCO_STATE sco_state; static uint8_t sco_buffer[255+3 + SCO_PACKET_SIZE];