diff --git a/src/hfp.c b/src/hfp.c index 94c6afb7c..c545df22a 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -121,8 +121,8 @@ int send_str_over_rfcomm(uint16_t cid, char * command){ return err; } -void join(char * buffer, int buffer_size, uint8_t * values, int values_nr){ - if (buffer_size < values_nr * 3) return; +int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){ + if (buffer_size < values_nr * 3) return 0; int i; int offset = 0; for (i = 0; i < values_nr-1; i++) { @@ -131,9 +131,7 @@ void join(char * buffer, int buffer_size, uint8_t * values, int values_nr){ if (inegotiated_codec); } + +// UTILS +int get_bit(uint16_t bitmap, int position){ + return (bitmap >> position) & 1; +} + +int store_bit(uint32_t bitmap, int position, uint8_t value){ + if (value){ + bitmap |= 1 << position; + } else { + bitmap &= ~ (1 << position); + } + return bitmap; +} diff --git a/src/hfp.h b/src/hfp.h index 1067d947e..f80c9ee2a 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -191,6 +191,7 @@ typedef struct hfp_connection { uint16_t rfcomm_channel_nr; uint16_t rfcomm_cid; + // Retrieved during connection setup, not used yet uint8_t negotiated_codec; uint32_t remote_supported_features; @@ -220,7 +221,9 @@ linked_list_t * hfp_get_connections(); // TODO: move to utils int send_str_over_rfcomm(uint16_t cid, char * command); -void join(char * buffer, int buffer_size, uint8_t * values, int values_nr); +int join(char * buffer, int buffer_size, uint8_t * values, int values_nr); +int get_bit(uint16_t bitmap, int position); +int store_bit(uint32_t bitmap, int position, uint8_t value); const char * hfp_hf_feature(int index); const char * hfp_ag_feature(int index); diff --git a/src/hfp_ag.c b/src/hfp_ag.c index a2704d784..706b50d2c 100644 --- a/src/hfp_ag.c +++ b/src/hfp_ag.c @@ -62,10 +62,14 @@ #include "hfp_ag.h" static const char default_hfp_ag_service_name[] = "Voice gateway"; -static uint16_t hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES; +static uint16_t hfp_supported_features = HFP_DEFAULT_AG_SUPPORTED_FEATURES; static uint8_t hfp_codecs_nr = 0; static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS]; +static uint8_t hfp_indicators_nr = 0; +static uint8_t hfp_indicators[HFP_MAX_NUM_INDICATORS]; +static uint8_t hfp_indicators_status; + static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); void hfp_ag_create_service(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features){ @@ -82,54 +86,357 @@ void hfp_ag_create_service(uint8_t * service, int rfcomm_channel_nr, const char */ } -static void hfp_run(hfp_connection_t * connection){ - if (!connection) return; +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); + // printf("exchange_supported_features %s\n", buffer); + return send_str_over_rfcomm(cid, buffer); +} + +int hfp_ag_retrieve_indicators_cmd(uint16_t cid){ + char buffer[20]; + sprintf(buffer, "%s=?\r\nOK\r\n", HFP_INDICATOR); + // printf("retrieve_indicators %s\n", buffer); + return send_str_over_rfcomm(cid, buffer); +} + +int hfp_ag_retrieve_indicators_status_cmd(uint16_t cid){ + char buffer[20]; + sprintf(buffer, "%s?\r\nOK\r\n", HFP_INDICATOR); + // printf("retrieve_indicators_status %s\n", buffer); + return send_str_over_rfcomm(cid, buffer); +} + +int hfp_ag_toggle_indicator_status_update_cmd(uint16_t cid, uint8_t activate){ + char buffer[20]; + sprintf(buffer, "%s=3,0,0,%d\r\nOK\r\n", HFP_ENABLE_INDICATOR_STATUS_UPDATE, activate); + // printf("toggle_indicator_status_update %s\n", buffer); + return send_str_over_rfcomm(cid, buffer); +} + + +int hfp_ag_retrieve_can_hold_call_cmd(uint16_t cid){ + char buffer[20]; + sprintf(buffer, "%s=?\r\nOK\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES); + // printf("retrieve_can_hold_call %s\n", buffer); + return send_str_over_rfcomm(cid, buffer); +} + + +int hfp_ag_retrieve_codec_cmd(uint16_t cid){ + char buffer[30]; + int offset = snprintf(buffer, sizeof(buffer), "%s=", HFP_AVAILABLE_CODECS); + offset += join(buffer+offset, sizeof(buffer)-offset, hfp_codecs, hfp_codecs_nr); + 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_supported_generic_status_indicators_cmd(uint16_t cid){ + char buffer[30]; + int offset = snprintf(buffer, sizeof(buffer), "%s=", HFP_GENERIC_STATUS_INDICATOR); + offset += join(buffer+offset, sizeof(buffer)-offset, hfp_indicators, hfp_indicators_nr); + offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\nOK\r\n"); + buffer[offset] = 0; + return send_str_over_rfcomm(cid, buffer); +} + +int hfp_ag_retrieve_supported_generic_status_indicators_cmd(uint16_t cid){ + char buffer[20]; + sprintf(buffer, "%s=?\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR); + // printf("retrieve_supported_generic_status_indicators %s\n", buffer); + return send_str_over_rfcomm(cid, buffer); +} + +int hfp_ag_list_initital_supported_generic_status_indicators_cmd(uint16_t cid){ + char buffer[20]; + sprintf(buffer, "%s?\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR); + // printf("list_initital_supported_generic_status_indicators %s\n", buffer); + 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; } } -hfp_connection_t * 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 NULL; - while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){ - size--; - packet++; +void update_command(hfp_connection_t * context){ + context->command = HFP_CMD_NONE; + + if (strncmp((char *)context->line_buffer+2, HFP_SUPPORTED_FEATURES, strlen(HFP_SUPPORTED_FEATURES)) == 0){ + printf("Received AT+BRSF\n"); + context->command = HFP_CMD_SUPPORTED_FEATURES; + return; } - return context; + if (strncmp((char *)context->line_buffer+2, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){ + printf("Received AT+CIND\n"); + context->command = HFP_CMD_INDICATOR; + return; + } + + + if (strncmp((char *)context->line_buffer+2, HFP_AVAILABLE_CODECS, strlen(HFP_AVAILABLE_CODECS)) == 0){ + printf("Received AT+BAC\n"); + context->command = HFP_CMD_AVAILABLE_CODECS; + return; + } + + if (strncmp((char *)context->line_buffer+2, HFP_ENABLE_INDICATOR_STATUS_UPDATE, strlen(HFP_ENABLE_INDICATOR_STATUS_UPDATE)) == 0){ + printf("Received AT+CMER\n"); + context->command = HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE; + return; + } + + if (strncmp((char *)context->line_buffer+2, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)) == 0){ + printf("Received AT+CHLD\n"); + context->command = HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; + return; + } + + if (strncmp((char *)context->line_buffer+2, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){ + printf("Received AT+BIND\n"); + context->command = HFP_CMD_GENERIC_STATUS_INDICATOR; + return; + } +} + +static void hfp_parse(hfp_connection_t * context, uint8_t byte){ + int i; + if (byte == ' ') return; + /*if ( (byte == '\n' || byte == '\r') && context->parser_state > HFP_PARSER_CMD_SEQUENCE) return; + + switch (context->parser_state){ + case HFP_PARSER_CMD_HEADER: // header + if (byte == ':'){ + context->parser_state = HFP_PARSER_CMD_SEQUENCE; + context->line_buffer[context->line_size] = 0; + context->line_size = 0; + update_command(context); + return; + } + if (byte == '\n' || byte == '\r'){ + // received OK + context->line_buffer[context->line_size] = 0; + context->line_size = 0; + update_command(context); + return; + } + context->line_buffer[context->line_size++] = byte; + break; + + case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes + if (byte == '"'){ // indicators + context->parser_state = HFP_PARSER_CMD_INDICATOR_NAME; + context->line_size = 0; + break; + } + + if (byte == '(' ){ // tuple separated mit comma + break; + } + + if (byte == ',' || byte == '\n' || byte == '\r' || byte == ')'){ + context->line_buffer[context->line_size] = 0; + context->line_size = 0; + switch (context->state){ + case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: + context->remote_supported_features = atoi((char *)&context->line_buffer[0]); + for (i=0; i<16; i++){ + if (get_bit(context->remote_supported_features,i)){ + 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: + break; + case HFP_W4_RETRIEVE_INDICATORS_STATUS: + printf("Indicator with status: %s\n", context->line_buffer); + break; + case HFP_W4_RETRIEVE_CAN_HOLD_CALL: + printf("Support call hold: %s\n", context->line_buffer); + break; + case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: // comma separated ints + printf("Generic status indicator: %s\n", context->line_buffer); + break; + case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: + printf("Generic status indicator: %s, ", context->line_buffer); + context->parser_state = HFP_PARSER_CMD_INITITAL_STATE_GENERIC_STATUS_INDICATORS; + break; + default: + 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; + } + break; + } + context->line_buffer[context->line_size++] = byte; + break; + case HFP_PARSER_CMD_INITITAL_STATE_GENERIC_STATUS_INDICATORS: + if (byte == '\n' || byte == '\r'){ + context->line_buffer[context->line_size] = 0; + context->line_size = 0; + context->command = HFP_CMD_NONE; + context->parser_state = HFP_PARSER_CMD_HEADER; + printf("status %s [0-dissabled, 1-enabled]\n", context->line_buffer); + break; + } + break; + case HFP_PARSER_CMD_INDICATOR_NAME: // parse indicator name + if (byte == '"'){ + context->line_buffer[context->line_size] = 0; + printf("Indicator %d: %s (", context->remote_indicators_nr, context->line_buffer); + context->line_size = 0; + break; + } + if (byte == '('){ // parse indicator range + context->parser_state = HFP_PARSER_CMD_INDICATOR_MIN_RANGE; + break; + } + context->line_buffer[context->line_size++] = byte; + break; + case HFP_PARSER_CMD_INDICATOR_MIN_RANGE: + if (byte == ',' || byte == '-'){ // end min_range + context->parser_state = HFP_PARSER_CMD_INDICATOR_MAX_RANGE; + context->line_buffer[context->line_size] = 0; + printf("%d, ", atoi((char *)&context->line_buffer[0])); + context->line_size = 0; + break; + } + // min. range + context->line_buffer[context->line_size++] = byte; + break; + case HFP_PARSER_CMD_INDICATOR_MAX_RANGE: + if (byte == ')'){ // end max_range + context->parser_state = HFP_PARSER_CMD_SEQUENCE; + + context->line_buffer[context->line_size] = 0; + printf("%d)\n", atoi((char *)&context->line_buffer[0])); + context->line_size = 0; + context->remote_indicators_nr+=1; + break; + } + // + context->line_buffer[context->line_size++] = byte; + break; + }*/ +} + + +void handle_switch_on_ok(hfp_connection_t *context){ + printf("handle switch on OK\n"); + switch (context->state){ + default: + break; + } + // done + context->command = HFP_CMD_NONE; +} + +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; + + packet[size] = 0; + int pos; + for (pos = 0; pos < size ; pos++){ + hfp_parse(context, packet[pos]); + + // trigger next action after CMD received + if (context->command != HFP_CMD_OK) continue; + handle_switch_on_ok(context); + } +} + +static void hfp_run(){ + linked_list_iterator_t it; + linked_list_iterator_init(&it, hfp_get_connections()); + while (linked_list_iterator_has_next(&it)){ + hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_run_for_context(connection); + } } 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]); - hfp_connection_t * context = NULL; - switch (packet_type){ case RFCOMM_DATA_PACKET: - context = hfp_handle_rfcomm_event(packet_type, channel, packet, size); + hfp_handle_rfcomm_event(packet_type, channel, packet, size); break; case HCI_EVENT_PACKET: - context = hfp_handle_hci_event(packet_type, packet, size); + hfp_handle_hci_event(packet_type, packet, size); break; default: break; } - hfp_run(context); + hfp_run(); } -void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint8_t * codecs, int codecs_nr){ +void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint8_t * codecs, int codecs_nr, uint16_t * indicators, int indicators_nr, uint32_t indicators_status){ if (codecs_nr > HFP_MAX_NUM_CODECS){ log_error("hfp_init: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS); return; } - hfp_init(rfcomm_channel_nr); rfcomm_register_packet_handler(packet_handler); - // connection->codecs = codecs; + hfp_init(rfcomm_channel_nr); + hfp_supported_features = supported_features; hfp_codecs_nr = codecs_nr; @@ -137,6 +444,12 @@ void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint8_ for (i=0; i> position) & 1; -} - int has_codec_negotiation_feature(hfp_connection_t * connection){ int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION); @@ -104,14 +100,6 @@ void hfp_hf_create_service(uint8_t * service, int rfcomm_channel_nr, const char hfp_create_service(service, SDP_Handsfree, rfcomm_channel_nr, name, supported_features); } -static int store_bit(uint32_t bitmap, int position, uint8_t value){ - if (value){ - bitmap |= 1 << position; - } else { - bitmap &= ~ (1 << position); - } - return bitmap; -} int hfp_hs_exchange_supported_features_cmd(uint16_t cid){ char buffer[20]; @@ -120,14 +108,6 @@ int hfp_hs_exchange_supported_features_cmd(uint16_t cid){ return send_str_over_rfcomm(cid, buffer); } -int hfp_hs_retrieve_codec_cmd(uint16_t cid){ - char buffer[30]; - int buffer_offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_AVAILABLE_CODECS); - join(buffer+buffer_offset, sizeof(buffer)-buffer_offset, hfp_codecs, hfp_codecs_nr); - // printf("retrieve_codec %s\n", buffer); - return send_str_over_rfcomm(cid, buffer); -} - int hfp_hs_retrieve_indicators_cmd(uint16_t cid){ char buffer[20]; @@ -159,17 +139,27 @@ int hfp_hs_retrieve_can_hold_call_cmd(uint16_t cid){ } +int hfp_hs_retrieve_codec_cmd(uint16_t cid){ + char buffer[30]; + int offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_AVAILABLE_CODECS); + offset += join(buffer+offset, sizeof(buffer)-offset, hfp_codecs, hfp_codecs_nr); + offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n"); + buffer[offset] = 0; + return send_str_over_rfcomm(cid, buffer); +} + int hfp_hs_list_supported_generic_status_indicators_cmd(uint16_t cid){ char buffer[30]; - int buffer_offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_GENERIC_STATUS_INDICATOR); - join(buffer+buffer_offset, sizeof(buffer)-buffer_offset, hfp_indicators, hfp_indicators_nr); - // printf("list_supported_generic_status_indicators %s\n", buffer); + int offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_GENERIC_STATUS_INDICATOR); + offset += join(buffer+offset, sizeof(buffer)-offset, hfp_indicators, hfp_indicators_nr); + offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n"); + buffer[offset] = 0; return send_str_over_rfcomm(cid, buffer); } int hfp_hs_retrieve_supported_generic_status_indicators_cmd(uint16_t cid){ char buffer[20]; - sprintf(buffer, "AT%s=?\r\rn", HFP_GENERIC_STATUS_INDICATOR); + sprintf(buffer, "AT%s=?\r\n", HFP_GENERIC_STATUS_INDICATOR); // printf("retrieve_supported_generic_status_indicators %s\n", buffer); return send_str_over_rfcomm(cid, buffer); } @@ -533,12 +523,10 @@ void hfp_hf_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint8_ rfcomm_register_packet_handler(packet_handler); hfp_init(rfcomm_channel_nr); - int i; - - // connection->codecs = codecs; hfp_supported_features = supported_features; - hfp_codecs_nr = codecs_nr; + + int i; for (i=0; i #include #include @@ -67,26 +65,29 @@ #include "debug.h" #include "hfp_ag.h" #include "stdin_support.h" + const uint32_t hfp_service_buffer[150/4]; // implicit alignment to 4-byte memory address const uint8_t rfcomm_channel_nr = 1; -const char hfp_ag_service_name[] = "Headset Test"; +const char hfp_ag_service_name[] = "BTstack HFP AG Test"; static bd_addr_t pts_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF}; static bd_addr_t local_mac = {0x04, 0x0C, 0xCE, 0xE4, 0x85, 0xD3}; +static bd_addr_t phone = {0xD8,0xBb,0x2C,0xDf,0xF1,0x08}; +static uint8_t codecs[1] = {HFP_CODEC_CVSD}; +static uint16_t indicators[1] = {0x01}; // prototypes -static void show_usage(); - +static void show_usage(void); // Testig User Interface static void show_usage(void){ - printf("\n--- Bluetooth HFP Audio Gateway (AG) unit Test Console ---\n"); + printf("\n--- Bluetooth HFP Hands-Free (HF) unit Test Console ---\n"); printf("---\n"); - printf("p - establish audio connection to PTS module\n"); - printf("e - establish audio connection to local mac\n"); - printf("d - release audio connection from Bluetooth Speaker\n"); + printf("p - establish HFP connection to PTS module\n"); + printf("e - establish HFP connection to local mac\n"); + printf("d - release HFP connection\n"); printf("---\n"); printf("Ctrl-c - exit\n"); printf("---\n"); @@ -95,18 +96,17 @@ static void show_usage(void){ static int stdin_process(struct data_source *ds){ char buffer; read(ds->fd, &buffer, 1); - switch (buffer){ case 'p': - printf("Establishing audio connection to PTS module %s...\n", bd_addr_to_str(pts_addr)); + printf("Establishing HFP connection to PTS module %s...\n", bd_addr_to_str(pts_addr)); hfp_ag_connect(pts_addr); break; case 'e': - printf("Establishing audio connection to local mac %s...\n", bd_addr_to_str(local_mac)); - hfp_ag_connect(local_mac); + printf("Establishing HFP connection to %s...\n", bd_addr_to_str(phone)); + hfp_ag_connect(phone); break; case 'd': - printf("Releasing audio connection.\n"); + printf("Releasing HFP connection.\n"); hfp_ag_disconnect(pts_addr); break; default: @@ -125,26 +125,29 @@ void packet_handler(uint8_t * event, uint16_t event_size){ } } + int btstack_main(int argc, const char * argv[]){ // init L2CAP l2cap_init(); rfcomm_init(); - // TODO: hfp_ag_init(rfcomm_channel_nr); + // hfp_ag_init(rfcomm_channel_nr, HFP_DEFAULT_HF_SUPPORTED_FEATURES, codecs, sizeof(codecs), indicators, sizeof(indicators)/sizeof(uint16_t), 1); + hfp_ag_init(rfcomm_channel_nr, 438, codecs, sizeof(codecs), indicators, sizeof(indicators)/sizeof(uint16_t), 1); + hfp_register_packet_handler(packet_handler); - + sdp_init(); - // init SDP, create record for SPP and register with SDP memset((uint8_t *)hfp_service_buffer, 0, sizeof(hfp_service_buffer)); hfp_ag_create_service((uint8_t *)hfp_service_buffer, rfcomm_channel_nr, hfp_ag_service_name, 0, 0); + sdp_register_service_internal(NULL, (uint8_t *)hfp_service_buffer); - // turn on! hci_power_control(HCI_POWER_ON); btstack_stdin_setup(stdin_process); - + printf("Establishing HFP connection to %s...\n", bd_addr_to_str(phone)); + hfp_ag_connect(phone); return 0; } diff --git a/test/pts/hfp_hf_test.c b/test/pts/hfp_hf_test.c index cc447e355..16c9df2d4 100644 --- a/test/pts/hfp_hf_test.c +++ b/test/pts/hfp_hf_test.c @@ -70,11 +70,14 @@ const uint32_t hfp_service_buffer[150/4]; // implicit alignment to 4-byte memory address const uint8_t rfcomm_channel_nr = 1; -const char hfp_hf_service_name[] = "BTstack HF Test"; +const char hfp_hf_service_name[] = "BTstack HFP HF Test"; static bd_addr_t pts_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF}; static bd_addr_t local_mac = {0x04, 0x0C, 0xCE, 0xE4, 0x85, 0xD3}; static bd_addr_t phone = {0xD8,0xBb,0x2C,0xDf,0xF1,0x08}; +static uint8_t codecs[1] = {HFP_CODEC_CVSD}; +static uint16_t indicators[1] = {0x01}; + // prototypes static void show_usage(); @@ -94,7 +97,6 @@ static void show_usage(void){ static int stdin_process(struct data_source *ds){ char buffer; read(ds->fd, &buffer, 1); - switch (buffer){ case 'p': printf("Establishing HFP connection to PTS module %s...\n", bd_addr_to_str(pts_addr)); @@ -126,9 +128,6 @@ void packet_handler(uint8_t * event, uint16_t event_size){ int btstack_main(int argc, const char * argv[]){ // init L2CAP - uint8_t codecs[1] = {HFP_CODEC_CVSD}; - uint16_t indicators[1] = {0x01}; - l2cap_init(); rfcomm_init(); @@ -147,6 +146,7 @@ int btstack_main(int argc, const char * argv[]){ hci_power_control(HCI_POWER_ON); btstack_stdin_setup(stdin_process); - + // printf("Establishing HFP connection to %s...\n", bd_addr_to_str(phone)); + // hfp_hf_connect(phone); return 0; }