1 /** @file
2 * @brief Bluetooth Microphone Control Profile (MICP) Microphone Device role.
3 *
4 * Copyright (c) 2020 Bose Corporation
5 * Copyright (c) 2020-2022 Nordic Semiconductor ASA
6 * Copyright (c) 2022 Codecoup
7 *
8 * SPDX-License-Identifier: Apache-2.0
9 */
10
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <string.h>
14
15 #include <zephyr/bluetooth/audio/aics.h>
16 #include <zephyr/bluetooth/conn.h>
17 #include <zephyr/bluetooth/audio/micp.h>
18 #include <zephyr/kernel.h>
19 #include <zephyr/sys/printk.h>
20 #include <zephyr/sys/util.h>
21
micp_mic_dev_mute_cb(uint8_t mute)22 static void micp_mic_dev_mute_cb(uint8_t mute)
23 {
24 printk("Mute value %u\n", mute);
25 }
26
27 static struct bt_micp_mic_dev_cb micp_mic_dev_cbs = {
28 .mute = micp_mic_dev_mute_cb,
29 };
30
31 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
32 static struct bt_micp_included micp_included;
33
micp_mic_dev_aics_state_cb(struct bt_aics * inst,int err,int8_t gain,uint8_t mute,uint8_t mode)34 static void micp_mic_dev_aics_state_cb(struct bt_aics *inst, int err, int8_t gain, uint8_t mute,
35 uint8_t mode)
36 {
37 if (err != 0) {
38 printk("AICS state get failed (%d) for inst %p\n", err, inst);
39 } else {
40 printk("AICS inst %p state gain %d, mute %u, mode %u\n",
41 inst, gain, mute, mode);
42 }
43
44 }
micp_mic_dev_aics_gain_setting_cb(struct bt_aics * inst,int err,uint8_t units,int8_t minimum,int8_t maximum)45 static void micp_mic_dev_aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units,
46 int8_t minimum, int8_t maximum)
47 {
48 if (err != 0) {
49 printk("AICS gain settings get failed (%d) for inst %p\n", err, inst);
50 } else {
51 printk("AICS inst %p gain settings units %u, min %d, max %d\n",
52 inst, units, minimum, maximum);
53 }
54
55 }
micp_mic_dev_aics_input_type_cb(struct bt_aics * inst,int err,uint8_t input_type)56 static void micp_mic_dev_aics_input_type_cb(struct bt_aics *inst, int err, uint8_t input_type)
57 {
58 if (err != 0) {
59 printk("AICS input type get failed (%d) for inst %p\n", err, inst);
60 } else {
61 printk("AICS inst %p input type %u\n", inst, input_type);
62 }
63
64 }
micp_mic_dev_aics_status_cb(struct bt_aics * inst,int err,bool active)65 static void micp_mic_dev_aics_status_cb(struct bt_aics *inst, int err, bool active)
66 {
67 if (err != 0) {
68 printk("AICS status get failed (%d) for inst %p\n", err, inst);
69 } else {
70 printk("AICS inst %p status %s\n", inst, active ? "active" : "inactive");
71 }
72
73 }
micp_mic_dev_aics_description_cb(struct bt_aics * inst,int err,char * description)74 static void micp_mic_dev_aics_description_cb(struct bt_aics *inst, int err, char *description)
75 {
76 if (err != 0) {
77 printk("AICS description get failed (%d) for inst %p\n", err, inst);
78 } else {
79 printk("AICS inst %p description %s\n", inst, description);
80 }
81 }
82
83 static struct bt_aics_cb aics_cb = {
84 .state = micp_mic_dev_aics_state_cb,
85 .gain_setting = micp_mic_dev_aics_gain_setting_cb,
86 .type = micp_mic_dev_aics_input_type_cb,
87 .status = micp_mic_dev_aics_status_cb,
88 .description = micp_mic_dev_aics_description_cb,
89 };
90 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
91
micp_mic_dev_init(void)92 int micp_mic_dev_init(void)
93 {
94 int err;
95 struct bt_micp_mic_dev_register_param micp_param;
96
97 (void)memset(&micp_param, 0, sizeof(micp_param));
98
99 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
100 char input_desc[CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT][16];
101
102 for (int i = 0; i < ARRAY_SIZE(micp_param.aics_param); i++) {
103 micp_param.aics_param[i].desc_writable = true;
104 snprintf(input_desc[i], sizeof(input_desc[i]), "Input %d", i + 1);
105 micp_param.aics_param[i].description = input_desc[i];
106 micp_param.aics_param[i].type = BT_AICS_INPUT_TYPE_UNSPECIFIED;
107 micp_param.aics_param[i].status = true;
108 micp_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL;
109 micp_param.aics_param[i].units = 1;
110 micp_param.aics_param[i].min_gain = -100;
111 micp_param.aics_param[i].max_gain = 100;
112 micp_param.aics_param[i].cb = &aics_cb;
113 }
114 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
115
116 micp_param.cb = &micp_mic_dev_cbs;
117
118 err = bt_micp_mic_dev_register(&micp_param);
119 if (err != 0) {
120 return err;
121 }
122
123 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
124 err = bt_micp_mic_dev_included_get(&micp_included);
125 if (err != 0) {
126 return err;
127 }
128 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
129
130 return 0;
131 }
132