mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-16 08:42:28 +00:00
gatt-service/aics,mics,vcs.vocs_server: update struct name
This commit is contained in:
parent
667e58960b
commit
374a3da36f
@ -57,11 +57,11 @@
|
||||
|
||||
static btstack_linked_list_t aics_services;
|
||||
|
||||
static audio_input_control_service_server_t * aics_server_find_service_for_attribute_handle(uint16_t attribute_handle){
|
||||
static aics_server_connection_t * aics_server_find_service_for_attribute_handle(uint16_t attribute_handle){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &aics_services);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
audio_input_control_service_server_t * item = (audio_input_control_service_server_t*) btstack_linked_list_iterator_next(&it);
|
||||
aics_server_connection_t * item = (aics_server_connection_t*) btstack_linked_list_iterator_next(&it);
|
||||
if (attribute_handle < item->start_handle) continue;
|
||||
if (attribute_handle > item->end_handle) continue;
|
||||
return item;
|
||||
@ -71,60 +71,60 @@ static audio_input_control_service_server_t * aics_server_find_service_for_attri
|
||||
|
||||
static uint16_t aics_server_read_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
|
||||
UNUSED(con_handle);
|
||||
audio_input_control_service_server_t * client = aics_server_find_service_for_attribute_handle(attribute_handle);
|
||||
if (client == NULL){
|
||||
aics_server_connection_t * connection = aics_server_find_service_for_attribute_handle(attribute_handle);
|
||||
if (connection == NULL){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_state_value_handle){
|
||||
if (attribute_handle == connection->audio_input_state_value_handle){
|
||||
uint8_t value[4];
|
||||
value[0] = (uint8_t)client->info->audio_input_state.gain_setting_db;
|
||||
value[1] = client->info->audio_input_state.mute_mode;
|
||||
value[2] = client->info->audio_input_state.gain_mode;
|
||||
value[3] = client->audio_input_state_change_counter;
|
||||
value[0] = (uint8_t)connection->info->audio_input_state.gain_setting_db;
|
||||
value[1] = connection->info->audio_input_state.mute_mode;
|
||||
value[2] = connection->info->audio_input_state.gain_mode;
|
||||
value[3] = connection->audio_input_state_change_counter;
|
||||
return att_read_callback_handle_blob(value, sizeof(value), offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
|
||||
if (attribute_handle == client->gain_settings_properties_value_handle){
|
||||
if (attribute_handle == connection->gain_settings_properties_value_handle){
|
||||
uint8_t value[3];
|
||||
|
||||
value[0] = client->info->gain_settings_properties.gain_settings_units;
|
||||
value[1] = (uint8_t)client->info->gain_settings_properties.gain_settings_minimum;
|
||||
value[2] = (uint8_t)client->info->gain_settings_properties.gain_settings_maximum;
|
||||
value[0] = connection->info->gain_settings_properties.gain_settings_units;
|
||||
value[1] = (uint8_t)connection->info->gain_settings_properties.gain_settings_minimum;
|
||||
value[2] = (uint8_t)connection->info->gain_settings_properties.gain_settings_maximum;
|
||||
return att_read_callback_handle_blob(value, sizeof(value), offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_type_value_handle){
|
||||
return att_read_callback_handle_byte((uint8_t)client->info->audio_input_type, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_input_type_value_handle){
|
||||
return att_read_callback_handle_byte((uint8_t)connection->info->audio_input_type, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_status_value_handle){
|
||||
return att_read_callback_handle_byte((uint8_t)client->audio_input_status, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_input_status_value_handle){
|
||||
return att_read_callback_handle_byte((uint8_t)connection->audio_input_status, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_description_value_handle){
|
||||
return att_read_callback_handle_blob((uint8_t *)client->info->audio_input_description, client->audio_input_description_len, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_input_description_value_handle){
|
||||
return att_read_callback_handle_blob((uint8_t *)connection->info->audio_input_description, connection->audio_input_description_len, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
|
||||
if (attribute_handle == client->audio_input_state_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(client->audio_input_state_client_configuration, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_input_state_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(connection->audio_input_state_client_configuration, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_status_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(client->audio_input_status_client_configuration, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_input_status_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(connection->audio_input_status_client_configuration, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_description_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(client->audio_input_description_client_configuration, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_input_description_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(connection->audio_input_description_client_configuration, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void aics_server_emit_mute_mode(audio_input_control_service_server_t * connection){
|
||||
static void aics_server_emit_mute_mode(aics_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
@ -141,7 +141,7 @@ static void aics_server_emit_mute_mode(audio_input_control_service_server_t * co
|
||||
(*connection->info->packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void aics_server_emit_gain_mode(audio_input_control_service_server_t * connection){
|
||||
static void aics_server_emit_gain_mode(aics_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
@ -158,7 +158,7 @@ static void aics_server_emit_gain_mode(audio_input_control_service_server_t * co
|
||||
(*connection->info->packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void aics_server_emit_gain(audio_input_control_service_server_t * connection){
|
||||
static void aics_server_emit_gain(aics_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
@ -175,7 +175,7 @@ static void aics_server_emit_gain(audio_input_control_service_server_t * connect
|
||||
(*connection->info->packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void aics_server_emit_audio_input_description(audio_input_control_service_server_t * connection){
|
||||
static void aics_server_emit_audio_input_description(aics_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
@ -195,73 +195,73 @@ static void aics_server_emit_audio_input_description(audio_input_control_service
|
||||
(*connection->info->packet_handler)(HCI_EVENT_PACKET, 0, event, pos);
|
||||
}
|
||||
|
||||
static bool aics_server_set_gain(audio_input_control_service_server_t * aics, int8_t gain_db){
|
||||
if (gain_db < aics->info->gain_settings_properties.gain_settings_minimum) return false;
|
||||
if (gain_db > aics->info->gain_settings_properties.gain_settings_maximum) return false;
|
||||
static bool aics_server_set_gain(aics_server_connection_t * connection, int8_t gain_db){
|
||||
if (gain_db < connection->info->gain_settings_properties.gain_settings_minimum) return false;
|
||||
if (gain_db > connection->info->gain_settings_properties.gain_settings_maximum) return false;
|
||||
|
||||
aics->info->audio_input_state.gain_setting_db = gain_db;
|
||||
connection->info->audio_input_state.gain_setting_db = gain_db;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void aics_server_update_change_counter(audio_input_control_service_server_t * aics){
|
||||
aics->audio_input_state_change_counter++;
|
||||
static void aics_server_update_change_counter(aics_server_connection_t * connection){
|
||||
connection->audio_input_state_change_counter++;
|
||||
}
|
||||
|
||||
static void aics_server_can_send_now(void * context){
|
||||
audio_input_control_service_server_t * aics = (audio_input_control_service_server_t *) context;
|
||||
aics_server_connection_t * connection = (aics_server_connection_t *) context;
|
||||
|
||||
if ((aics->scheduled_tasks & AICS_TASK_SEND_AUDIO_INPUT_STATE) != 0){
|
||||
aics->scheduled_tasks &= ~AICS_TASK_SEND_AUDIO_INPUT_STATE;
|
||||
if ((connection->scheduled_tasks & AICS_TASK_SEND_AUDIO_INPUT_STATE) != 0){
|
||||
connection->scheduled_tasks &= ~AICS_TASK_SEND_AUDIO_INPUT_STATE;
|
||||
|
||||
uint8_t value[4];
|
||||
value[0] = (uint8_t)aics->info->audio_input_state.gain_setting_db;
|
||||
value[1] = aics->info->audio_input_state.mute_mode;
|
||||
value[2] = aics->info->audio_input_state.gain_mode;
|
||||
value[3] = aics->audio_input_state_change_counter;
|
||||
value[0] = (uint8_t)connection->info->audio_input_state.gain_setting_db;
|
||||
value[1] = connection->info->audio_input_state.mute_mode;
|
||||
value[2] = connection->info->audio_input_state.gain_mode;
|
||||
value[3] = connection->audio_input_state_change_counter;
|
||||
|
||||
att_server_notify(aics->con_handle, aics->audio_input_state_value_handle, &value[0], sizeof(value));
|
||||
att_server_notify(connection->con_handle, connection->audio_input_state_value_handle, &value[0], sizeof(value));
|
||||
|
||||
} else if ((aics->scheduled_tasks & AICS_TASK_SEND_AUDIO_INPUT_STATUS) != 0){
|
||||
aics->scheduled_tasks &= ~AICS_TASK_SEND_AUDIO_INPUT_STATUS;
|
||||
uint8_t value = (uint8_t)aics->audio_input_status;
|
||||
att_server_notify(aics->con_handle, aics->audio_input_status_value_handle, &value, 1);
|
||||
} else if ((connection->scheduled_tasks & AICS_TASK_SEND_AUDIO_INPUT_STATUS) != 0){
|
||||
connection->scheduled_tasks &= ~AICS_TASK_SEND_AUDIO_INPUT_STATUS;
|
||||
uint8_t value = (uint8_t)connection->audio_input_status;
|
||||
att_server_notify(connection->con_handle, connection->audio_input_status_value_handle, &value, 1);
|
||||
|
||||
} else if ((aics->scheduled_tasks & AICS_TASK_SEND_AUDIO_INPUT_DESCRIPTION) != 0){
|
||||
aics->scheduled_tasks &= ~AICS_TASK_SEND_AUDIO_INPUT_DESCRIPTION;
|
||||
att_server_notify(aics->con_handle, aics->audio_input_description_value_handle, (uint8_t *)aics->info->audio_input_description, aics->audio_input_description_len);
|
||||
} else if ((connection->scheduled_tasks & AICS_TASK_SEND_AUDIO_INPUT_DESCRIPTION) != 0){
|
||||
connection->scheduled_tasks &= ~AICS_TASK_SEND_AUDIO_INPUT_DESCRIPTION;
|
||||
att_server_notify(connection->con_handle, connection->audio_input_description_value_handle, (uint8_t *)connection->info->audio_input_description, connection->audio_input_description_len);
|
||||
}
|
||||
|
||||
if (aics->scheduled_tasks != 0){
|
||||
att_server_register_can_send_now_callback(&aics->scheduled_tasks_callback, aics->con_handle);
|
||||
if (connection->scheduled_tasks != 0){
|
||||
att_server_register_can_send_now_callback(&connection->scheduled_tasks_callback, connection->con_handle);
|
||||
} else {
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &aics_services);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
audio_input_control_service_server_t * item = (audio_input_control_service_server_t*) btstack_linked_list_iterator_next(&it);
|
||||
aics_server_connection_t * item = (aics_server_connection_t*) btstack_linked_list_iterator_next(&it);
|
||||
if (item->scheduled_tasks == 0) continue;
|
||||
att_server_register_can_send_now_callback(&aics->scheduled_tasks_callback, aics->con_handle);
|
||||
att_server_register_can_send_now_callback(&connection->scheduled_tasks_callback, connection->con_handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aics_server_set_callback(audio_input_control_service_server_t * aics, uint8_t task){
|
||||
if (aics->con_handle == HCI_CON_HANDLE_INVALID){
|
||||
aics->scheduled_tasks &= ~task;
|
||||
static void aics_server_set_callback(aics_server_connection_t * connection, uint8_t task){
|
||||
if (connection->con_handle == HCI_CON_HANDLE_INVALID){
|
||||
connection->scheduled_tasks &= ~task;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t scheduled_tasks = aics->scheduled_tasks;
|
||||
aics->scheduled_tasks |= task;
|
||||
uint8_t scheduled_tasks = connection->scheduled_tasks;
|
||||
connection->scheduled_tasks |= task;
|
||||
if (scheduled_tasks == 0){
|
||||
aics->scheduled_tasks_callback.callback = &aics_server_can_send_now;
|
||||
aics->scheduled_tasks_callback.context = (void*) aics;
|
||||
att_server_register_can_send_now_callback(&aics->scheduled_tasks_callback, aics->con_handle);
|
||||
connection->scheduled_tasks_callback.callback = &aics_server_can_send_now;
|
||||
connection->scheduled_tasks_callback.context = (void*) connection;
|
||||
att_server_register_can_send_now_callback(&connection->scheduled_tasks_callback, connection->con_handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void aics_server_set_con_handle(audio_input_control_service_server_t * aics, hci_con_handle_t con_handle, uint16_t configuration){
|
||||
aics->con_handle = (configuration == 0) ? HCI_CON_HANDLE_INVALID : con_handle;
|
||||
static void aics_server_set_con_handle(aics_server_connection_t * connection, hci_con_handle_t con_handle, uint16_t configuration){
|
||||
connection->con_handle = (configuration == 0) ? HCI_CON_HANDLE_INVALID : con_handle;
|
||||
}
|
||||
|
||||
static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
|
||||
@ -269,12 +269,12 @@ static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
UNUSED(transaction_mode);
|
||||
UNUSED(offset);
|
||||
|
||||
audio_input_control_service_server_t * client = aics_server_find_service_for_attribute_handle(attribute_handle);
|
||||
if (client == NULL){
|
||||
aics_server_connection_t * connection = aics_server_find_service_for_attribute_handle(attribute_handle);
|
||||
if (connection == NULL){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_control_value_handle){
|
||||
if (attribute_handle == connection->audio_input_control_value_handle){
|
||||
if (buffer_size == 0){
|
||||
return AICS_ERROR_CODE_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
@ -285,7 +285,7 @@ static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
}
|
||||
uint8_t change_counter = buffer[1];
|
||||
|
||||
if (change_counter != client->audio_input_state_change_counter){
|
||||
if (change_counter != connection->audio_input_state_change_counter){
|
||||
return AICS_ERROR_CODE_INVALID_CHANGE_COUNTER;
|
||||
}
|
||||
|
||||
@ -295,14 +295,14 @@ static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
return AICS_ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
if (!aics_server_set_gain(client, (int8_t)buffer[2])) {
|
||||
if (!aics_server_set_gain(connection, (int8_t)buffer[2])) {
|
||||
return AICS_ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
switch (client->info->audio_input_state.gain_mode){
|
||||
switch (connection->info->audio_input_state.gain_mode){
|
||||
case AICS_GAIN_MODE_MANUAL_ONLY:
|
||||
case AICS_GAIN_MODE_MANUAL:
|
||||
aics_server_emit_gain(client);
|
||||
aics_server_emit_gain(connection);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -310,13 +310,13 @@ static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
break;
|
||||
|
||||
case AICS_OPCODE_UMUTE:
|
||||
switch (client->info->audio_input_state.mute_mode){
|
||||
switch (connection->info->audio_input_state.mute_mode){
|
||||
case AICS_MUTE_MODE_DISABLED:
|
||||
aics_server_emit_mute_mode(client);
|
||||
aics_server_emit_mute_mode(connection);
|
||||
return AICS_ERROR_CODE_MUTE_DISABLED;
|
||||
case AICS_MUTE_MODE_MUTED:
|
||||
client->info->audio_input_state.mute_mode = AICS_MUTE_MODE_NOT_MUTED;
|
||||
aics_server_emit_mute_mode(client);
|
||||
connection->info->audio_input_state.mute_mode = AICS_MUTE_MODE_NOT_MUTED;
|
||||
aics_server_emit_mute_mode(connection);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -324,13 +324,13 @@ static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
break;
|
||||
|
||||
case AICS_OPCODE_MUTE:
|
||||
switch (client->info->audio_input_state.mute_mode){
|
||||
switch (connection->info->audio_input_state.mute_mode){
|
||||
case AICS_MUTE_MODE_DISABLED:
|
||||
aics_server_emit_mute_mode(client);
|
||||
aics_server_emit_mute_mode(connection);
|
||||
return AICS_ERROR_CODE_MUTE_DISABLED;
|
||||
case AICS_MUTE_MODE_NOT_MUTED:
|
||||
client->info->audio_input_state.mute_mode = AICS_MUTE_MODE_MUTED;
|
||||
aics_server_emit_mute_mode(client);
|
||||
connection->info->audio_input_state.mute_mode = AICS_MUTE_MODE_MUTED;
|
||||
aics_server_emit_mute_mode(connection);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -338,10 +338,10 @@ static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
break;
|
||||
|
||||
case AICS_OPCODE_SET_MANUAL_GAIN_MODE:
|
||||
switch (client->info->audio_input_state.gain_mode){
|
||||
switch (connection->info->audio_input_state.gain_mode){
|
||||
case AICS_GAIN_MODE_AUTOMATIC:
|
||||
client->info->audio_input_state.gain_mode = AICS_GAIN_MODE_MANUAL;
|
||||
aics_server_emit_gain_mode(client);
|
||||
connection->info->audio_input_state.gain_mode = AICS_GAIN_MODE_MANUAL;
|
||||
aics_server_emit_gain_mode(connection);
|
||||
break;
|
||||
default:
|
||||
return AICS_ERROR_CODE_GAIN_MODE_CHANGE_NOT_ALLOWED;
|
||||
@ -349,10 +349,10 @@ static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
break;
|
||||
|
||||
case AICS_OPCODE_SET_AUTOMATIC_GAIN_MODE:
|
||||
switch (client->info->audio_input_state.gain_mode){
|
||||
switch (connection->info->audio_input_state.gain_mode){
|
||||
case AICS_GAIN_MODE_MANUAL:
|
||||
client->info->audio_input_state.gain_mode = AICS_GAIN_MODE_AUTOMATIC;
|
||||
aics_server_emit_gain_mode(client);
|
||||
connection->info->audio_input_state.gain_mode = AICS_GAIN_MODE_AUTOMATIC;
|
||||
aics_server_emit_gain_mode(connection);
|
||||
break;
|
||||
default:
|
||||
return AICS_ERROR_CODE_GAIN_MODE_CHANGE_NOT_ALLOWED;
|
||||
@ -363,30 +363,30 @@ static int aics_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
return AICS_ERROR_CODE_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
aics_server_update_change_counter(client);
|
||||
aics_server_set_callback(client, AICS_TASK_SEND_AUDIO_INPUT_STATE);
|
||||
aics_server_update_change_counter(connection);
|
||||
aics_server_set_callback(connection, AICS_TASK_SEND_AUDIO_INPUT_STATE);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_description_value_handle){
|
||||
btstack_strcpy(client->info->audio_input_description, AICS_MAX_AUDIO_INPUT_DESCRIPTION_LENGTH, (char *)buffer);
|
||||
client->audio_input_description_len = (uint8_t) strlen(client->info->audio_input_description);
|
||||
aics_server_emit_audio_input_description(client);
|
||||
aics_server_set_callback(client, AICS_TASK_SEND_AUDIO_INPUT_DESCRIPTION);
|
||||
if (attribute_handle == connection->audio_input_description_value_handle){
|
||||
btstack_strcpy(connection->info->audio_input_description, AICS_MAX_AUDIO_INPUT_DESCRIPTION_LENGTH, (char *)buffer);
|
||||
connection->audio_input_description_len = (uint8_t) strlen(connection->info->audio_input_description);
|
||||
aics_server_emit_audio_input_description(connection);
|
||||
aics_server_set_callback(connection, AICS_TASK_SEND_AUDIO_INPUT_DESCRIPTION);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_state_client_configuration_handle){
|
||||
client->audio_input_state_client_configuration = little_endian_read_16(buffer, 0);
|
||||
aics_server_set_con_handle(client, con_handle, client->audio_input_state_client_configuration);
|
||||
if (attribute_handle == connection->audio_input_state_client_configuration_handle){
|
||||
connection->audio_input_state_client_configuration = little_endian_read_16(buffer, 0);
|
||||
aics_server_set_con_handle(connection, con_handle, connection->audio_input_state_client_configuration);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_status_client_configuration_handle){
|
||||
client->audio_input_status_client_configuration = little_endian_read_16(buffer, 0);
|
||||
aics_server_set_con_handle(client, con_handle, client->audio_input_status_client_configuration);
|
||||
if (attribute_handle == connection->audio_input_status_client_configuration_handle){
|
||||
connection->audio_input_status_client_configuration = little_endian_read_16(buffer, 0);
|
||||
aics_server_set_con_handle(connection, con_handle, connection->audio_input_status_client_configuration);
|
||||
}
|
||||
|
||||
if (attribute_handle == client->audio_input_description_client_configuration_handle){
|
||||
client->audio_input_description_client_configuration = little_endian_read_16(buffer, 0);
|
||||
aics_server_set_con_handle(client, con_handle, client->audio_input_description_client_configuration);
|
||||
if (attribute_handle == connection->audio_input_description_client_configuration_handle){
|
||||
connection->audio_input_description_client_configuration = little_endian_read_16(buffer, 0);
|
||||
aics_server_set_con_handle(connection, con_handle, connection->audio_input_description_client_configuration);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -409,7 +409,7 @@ static void aics_server_packet_handler(uint8_t packet_type, uint16_t channel, ui
|
||||
btstack_linked_list_iterator_init(&it, &aics_services);
|
||||
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
audio_input_control_service_server_t * connection = (audio_input_control_service_server_t*) btstack_linked_list_iterator_next(&it);
|
||||
aics_server_connection_t * connection = (aics_server_connection_t*) btstack_linked_list_iterator_next(&it);
|
||||
if (connection->con_handle != con_handle) continue;
|
||||
connection->con_handle = HCI_CON_HANDLE_INVALID;
|
||||
}
|
||||
@ -419,83 +419,83 @@ static void aics_server_packet_handler(uint8_t packet_type, uint16_t channel, ui
|
||||
}
|
||||
}
|
||||
|
||||
void audio_input_control_service_server_init(audio_input_control_service_server_t * aics){
|
||||
btstack_assert(aics != NULL);
|
||||
btstack_assert(aics->info->packet_handler != NULL);
|
||||
void audio_input_control_service_server_init(aics_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
|
||||
btstack_linked_list_add(&aics_services, (btstack_linked_item_t *)aics);
|
||||
btstack_linked_list_add(&aics_services, (btstack_linked_item_t *)connection);
|
||||
|
||||
aics->scheduled_tasks = 0;
|
||||
aics->con_handle = HCI_CON_HANDLE_INVALID;
|
||||
connection->scheduled_tasks = 0;
|
||||
connection->con_handle = HCI_CON_HANDLE_INVALID;
|
||||
|
||||
// get characteristic value handle and client configuration handle
|
||||
aics->audio_input_state_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_STATE);
|
||||
aics->audio_input_state_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_STATE);
|
||||
connection->audio_input_state_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_STATE);
|
||||
connection->audio_input_state_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_STATE);
|
||||
|
||||
aics->gain_settings_properties_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_GAIN_SETTINGS_ATTRIBUTE);
|
||||
|
||||
aics->audio_input_type_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_TYPE);
|
||||
|
||||
aics->audio_input_status_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_STATUS);
|
||||
aics->audio_input_status_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_STATUS);
|
||||
connection->gain_settings_properties_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_GAIN_SETTINGS_ATTRIBUTE);
|
||||
|
||||
aics->audio_input_control_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_CONTROL_POINT);
|
||||
|
||||
aics->audio_input_description_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_DESCRIPTION);
|
||||
aics->audio_input_description_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(aics->start_handle, aics->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_DESCRIPTION);
|
||||
connection->audio_input_type_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_TYPE);
|
||||
|
||||
connection->audio_input_status_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_STATUS);
|
||||
connection->audio_input_status_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_STATUS);
|
||||
|
||||
connection->audio_input_control_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_CONTROL_POINT);
|
||||
|
||||
connection->audio_input_description_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_DESCRIPTION);
|
||||
connection->audio_input_description_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_INPUT_DESCRIPTION);
|
||||
|
||||
#ifdef ENABLE_TESTING_SUPPORT
|
||||
printf("AICS[%d] 0x%02x - 0x%02x \n", aics->index, aics->start_handle, aics->end_handle);
|
||||
printf(" audio_input_state 0x%02x \n", aics->audio_input_state_value_handle);
|
||||
printf(" audio_input_state CCC 0x%02x \n", aics->audio_input_state_client_configuration_handle);
|
||||
printf("AICS[%d] 0x%02x - 0x%02x \n", connection->index, connection->start_handle, connection->end_handle);
|
||||
printf(" audio_input_state 0x%02x \n", connection->audio_input_state_value_handle);
|
||||
printf(" audio_input_state CCC 0x%02x \n", connection->audio_input_state_client_configuration_handle);
|
||||
|
||||
printf(" gain_settings_properties 0x%02x \n", aics->gain_settings_properties_value_handle);
|
||||
printf(" audio_input_type 0x%02x \n", aics->audio_input_type_value_handle);
|
||||
printf(" gain_settings_properties 0x%02x \n", connection->gain_settings_properties_value_handle);
|
||||
printf(" audio_input_type 0x%02x \n", connection->audio_input_type_value_handle);
|
||||
|
||||
printf(" audio_input_status 0x%02x \n", aics->audio_input_status_value_handle);
|
||||
printf(" audio_input_status CCC 0x%02x \n", aics->audio_input_status_client_configuration_handle);
|
||||
printf(" audio_input_status 0x%02x \n", connection->audio_input_status_value_handle);
|
||||
printf(" audio_input_status CCC 0x%02x \n", connection->audio_input_status_client_configuration_handle);
|
||||
|
||||
printf(" control_value_handle 0x%02x \n", aics->audio_input_control_value_handle);
|
||||
printf(" description_value_handle 0x%02x \n", aics->audio_input_description_value_handle);
|
||||
printf(" description_value_handle CCC 0x%02x \n", aics->audio_input_description_client_configuration_handle);
|
||||
printf(" control_value_handle 0x%02x \n", connection->audio_input_control_value_handle);
|
||||
printf(" description_value_handle 0x%02x \n", connection->audio_input_description_value_handle);
|
||||
printf(" description_value_handle CCC 0x%02x \n", connection->audio_input_description_client_configuration_handle);
|
||||
#endif
|
||||
|
||||
// register service with ATT Server
|
||||
aics->service_handler.start_handle = aics->start_handle;
|
||||
aics->service_handler.end_handle = aics->end_handle;
|
||||
aics->service_handler.read_callback = &aics_server_read_callback;
|
||||
aics->service_handler.write_callback = &aics_server_write_callback;
|
||||
aics->service_handler.packet_handler = aics_server_packet_handler;
|
||||
att_server_register_service_handler(&aics->service_handler);
|
||||
connection->service_handler.start_handle = connection->start_handle;
|
||||
connection->service_handler.end_handle = connection->end_handle;
|
||||
connection->service_handler.read_callback = &aics_server_read_callback;
|
||||
connection->service_handler.write_callback = &aics_server_write_callback;
|
||||
connection->service_handler.packet_handler = aics_server_packet_handler;
|
||||
att_server_register_service_handler(&connection->service_handler);
|
||||
}
|
||||
|
||||
uint8_t audio_input_control_service_server_set_audio_input_state(audio_input_control_service_server_t * aics, aics_audio_input_state_t * audio_input_state){
|
||||
btstack_assert(aics != NULL);
|
||||
uint8_t audio_input_control_service_server_set_audio_input_state(aics_server_connection_t * connection, aics_audio_input_state_t * audio_input_state){
|
||||
btstack_assert(connection != NULL);
|
||||
|
||||
bool valid_range = aics_server_set_gain(aics, audio_input_state->gain_setting_db);
|
||||
bool valid_range = aics_server_set_gain(connection, audio_input_state->gain_setting_db);
|
||||
if (!valid_range){
|
||||
return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
|
||||
}
|
||||
|
||||
aics->info->audio_input_state.mute_mode = audio_input_state->mute_mode;
|
||||
aics->info->audio_input_state.gain_mode = audio_input_state->gain_mode;
|
||||
aics_server_update_change_counter(aics);
|
||||
connection->info->audio_input_state.mute_mode = audio_input_state->mute_mode;
|
||||
connection->info->audio_input_state.gain_mode = audio_input_state->gain_mode;
|
||||
aics_server_update_change_counter(connection);
|
||||
|
||||
aics_server_set_callback(aics, AICS_TASK_SEND_AUDIO_INPUT_STATE);
|
||||
aics_server_set_callback(connection, AICS_TASK_SEND_AUDIO_INPUT_STATE);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void audio_input_control_service_server_set_audio_input_status(audio_input_control_service_server_t * aics, aics_audio_input_status_t audio_input_status){
|
||||
btstack_assert(aics != NULL);
|
||||
aics->audio_input_status = audio_input_status;
|
||||
aics_server_set_callback(aics, AICS_TASK_SEND_AUDIO_INPUT_STATUS);
|
||||
void audio_input_control_service_server_set_audio_input_status(aics_server_connection_t * connection, aics_audio_input_status_t audio_input_status){
|
||||
btstack_assert(connection != NULL);
|
||||
connection->audio_input_status = audio_input_status;
|
||||
aics_server_set_callback(connection, AICS_TASK_SEND_AUDIO_INPUT_STATUS);
|
||||
}
|
||||
|
||||
void audio_input_control_service_server_set_audio_input_description(audio_input_control_service_server_t * aics, const char * audio_input_desc){
|
||||
btstack_assert(aics != NULL);
|
||||
btstack_strcpy(aics->info->audio_input_description, AICS_MAX_AUDIO_INPUT_DESCRIPTION_LENGTH, (char *)audio_input_desc);
|
||||
aics->audio_input_description_len = (uint8_t) strlen(aics->info->audio_input_description);
|
||||
aics_server_set_callback(aics, AICS_TASK_SEND_AUDIO_INPUT_DESCRIPTION);
|
||||
void audio_input_control_service_server_set_audio_input_description(aics_server_connection_t * connection, const char * audio_input_desc){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_strcpy(connection->info->audio_input_description, AICS_MAX_AUDIO_INPUT_DESCRIPTION_LENGTH, (char *)audio_input_desc);
|
||||
connection->audio_input_description_len = (uint8_t) strlen(connection->info->audio_input_description);
|
||||
aics_server_set_callback(connection, AICS_TASK_SEND_AUDIO_INPUT_DESCRIPTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -176,7 +176,7 @@ typedef struct {
|
||||
uint16_t audio_input_description_client_configuration;
|
||||
btstack_context_callback_registration_t audio_input_description_callback;
|
||||
|
||||
} audio_input_control_service_server_t;
|
||||
} aics_server_connection_t;
|
||||
|
||||
|
||||
/**
|
||||
@ -185,9 +185,9 @@ typedef struct {
|
||||
* - GATTSERVICE_SUBEVENT_AICS_SERVER_GAIN_MODE
|
||||
* - GATTSERVICE_SUBEVENT_AICS_SERVER_GAIN_CHANGED
|
||||
* - GATTSERVICE_SUBEVENT_AICS_SERVER_AUDIO_INPUT_DESC_CHANGED
|
||||
* @param aics service storage
|
||||
* @param connection service storage
|
||||
*/
|
||||
void audio_input_control_service_server_init(audio_input_control_service_server_t * aics);
|
||||
void audio_input_control_service_server_init(aics_server_connection_t * connection);
|
||||
|
||||
/**
|
||||
* @brief Set audio input state of the AICS service. If successful, all registered clients will be notified of change.
|
||||
@ -195,21 +195,21 @@ void audio_input_control_service_server_init(audio_input_control_service_server_
|
||||
* @param audio_input_state see aics_audio_input_state_t
|
||||
* @return status ERROR_CODE_SUCCESS if successful, otherwise ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS if gain setting is out of a valid range [gain_settings_minimum, gain_settings_maximum] .
|
||||
*/
|
||||
uint8_t audio_input_control_service_server_set_audio_input_state(audio_input_control_service_server_t * aics, aics_audio_input_state_t * audio_input_state);
|
||||
uint8_t audio_input_control_service_server_set_audio_input_state(aics_server_connection_t * aics, aics_audio_input_state_t * audio_input_state);
|
||||
|
||||
/**
|
||||
* @brief Set audio input status of the AICS service. If successful, all registered clients will be notified of change.
|
||||
* @param aics service
|
||||
* @param audio_input_status see aics_audio_input_status_t
|
||||
*/
|
||||
void audio_input_control_service_server_set_audio_input_status(audio_input_control_service_server_t * aics, aics_audio_input_status_t audio_input_status);
|
||||
void audio_input_control_service_server_set_audio_input_status(aics_server_connection_t * aics, aics_audio_input_status_t audio_input_status);
|
||||
|
||||
/**
|
||||
* @brief Set audio input description of the AICS service. If successful, all registered clients will be notified of change.
|
||||
* @param aics service
|
||||
* @param audio_input_desc
|
||||
*/
|
||||
void audio_input_control_service_server_set_audio_input_description(audio_input_control_service_server_t * aics, const char * audio_input_desc);
|
||||
void audio_input_control_service_server_set_audio_input_description(aics_server_connection_t * aics, const char * audio_input_desc);
|
||||
|
||||
/* API_END */
|
||||
|
||||
|
@ -65,7 +65,7 @@ static uint16_t mics_server_mute_state_handle_client_configuration;
|
||||
|
||||
static btstack_packet_handler_t mics_server_callback;
|
||||
|
||||
static audio_input_control_service_server_t aics_services[AICS_MAX_NUM_SERVICES];
|
||||
static aics_server_connection_t aics_services[AICS_MAX_NUM_SERVICES];
|
||||
static uint8_t aics_services_num;
|
||||
|
||||
static void mics_server_emit_mute(gatt_microphone_control_mute_t mute_state){
|
||||
@ -174,7 +174,7 @@ void microphone_control_service_server_init(gatt_microphone_control_mute_t mute_
|
||||
}
|
||||
log_info("Include AICS service 0x%02x-0x%02x", included_service_start_handle, included_service_end_handle);
|
||||
|
||||
audio_input_control_service_server_t * service = &aics_services[aics_services_num];
|
||||
aics_server_connection_t * service = &aics_services[aics_services_num];
|
||||
service->start_handle = included_service_start_handle;
|
||||
service->end_handle = included_service_end_handle;
|
||||
service->index = aics_services_num;
|
||||
|
@ -99,10 +99,10 @@ static uint16_t vcs_control_point_value_handle;
|
||||
|
||||
static btstack_packet_handler_t vcs_server_event_callback;
|
||||
|
||||
static audio_input_control_service_server_t aics_services[AICS_MAX_NUM_SERVICES];
|
||||
static aics_server_connection_t aics_services[AICS_MAX_NUM_SERVICES];
|
||||
static uint8_t aics_services_num;
|
||||
|
||||
static volume_offset_control_service_server_t vocs_services[VOCS_MAX_NUM_SERVICES];
|
||||
static vocs_server_connection_t vocs_services[VOCS_MAX_NUM_SERVICES];
|
||||
static uint8_t vocs_services_num;
|
||||
|
||||
|
||||
@ -356,7 +356,7 @@ static void vcs_server_init_included_aics_services(uint16_t vcs_start_handle, ui
|
||||
}
|
||||
log_info("Include AICS service 0x%02x-0x%02x", included_service_start_handle, included_service_end_handle);
|
||||
|
||||
audio_input_control_service_server_t * service = &aics_services[aics_services_num];
|
||||
aics_server_connection_t * service = &aics_services[aics_services_num];
|
||||
service->start_handle = included_service_start_handle;
|
||||
service->end_handle = included_service_end_handle;
|
||||
service->index = aics_services_num;
|
||||
@ -389,7 +389,7 @@ static void vcs_server_init_included_vocs_services(uint16_t start_handle, uint16
|
||||
}
|
||||
log_info("Include VOCS service 0x%02x-0x%02x", included_service_start_handle, included_service_end_handle);
|
||||
|
||||
volume_offset_control_service_server_t * service = &vocs_services[vocs_services_num];
|
||||
vocs_server_connection_t * service = &vocs_services[vocs_services_num];
|
||||
service->start_handle = included_service_start_handle;
|
||||
service->end_handle = included_service_end_handle;
|
||||
service->index = vocs_services_num;
|
||||
|
@ -57,11 +57,11 @@
|
||||
|
||||
static btstack_linked_list_t vocs_services;
|
||||
|
||||
static volume_offset_control_service_server_t * vocs_server_find_service_for_attribute_handle(uint16_t attribute_handle){
|
||||
static vocs_server_connection_t * vocs_server_find_service_for_attribute_handle(uint16_t attribute_handle){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &vocs_services);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
volume_offset_control_service_server_t * item = (volume_offset_control_service_server_t*) btstack_linked_list_iterator_next(&it);
|
||||
vocs_server_connection_t * item = (vocs_server_connection_t*) btstack_linked_list_iterator_next(&it);
|
||||
if (attribute_handle < item->start_handle) continue;
|
||||
if (attribute_handle > item->end_handle) continue;
|
||||
return item;
|
||||
@ -71,100 +71,100 @@ static volume_offset_control_service_server_t * vocs_server_find_service_for_att
|
||||
|
||||
static uint16_t vocs_server_read_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
|
||||
UNUSED(con_handle);
|
||||
volume_offset_control_service_server_t * vocs = vocs_server_find_service_for_attribute_handle(attribute_handle);
|
||||
if (vocs == NULL){
|
||||
vocs_server_connection_t * connection = vocs_server_find_service_for_attribute_handle(attribute_handle);
|
||||
if (connection == NULL){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->volume_offset_state_value_handle){
|
||||
if (attribute_handle == connection->volume_offset_state_value_handle){
|
||||
uint8_t value[3];
|
||||
little_endian_store_16(value, 0, vocs->info->volume_offset);
|
||||
value[2] = vocs->volume_offset_state_change_counter;
|
||||
little_endian_store_16(value, 0, connection->info->volume_offset);
|
||||
value[2] = connection->volume_offset_state_change_counter;
|
||||
return att_read_callback_handle_blob(value, sizeof(value), offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->audio_location_value_handle){
|
||||
return att_read_callback_handle_little_endian_32(vocs->info->audio_location, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_location_value_handle){
|
||||
return att_read_callback_handle_little_endian_32(connection->info->audio_location, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->audio_output_description_value_handle){
|
||||
return att_read_callback_handle_blob((uint8_t *)vocs->info->audio_output_description, (uint16_t) strlen(vocs->info->audio_output_description), offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_output_description_value_handle){
|
||||
return att_read_callback_handle_blob((uint8_t *)connection->info->audio_output_description, (uint16_t) strlen(connection->info->audio_output_description), offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
|
||||
if (attribute_handle == vocs->volume_offset_state_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(vocs->volume_offset_state_client_configuration, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->volume_offset_state_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(connection->volume_offset_state_client_configuration, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->audio_location_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(vocs->audio_location_client_configuration, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_location_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(connection->audio_location_client_configuration, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->audio_output_description_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(vocs->audio_output_description_client_configuration, offset, buffer, buffer_size);
|
||||
if (attribute_handle == connection->audio_output_description_client_configuration_handle){
|
||||
return att_read_callback_handle_little_endian_16(connection->audio_output_description_client_configuration, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vocs_server_update_change_counter(volume_offset_control_service_server_t * vocs){
|
||||
vocs->volume_offset_state_change_counter++;
|
||||
static void vocs_server_update_change_counter(vocs_server_connection_t * connection){
|
||||
connection->volume_offset_state_change_counter++;
|
||||
}
|
||||
|
||||
static void vocs_server_can_send_now(void * context){
|
||||
volume_offset_control_service_server_t * vocs = (volume_offset_control_service_server_t *) context;
|
||||
vocs_server_connection_t * connection = (vocs_server_connection_t *) context;
|
||||
|
||||
if ((vocs->scheduled_tasks & VOCS_TASK_SEND_VOLUME_OFFSET) != 0){
|
||||
vocs->scheduled_tasks &= ~VOCS_TASK_SEND_VOLUME_OFFSET;
|
||||
if ((connection->scheduled_tasks & VOCS_TASK_SEND_VOLUME_OFFSET) != 0){
|
||||
connection->scheduled_tasks &= ~VOCS_TASK_SEND_VOLUME_OFFSET;
|
||||
uint8_t value[3];
|
||||
little_endian_store_16(value, 0, (uint16_t)vocs->info->volume_offset);
|
||||
value[2] = vocs->volume_offset_state_change_counter;
|
||||
att_server_notify(vocs->con_handle, vocs->volume_offset_state_value_handle, &value[0], sizeof(value));
|
||||
little_endian_store_16(value, 0, (uint16_t)connection->info->volume_offset);
|
||||
value[2] = connection->volume_offset_state_change_counter;
|
||||
att_server_notify(connection->con_handle, connection->volume_offset_state_value_handle, &value[0], sizeof(value));
|
||||
|
||||
} else if ((vocs->scheduled_tasks & VOCS_TASK_SEND_AUDIO_LOCATION) != 0) {
|
||||
vocs->scheduled_tasks &= ~VOCS_TASK_SEND_AUDIO_LOCATION;
|
||||
} else if ((connection->scheduled_tasks & VOCS_TASK_SEND_AUDIO_LOCATION) != 0) {
|
||||
connection->scheduled_tasks &= ~VOCS_TASK_SEND_AUDIO_LOCATION;
|
||||
uint8_t value[4];
|
||||
little_endian_store_32(value, 0, vocs->info->audio_location);
|
||||
att_server_notify(vocs->con_handle, vocs->audio_location_value_handle, &value[0], sizeof(value));
|
||||
} else if ((vocs->scheduled_tasks & VOCS_TASK_SEND_AUDIO_OUTPUT_DESCRIPTION) != 0) {
|
||||
vocs->scheduled_tasks &= ~VOCS_TASK_SEND_AUDIO_OUTPUT_DESCRIPTION;
|
||||
att_server_notify(vocs->con_handle, vocs->audio_output_description_value_handle, (uint8_t *)vocs->info->audio_output_description, vocs->audio_output_description_len);
|
||||
little_endian_store_32(value, 0, connection->info->audio_location);
|
||||
att_server_notify(connection->con_handle, connection->audio_location_value_handle, &value[0], sizeof(value));
|
||||
} else if ((connection->scheduled_tasks & VOCS_TASK_SEND_AUDIO_OUTPUT_DESCRIPTION) != 0) {
|
||||
connection->scheduled_tasks &= ~VOCS_TASK_SEND_AUDIO_OUTPUT_DESCRIPTION;
|
||||
att_server_notify(connection->con_handle, connection->audio_output_description_value_handle, (uint8_t *)connection->info->audio_output_description, connection->audio_output_description_len);
|
||||
}
|
||||
|
||||
if (vocs->scheduled_tasks != 0){
|
||||
att_server_register_can_send_now_callback(&vocs->scheduled_tasks_callback, vocs->con_handle);
|
||||
if (connection->scheduled_tasks != 0){
|
||||
att_server_register_can_send_now_callback(&connection->scheduled_tasks_callback, connection->con_handle);
|
||||
} else {
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &vocs_services);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
volume_offset_control_service_server_t * item = (volume_offset_control_service_server_t*) btstack_linked_list_iterator_next(&it);
|
||||
vocs_server_connection_t * item = (vocs_server_connection_t*) btstack_linked_list_iterator_next(&it);
|
||||
if (item->scheduled_tasks == 0) continue;
|
||||
att_server_register_can_send_now_callback(&vocs->scheduled_tasks_callback, vocs->con_handle);
|
||||
att_server_register_can_send_now_callback(&connection->scheduled_tasks_callback, connection->con_handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vocs_server_set_callback(volume_offset_control_service_server_t * vocs, uint8_t task){
|
||||
if (vocs->con_handle == HCI_CON_HANDLE_INVALID){
|
||||
vocs->scheduled_tasks &= ~task;
|
||||
static void vocs_server_set_callback(vocs_server_connection_t * connection, uint8_t task){
|
||||
if (connection->con_handle == HCI_CON_HANDLE_INVALID){
|
||||
connection->scheduled_tasks &= ~task;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t scheduled_tasks = vocs->scheduled_tasks;
|
||||
vocs->scheduled_tasks |= task;
|
||||
uint8_t scheduled_tasks = connection->scheduled_tasks;
|
||||
connection->scheduled_tasks |= task;
|
||||
if (scheduled_tasks == 0){
|
||||
vocs->scheduled_tasks_callback.callback = &vocs_server_can_send_now;
|
||||
vocs->scheduled_tasks_callback.context = (void*) vocs;
|
||||
att_server_register_can_send_now_callback(&vocs->scheduled_tasks_callback, vocs->con_handle);
|
||||
connection->scheduled_tasks_callback.callback = &vocs_server_can_send_now;
|
||||
connection->scheduled_tasks_callback.context = (void*) connection;
|
||||
att_server_register_can_send_now_callback(&connection->scheduled_tasks_callback, connection->con_handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void vocs_server_set_con_handle(volume_offset_control_service_server_t * vocs, hci_con_handle_t con_handle, uint16_t configuration){
|
||||
vocs->con_handle = (configuration == 0) ? HCI_CON_HANDLE_INVALID : con_handle;
|
||||
static void vocs_server_set_con_handle(vocs_server_connection_t * connection, hci_con_handle_t con_handle, uint16_t configuration){
|
||||
connection->con_handle = (configuration == 0) ? HCI_CON_HANDLE_INVALID : con_handle;
|
||||
}
|
||||
|
||||
static bool vocs_server_set_volume_offset(volume_offset_control_service_server_t * vocs, int16_t volume_offset){
|
||||
static bool vocs_server_set_volume_offset(vocs_server_connection_t * vocs, int16_t volume_offset){
|
||||
if (volume_offset < -255) return false;
|
||||
if (volume_offset > 255) return false;
|
||||
|
||||
@ -172,68 +172,68 @@ static bool vocs_server_set_volume_offset(volume_offset_control_service_server_t
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vocs_server_set_audio_location(volume_offset_control_service_server_t * vocs, uint32_t audio_location){
|
||||
static bool vocs_server_set_audio_location(vocs_server_connection_t * connection, uint32_t audio_location){
|
||||
if (audio_location == LE_AUDIO_LOCATION_MASK_NOT_ALLOWED) return false;
|
||||
if ( (audio_location & LE_AUDIO_LOCATION_MASK_RFU) != 0) return false;
|
||||
|
||||
vocs->info->audio_location = audio_location;
|
||||
connection->info->audio_location = audio_location;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void vocs_server_emit_volume_offset(volume_offset_control_service_server_t * vocs){
|
||||
btstack_assert(vocs != NULL);
|
||||
btstack_assert(vocs->info != NULL);
|
||||
btstack_assert(vocs->info->packet_handler != NULL);
|
||||
static void vocs_server_emit_volume_offset(vocs_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
|
||||
uint8_t event[8];
|
||||
uint8_t pos = 0;
|
||||
event[pos++] = HCI_EVENT_GATTSERVICE_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = GATTSERVICE_SUBEVENT_VOCS_SERVER_VOLUME_OFFSET;
|
||||
little_endian_store_16(event, pos, vocs->con_handle);
|
||||
little_endian_store_16(event, pos, connection->con_handle);
|
||||
pos += 2;
|
||||
event[pos++] = vocs->index;
|
||||
little_endian_store_16(event, pos, vocs->info->volume_offset);
|
||||
event[pos++] = connection->index;
|
||||
little_endian_store_16(event, pos, connection->info->volume_offset);
|
||||
pos += 2;
|
||||
(*vocs->info->packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
(*connection->info->packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void vocs_server_emit_audio_location(volume_offset_control_service_server_t * vocs){
|
||||
btstack_assert(vocs != NULL);
|
||||
btstack_assert(vocs->info != NULL);
|
||||
btstack_assert(vocs->info->packet_handler != NULL);
|
||||
static void vocs_server_emit_audio_location(vocs_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
|
||||
uint8_t event[10];
|
||||
uint8_t pos = 0;
|
||||
event[pos++] = HCI_EVENT_GATTSERVICE_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = GATTSERVICE_SUBEVENT_VOCS_SERVER_AUDIO_LOCATION;
|
||||
little_endian_store_16(event, pos, vocs->con_handle);
|
||||
little_endian_store_16(event, pos, connection->con_handle);
|
||||
pos += 2;
|
||||
event[pos++] = vocs->index;
|
||||
little_endian_store_32(event, pos, vocs->info->audio_location);
|
||||
event[pos++] = connection->index;
|
||||
little_endian_store_32(event, pos, connection->info->audio_location);
|
||||
pos += 4;
|
||||
(*vocs->info->packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
(*connection->info->packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void vocs_server_emit_audio_output_description(volume_offset_control_service_server_t * vocs){
|
||||
btstack_assert(vocs != NULL);
|
||||
btstack_assert(vocs->info != NULL);
|
||||
btstack_assert(vocs->info->packet_handler != NULL);
|
||||
static void vocs_server_emit_audio_output_description(vocs_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
|
||||
uint8_t event[7 + VOCS_MAX_AUDIO_OUTPUT_DESCRIPTION_LENGTH];
|
||||
uint8_t pos = 0;
|
||||
event[pos++] = HCI_EVENT_GATTSERVICE_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = GATTSERVICE_SUBEVENT_VOCS_SERVER_AUDIO_OUTPUT_DESCRIPTION;
|
||||
little_endian_store_16(event, pos, vocs->con_handle);
|
||||
little_endian_store_16(event, pos, connection->con_handle);
|
||||
pos += 2;
|
||||
event[pos++] = vocs->index;
|
||||
event[pos++] = (uint8_t)vocs->audio_output_description_len;
|
||||
memcpy(&event[pos], (uint8_t *)vocs->info->audio_output_description, vocs->audio_output_description_len + 1);
|
||||
pos += vocs->audio_output_description_len;
|
||||
event[pos++] = connection->index;
|
||||
event[pos++] = (uint8_t)connection->audio_output_description_len;
|
||||
memcpy(&event[pos], (uint8_t *)connection->info->audio_output_description, connection->audio_output_description_len + 1);
|
||||
pos += connection->audio_output_description_len;
|
||||
event[pos++] = 0;
|
||||
(*vocs->info->packet_handler)(HCI_EVENT_PACKET, 0, event, pos);
|
||||
(*connection->info->packet_handler)(HCI_EVENT_PACKET, 0, event, pos);
|
||||
}
|
||||
|
||||
|
||||
@ -242,12 +242,12 @@ static int vocs_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
UNUSED(transaction_mode);
|
||||
UNUSED(offset);
|
||||
|
||||
volume_offset_control_service_server_t * vocs = vocs_server_find_service_for_attribute_handle(attribute_handle);
|
||||
if (vocs == NULL){
|
||||
vocs_server_connection_t * connection = vocs_server_find_service_for_attribute_handle(attribute_handle);
|
||||
if (connection == NULL){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->volume_offset_control_point_value_handle){
|
||||
if (attribute_handle == connection->volume_offset_control_point_value_handle){
|
||||
if (buffer_size == 0){
|
||||
return VOCS_ERROR_CODE_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
@ -258,7 +258,7 @@ static int vocs_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
}
|
||||
uint8_t change_counter = buffer[1];
|
||||
|
||||
if (change_counter != vocs->volume_offset_state_change_counter){
|
||||
if (change_counter != connection->volume_offset_state_change_counter){
|
||||
return VOCS_ERROR_CODE_INVALID_CHANGE_COUNTER;
|
||||
}
|
||||
|
||||
@ -269,51 +269,51 @@ static int vocs_server_write_callback(hci_con_handle_t con_handle, uint16_t attr
|
||||
return VOCS_ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
if (!vocs_server_set_volume_offset(vocs, volume_offset)) {
|
||||
if (!vocs_server_set_volume_offset(connection, volume_offset)) {
|
||||
return VOCS_ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
vocs_server_emit_volume_offset(vocs);
|
||||
vocs_server_emit_volume_offset(connection);
|
||||
break;
|
||||
|
||||
default:
|
||||
return VOCS_ERROR_CODE_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
vocs_server_update_change_counter(vocs);
|
||||
vocs_server_set_callback(vocs, VOCS_TASK_SEND_VOLUME_OFFSET);
|
||||
vocs_server_update_change_counter(connection);
|
||||
vocs_server_set_callback(connection, VOCS_TASK_SEND_VOLUME_OFFSET);
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->audio_location_value_handle){
|
||||
if (attribute_handle == connection->audio_location_value_handle){
|
||||
if (buffer_size != 4){
|
||||
return 0;
|
||||
}
|
||||
uint32_t audio_location = little_endian_read_32(buffer, 0);
|
||||
if (vocs_server_set_audio_location(vocs, audio_location)) {
|
||||
vocs_server_emit_audio_location(vocs);
|
||||
vocs_server_set_callback(vocs, VOCS_TASK_SEND_AUDIO_LOCATION);
|
||||
if (vocs_server_set_audio_location(connection, audio_location)) {
|
||||
vocs_server_emit_audio_location(connection);
|
||||
vocs_server_set_callback(connection, VOCS_TASK_SEND_AUDIO_LOCATION);
|
||||
}
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->audio_output_description_value_handle){
|
||||
btstack_strcpy(vocs->info->audio_output_description, vocs->audio_output_description_len, (char *)buffer);
|
||||
vocs->audio_output_description_len = (uint8_t) strlen(vocs->info->audio_output_description);
|
||||
vocs_server_emit_audio_output_description(vocs);
|
||||
vocs_server_set_callback(vocs, VOCS_TASK_SEND_AUDIO_OUTPUT_DESCRIPTION);
|
||||
if (attribute_handle == connection->audio_output_description_value_handle){
|
||||
btstack_strcpy(connection->info->audio_output_description, connection->audio_output_description_len, (char *)buffer);
|
||||
connection->audio_output_description_len = (uint8_t) strlen(connection->info->audio_output_description);
|
||||
vocs_server_emit_audio_output_description(connection);
|
||||
vocs_server_set_callback(connection, VOCS_TASK_SEND_AUDIO_OUTPUT_DESCRIPTION);
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->volume_offset_state_client_configuration_handle){
|
||||
vocs->volume_offset_state_client_configuration = little_endian_read_16(buffer, 0);
|
||||
vocs_server_set_con_handle(vocs, con_handle, vocs->volume_offset_state_client_configuration);
|
||||
if (attribute_handle == connection->volume_offset_state_client_configuration_handle){
|
||||
connection->volume_offset_state_client_configuration = little_endian_read_16(buffer, 0);
|
||||
vocs_server_set_con_handle(connection, con_handle, connection->volume_offset_state_client_configuration);
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->audio_location_client_configuration_handle){
|
||||
vocs->audio_location_client_configuration = little_endian_read_16(buffer, 0);
|
||||
vocs_server_set_con_handle(vocs, con_handle, vocs->audio_location_client_configuration);
|
||||
if (attribute_handle == connection->audio_location_client_configuration_handle){
|
||||
connection->audio_location_client_configuration = little_endian_read_16(buffer, 0);
|
||||
vocs_server_set_con_handle(connection, con_handle, connection->audio_location_client_configuration);
|
||||
}
|
||||
|
||||
if (attribute_handle == vocs->audio_output_description_client_configuration_handle){
|
||||
vocs->audio_output_description_client_configuration = little_endian_read_16(buffer, 0);
|
||||
vocs_server_set_con_handle(vocs, con_handle, vocs->audio_output_description_client_configuration);
|
||||
if (attribute_handle == connection->audio_output_description_client_configuration_handle){
|
||||
connection->audio_output_description_client_configuration = little_endian_read_16(buffer, 0);
|
||||
vocs_server_set_con_handle(connection, con_handle, connection->audio_output_description_client_configuration);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -336,7 +336,7 @@ static void vocs_server_packet_handler(uint8_t packet_type, uint16_t channel, ui
|
||||
btstack_linked_list_iterator_init(&it, &vocs_services);
|
||||
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
volume_offset_control_service_server_t * item = (volume_offset_control_service_server_t*) btstack_linked_list_iterator_next(&it);
|
||||
vocs_server_connection_t * item = (vocs_server_connection_t*) btstack_linked_list_iterator_next(&it);
|
||||
if (item->con_handle != con_handle) continue;
|
||||
item->con_handle = HCI_CON_HANDLE_INVALID;
|
||||
}
|
||||
@ -347,68 +347,68 @@ static void vocs_server_packet_handler(uint8_t packet_type, uint16_t channel, ui
|
||||
}
|
||||
|
||||
|
||||
void volume_offset_control_service_server_init(volume_offset_control_service_server_t * vocs){
|
||||
btstack_assert(vocs != NULL);
|
||||
btstack_assert(vocs->info->packet_handler != NULL);
|
||||
void volume_offset_control_service_server_init(vocs_server_connection_t * connection){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_assert(connection->info->packet_handler != NULL);
|
||||
|
||||
btstack_linked_list_add(&vocs_services, (btstack_linked_item_t *)vocs);
|
||||
btstack_linked_list_add(&vocs_services, (btstack_linked_item_t *)connection);
|
||||
|
||||
vocs->scheduled_tasks = 0;
|
||||
vocs->con_handle = HCI_CON_HANDLE_INVALID;
|
||||
connection->scheduled_tasks = 0;
|
||||
connection->con_handle = HCI_CON_HANDLE_INVALID;
|
||||
|
||||
// get characteristic value handle and client configuration handle
|
||||
vocs->volume_offset_state_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(vocs->start_handle, vocs->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_OFFSET_STATE);
|
||||
vocs->volume_offset_state_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(vocs->start_handle, vocs->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_OFFSET_STATE);
|
||||
connection->volume_offset_state_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_OFFSET_STATE);
|
||||
connection->volume_offset_state_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_OFFSET_STATE);
|
||||
|
||||
vocs->audio_location_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(vocs->start_handle, vocs->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_LOCATION);
|
||||
vocs->audio_location_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(vocs->start_handle, vocs->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_LOCATION);
|
||||
connection->audio_location_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_LOCATION);
|
||||
connection->audio_location_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_LOCATION);
|
||||
|
||||
vocs->volume_offset_control_point_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(vocs->start_handle, vocs->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_VOLUME_OFFSET_CONTROL_POINT);
|
||||
|
||||
vocs->audio_output_description_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(vocs->start_handle, vocs->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_OUTPUT_DESCRIPTION);
|
||||
vocs->audio_output_description_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(vocs->start_handle, vocs->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_OUTPUT_DESCRIPTION);
|
||||
connection->volume_offset_control_point_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_VOLUME_OFFSET_CONTROL_POINT);
|
||||
|
||||
connection->audio_output_description_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_OUTPUT_DESCRIPTION);
|
||||
connection->audio_output_description_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(connection->start_handle, connection->end_handle, ORG_BLUETOOTH_CHARACTERISTIC_AUDIO_OUTPUT_DESCRIPTION);
|
||||
|
||||
#ifdef ENABLE_TESTING_SUPPORT
|
||||
printf("VOCS[%d] 0x%02x - 0x%02x \n", vocs->index, vocs->start_handle, vocs->end_handle);
|
||||
printf(" volume_offset_state 0x%02x \n", vocs->volume_offset_state_value_handle);
|
||||
printf(" volume_offset_state CCC 0x%02x \n", vocs->volume_offset_state_client_configuration_handle);
|
||||
printf("VOCS[%d] 0x%02x - 0x%02x \n", connection->index, connection->start_handle, connection->end_handle);
|
||||
printf(" volume_offset_state 0x%02x \n", connection->volume_offset_state_value_handle);
|
||||
printf(" volume_offset_state CCC 0x%02x \n", connection->volume_offset_state_client_configuration_handle);
|
||||
|
||||
printf(" audio_location 0x%02x \n", vocs->audio_location_value_handle);
|
||||
printf(" audio_location CCC 0x%02x \n", vocs->audio_location_client_configuration_handle);
|
||||
printf(" audio_location 0x%02x \n", connection->audio_location_value_handle);
|
||||
printf(" audio_location CCC 0x%02x \n", connection->audio_location_client_configuration_handle);
|
||||
|
||||
printf(" control_point_value_handle 0x%02x \n", vocs->volume_offset_control_point_value_handle);
|
||||
printf(" control_point_value_handle 0x%02x \n", connection->volume_offset_control_point_value_handle);
|
||||
|
||||
printf(" description_value_handle 0x%02x \n", vocs->audio_output_description_value_handle);
|
||||
printf(" description_value_handle CCC 0x%02x \n", vocs->audio_output_description_client_configuration_handle);
|
||||
printf(" description_value_handle 0x%02x \n", connection->audio_output_description_value_handle);
|
||||
printf(" description_value_handle CCC 0x%02x \n", connection->audio_output_description_client_configuration_handle);
|
||||
#endif
|
||||
|
||||
// register service with ATT Server
|
||||
vocs->service_handler.start_handle = vocs->start_handle;
|
||||
vocs->service_handler.end_handle = vocs->end_handle;
|
||||
vocs->service_handler.read_callback = &vocs_server_read_callback;
|
||||
vocs->service_handler.write_callback = &vocs_server_write_callback;
|
||||
vocs->service_handler.packet_handler = vocs_server_packet_handler;
|
||||
att_server_register_service_handler(&vocs->service_handler);
|
||||
connection->service_handler.start_handle = connection->start_handle;
|
||||
connection->service_handler.end_handle = connection->end_handle;
|
||||
connection->service_handler.read_callback = &vocs_server_read_callback;
|
||||
connection->service_handler.write_callback = &vocs_server_write_callback;
|
||||
connection->service_handler.packet_handler = vocs_server_packet_handler;
|
||||
att_server_register_service_handler(&connection->service_handler);
|
||||
}
|
||||
|
||||
uint8_t volume_offset_control_service_server_set_volume_offset(volume_offset_control_service_server_t * vocs, int16_t volume_offset){
|
||||
btstack_assert(vocs != NULL);
|
||||
vocs->info->volume_offset = volume_offset;
|
||||
vocs_server_update_change_counter(vocs);
|
||||
vocs_server_set_callback(vocs, VOCS_TASK_SEND_VOLUME_OFFSET);
|
||||
uint8_t volume_offset_control_service_server_set_volume_offset(vocs_server_connection_t * connection, int16_t volume_offset){
|
||||
btstack_assert(connection != NULL);
|
||||
connection->info->volume_offset = volume_offset;
|
||||
vocs_server_update_change_counter(connection);
|
||||
vocs_server_set_callback(connection, VOCS_TASK_SEND_VOLUME_OFFSET);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t volume_offset_control_service_server_set_audio_location(volume_offset_control_service_server_t * vocs, uint32_t audio_location){
|
||||
btstack_assert(vocs != NULL);
|
||||
vocs->info->audio_location = audio_location;
|
||||
vocs_server_set_callback(vocs, VOCS_TASK_SEND_AUDIO_LOCATION);
|
||||
uint8_t volume_offset_control_service_server_set_audio_location(vocs_server_connection_t * connection, uint32_t audio_location){
|
||||
btstack_assert(connection != NULL);
|
||||
connection->info->audio_location = audio_location;
|
||||
vocs_server_set_callback(connection, VOCS_TASK_SEND_AUDIO_LOCATION);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void volume_offset_control_service_server_set_audio_output_description(volume_offset_control_service_server_t * vocs, const char * audio_output_desc){
|
||||
btstack_assert(vocs != NULL);
|
||||
btstack_strcpy(vocs->info->audio_output_description, vocs->audio_output_description_len, (char *)audio_output_desc);
|
||||
vocs->audio_output_description_len = (uint8_t) strlen(vocs->info->audio_output_description);
|
||||
vocs_server_set_callback(vocs, VOCS_TASK_SEND_AUDIO_OUTPUT_DESCRIPTION);
|
||||
void volume_offset_control_service_server_set_audio_output_description(vocs_server_connection_t * connection, const char * audio_output_desc){
|
||||
btstack_assert(connection != NULL);
|
||||
btstack_strcpy(connection->info->audio_output_description, connection->audio_output_description_len, (char *)audio_output_desc);
|
||||
connection->audio_output_description_len = (uint8_t) strlen(connection->info->audio_output_description);
|
||||
vocs_server_set_callback(connection, VOCS_TASK_SEND_AUDIO_OUTPUT_DESCRIPTION);
|
||||
}
|
||||
|
@ -118,42 +118,42 @@ typedef struct {
|
||||
uint16_t audio_output_description_client_configuration_handle;
|
||||
uint16_t audio_output_description_client_configuration;
|
||||
btstack_context_callback_registration_t audio_output_description_callback;
|
||||
} volume_offset_control_service_server_t;
|
||||
} vocs_server_connection_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Init Volume Offset Control Service Server with ATT DB. Event emitted to the event callback of the volume_offset_control_service_server_t struct:
|
||||
* @brief Init Volume Offset Control Service Server with ATT DB. Event emitted to the event callback of the vocs_server_connection_t struct:
|
||||
* - GATTSERVICE_SUBEVENT_VOCS_SERVER_VOLUME_OFFSET
|
||||
* - GATTSERVICE_SUBEVENT_VOCS_SERVER_AUDIO_LOCATION
|
||||
* - GATTSERVICE_SUBEVENT_VOCS_SERVER_AUDIO_OUTPUT_DESCRIPTION
|
||||
* -
|
||||
* @param vocs service storage
|
||||
* @param connection service storage
|
||||
*/
|
||||
void volume_offset_control_service_server_init(volume_offset_control_service_server_t * vocs);
|
||||
void volume_offset_control_service_server_init(vocs_server_connection_t * connection);
|
||||
|
||||
/**
|
||||
* @brief Set volume offset of the VOCS service. If successful, all registered clients will be notified of change.
|
||||
* @param vocs service
|
||||
* @param connection service
|
||||
* @param volume_offset
|
||||
* @return status ERROR_CODE_SUCCESS if successful
|
||||
*/
|
||||
uint8_t volume_offset_control_service_server_set_volume_offset(volume_offset_control_service_server_t * vocs, int16_t volume_offset);
|
||||
uint8_t volume_offset_control_service_server_set_volume_offset(vocs_server_connection_t * connection, int16_t volume_offset);
|
||||
|
||||
/**
|
||||
* @brief Set audio location of the VOCS service. If successful, all registered clients will be notified of change.
|
||||
* @param vocs service
|
||||
* @param connection service
|
||||
* @param audio_location see VOCS_AUDIO_LOCATION_* defines above
|
||||
* @return status ERROR_CODE_SUCCESS if successful
|
||||
*/
|
||||
uint8_t volume_offset_control_service_server_set_audio_location(volume_offset_control_service_server_t * vocs, uint32_t audio_location);
|
||||
uint8_t volume_offset_control_service_server_set_audio_location(vocs_server_connection_t * connection, uint32_t audio_location);
|
||||
|
||||
/**
|
||||
* @brief Set audio output description of the VOCS service. If successful, all registered clients will be notified of change.
|
||||
* @param vocs service
|
||||
* @param connection service
|
||||
* @param audio_output_desc
|
||||
* @return status ERROR_CODE_SUCCESS if successful
|
||||
*/
|
||||
void volume_offset_control_service_server_set_audio_output_description(volume_offset_control_service_server_t * vocs, const char * audio_output_desc);
|
||||
void volume_offset_control_service_server_set_audio_output_description(vocs_server_connection_t * connection, const char * audio_output_desc);
|
||||
|
||||
/* API_END */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user