diff --git a/tests/bluetooth/tester/CMakeLists.txt b/tests/bluetooth/tester/CMakeLists.txt index e44159223fc1638..622f9f5a3bdee32 100644 --- a/tests/bluetooth/tester/CMakeLists.txt +++ b/tests/bluetooth/tester/CMakeLists.txt @@ -39,3 +39,7 @@ endif() if(CONFIG_BT_HAS) target_sources(app PRIVATE src/btp_has.c) endif() + +if(CONFIG_BT_MICP_MIC_DEV) + target_sources(app PRIVATE src/btp_micp.c) +endif() diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index d8903d56cb6f283..5c26451d7f86590 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -15,6 +15,11 @@ CONFIG_BT_BUF_EVT_RX_COUNT=16 CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_CMD_TX_SIZE=255 +# MICP +CONFIG_BT_MICP_MIC_DEV=y +CONFIG_BT_MICP_MIC_CTLR=y +CONFIG_BT_MICP_MIC_CTLR_MAX_AICS_INST=2 + # ASCS CONFIG_BT_ASCS_ASE_SNK_COUNT=2 CONFIG_BT_ASCS_ASE_SRC_COUNT=2 diff --git a/tests/bluetooth/tester/src/btp/btp.h b/tests/bluetooth/tester/src/btp/btp.h index 3edbf6b036fb281..4d3305bc1077b71 100644 --- a/tests/bluetooth/tester/src/btp/btp.h +++ b/tests/bluetooth/tester/src/btp/btp.h @@ -24,6 +24,7 @@ #include "btp_ascs.h" #include "btp_bap.h" #include "btp_has.h" +#include "btp_micp.h" #define BTP_MTU 1024 #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -47,8 +48,10 @@ #define BTP_SERVICE_ID_ASCS 13 #define BTP_SERVICE_ID_BAP 14 #define BTP_SERVICE_ID_HAS 15 +#define BTP_SERVICE_ID_MICP 16 +#define BTP_SERVICE_ID_MICS 17 -#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_HAS +#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_MICS #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 diff --git a/tests/bluetooth/tester/src/btp/btp_micp.h b/tests/bluetooth/tester/src/btp/btp_micp.h new file mode 100644 index 000000000000000..00f581c6bee9351 --- /dev/null +++ b/tests/bluetooth/tester/src/btp/btp_micp.h @@ -0,0 +1,109 @@ +/* btp_micp.h - Bluetooth tester headers */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* MICP commands */ +#define BTP_MICP_READ_SUPPORTED_COMMANDS 0x01 +struct btp_micp_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_MICP_DISCOVER 0x02 +struct btp_micp_discover_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_SET_GAIN 0x03 +struct btp_micp_set_gain_cmd { + bt_addr_le_t address; + int8_t gain; +} __packed; + +#define BTP_MICP_AICS_STATE 0x04 +struct btp_micp_aics_state_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_MUTE_READ 0x05 +struct btp_micp_mute_read_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_GAIN_SETTING_PROP 0x06 +struct btp_micp_gain_setting_prop_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_MUTE 0x07 +struct btp_micp_mute_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_AICS_TYPE 0x08 +struct btp_micp_aics_type_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_AICS_STATUS 0x09 +struct btp_micp_aics_status_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_AICS_UNMUTE 0x0a +struct btp_micp_aics_unmute_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_AICS_MUTE 0x0b +struct btp_micp_aics_mute_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_AICS_MAN_GAIN 0x0c +struct btp_micp_aics_manual_gain_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_AICS_AUTO_GAIN 0x0d +struct btp_micp_aics_auto_gain_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_MICP_DISCOVERY_STATUS_SUCCESS 0x00 +#define BTP_MICP_DISCOVERY_STATUS_FAILED 0x01 + +/* MICP events */ +#define BTP_MICP_DISCOVERED_EV 0x80 +struct btp_micp_discovered_ev { + bt_addr_le_t address; + uint16_t mute_handle; +} __packed; + +#define BTP_MICP_AICS_STATE_EV 0x81 +struct btp_micp_aics_state_ev { + bt_addr_le_t address; + int8_t gain; + uint8_t mute; + uint8_t mode; +} __packed; + +#define BTP_MICP_MUTE_READ_EV 0x82 +struct btp_micp_mute_read_ev { + bt_addr_le_t address; + uint8_t mute; +} __packed; + +#define BTP_MICP_AICS_CHRC_EV 0x83 +struct btp_micp_aics_handle_ev { + bt_addr_le_t address; + uint16_t state_handle; + uint16_t gain_handle; + uint16_t type_handle; + uint16_t status_handle; + uint16_t control_handle; + uint16_t desc_handle; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/bttester.h b/tests/bluetooth/tester/src/btp/bttester.h index a68cb3c5c737ad8..50aacd81bf88dc8 100644 --- a/tests/bluetooth/tester/src/btp/bttester.h +++ b/tests/bluetooth/tester/src/btp/bttester.h @@ -89,3 +89,6 @@ uint8_t tester_unregister_bap(void); uint8_t tester_init_has(void); uint8_t tester_unregister_has(void); + +uint8_t tester_init_micp(void); +uint8_t tester_unregister_micp(void); diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index b0b9a366a93cb8d..81f4afdd910062c 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -77,6 +77,9 @@ static uint8_t supported_services(const void *cmd, uint16_t cmd_len, #if defined(CONFIG_BT_HAS) || defined(CONFIG_BT_HAS_CLIENT) tester_set_bit(rp->data, BTP_SERVICE_ID_HAS); #endif /* CONFIG_BT_HAS */ +#if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR) + tester_set_bit(rp->data, BTP_SERVICE_ID_MICP); +#endif /* CONFIG_BT_MICP_MIC_DEV */ *rsp_len = sizeof(*rp) + 2; @@ -142,6 +145,9 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_init_bap(); break; + case BTP_SERVICE_ID_MICP: + status = tester_init_micp(); + break; #endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ #if defined(CONFIG_BT_HAS) case BTP_SERVICE_ID_HAS: @@ -220,6 +226,9 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_unregister_bap(); break; + case BTP_SERVICE_ID_MICP: + status = tester_unregister_micp(); + break; #endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ #if defined(CONFIG_BT_HAS) case BTP_SERVICE_ID_HAS: diff --git a/tests/bluetooth/tester/src/btp_micp.c b/tests/bluetooth/tester/src/btp_micp.c new file mode 100644 index 000000000000000..e59e1f22877edc1 --- /dev/null +++ b/tests/bluetooth/tester/src/btp_micp.c @@ -0,0 +1,534 @@ +/* btp_micp.c - Bluetooth MICP Tester */ + +/* + * Copyright (c) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "bap_endpoint.h" +#include +#include + +#define LOG_MODULE_NAME bttester_micp +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL +); + +#include "btp/btp.h" + +static struct bt_micp_mic_ctlr *mic_ctlr; +#if defined(CONFIG_BT_MICP_MIC_CTLR_AICS) +static struct bt_micp_included micp_included; + +#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */ + +static void btp_send_micp_found_ev(struct bt_conn *conn, uint16_t mute_handle) +{ + struct btp_micp_discovered_ev ev; + struct bt_conn_info info; + + (void) bt_conn_get_info(conn, &info); + bt_addr_le_copy(&ev.address, info.le.dst); + + ev.mute_handle = mute_handle; + + tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_DISCOVERED_EV, &ev, sizeof(ev)); +} + +static void btp_send_micp_aics_handle_ev(struct bt_conn *conn, uint16_t state_handle, + uint16_t gain_handle, uint16_t type_handle, + uint16_t status_handle, uint16_t control_handle, + uint16_t desc_handle) +{ + struct btp_micp_aics_handle_ev ev; + struct bt_conn_info info; + + (void) bt_conn_get_info(conn, &info); + bt_addr_le_copy(&ev.address, info.le.dst); + + ev.state_handle = state_handle; + ev.gain_handle = gain_handle; + ev.type_handle = type_handle; + ev.status_handle = status_handle; + ev.control_handle = control_handle; + ev.desc_handle = desc_handle; + + tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_AICS_CHRC_EV, &ev, sizeof(ev)); + +} + +static void btp_send_micp_mute_state_ev(struct bt_conn *conn, uint8_t mute) +{ + struct btp_micp_mute_read_ev ev; + struct bt_conn_info info; + + (void) bt_conn_get_info(conn, &info); + bt_addr_le_copy(&ev.address, info.le.dst); + + ev.mute = mute; + + tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_MUTE_READ_EV, &ev, sizeof(ev)); + +} + +static void btp_send_aics_state_ev(struct bt_conn *conn, int8_t gain, uint8_t mute, uint8_t mode) +{ + struct btp_micp_aics_state_ev ev; + struct bt_conn_info info; + + (void) bt_conn_get_info(conn, &info); + bt_addr_le_copy(&ev.address, info.le.dst); + + ev.gain = gain; + ev.mute = mute; + ev.mode = mode; + + tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_AICS_STATE_EV, &ev, sizeof(ev)); +} + +static void micp_mic_ctlr_discover_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, + uint8_t aics_count) +{ + struct bt_conn *conn; + uint16_t mute_handle; + + if (err != 0) { + LOG_DBG("Discovery failed (%d)", err); + } else { + LOG_DBG("Discovery done with %u AICS", + aics_count); + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + +#if defined(CONFIG_BT_MICP_MIC_CTLR_AICS) + if (bt_micp_mic_ctlr_included_get(mic_ctlr, &micp_included) != 0) { + LOG_DBG("Could not get included services"); + } + + uint16_t state_handle; + uint16_t gain_handle; + uint16_t type_handle; + uint16_t status_handle; + uint16_t control_handle; + uint16_t desc_handle; + + bt_micp_mic_ctlr_aics_chrc_get(micp_included, &state_handle, &gain_handle, + &type_handle, &status_handle, &control_handle, + &desc_handle); + btp_send_micp_aics_handle_ev(conn, state_handle, gain_handle, type_handle, + status_handle, control_handle, desc_handle); +#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */ + } + bt_micp_mic_ctlr_chrc_get(mic_ctlr, &mute_handle); + btp_send_micp_found_ev(conn, mute_handle); +} + +static void micp_mic_ctlr_aics_state_cb(struct bt_aics *inst, int err, + int8_t gain, uint8_t mute, uint8_t mode) +{ + struct bt_conn *conn; + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + btp_send_aics_state_ev(conn, gain, mute, mode); +} + +static void micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, + uint8_t mute) +{ + struct bt_conn *conn; + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + btp_send_micp_mute_state_ev(conn, mute); +} + +static void micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, + int err) +{ + struct bt_conn *conn; + + uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr); + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + btp_send_micp_mute_state_ev(conn, mute_state); + +} + +static void micp_mic_ctlr_unmute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, + int err) +{ + struct bt_conn *conn; + uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr); + + bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn); + btp_send_micp_mute_state_ev(conn, mute_state); +} + +static void micp_mic_ctlr_aics_gain_setting_cb(struct bt_aics *inst, int err, + uint8_t units, int8_t minimum, + int8_t maximum) +{ + LOG_DBG("AICS gain setting cb (%d)", err); +} + +static void micp_mic_ctlr_aics_input_type_cb(struct bt_aics *inst, int err, + uint8_t input_type) +{ + LOG_DBG("AICS input type cb (%d)", err); +} + +static void micp_mic_ctlr_aics_status_cb(struct bt_aics *inst, int err, + bool active) +{ + LOG_DBG("AICS status cb (%d)", err); +} + +static void micp_mic_ctlr_aics_description_cb(struct bt_aics *inst, int err, + char *description) +{ + LOG_DBG("AICS description cb (%d)", err); +} + +static void micp_mic_ctlr_aics_set_gain_cb(struct bt_aics *inst, int err) +{ + LOG_DBG("AICS set gain cb (%d)", err); +} + +static void micp_mic_ctlr_aics_unmute_cb(struct bt_aics *inst, int err) +{ + LOG_DBG("AICS unmute cb (%d)", err); +} + +static void micp_mic_ctlr_aics_mute_cb(struct bt_aics *inst, int err) +{ + LOG_DBG("AICS mute cb (%d)", err); +} + +static void micp_mic_ctlr_aics_set_manual_mode_cb(struct bt_aics *inst, int err) +{ + LOG_DBG("AICS Set manual gain mode cb (%d)", err); +} + +static void micp_mic_ctlr_aics_automatic_mode_cb(struct bt_aics *inst, int err) +{ + LOG_DBG("AICS set automatic gain mode cb (%d)", err); +} + +static struct bt_micp_mic_ctlr_cb micp_cbs = { + .discover = micp_mic_ctlr_discover_cb, + .mute = micp_mic_ctlr_mute_cb, + .mute_written = micp_mic_ctlr_mute_written_cb, + .unmute_written = micp_mic_ctlr_unmute_written_cb, + + +#if defined(CONFIG_BT_MICP_MIC_CTLR_AICS) + /* Audio Input Control Service */ + .aics_cb = { + .state = micp_mic_ctlr_aics_state_cb, + .gain_setting = micp_mic_ctlr_aics_gain_setting_cb, + .type = micp_mic_ctlr_aics_input_type_cb, + .status = micp_mic_ctlr_aics_status_cb, + .description = micp_mic_ctlr_aics_description_cb, + .set_gain = micp_mic_ctlr_aics_set_gain_cb, + .unmute = micp_mic_ctlr_aics_unmute_cb, + .mute = micp_mic_ctlr_aics_mute_cb, + .set_manual_mode = micp_mic_ctlr_aics_set_manual_mode_cb, + .set_auto_mode = micp_mic_ctlr_aics_automatic_mode_cb, + } +#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */ +}; + +static uint8_t micp_supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct btp_micp_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_MICP_READ_SUPPORTED_COMMANDS); + + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_discover(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_micp_discover_cmd *cp = cmd; + struct bt_conn *conn; + int err; + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + + if (!conn) { + LOG_ERR("Unknown connection"); + return BTP_STATUS_FAILED; + } + + err = bt_micp_mic_ctlr_discover(conn, &mic_ctlr); + + if (err != 0) { + LOG_DBG("Fail: %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_set_gain(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_micp_set_gain_cmd *cp = cmd; + + LOG_DBG("MICP set gain %d", cp->gain); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_gain_set(micp_included.aics[i], cp->gain) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_aics_unmute(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("Unmute"); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_unmute(micp_included.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_aics_mute(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("Mute"); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_mute(micp_included.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_aics_state(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("AICS State"); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_state_get(micp_included.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_aics_type(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("AICS Type"); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_type_get(micp_included.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_aics_status(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("AICS Status"); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_status_get(micp_included.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_mute_read(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int rc; + + LOG_DBG("Read mute"); + + rc = bt_micp_mic_ctlr_mute_get(mic_ctlr); + if (rc != 0) { + BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_gain_setting_prop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("AICS Gain settings properties"); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_gain_setting_get(micp_included.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_mute(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int rc; + + LOG_DBG(""); + + rc = bt_micp_mic_ctlr_mute(mic_ctlr); + if (rc != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t micp_aics_man_gain(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("AICS set manual gain mode"); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_manual_gain_set(micp_included.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; + +} + +static uint8_t micp_aics_auto_gain(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + LOG_DBG("AICS set automatic gain mode"); + + for (int i = 0; i < micp_included.aics_cnt; i++) { + if (bt_aics_automatic_gain_set(micp_included.aics[i]) != 0) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static const struct btp_handler micp_handlers[] = { + { + .opcode = BTP_MICP_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = micp_supported_commands, + }, + { + .opcode = BTP_MICP_DISCOVER, + .expect_len = sizeof(struct btp_micp_discover_cmd), + .func = micp_discover, + }, + { + .opcode = BTP_MICP_SET_GAIN, + .expect_len = sizeof(struct btp_micp_set_gain_cmd), + .func = micp_set_gain, + }, + { + .opcode = BTP_MICP_AICS_STATE, + .expect_len = sizeof(struct btp_micp_aics_state_cmd), + .func = micp_aics_state, + }, + { + .opcode = BTP_MICP_MUTE_READ, + .expect_len = sizeof(struct btp_micp_mute_read_cmd), + .func = micp_mute_read, + }, + { + .opcode = BTP_MICP_GAIN_SETTING_PROP, + .expect_len = sizeof(struct btp_micp_gain_setting_prop_cmd), + .func = micp_gain_setting_prop, + }, + { + .opcode = BTP_MICP_MUTE, + .expect_len = sizeof(struct btp_micp_mute_cmd), + .func = micp_mute, + }, + { + .opcode = BTP_MICP_AICS_TYPE, + .expect_len = sizeof(struct btp_micp_aics_type_cmd), + .func = micp_aics_type, + }, + { + .opcode = BTP_MICP_AICS_STATUS, + .expect_len = sizeof(struct btp_micp_aics_status_cmd), + .func = micp_aics_status, + }, + { + .opcode = BTP_MICP_AICS_UNMUTE, + .expect_len = sizeof(struct btp_micp_aics_unmute_cmd), + .func = micp_aics_unmute, + }, + { + .opcode = BTP_MICP_AICS_MUTE, + .expect_len = sizeof(struct btp_micp_aics_mute_cmd), + .func = micp_aics_mute, + }, + { + .opcode = BTP_MICP_AICS_MAN_GAIN, + .expect_len = sizeof(struct btp_micp_aics_manual_gain_cmd), + .func = micp_aics_man_gain, + }, + { + .opcode = BTP_MICP_AICS_AUTO_GAIN, + .expect_len = sizeof(struct btp_micp_aics_auto_gain_cmd), + .func = micp_aics_auto_gain, + }, +}; + +uint8_t tester_init_micp(void) +{ + int err; + + err = bt_micp_mic_ctlr_cb_register(&micp_cbs); + if (err != 0) { + LOG_DBG("Failed to register callbacks: %d", err); + } + + tester_register_command_handlers(BTP_SERVICE_ID_MICP, micp_handlers, + ARRAY_SIZE(micp_handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t tester_unregister_micp(void) +{ + return BTP_STATUS_SUCCESS; +}