1 /** @file
2  *  @brief Bluetooth Media Control Profile (MCP) Controller role.
3  *
4  *  Copyright 2023 NXP
5  *  Copyright (c) 2024 Nordic Semiconductor ASA
6  *
7  *  SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #include <errno.h>
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #include <zephyr/bluetooth/audio/mcc.h>
15 #include <zephyr/bluetooth/audio/media_proxy.h>
16 #include <zephyr/bluetooth/conn.h>
17 #include <zephyr/kernel.h>
18 #include <zephyr/sys/printk.h>
19 
20 static struct bt_conn *default_conn;
21 
22 static K_SEM_DEFINE(sem_discovery_done, 0, 1);
23 
mcc_discover_mcs_cb(struct bt_conn * conn,int err)24 static void mcc_discover_mcs_cb(struct bt_conn *conn, int err)
25 {
26 	if (err) {
27 		printk("MCP: Discovery of MCS failed (%d)\n", err);
28 	} else {
29 		printk("MCP: Discovered MCS\n");
30 	}
31 	k_sem_give(&sem_discovery_done);
32 }
33 
mcc_send_command_cb(struct bt_conn * conn,int err,const struct mpl_cmd * cmd)34 static void mcc_send_command_cb(struct bt_conn *conn, int err, const struct mpl_cmd *cmd)
35 {
36 	if (err) {
37 		printk("MCP: Command send failed (%d) - opcode: %u, param: %d\n",
38 			err, cmd->opcode, cmd->param);
39 	} else {
40 		printk("MCP: Successfully sent command (%d) - opcode: %u, param: %d\n",
41 			err, cmd->opcode, cmd->param);
42 	}
43 }
44 
45 static struct bt_mcc_cb mcc_cb = {
46 	.discover_mcs = mcc_discover_mcs_cb,
47 	.send_cmd = mcc_send_command_cb,
48 };
49 
mcp_ctlr_init(struct bt_conn * conn)50 int mcp_ctlr_init(struct bt_conn *conn)
51 {
52 	int err;
53 
54 	default_conn = bt_conn_ref(conn);
55 
56 	err = bt_mcc_init(&mcc_cb);
57 	if (err != 0) {
58 		return err;
59 	}
60 
61 	err = bt_mcc_discover_mcs(default_conn, true);
62 	if (err == 0) {
63 		k_sem_take(&sem_discovery_done, K_FOREVER);
64 	}
65 	return err;
66 }
67 
mcp_send_cmd(uint8_t mcp_opcode)68 int mcp_send_cmd(uint8_t mcp_opcode)
69 {
70 	int err;
71 	struct mpl_cmd cmd;
72 
73 	cmd.opcode = mcp_opcode;
74 	cmd.use_param = false;
75 
76 	if (default_conn == NULL) {
77 		printk("MCP: No connection\n");
78 		return -EINVAL;
79 	}
80 
81 	err = bt_mcc_send_cmd(default_conn, &cmd);
82 	if (err != 0) {
83 		printk("MCP: Command failed: %d\n", err);
84 	}
85 
86 	return err;
87 }
88