mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-26 02:37:41 +00:00
hsp ag & hs pass pts tests
This commit is contained in:
parent
aa3feb0444
commit
8f74874871
@ -62,8 +62,8 @@
|
|||||||
|
|
||||||
#define RFCOMM_SERVER_CHANNEL 1
|
#define RFCOMM_SERVER_CHANNEL 1
|
||||||
|
|
||||||
#define HSP_HS_BUTTON_PRESS "AT+CKPD=200\r"
|
#define HSP_HS_BUTTON_PRESS "AT+CKPD=200\r\n"
|
||||||
#define HSP_HS_AT_CKPD "AT+CKPD\r"
|
#define HSP_HS_AT_CKPD "AT+CKPD\r\n"
|
||||||
#define HSP_AG_OK "\r\nOK\r\n"
|
#define HSP_AG_OK "\r\nOK\r\n"
|
||||||
#define HSP_AG_ERROR "\r\nERROR\r\n"
|
#define HSP_AG_ERROR "\r\nERROR\r\n"
|
||||||
#define HSP_AG_RING "\r\nRING\r\n"
|
#define HSP_AG_RING "\r\nRING\r\n"
|
||||||
@ -91,8 +91,8 @@ static int ag_speaker_gain = -1;
|
|||||||
static uint8_t ag_ring = 0;
|
static uint8_t ag_ring = 0;
|
||||||
static uint8_t ag_send_ok = 0;
|
static uint8_t ag_send_ok = 0;
|
||||||
static uint8_t ag_send_error = 0;
|
static uint8_t ag_send_error = 0;
|
||||||
static uint8_t ag_in_band_ring_tone = 0;
|
|
||||||
static uint8_t ag_num_button_press_received = 0;
|
static uint8_t ag_num_button_press_received = 0;
|
||||||
|
static uint8_t ag_support_custom_commands = 0;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HSP_IDLE,
|
HSP_IDLE,
|
||||||
@ -206,10 +206,6 @@ void hsp_ag_create_service(uint8_t * service, int rfcomm_channel_nr, const char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// remote audio volume control
|
|
||||||
// AG +VGM=13 [0..15] ; HS AT+VGM=6 | AG OK
|
|
||||||
|
|
||||||
static int send_str_over_rfcomm(uint16_t cid, char * command){
|
static int send_str_over_rfcomm(uint16_t cid, char * command){
|
||||||
if (!rfcomm_can_send_packet_now(rfcomm_cid)) return 1;
|
if (!rfcomm_can_send_packet_now(rfcomm_cid)) return 1;
|
||||||
int err = rfcomm_send_internal(cid, (uint8_t*) command, strlen(command));
|
int err = rfcomm_send_internal(cid, (uint8_t*) command, strlen(command));
|
||||||
@ -221,6 +217,16 @@ static int send_str_over_rfcomm(uint16_t cid, char * command){
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hsp_ag_support_custom_commands(int enable){
|
||||||
|
ag_support_custom_commands = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hsp_ag_send_result(char * result){
|
||||||
|
if (!ag_support_custom_commands) return 1;
|
||||||
|
return send_str_over_rfcomm(rfcomm_cid, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void hsp_ag_reset_state(){
|
static void hsp_ag_reset_state(){
|
||||||
hsp_state = HSP_IDLE;
|
hsp_state = HSP_IDLE;
|
||||||
|
|
||||||
@ -233,10 +239,10 @@ static void hsp_ag_reset_state(){
|
|||||||
ag_ring = 0;
|
ag_ring = 0;
|
||||||
|
|
||||||
ag_num_button_press_received = 0;
|
ag_num_button_press_received = 0;
|
||||||
|
ag_support_custom_commands = 0;
|
||||||
|
|
||||||
ag_microphone_gain = -1;
|
ag_microphone_gain = -1;
|
||||||
ag_speaker_gain = -1;
|
ag_speaker_gain = -1;
|
||||||
ag_in_band_ring_tone = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hsp_ag_init(uint8_t rfcomm_channel_nr){
|
void hsp_ag_init(uint8_t rfcomm_channel_nr){
|
||||||
@ -253,12 +259,6 @@ void hsp_ag_init(uint8_t rfcomm_channel_nr){
|
|||||||
hsp_ag_reset_state();
|
hsp_ag_reset_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hsp_ag_enable_in_band_ring_tone(int enabled){
|
|
||||||
// send is not yet implemented
|
|
||||||
ag_in_band_ring_tone = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hsp_ag_connect(bd_addr_t bd_addr){
|
void hsp_ag_connect(bd_addr_t bd_addr){
|
||||||
if (hsp_state != HSP_IDLE) return;
|
if (hsp_state != HSP_IDLE) return;
|
||||||
hsp_state = HSP_SDP_QUERY_RFCOMM_CHANNEL;
|
hsp_state = HSP_SDP_QUERY_RFCOMM_CHANNEL;
|
||||||
@ -364,11 +364,6 @@ static void hsp_run(){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ag_in_band_ring_tone){
|
|
||||||
log_error("in_band_ring_tone: send is not yet implemented");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ag_num_button_press_received) break;
|
if (!ag_num_button_press_received) break;
|
||||||
|
|
||||||
err = send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
|
err = send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
|
||||||
@ -422,7 +417,12 @@ static void hsp_run(){
|
|||||||
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
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]);
|
// printf("packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
|
||||||
if (packet_type == RFCOMM_DATA_PACKET){
|
if (packet_type == RFCOMM_DATA_PACKET){
|
||||||
if (strncmp((char *)packet, HSP_HS_BUTTON_PRESS, 7) == 0){
|
while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){
|
||||||
|
size--;
|
||||||
|
packet++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp((char *)packet, HSP_HS_BUTTON_PRESS, strlen(HSP_HS_BUTTON_PRESS)) == 0){
|
||||||
printf("Received button press %s\n", HSP_HS_BUTTON_PRESS);
|
printf("Received button press %s\n", HSP_HS_BUTTON_PRESS);
|
||||||
ag_num_button_press_received++;
|
ag_num_button_press_received++;
|
||||||
ag_send_ok = 1;
|
ag_send_ok = 1;
|
||||||
@ -430,21 +430,18 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
ag_num_button_press_received = 0;
|
ag_num_button_press_received = 0;
|
||||||
hsp_state = HSP_W2_DISCONNECT_SCO;
|
hsp_state = HSP_W2_DISCONNECT_SCO;
|
||||||
}
|
}
|
||||||
} else if (strncmp((char *)packet, HSP_HS_MICROPHONE_GAIN, 7) == 0){
|
} else if (strncmp((char *)packet, HSP_HS_MICROPHONE_GAIN, strlen(HSP_HS_MICROPHONE_GAIN)) == 0){
|
||||||
uint8_t gain = (uint8_t)atoi((char*)&packet[7]);
|
uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_HS_MICROPHONE_GAIN)]);
|
||||||
ag_send_ok = 1;
|
ag_send_ok = 1;
|
||||||
emit_event(HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED, gain);
|
emit_event(HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED, gain);
|
||||||
|
|
||||||
} else if (strncmp((char *)packet, HSP_HS_SPEAKER_GAIN, 7) == 0){
|
} else if (strncmp((char *)packet, HSP_HS_SPEAKER_GAIN, strlen(HSP_HS_SPEAKER_GAIN)) == 0){
|
||||||
uint8_t gain = (uint8_t)atoi((char*)&packet[7]);
|
uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_HS_SPEAKER_GAIN)]);
|
||||||
ag_send_ok = 1;
|
ag_send_ok = 1;
|
||||||
emit_event(HSP_SUBEVENT_SPEAKER_GAIN_CHANGED, gain);
|
emit_event(HSP_SUBEVENT_SPEAKER_GAIN_CHANGED, gain);
|
||||||
|
|
||||||
} else if (strncmp((char *)packet, "AT+", 3) == 0){
|
} else if (strncmp((char *)packet, "AT+", 3) == 0){
|
||||||
ag_send_error = 1;
|
ag_send_error = 1;
|
||||||
}
|
|
||||||
|
|
||||||
if (ag_send_error){
|
|
||||||
if (!hsp_ag_callback) return;
|
if (!hsp_ag_callback) return;
|
||||||
// re-use incoming buffer to avoid reserving large buffers - ugly but efficient
|
// re-use incoming buffer to avoid reserving large buffers - ugly but efficient
|
||||||
uint8_t * event = packet - 3;
|
uint8_t * event = packet - 3;
|
||||||
@ -453,6 +450,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
event[2] = HSP_SUBEVENT_HS_COMMAND;
|
event[2] = HSP_SUBEVENT_HS_COMMAND;
|
||||||
(*hsp_ag_callback)(event, size+3);
|
(*hsp_ag_callback)(event, size+3);
|
||||||
}
|
}
|
||||||
|
|
||||||
hsp_run();
|
hsp_run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -521,8 +519,8 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
hsp_state = HSP_W2_DISCONNECT_SCO;
|
hsp_state = HSP_W2_DISCONNECT_SCO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hsp_state = HSP_ACTIVE;
|
|
||||||
|
|
||||||
|
hsp_state = HSP_ACTIVE;
|
||||||
emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, 0);
|
emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,6 @@ void hsp_ag_init(uint8_t rfcomm_channel_nr);
|
|||||||
void hsp_ag_connect(bd_addr_t bd_addr);
|
void hsp_ag_connect(bd_addr_t bd_addr);
|
||||||
void hsp_ag_disconnect();
|
void hsp_ag_disconnect();
|
||||||
|
|
||||||
void hsp_ag_enable_in_band_ring_tone(int enabled);
|
|
||||||
|
|
||||||
// +VGM=[0..15]
|
// +VGM=[0..15]
|
||||||
void hsp_ag_set_microphone_gain(uint8_t gain);
|
void hsp_ag_set_microphone_gain(uint8_t gain);
|
||||||
// +VGS=[0..15]
|
// +VGS=[0..15]
|
||||||
@ -71,6 +69,13 @@ void hsp_ag_set_speaker_gain(uint8_t gain);
|
|||||||
void hsp_ag_start_ringing();
|
void hsp_ag_start_ringing();
|
||||||
void hsp_ag_stop_ringing();
|
void hsp_ag_stop_ringing();
|
||||||
|
|
||||||
|
void hsp_ag_support_custom_commands(int 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_ag_send_result function.
|
||||||
|
int hsp_ag_send_result(char * result);
|
||||||
|
|
||||||
#if defined __cplusplus
|
#if defined __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,12 +82,11 @@ static void show_usage();
|
|||||||
static data_source_t stdin_source;
|
static data_source_t stdin_source;
|
||||||
|
|
||||||
static void show_usage(){
|
static void show_usage(){
|
||||||
|
|
||||||
printf("\n--- Bluetooth HSP AudioGateway Test Console ---\n");
|
printf("\n--- Bluetooth HSP AudioGateway Test Console ---\n");
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
printf("p - establish audio connection to PTS module\n");
|
printf("p - establish audio connection to PTS module\n");
|
||||||
printf("e - establish audio connection to Bluetooth Speaker\n");
|
printf("e - establish audio connection to Bluetooth Speaker\n");
|
||||||
printf("d - release audio connection from Bluetooth Speaker\n");
|
printf("d - release audio connection\n");
|
||||||
printf("m - set microphone gain 8\n");
|
printf("m - set microphone gain 8\n");
|
||||||
printf("M - set microphone gain 15\n");
|
printf("M - set microphone gain 15\n");
|
||||||
printf("o - set speaker gain 0\n");
|
printf("o - set speaker gain 0\n");
|
||||||
@ -114,7 +113,7 @@ static int stdin_process(struct data_source *ds){
|
|||||||
hsp_ag_connect(bt_speaker_addr);
|
hsp_ag_connect(bt_speaker_addr);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
printf("Releasing audio connection from Bluetooth Speaker %s...\n", bd_addr_to_str(bt_speaker_addr));
|
printf("Releasing audio connection\n");
|
||||||
hsp_ag_disconnect();
|
hsp_ag_disconnect();
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
@ -154,7 +153,6 @@ static int stdin_process(struct data_source *ds){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void setup_cli(){
|
static void setup_cli(){
|
||||||
|
|
||||||
struct termios term = {0};
|
struct termios term = {0};
|
||||||
if (tcgetattr(0, &term) < 0)
|
if (tcgetattr(0, &term) < 0)
|
||||||
perror("tcsetattr()");
|
perror("tcsetattr()");
|
||||||
@ -177,14 +175,14 @@ void packet_handler(uint8_t * event, uint16_t event_size){
|
|||||||
switch (event[2]) {
|
switch (event[2]) {
|
||||||
case HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE:
|
case HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE:
|
||||||
if (event[3] == 0){
|
if (event[3] == 0){
|
||||||
printf("Audio connection established.\n");
|
printf("Audio connection established.\n\n");
|
||||||
} else {
|
} else {
|
||||||
printf("Audio connection establishment failed with status %u\n", event[3]);
|
printf("Audio connection establishment failed with status %u\n", event[3]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE:
|
case HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE:
|
||||||
if (event[3] == 0){
|
if (event[3] == 0){
|
||||||
printf("Audio connection released.\n");
|
printf("Audio connection released.\n\n");
|
||||||
} else {
|
} else {
|
||||||
printf("Audio connection releasing failed with status %u\n", event[3]);
|
printf("Audio connection releasing failed with status %u\n", event[3]);
|
||||||
}
|
}
|
||||||
@ -199,7 +197,7 @@ void packet_handler(uint8_t * event, uint16_t event_size){
|
|||||||
memset(hs_cmd_buffer, 0, sizeof(hs_cmd_buffer));
|
memset(hs_cmd_buffer, 0, sizeof(hs_cmd_buffer));
|
||||||
int size = event_size <= sizeof(hs_cmd_buffer)? event_size : sizeof(hs_cmd_buffer);
|
int size = event_size <= sizeof(hs_cmd_buffer)? event_size : sizeof(hs_cmd_buffer);
|
||||||
memcpy(hs_cmd_buffer, &event[3], size - 1);
|
memcpy(hs_cmd_buffer, &event[3], size - 1);
|
||||||
printf("Received command: \"%s\"\n", hs_cmd_buffer);
|
printf("Received custom command: \"%s\". \nExit code or call hsp_ag_send_result.\n", hs_cmd_buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -214,10 +212,11 @@ int btstack_main(int argc, const char * argv[]){
|
|||||||
|
|
||||||
hsp_ag_init(rfcomm_channel_nr);
|
hsp_ag_init(rfcomm_channel_nr);
|
||||||
hsp_ag_register_packet_handler(packet_handler);
|
hsp_ag_register_packet_handler(packet_handler);
|
||||||
// turn on!
|
|
||||||
sdp_init();
|
sdp_init();
|
||||||
sdp_register_service_internal(NULL, (uint8_t *)hsp_service_buffer);
|
sdp_register_service_internal(NULL, (uint8_t *)hsp_service_buffer);
|
||||||
|
|
||||||
|
// turn on!
|
||||||
hci_power_control(HCI_POWER_ON);
|
hci_power_control(HCI_POWER_ON);
|
||||||
|
|
||||||
setup_cli();
|
setup_cli();
|
||||||
|
@ -60,16 +60,17 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "hsp_hs.h"
|
#include "hsp_hs.h"
|
||||||
|
|
||||||
#define HSP_HS_BUTTON_PRESS "AT+CKPD=200\r"
|
|
||||||
#define HSP_HS_AT_CKPD "AT+CKPD\r"
|
|
||||||
#define HSP_AG_OK "\r\nOK\r\n"
|
|
||||||
#define HSP_AG_ERROR "\r\nERROR\r\n"
|
|
||||||
#define HSP_AG_RING "\r\nRING\r\n"
|
|
||||||
#define HSP_MICROPHONE_GAIN "+VGM"
|
|
||||||
#define HSP_SPEAKER_GAIN "+VGS"
|
|
||||||
|
|
||||||
#define HSP_HS_MICROPHONE_GAIN "AT+VGM="
|
#define HSP_AG_OK "OK"
|
||||||
#define HSP_HS_SPEAKER_GAIN "AT+VGS="
|
#define HSP_AG_ERROR "ERROR"
|
||||||
|
#define HSP_AG_RING "RING"
|
||||||
|
#define HSP_MICROPHONE_GAIN "+VGM="
|
||||||
|
#define HSP_SPEAKER_GAIN "+VGS="
|
||||||
|
|
||||||
|
#define HSP_HS_BUTTON_PRESS "AT+CKPD=200\r\n"
|
||||||
|
#define HSP_HS_AT_CKPD "AT+CKPD=200\r\n"
|
||||||
|
#define HSP_HS_MICROPHONE_GAIN "AT+VGM"
|
||||||
|
#define HSP_HS_SPEAKER_GAIN "AT+VGS"
|
||||||
|
|
||||||
static const char default_hsp_hs_service_name[] = "Headset";
|
static const char default_hsp_hs_service_name[] = "Headset";
|
||||||
|
|
||||||
@ -87,10 +88,9 @@ static int hs_microphone_gain = -1;
|
|||||||
static int hs_speaker_gain = -1;
|
static int hs_speaker_gain = -1;
|
||||||
|
|
||||||
static uint8_t hs_send_button_press = 0;
|
static uint8_t hs_send_button_press = 0;
|
||||||
static uint8_t hs_send_at_cpkd = 0;
|
|
||||||
static uint8_t hs_ok_received = 0;
|
static uint8_t hs_ok_received = 0;
|
||||||
static uint8_t hs_ring_received = 0;
|
static uint8_t hs_ring_received = 0;
|
||||||
|
static uint8_t hs_support_custom_indications = 0;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -98,6 +98,7 @@ typedef enum {
|
|||||||
HSP_SDP_QUERY_RFCOMM_CHANNEL,
|
HSP_SDP_QUERY_RFCOMM_CHANNEL,
|
||||||
HSP_W4_SDP_QUERY_COMPLETE,
|
HSP_W4_SDP_QUERY_COMPLETE,
|
||||||
HSP_W4_RFCOMM_CONNECTED,
|
HSP_W4_RFCOMM_CONNECTED,
|
||||||
|
HSP_W4_USER_ACTION,
|
||||||
HSP_W2_CONNECT_SCO,
|
HSP_W2_CONNECT_SCO,
|
||||||
HSP_W4_SCO_CONNECTED,
|
HSP_W4_SCO_CONNECTED,
|
||||||
HSP_ACTIVE,
|
HSP_ACTIVE,
|
||||||
@ -124,11 +125,15 @@ void hsp_hs_register_packet_handler(hsp_hs_callback_t callback){
|
|||||||
hsp_hs_callback = callback;
|
hsp_hs_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_event(uint8_t * event, uint16_t size){
|
static void emit_event(uint8_t event_subtype, uint8_t value){
|
||||||
if (!hsp_hs_callback) return;
|
if (!hsp_hs_callback) return;
|
||||||
(*hsp_hs_callback)(event, size);
|
uint8_t event[4];
|
||||||
|
event[0] = HCI_EVENT_HSP_META;
|
||||||
|
event[1] = sizeof(event) - 2;
|
||||||
|
event[2] = event_subtype;
|
||||||
|
event[3] = value; // status 0 == OK
|
||||||
|
(*hsp_hs_callback)(event, sizeof(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
// remote audio volume control
|
// remote audio volume control
|
||||||
// AG +VGM=13 [0..15] ; HS AT+VGM=6 | AG OK
|
// AG +VGM=13 [0..15] ; HS AT+VGM=6 | AG OK
|
||||||
|
|
||||||
@ -141,6 +146,18 @@ static int send_str_over_rfcomm(uint16_t cid, char * command){
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hsp_hs_support_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 send_str_over_rfcomm(rfcomm_cid, 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_service(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t have_remote_audio_control){
|
||||||
uint8_t* attribute;
|
uint8_t* attribute;
|
||||||
@ -224,11 +241,9 @@ static void hsp_hs_reset_state(){
|
|||||||
hs_speaker_gain = -1;
|
hs_speaker_gain = -1;
|
||||||
|
|
||||||
hs_send_button_press = 0;
|
hs_send_button_press = 0;
|
||||||
hs_send_at_cpkd = 0;
|
|
||||||
|
|
||||||
hs_ok_received = 0;
|
hs_ok_received = 0;
|
||||||
hs_ring_received = 0;
|
hs_ring_received = 0;
|
||||||
// TODO
|
hs_support_custom_indications = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hsp_hs_init(uint8_t rfcomm_channel_nr){
|
void hsp_hs_init(uint8_t rfcomm_channel_nr){
|
||||||
@ -256,11 +271,12 @@ void hsp_hs_connect(bd_addr_t bd_addr){
|
|||||||
void hsp_hs_disconnect(bd_addr_t bd_addr){
|
void hsp_hs_disconnect(bd_addr_t bd_addr){
|
||||||
switch (hsp_state){
|
switch (hsp_state){
|
||||||
case HSP_ACTIVE:
|
case HSP_ACTIVE:
|
||||||
hsp_state = HSP_W2_DISCONNECT_SCO;
|
printf("HSP_W4_USER_ACTION\n");
|
||||||
hs_send_at_cpkd = 1;
|
hsp_state = HSP_W4_USER_ACTION;
|
||||||
|
hs_send_button_press = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HSP_W4_RFCOMM_CONNECTED:
|
case HSP_W4_RFCOMM_CONNECTED:
|
||||||
|
printf("HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN \n");
|
||||||
hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
|
hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -296,15 +312,18 @@ static void hsp_run(){
|
|||||||
hs_ring_received = 0;
|
hs_ring_received = 0;
|
||||||
hs_send_button_press = 1;
|
hs_send_button_press = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hs_send_at_cpkd){
|
if (hs_ok_received){
|
||||||
int err = send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
|
hs_ok_received = 0;
|
||||||
if (!err) hs_send_at_cpkd = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hs_send_button_press){
|
if (hs_send_button_press){
|
||||||
int err = send_str_over_rfcomm(rfcomm_cid, HSP_HS_BUTTON_PRESS);
|
int err = 0;
|
||||||
|
if (hsp_state == HSP_W4_USER_ACTION){
|
||||||
|
err = send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
|
||||||
|
} else {
|
||||||
|
err = send_str_over_rfcomm(rfcomm_cid, HSP_HS_BUTTON_PRESS);
|
||||||
|
}
|
||||||
if (!err) hs_send_button_press = 0;
|
if (!err) hs_send_button_press = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -316,36 +335,32 @@ static void hsp_run(){
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HSP_W2_CONNECT_SCO:
|
case HSP_W2_CONNECT_SCO:
|
||||||
if (hs_ok_received){
|
hsp_state = HSP_W4_SCO_CONNECTED;
|
||||||
hs_ok_received = 0;
|
|
||||||
hsp_state = HSP_W4_SCO_CONNECTED;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HSP_W2_DISCONNECT_SCO:
|
case HSP_W2_DISCONNECT_SCO:
|
||||||
if (hs_ok_received){
|
hsp_state = HSP_W4_SCO_DISCONNECTED;
|
||||||
hs_ok_received = 0;
|
|
||||||
hsp_state = HSP_W4_SCO_DISCONNECTED;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HSP_ACTIVE:
|
case HSP_ACTIVE:
|
||||||
|
if (hs_ok_received) break;
|
||||||
if (hs_microphone_gain >= 0){
|
|
||||||
char buffer[10];
|
if (hs_microphone_gain >= 0){
|
||||||
sprintf(buffer, "%s=%d\r", HSP_HS_MICROPHONE_GAIN, hs_microphone_gain);
|
char buffer[20];
|
||||||
|
sprintf(buffer, "%s=%d\r\n", HSP_HS_MICROPHONE_GAIN, hs_microphone_gain);
|
||||||
err = send_str_over_rfcomm(rfcomm_cid, buffer);
|
err = send_str_over_rfcomm(rfcomm_cid, buffer);
|
||||||
if (!err) hs_microphone_gain = -1;
|
if (!err) hs_microphone_gain = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hs_speaker_gain >= 0){
|
if (hs_speaker_gain >= 0){
|
||||||
char buffer[10];
|
char buffer[20];
|
||||||
sprintf(buffer, "%s=%d\r", HSP_HS_SPEAKER_GAIN, hs_speaker_gain);
|
sprintf(buffer, "%s=%d\r\n", HSP_HS_SPEAKER_GAIN, hs_speaker_gain);
|
||||||
err = send_str_over_rfcomm(rfcomm_cid, buffer);
|
err = send_str_over_rfcomm(rfcomm_cid, buffer);
|
||||||
if (!err) hs_speaker_gain = -1;
|
if (!err) hs_speaker_gain = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -356,17 +371,39 @@ static void hsp_run(){
|
|||||||
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
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]);
|
// printf("packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
|
||||||
if (packet_type == RFCOMM_DATA_PACKET){
|
if (packet_type == RFCOMM_DATA_PACKET){
|
||||||
|
while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){
|
||||||
|
size--;
|
||||||
|
packet++;
|
||||||
|
}
|
||||||
if (strncmp((char *)packet, HSP_AG_RING, strlen(HSP_AG_RING)) == 0){
|
if (strncmp((char *)packet, HSP_AG_RING, strlen(HSP_AG_RING)) == 0){
|
||||||
printf("Received RING %s\n", HSP_AG_RING);
|
|
||||||
hs_ring_received = 1;
|
hs_ring_received = 1;
|
||||||
} if (strncmp((char *)packet, HSP_AG_OK, strlen(HSP_AG_OK)) == 0){
|
} if (strncmp((char *)packet, HSP_AG_OK, strlen(HSP_AG_OK)) == 0){
|
||||||
printf("Received OK %s\n", HSP_AG_OK);
|
|
||||||
hs_ok_received = 1;
|
hs_ok_received = 1;
|
||||||
} else if (strncmp((char *)packet, HSP_MICROPHONE_GAIN, strlen(HSP_MICROPHONE_GAIN)) == 0 ||
|
switch (hsp_state){
|
||||||
strncmp((char *)packet, HSP_SPEAKER_GAIN, strlen(HSP_SPEAKER_GAIN)) == 0){
|
case HSP_W4_RFCOMM_CONNECTED:
|
||||||
printf("Received changed gain info %c\n", packet[8]);
|
hsp_state = HSP_W2_CONNECT_SCO;
|
||||||
|
break;
|
||||||
|
case HSP_W4_USER_ACTION:
|
||||||
|
hsp_state = HSP_W2_DISCONNECT_SCO;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (strncmp((char *)packet, HSP_MICROPHONE_GAIN, strlen(HSP_MICROPHONE_GAIN)) == 0){
|
||||||
|
uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_MICROPHONE_GAIN)]);
|
||||||
|
emit_event(HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED, gain);
|
||||||
|
|
||||||
|
} else if (strncmp((char *)packet, HSP_SPEAKER_GAIN, strlen(HSP_SPEAKER_GAIN)) == 0){
|
||||||
|
uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_SPEAKER_GAIN)]);
|
||||||
|
emit_event(HSP_SUBEVENT_SPEAKER_GAIN_CHANGED, gain);
|
||||||
} else {
|
} else {
|
||||||
log_info("Received not yet supported command.\n");
|
if (!hsp_hs_callback) return;
|
||||||
|
// re-use incoming buffer to avoid reserving large buffers - ugly but efficient
|
||||||
|
uint8_t * event = packet - 3;
|
||||||
|
event[0] = HCI_EVENT_HSP_META;
|
||||||
|
event[1] = size + 1;
|
||||||
|
event[2] = HSP_SUBEVENT_AG_INDICATION;
|
||||||
|
(*hsp_hs_callback)(event, size+3);
|
||||||
}
|
}
|
||||||
hsp_run();
|
hsp_run();
|
||||||
return;
|
return;
|
||||||
@ -381,7 +418,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
case BTSTACK_EVENT_STATE:
|
case BTSTACK_EVENT_STATE:
|
||||||
// bt stack activated, get started
|
// bt stack activated, get started
|
||||||
if (packet[2] == HCI_STATE_WORKING){
|
if (packet[2] == HCI_STATE_WORKING){
|
||||||
hsp_hs_connect(remote);
|
printf("BTstack activated, get started .\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -436,7 +473,9 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
hsp_state = HSP_W2_DISCONNECT_SCO;
|
hsp_state = HSP_W2_DISCONNECT_SCO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hsp_state = HSP_ACTIVE;
|
hsp_state = HSP_ACTIVE;
|
||||||
|
emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,7 +487,8 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
rfcomm_cid = READ_BT_16(packet, 9);
|
rfcomm_cid = READ_BT_16(packet, 9);
|
||||||
printf("RFCOMM channel %u requested for %s\n", packet[8], bd_addr_to_str(event_addr));
|
printf("RFCOMM channel %u requested for %s\n", packet[8], bd_addr_to_str(event_addr));
|
||||||
rfcomm_accept_connection_internal(rfcomm_cid);
|
rfcomm_accept_connection_internal(rfcomm_cid);
|
||||||
hsp_state = HSP_W2_CONNECT_SCO;
|
|
||||||
|
hsp_state = HSP_W4_RFCOMM_CONNECTED;
|
||||||
hs_send_button_press = 1;
|
hs_send_button_press = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -458,6 +498,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
if (packet[2]) {
|
if (packet[2]) {
|
||||||
printf("RFCOMM channel open failed, status %u\n", packet[2]);
|
printf("RFCOMM channel open failed, status %u\n", packet[2]);
|
||||||
hsp_hs_reset_state();
|
hsp_hs_reset_state();
|
||||||
|
emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, packet[2]);
|
||||||
} else {
|
} else {
|
||||||
// data: event(8) , len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
|
// data: event(8) , len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
|
||||||
rfcomm_handle = READ_BT_16(packet, 9);
|
rfcomm_handle = READ_BT_16(packet, 9);
|
||||||
@ -468,7 +509,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
switch (hsp_state){
|
switch (hsp_state){
|
||||||
case HSP_W4_RFCOMM_CONNECTED:
|
case HSP_W4_RFCOMM_CONNECTED:
|
||||||
hsp_state = HSP_W2_CONNECT_SCO;
|
hsp_state = HSP_W2_CONNECT_SCO;
|
||||||
hs_send_at_cpkd = 1;
|
hs_send_button_press = 1;
|
||||||
break;
|
break;
|
||||||
case HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
|
case HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
|
||||||
hsp_state = HSP_W2_DISCONNECT_RFCOMM;
|
hsp_state = HSP_W2_DISCONNECT_RFCOMM;
|
||||||
@ -483,22 +524,26 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||||
|
printf("HCI_EVENT_DISCONNECTION_COMPLETE \n");
|
||||||
if (hsp_state != HSP_W4_SCO_DISCONNECTED){
|
if (hsp_state != HSP_W4_SCO_DISCONNECTED){
|
||||||
log_info("received gap disconnect in wrong hsp state");
|
printf("received gap disconnect in wrong hsp state");
|
||||||
}
|
}
|
||||||
handle = READ_BT_16(packet,3);
|
handle = READ_BT_16(packet,3);
|
||||||
if (handle == sco_handle){
|
if (handle == sco_handle){
|
||||||
sco_handle = 0;
|
sco_handle = 0;
|
||||||
hsp_state = HSP_W4_RFCOMM_DISCONNECTED;
|
hsp_state = HSP_W2_DISCONNECT_RFCOMM;
|
||||||
|
printf(" HSP_W2_DISCONNECT_RFCOMM\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RFCOMM_EVENT_CHANNEL_CLOSED:
|
case RFCOMM_EVENT_CHANNEL_CLOSED:
|
||||||
|
printf(" RFCOMM_EVENT_CHANNEL_CLOSED\n");
|
||||||
if (hsp_state != HSP_W4_RFCOMM_DISCONNECTED){
|
if (hsp_state != HSP_W4_RFCOMM_DISCONNECTED){
|
||||||
log_info("received RFCOMM disconnect in wrong hsp state");
|
printf("received RFCOMM disconnect in wrong hsp state");
|
||||||
}
|
}
|
||||||
printf("RFCOMM channel closed\n");
|
printf("RFCOMM channel closed\n");
|
||||||
hsp_hs_reset_state();
|
hsp_hs_reset_state();
|
||||||
|
emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -66,6 +66,13 @@ void hsp_hs_set_microphone_gain(uint8_t gain);
|
|||||||
// AT+VGS=[0..15]
|
// AT+VGS=[0..15]
|
||||||
void hsp_hs_set_speaker_gain(uint8_t gain);
|
void hsp_hs_set_speaker_gain(uint8_t gain);
|
||||||
|
|
||||||
|
void hsp_hs_support_custom_indications(int enable);
|
||||||
|
|
||||||
|
// When support custom commands is enabled, AG will send HSP_SUBEVENT_AG_INDICATION.
|
||||||
|
// 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 * indication);
|
||||||
|
|
||||||
#if defined __cplusplus
|
#if defined __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,9 +47,20 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
|
||||||
#include <btstack/hci_cmds.h>
|
#include <btstack/hci_cmds.h>
|
||||||
#include <btstack/run_loop.h>
|
#include <btstack/run_loop.h>
|
||||||
|
#include <btstack/sdp_util.h>
|
||||||
|
|
||||||
#include "hci.h"
|
#include "hci.h"
|
||||||
#include "l2cap.h"
|
#include "l2cap.h"
|
||||||
@ -59,24 +70,155 @@
|
|||||||
|
|
||||||
const uint8_t hsp_service_buffer[150];
|
const uint8_t hsp_service_buffer[150];
|
||||||
const uint8_t rfcomm_channel_nr = 1;
|
const uint8_t rfcomm_channel_nr = 1;
|
||||||
const char hsp_ag_service_name[] = "Headset Test";
|
const char hsp_hs_service_name[] = "Headset 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 char hs_cmd_buffer[100];
|
||||||
|
|
||||||
|
// prototypes
|
||||||
|
static void show_usage();
|
||||||
|
|
||||||
|
|
||||||
|
// Testig User Interface
|
||||||
|
static data_source_t stdin_source;
|
||||||
|
|
||||||
|
static void show_usage(){
|
||||||
|
printf("\n--- Bluetooth HSP Headset 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("z - set microphone gain 0\n");
|
||||||
|
printf("m - set microphone gain 8\n");
|
||||||
|
printf("M - set microphone gain 15\n");
|
||||||
|
printf("o - set speaker gain 0\n");
|
||||||
|
printf("s - set speaker gain 8\n");
|
||||||
|
printf("S - set speaker gain 15\n");
|
||||||
|
printf("---\n");
|
||||||
|
printf("Ctrl-c - exit\n");
|
||||||
|
printf("---\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
hsp_hs_connect(pts_addr);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
printf("Establishing audio connection to local mac %s...\n", bd_addr_to_str(local_mac));
|
||||||
|
hsp_hs_connect(local_mac);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
printf("Releasing audio connection.\n");
|
||||||
|
hsp_hs_disconnect();
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
printf("Setting microphone gain 0\n");
|
||||||
|
hsp_hs_set_microphone_gain(0);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
printf("Setting microphone gain 8\n");
|
||||||
|
hsp_hs_set_microphone_gain(8);
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
printf("Setting microphone gain 15\n");
|
||||||
|
hsp_hs_set_microphone_gain(15);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
printf("Setting speaker gain 0\n");
|
||||||
|
hsp_hs_set_speaker_gain(0);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
printf("Setting speaker gain 8\n");
|
||||||
|
hsp_hs_set_speaker_gain(8);
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
printf("Setting speaker gain 15\n");
|
||||||
|
hsp_hs_set_speaker_gain(15);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
show_usage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void setup_cli(){
|
||||||
|
struct termios term = {0};
|
||||||
|
if (tcgetattr(0, &term) < 0)
|
||||||
|
perror("tcsetattr()");
|
||||||
|
term.c_lflag &= ~ICANON;
|
||||||
|
term.c_lflag &= ~ECHO;
|
||||||
|
term.c_cc[VMIN] = 1;
|
||||||
|
term.c_cc[VTIME] = 0;
|
||||||
|
if (tcsetattr(0, TCSANOW, &term) < 0)
|
||||||
|
perror("tcsetattr ICANON");
|
||||||
|
|
||||||
|
stdin_source.fd = 0; // stdin
|
||||||
|
stdin_source.process = &stdin_process;
|
||||||
|
run_loop_add_data_source(&stdin_source);
|
||||||
|
|
||||||
|
show_usage();
|
||||||
|
}
|
||||||
|
|
||||||
void packet_handler(uint8_t * event, uint16_t event_size){
|
void packet_handler(uint8_t * event, uint16_t event_size){
|
||||||
|
switch (event[2]) {
|
||||||
|
case HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE:
|
||||||
|
if (event[3] == 0){
|
||||||
|
printf("Audio connection established.\n\n");
|
||||||
|
} else {
|
||||||
|
printf("Audio connection establishment failed with status %u\n", event[3]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE:
|
||||||
|
if (event[3] == 0){
|
||||||
|
printf("Audio connection released.\n\n");
|
||||||
|
} else {
|
||||||
|
printf("Audio connection releasing failed with status %u\n", event[3]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED:
|
||||||
|
printf("Received microphone gain change %d\n", event[3]);
|
||||||
|
break;
|
||||||
|
case HSP_SUBEVENT_SPEAKER_GAIN_CHANGED:
|
||||||
|
printf("Received speaker gain change %d\n", event[3]);
|
||||||
|
break;
|
||||||
|
case HSP_SUBEVENT_AG_INDICATION:
|
||||||
|
memset(hs_cmd_buffer, 0, sizeof(hs_cmd_buffer));
|
||||||
|
int size = event_size <= sizeof(hs_cmd_buffer)? event_size : sizeof(hs_cmd_buffer);
|
||||||
|
memcpy(hs_cmd_buffer, &event[3], size - 1);
|
||||||
|
printf("Received custom indication: \"%s\". \nExit code or call hsp_hs_send_result.\n", hs_cmd_buffer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("event not handled %u\n", event[2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// init SDP, create record for SPP and register with SDP
|
||||||
memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer));
|
memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer));
|
||||||
hsp_hs_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_ag_service_name, 0);
|
hsp_hs_create_service((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);
|
||||||
|
|
||||||
sdp_init();
|
sdp_init();
|
||||||
sdp_register_service_internal(NULL, (uint8_t *)hsp_service_buffer);
|
sdp_register_service_internal(NULL, (uint8_t *)hsp_service_buffer);
|
||||||
|
|
||||||
hsp_hs_init(rfcomm_channel_nr);
|
|
||||||
hsp_hs_register_packet_handler(packet_handler);
|
|
||||||
// turn on!
|
// turn on!
|
||||||
hci_power_control(HCI_POWER_ON);
|
hci_power_control(HCI_POWER_ON);
|
||||||
|
|
||||||
|
setup_cli();
|
||||||
|
|
||||||
// go!
|
// go!
|
||||||
run_loop_execute();
|
run_loop_execute();
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user