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