mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-25 18:35:17 +00:00
Merge branch 'master' of https://github.com/bluekitchen/btstack
This commit is contained in:
commit
9eeb95b810
@ -420,7 +420,7 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
||||
|
||||
switch (context->parser_state){
|
||||
case HFP_PARSER_CMD_HEADER: // header
|
||||
if (byte == ':'){
|
||||
if (byte == ':' || byte == '='){
|
||||
context->parser_state = HFP_PARSER_CMD_SEQUENCE;
|
||||
context->line_buffer[context->line_size] = 0;
|
||||
context->line_size = 0;
|
||||
@ -459,7 +459,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
||||
printf("AG supported feature: %s\n", hfp_ag_feature(i));
|
||||
}
|
||||
}
|
||||
context->command = HFP_CMD_NONE;
|
||||
context->parser_state = HFP_PARSER_CMD_HEADER;
|
||||
break;
|
||||
case HFP_W4_RETRIEVE_INDICATORS:
|
||||
@ -481,12 +480,10 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
||||
break;
|
||||
}
|
||||
if (byte == '\n' || byte == '\r'){
|
||||
context->command = HFP_CMD_NONE;
|
||||
context->parser_state = HFP_PARSER_CMD_HEADER;
|
||||
break;
|
||||
}
|
||||
if (byte == ')' && context->state == HFP_W4_RETRIEVE_CAN_HOLD_CALL){ // tuple separated mit comma
|
||||
context->command = HFP_CMD_NONE;
|
||||
context->parser_state = HFP_PARSER_CMD_HEADER;
|
||||
break;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ typedef enum {
|
||||
HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS, // 20
|
||||
HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS,
|
||||
|
||||
HFP_ACTIVE,
|
||||
HFP_ACTIVE, // 22
|
||||
HFP_W2_DISCONNECT_RFCOMM,
|
||||
HFP_W4_RFCOMM_DISCONNECTED,
|
||||
HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN
|
||||
|
221
src/hfp_ag.c
221
src/hfp_ag.c
@ -112,15 +112,15 @@ void hfp_ag_create_service(uint8_t * service, int rfcomm_channel_nr, const char
|
||||
}
|
||||
|
||||
int hfp_ag_exchange_supported_features_cmd(uint16_t cid){
|
||||
char buffer[20];
|
||||
sprintf(buffer, "%s=%d\r\nOK\r\n", HFP_SUPPORTED_FEATURES, hfp_supported_features);
|
||||
char buffer[40];
|
||||
sprintf(buffer, "\r\n%s:%d\r\n\r\nOK\r\n", HFP_SUPPORTED_FEATURES, hfp_supported_features);
|
||||
// printf("exchange_supported_features %s\n", buffer);
|
||||
return send_str_over_rfcomm(cid, buffer);
|
||||
}
|
||||
|
||||
int hfp_ag_ok(uint16_t cid){
|
||||
char buffer[5];
|
||||
sprintf(buffer, "OK\r\n");
|
||||
char buffer[10];
|
||||
sprintf(buffer, "\r\nOK\r\n");
|
||||
return send_str_over_rfcomm(cid, buffer);
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ int hfp_hf_indicators_initial_status_join(char * buffer, int buffer_size){
|
||||
int i;
|
||||
int offset = 0;
|
||||
for (i = 0; i < hfp_hf_indicators_nr; i++) {
|
||||
offset += snprintf(buffer+offset, buffer_size-offset, "%s=%d,%d\r\n", HFP_GENERIC_STATUS_INDICATOR, hfp_hf_indicators[i].uuid, hfp_hf_indicators[i].initial_state);
|
||||
offset += snprintf(buffer+offset, buffer_size-offset, "\r\n%s:%d,%d\r\n", HFP_GENERIC_STATUS_INDICATOR, hfp_hf_indicators[i].uuid, hfp_hf_indicators[i].initial_state);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
@ -192,33 +192,33 @@ int hfp_ag_call_services_join(char * buffer, int buffer_size){
|
||||
|
||||
int hfp_ag_retrieve_indicators_cmd(uint16_t cid){
|
||||
char buffer[150];
|
||||
int offset = snprintf(buffer, sizeof(buffer), "%s=", HFP_INDICATOR);
|
||||
int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_INDICATOR);
|
||||
offset += hfp_ag_indicators_join(buffer+offset, sizeof(buffer)-offset);
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\nOK\r\n");
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n");
|
||||
buffer[offset] = 0;
|
||||
return send_str_over_rfcomm(cid, buffer);
|
||||
}
|
||||
|
||||
int hfp_ag_retrieve_indicators_status_cmd(uint16_t cid){
|
||||
char buffer[20];
|
||||
int offset = snprintf(buffer, sizeof(buffer), "%s=", HFP_INDICATOR);
|
||||
char buffer[40];
|
||||
int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_INDICATOR);
|
||||
offset += hfp_ag_indicators_status_join(buffer+offset, sizeof(buffer)-offset);
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\nOK\r\n");
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n");
|
||||
buffer[offset] = 0;
|
||||
return send_str_over_rfcomm(cid, buffer);
|
||||
}
|
||||
|
||||
int hfp_ag_toggle_indicator_status_update_cmd(uint16_t cid, uint8_t activate){
|
||||
// AT%s=3,0,0,%d\r\n
|
||||
// AT\r\n%s:3,0,0,%d\r\n
|
||||
return hfp_ag_ok(cid);
|
||||
}
|
||||
|
||||
|
||||
int hfp_ag_retrieve_can_hold_call_cmd(uint16_t cid){
|
||||
char buffer[20];
|
||||
int offset = snprintf(buffer, sizeof(buffer), "%s=", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES);
|
||||
char buffer[100];
|
||||
int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES);
|
||||
offset += hfp_ag_call_services_join(buffer+offset, sizeof(buffer)-offset);
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\nOK\r\n");
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n");
|
||||
buffer[offset] = 0;
|
||||
return send_str_over_rfcomm(cid, buffer);
|
||||
}
|
||||
@ -229,73 +229,22 @@ int hfp_ag_list_supported_generic_status_indicators_cmd(uint16_t cid){
|
||||
}
|
||||
|
||||
int hfp_ag_retrieve_supported_generic_status_indicators_cmd(uint16_t cid){
|
||||
char buffer[30];
|
||||
int offset = snprintf(buffer, sizeof(buffer), "%s=", HFP_GENERIC_STATUS_INDICATOR);
|
||||
char buffer[40];
|
||||
int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_GENERIC_STATUS_INDICATOR);
|
||||
offset += hfp_hf_indicators_join(buffer+offset, sizeof(buffer)-offset);
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n");
|
||||
buffer[offset] = 0;
|
||||
return send_str_over_rfcomm(cid, buffer);
|
||||
}
|
||||
|
||||
int hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(uint16_t cid){
|
||||
char buffer[40];
|
||||
int offset = hfp_hf_indicators_initial_status_join(buffer, sizeof(buffer));
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\nOK\r\n");
|
||||
buffer[offset] = 0;
|
||||
return send_str_over_rfcomm(cid, buffer);
|
||||
}
|
||||
|
||||
int hfp_ag_list_initital_supported_generic_status_indicators_cmd(uint16_t cid){
|
||||
char buffer[30];
|
||||
int offset = hfp_hf_indicators_initial_status_join(buffer, sizeof(buffer));
|
||||
offset += snprintf(buffer+offset, sizeof(buffer)-offset, "OK\r\n");
|
||||
buffer[offset] = 0;
|
||||
return send_str_over_rfcomm(cid, buffer);
|
||||
}
|
||||
|
||||
|
||||
static void hfp_run_for_context(hfp_connection_t * connection){
|
||||
if (!connection) return;
|
||||
// printf("hfp send cmd: context %p, RFCOMM cid %u \n", connection, connection->rfcomm_cid );
|
||||
if (!rfcomm_can_send_packet_now(connection->rfcomm_cid)) return;
|
||||
|
||||
switch (connection->state){
|
||||
case HFP_EXCHANGE_SUPPORTED_FEATURES:
|
||||
hfp_ag_exchange_supported_features_cmd(connection->rfcomm_cid);
|
||||
connection->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES;
|
||||
break;
|
||||
case HFP_NOTIFY_ON_CODECS:
|
||||
hfp_ag_retrieve_codec_cmd(connection->rfcomm_cid);
|
||||
connection->state = HFP_W4_NOTIFY_ON_CODECS;
|
||||
break;
|
||||
case HFP_RETRIEVE_INDICATORS:
|
||||
hfp_ag_retrieve_indicators_cmd(connection->rfcomm_cid);
|
||||
connection->state = HFP_W4_RETRIEVE_INDICATORS;
|
||||
break;
|
||||
case HFP_RETRIEVE_INDICATORS_STATUS:
|
||||
hfp_ag_retrieve_indicators_status_cmd(connection->rfcomm_cid);
|
||||
connection->state = HFP_W4_RETRIEVE_INDICATORS_STATUS;
|
||||
break;
|
||||
case HFP_ENABLE_INDICATORS_STATUS_UPDATE:
|
||||
hfp_ag_toggle_indicator_status_update_cmd(connection->rfcomm_cid, 1);
|
||||
connection->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE;
|
||||
break;
|
||||
case HFP_RETRIEVE_CAN_HOLD_CALL:
|
||||
hfp_ag_retrieve_can_hold_call_cmd(connection->rfcomm_cid);
|
||||
connection->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL;
|
||||
break;
|
||||
case HFP_LIST_GENERIC_STATUS_INDICATORS:
|
||||
hfp_ag_list_supported_generic_status_indicators_cmd(connection->rfcomm_cid);
|
||||
connection->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS:
|
||||
hfp_ag_retrieve_supported_generic_status_indicators_cmd(connection->rfcomm_cid);
|
||||
connection->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
|
||||
hfp_ag_list_initital_supported_generic_status_indicators_cmd(connection->rfcomm_cid);
|
||||
connection->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
case HFP_ACTIVE:
|
||||
printf("HFP_ACTIVE\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void update_command(hfp_connection_t * context){
|
||||
context->command = HFP_CMD_NONE;
|
||||
@ -339,15 +288,110 @@ void update_command(hfp_connection_t * context){
|
||||
}
|
||||
|
||||
|
||||
void handle_switch_on_ok(hfp_connection_t *context){
|
||||
printf("handle switch on OK\n");
|
||||
switch (context->state){
|
||||
case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
|
||||
if (has_codec_negotiation_feature(context)){
|
||||
context->state = HFP_NOTIFY_ON_CODECS;
|
||||
break;
|
||||
}
|
||||
context->state = HFP_RETRIEVE_INDICATORS;
|
||||
void hfp_run_for_context(hfp_connection_t *context){
|
||||
if (!context) return;
|
||||
if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;
|
||||
printf("hfp_run_for_context: command %d, state %d\n", context->command, context->state);
|
||||
switch(context->command){
|
||||
case HFP_CMD_SUPPORTED_FEATURES:
|
||||
switch(context->state){
|
||||
case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
|
||||
hfp_ag_exchange_supported_features_cmd(context->rfcomm_cid);
|
||||
if (has_codec_negotiation_feature(context)){
|
||||
context->state = HFP_W4_NOTIFY_ON_CODECS;
|
||||
break;
|
||||
}
|
||||
context->state = HFP_W4_RETRIEVE_INDICATORS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HFP_CMD_AVAILABLE_CODECS:
|
||||
switch(context->state){
|
||||
case HFP_W4_NOTIFY_ON_CODECS:
|
||||
hfp_ag_retrieve_codec_cmd(context->rfcomm_cid);
|
||||
context->state = HFP_W4_RETRIEVE_INDICATORS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HFP_CMD_INDICATOR:
|
||||
switch(context->state){
|
||||
case HFP_W4_RETRIEVE_INDICATORS:
|
||||
hfp_ag_retrieve_indicators_cmd(context->rfcomm_cid);
|
||||
context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS;
|
||||
break;
|
||||
case HFP_W4_RETRIEVE_INDICATORS_STATUS:
|
||||
hfp_ag_retrieve_indicators_status_cmd(context->rfcomm_cid);
|
||||
if (context->remote_indicators_update_enabled == 0){
|
||||
context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE;
|
||||
break;
|
||||
}
|
||||
if (has_call_waiting_and_3way_calling_feature(context)){
|
||||
context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL;
|
||||
break;
|
||||
}
|
||||
if (has_hf_indicators_feature(context)){
|
||||
context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
}
|
||||
context->state = HFP_ACTIVE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
|
||||
switch(context->state){
|
||||
case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE:
|
||||
hfp_ag_toggle_indicator_status_update_cmd(context->rfcomm_cid, 1);
|
||||
if (has_call_waiting_and_3way_calling_feature(context)){
|
||||
context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL;
|
||||
break;
|
||||
}
|
||||
if (has_hf_indicators_feature(context)){
|
||||
context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
}
|
||||
context->state = HFP_ACTIVE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
|
||||
switch(context->state){
|
||||
case HFP_W4_RETRIEVE_CAN_HOLD_CALL:
|
||||
hfp_ag_retrieve_can_hold_call_cmd(context->rfcomm_cid);
|
||||
if (has_hf_indicators_feature(context)){
|
||||
context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
}
|
||||
context->state = HFP_ACTIVE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HFP_CMD_GENERIC_STATUS_INDICATOR:
|
||||
switch(context->state){
|
||||
case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
|
||||
hfp_ag_list_supported_generic_status_indicators_cmd(context->rfcomm_cid);
|
||||
context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
|
||||
hfp_ag_retrieve_supported_generic_status_indicators_cmd(context->rfcomm_cid);
|
||||
context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
|
||||
hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(context->rfcomm_cid);
|
||||
context->state = HFP_ACTIVE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -359,6 +403,9 @@ void handle_switch_on_ok(hfp_connection_t *context){
|
||||
static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
hfp_connection_t * context = provide_hfp_connection_context_for_rfcomm_cid(channel);
|
||||
if (!context) return;
|
||||
if (context->state == HFP_EXCHANGE_SUPPORTED_FEATURES){
|
||||
context->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES;
|
||||
}
|
||||
|
||||
packet[size] = 0;
|
||||
int pos;
|
||||
@ -366,8 +413,8 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8
|
||||
hfp_parse(context, packet[pos]);
|
||||
|
||||
// trigger next action after CMD received
|
||||
if (context->command != HFP_CMD_OK) continue;
|
||||
handle_switch_on_ok(context);
|
||||
if (context->command == HFP_CMD_NONE) continue;
|
||||
// hfp_run_for_context(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,7 +468,7 @@ void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features,
|
||||
memcpy(hfp_hf_indicators, hf_indicators, hf_indicators_nr * sizeof(hfp_hf_indicator_t));
|
||||
|
||||
hfp_ag_call_hold_services_nr = call_hold_services_nr;
|
||||
memcpy(hfp_ag_call_hold_services, call_hold_services, sizeof(char *));
|
||||
memcpy(hfp_ag_call_hold_services, call_hold_services, call_hold_services_nr * sizeof(char *));
|
||||
}
|
||||
|
||||
void hfp_ag_connect(bd_addr_t bd_addr){
|
||||
|
30
src/hfp_hf.c
30
src/hfp_hf.c
@ -267,21 +267,7 @@ void update_command(hfp_connection_t * context){
|
||||
|
||||
|
||||
void handle_switch_on_ok(hfp_connection_t *context){
|
||||
printf("handle switch on OK\n");
|
||||
switch (context->state){
|
||||
case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
|
||||
context->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
|
||||
case HFP_W4_NOTIFY_ON_CODECS:
|
||||
printf("switch on OK: HFP_RETRIEVE_INDICATORS\n");
|
||||
context->state = HFP_RETRIEVE_INDICATORS;
|
||||
break;
|
||||
case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
|
||||
printf("switch on OK: HFP_W4_LIST_GENERIC_STATUS_INDICATORS\n");
|
||||
context->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
|
||||
case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
|
||||
if (has_codec_negotiation_feature(context)){
|
||||
context->state = HFP_NOTIFY_ON_CODECS;
|
||||
@ -289,6 +275,11 @@ void handle_switch_on_ok(hfp_connection_t *context){
|
||||
}
|
||||
context->state = HFP_RETRIEVE_INDICATORS;
|
||||
break;
|
||||
|
||||
case HFP_W4_NOTIFY_ON_CODECS:
|
||||
context->state = HFP_RETRIEVE_INDICATORS;
|
||||
break;
|
||||
|
||||
case HFP_W4_RETRIEVE_INDICATORS:
|
||||
context->state = HFP_RETRIEVE_INDICATORS_STATUS;
|
||||
break;
|
||||
@ -328,9 +319,18 @@ void handle_switch_on_ok(hfp_connection_t *context){
|
||||
}
|
||||
context->state = HFP_ACTIVE;
|
||||
break;
|
||||
|
||||
|
||||
case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
|
||||
context->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
|
||||
case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
|
||||
context->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
|
||||
break;
|
||||
|
||||
case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
|
||||
printf("Supported initial state generic status indicators \n");
|
||||
context->state = HFP_ACTIVE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -149,7 +149,7 @@ int btstack_main(int argc, const char * argv[]){
|
||||
l2cap_init();
|
||||
rfcomm_init();
|
||||
|
||||
hfp_ag_init(rfcomm_channel_nr, 438, codecs, sizeof(codecs),
|
||||
hfp_ag_init(rfcomm_channel_nr, 1007, codecs, sizeof(codecs),
|
||||
ag_indicators, ag_indicators_nr,
|
||||
hf_indicators, hf_indicators_nr,
|
||||
call_hold_services, call_hold_services_nr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user