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