1 /* btp_mcp.c - Bluetooth MCP Tester */
2 
3 /*
4  * Copyright (c) 2023 Codecoup
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <stddef.h>
10 #include <errno.h>
11 #include <stdio.h>
12 
13 #include <zephyr/types.h>
14 #include <zephyr/kernel.h>
15 
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/audio/audio.h>
18 #include <zephyr/bluetooth/audio/mcc.h>
19 #include <zephyr/bluetooth/audio/mcs.h>
20 #include <../../subsys/bluetooth/audio/mpl_internal.h>
21 #include <../../subsys/bluetooth/audio/mcc_internal.h>
22 #include <zephyr/bluetooth/services/ots.h>
23 #include <zephyr/bluetooth/audio/media_proxy.h>
24 
25 #include <zephyr/logging/log.h>
26 #include <zephyr/sys/byteorder.h>
27 
28 #include "bap_endpoint.h"
29 #include "btp/btp.h"
30 #include "../../../../include/zephyr/bluetooth/audio/media_proxy.h"
31 
32 #define LOG_MODULE_NAME bttester_mcp
33 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
34 
35 static struct media_player *mcs_media_player;
36 static uint64_t current_track_obj_id;
37 static uint64_t next_track_obj_id;
38 static uint8_t media_player_state;
39 static uint64_t current_id;
40 static uint64_t parent_id;
41 struct service_handles {
42 	struct {
43 		uint16_t player_name;
44 		uint16_t icon_obj_id;
45 		uint16_t icon_url;
46 		uint16_t track_changed;
47 		uint16_t track_title;
48 		uint16_t track_duration;
49 		uint16_t track_position;
50 		uint16_t playback_speed;
51 		uint16_t seeking_speed;
52 		uint16_t segments_obj_id;
53 		uint16_t current_track_obj_id;
54 		uint16_t next_track_obj_id;
55 		uint16_t current_group_obj_id;
56 		uint16_t parent_group_obj_id;
57 		uint16_t playing_order;
58 		uint16_t playing_orders_supported;
59 		uint16_t media_state;
60 		uint16_t cp;
61 		uint16_t opcodes_supported;
62 		uint16_t search_results_obj_id;
63 		uint16_t scp;
64 		uint16_t content_control_id;
65 	} gmcs_handles;
66 
67 	struct {
68 		uint16_t feature;
69 		uint16_t obj_name;
70 		uint16_t obj_type;
71 		uint16_t obj_size;
72 		uint16_t obj_properties;
73 		uint16_t obj_created;
74 		uint16_t obj_modified;
75 		uint16_t obj_id;
76 		uint16_t oacp;
77 		uint16_t olcp;
78 	} ots_handles;
79 };
80 
81 struct service_handles svc_chrc_handles;
82 
83 #define SEARCH_LEN_MAX 64
84 
85 static struct net_buf_simple *rx_ev_buf = NET_BUF_SIMPLE(SEARCH_LEN_MAX +
86 							 sizeof(struct btp_mcp_search_cp_ev));
87 
88 /* Media Control Profile */
btp_send_mcp_found_ev(struct bt_conn * conn,uint8_t status,const struct service_handles svc_chrc_handles)89 static void btp_send_mcp_found_ev(struct bt_conn *conn, uint8_t status,
90 				  const struct service_handles svc_chrc_handles)
91 {
92 	struct btp_mcp_discovered_ev ev;
93 
94 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
95 
96 	ev.status = status;
97 	ev.gmcs_handles.player_name = sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.player_name);
98 	ev.gmcs_handles.icon_obj_id = sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.icon_obj_id);
99 	ev.gmcs_handles.icon_url = sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.icon_url);
100 	ev.gmcs_handles.track_changed =
101 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.track_changed);
102 	ev.gmcs_handles.track_title = sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.track_title);
103 	ev.gmcs_handles.track_duration =
104 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.track_duration);
105 	ev.gmcs_handles.track_position =
106 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.track_position);
107 	ev.gmcs_handles.playback_speed =
108 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.playback_speed);
109 	ev.gmcs_handles.seeking_speed =
110 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.seeking_speed);
111 	ev.gmcs_handles.segments_obj_id =
112 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.segments_obj_id);
113 	ev.gmcs_handles.current_track_obj_id =
114 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.current_track_obj_id);
115 	ev.gmcs_handles.next_track_obj_id =
116 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.next_track_obj_id);
117 	ev.gmcs_handles.current_group_obj_id =
118 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.current_group_obj_id);
119 	ev.gmcs_handles.parent_group_obj_id =
120 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.parent_group_obj_id);
121 	ev.gmcs_handles.playing_order =
122 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.playing_order);
123 	ev.gmcs_handles.playing_orders_supported =
124 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.playing_orders_supported);
125 	ev.gmcs_handles.media_state = sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.media_state);
126 	ev.gmcs_handles.cp = sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.cp);
127 	ev.gmcs_handles.opcodes_supported =
128 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.opcodes_supported);
129 	ev.gmcs_handles.search_results_obj_id =
130 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.search_results_obj_id);
131 	ev.gmcs_handles.scp = sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.scp);
132 	ev.gmcs_handles.content_control_id =
133 		sys_cpu_to_le16(svc_chrc_handles.gmcs_handles.content_control_id);
134 	ev.ots_handles.feature = sys_cpu_to_le16(svc_chrc_handles.ots_handles.feature);
135 	ev.ots_handles.obj_name = sys_cpu_to_le16(svc_chrc_handles.ots_handles.obj_name);
136 	ev.ots_handles.obj_type = sys_cpu_to_le16(svc_chrc_handles.ots_handles.obj_type);
137 	ev.ots_handles.obj_size = sys_cpu_to_le16(svc_chrc_handles.ots_handles.obj_size);
138 	ev.ots_handles.obj_properties =
139 		sys_cpu_to_le16(svc_chrc_handles.ots_handles.obj_properties);
140 	ev.ots_handles.obj_created = sys_cpu_to_le16(svc_chrc_handles.ots_handles.obj_created);
141 	ev.ots_handles.obj_modified = sys_cpu_to_le16(svc_chrc_handles.ots_handles.obj_modified);
142 	ev.ots_handles.obj_id = sys_cpu_to_le16(svc_chrc_handles.ots_handles.obj_id);
143 	ev.ots_handles.oacp = sys_cpu_to_le16(svc_chrc_handles.ots_handles.oacp);
144 	ev.ots_handles.olcp = sys_cpu_to_le16(svc_chrc_handles.ots_handles.olcp);
145 
146 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_DISCOVERED_EV, &ev, sizeof(ev));
147 }
148 
btp_send_mcp_track_duration_ev(struct bt_conn * conn,uint8_t status,int32_t dur)149 static void btp_send_mcp_track_duration_ev(struct bt_conn *conn, uint8_t status, int32_t dur)
150 {
151 	struct btp_mcp_track_duration_ev ev;
152 
153 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
154 
155 	ev.status = status;
156 	ev.dur = sys_cpu_to_le32(dur);
157 
158 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_TRACK_DURATION_EV, &ev, sizeof(ev));
159 }
160 
btp_send_mcp_track_position_ev(struct bt_conn * conn,uint8_t status,int32_t pos)161 static void btp_send_mcp_track_position_ev(struct bt_conn *conn, uint8_t status, int32_t pos)
162 {
163 	struct btp_mcp_track_position_ev ev;
164 
165 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
166 
167 	ev.status = status;
168 	ev.pos = sys_cpu_to_le32(pos);
169 
170 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_TRACK_POSITION_EV, &ev, sizeof(ev));
171 }
172 
btp_send_mcp_playback_speed_ev(struct bt_conn * conn,uint8_t status,int8_t speed)173 static void btp_send_mcp_playback_speed_ev(struct bt_conn *conn, uint8_t status, int8_t speed)
174 {
175 	struct btp_mcp_playback_speed_ev ev;
176 
177 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
178 
179 	ev.status = status;
180 	ev.speed = speed;
181 
182 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_PLAYBACK_SPEED_EV, &ev, sizeof(ev));
183 }
184 
btp_send_mcp_seeking_speed_ev(struct bt_conn * conn,uint8_t status,int8_t speed)185 static void btp_send_mcp_seeking_speed_ev(struct bt_conn *conn, uint8_t status, int8_t speed)
186 {
187 	struct btp_mcp_seeking_speed_ev ev;
188 
189 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
190 
191 	ev.status = status;
192 	ev.speed = speed;
193 
194 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_SEEKING_SPEED_EV, &ev, sizeof(ev));
195 }
196 
btp_send_mcp_icon_obj_id_ev(struct bt_conn * conn,uint8_t status,uint64_t id)197 static void btp_send_mcp_icon_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id)
198 {
199 	struct btp_mcp_icon_obj_id_ev ev;
200 
201 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
202 
203 	ev.status = status;
204 	sys_put_le48(id, ev.id);
205 
206 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_ICON_OBJ_ID_EV, &ev, sizeof(ev));
207 }
208 
btp_send_mcp_next_track_obj_id_ev(struct bt_conn * conn,uint8_t status,uint64_t id)209 static void btp_send_mcp_next_track_obj_id_ev(struct bt_conn *conn, uint8_t status,
210 					      uint64_t id)
211 {
212 	struct btp_mcp_next_track_obj_id_ev ev;
213 
214 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
215 
216 	ev.status = status;
217 	sys_put_le48(id, ev.id);
218 
219 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_NEXT_TRACK_OBJ_ID_EV, &ev, sizeof(ev));
220 }
221 
btp_send_parent_group_obj_id_ev(struct bt_conn * conn,uint8_t status,uint64_t id)222 static void btp_send_parent_group_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id)
223 {
224 	struct btp_mcp_parent_group_obj_id_ev ev;
225 
226 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
227 
228 	ev.status = status;
229 	sys_put_le48(id, ev.id);
230 
231 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_PARENT_GROUP_OBJ_ID_EV, &ev, sizeof(ev));
232 }
233 
btp_send_current_group_obj_id_ev(struct bt_conn * conn,uint8_t status,uint64_t id)234 static void btp_send_current_group_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id)
235 {
236 	struct btp_mcp_current_group_obj_id_ev ev;
237 
238 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
239 
240 	ev.status = status;
241 	sys_put_le48(id, ev.id);
242 
243 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_CURRENT_GROUP_OBJ_ID_EV, &ev, sizeof(ev));
244 }
245 
btp_send_mcp_playing_order_ev(struct bt_conn * conn,uint8_t status,uint8_t order)246 static void btp_send_mcp_playing_order_ev(struct bt_conn *conn, uint8_t status, uint8_t order)
247 {
248 	struct btp_mcp_playing_order_ev ev;
249 
250 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
251 
252 	ev.status = status;
253 	ev.order = order;
254 
255 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_PLAYING_ORDER_EV, &ev, sizeof(ev));
256 }
257 
btp_send_mcp_playing_orders_supported_ev(struct bt_conn * conn,uint8_t status,uint16_t orders)258 static void btp_send_mcp_playing_orders_supported_ev(struct bt_conn *conn, uint8_t status,
259 						     uint16_t orders)
260 {
261 	struct btp_mcp_playing_orders_supported_ev ev;
262 
263 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
264 
265 	ev.status = status;
266 	ev.orders = sys_cpu_to_le16(orders);
267 
268 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_PLAYING_ORDERS_SUPPORTED_EV, &ev, sizeof(ev));
269 }
270 
btp_send_mcp_media_state_ev(struct bt_conn * conn,uint8_t status,uint8_t state)271 static void btp_send_mcp_media_state_ev(struct bt_conn *conn, uint8_t status, uint8_t state)
272 {
273 	struct btp_mcp_media_state_ev ev;
274 
275 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
276 
277 	ev.status = status;
278 	ev.state = state;
279 
280 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_MEDIA_STATE_EV, &ev, sizeof(ev));
281 }
282 
btp_send_mcp_opcodes_supported_ev(struct bt_conn * conn,uint8_t status,uint32_t opcodes)283 static void btp_send_mcp_opcodes_supported_ev(struct bt_conn *conn, uint8_t status,
284 					      uint32_t opcodes)
285 {
286 	struct btp_mcp_opcodes_supported_ev ev;
287 
288 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
289 
290 	ev.status = status;
291 	ev.opcodes = sys_cpu_to_le32(opcodes);
292 
293 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_OPCODES_SUPPORTED_EV, &ev, sizeof(ev));
294 }
295 
btp_send_mcp_content_control_id_ev(struct bt_conn * conn,uint8_t status,uint8_t ccid)296 static void btp_send_mcp_content_control_id_ev(struct bt_conn *conn, uint8_t status,
297 					       uint8_t ccid)
298 {
299 	struct btp_mcp_content_control_id_ev ev;
300 
301 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
302 
303 	ev.status = status;
304 	ev.ccid = ccid;
305 
306 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_CONTENT_CONTROL_ID_EV, &ev, sizeof(ev));
307 }
308 
btp_send_segments_obj_id_ev(struct bt_conn * conn,uint8_t status,uint64_t id)309 static void btp_send_segments_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id)
310 {
311 	struct btp_mcp_segments_obj_id_ev ev;
312 
313 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
314 
315 	ev.status = status;
316 	sys_put_le48(id, ev.id);
317 
318 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_SEGMENTS_OBJ_ID_EV, &ev, sizeof(ev));
319 }
320 
btp_send_current_track_obj_id_ev(struct bt_conn * conn,uint8_t status,uint64_t id)321 static void btp_send_current_track_obj_id_ev(struct bt_conn *conn, uint8_t status, uint64_t id)
322 {
323 	struct btp_mcp_current_track_obj_id_ev ev;
324 
325 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
326 
327 	ev.status = status;
328 	sys_put_le48(id, ev.id);
329 
330 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_CURRENT_TRACK_OBJ_ID_EV, &ev, sizeof(ev));
331 }
332 
btp_send_media_cp_ev(struct bt_conn * conn,uint8_t status,const struct mpl_cmd * cmd)333 static void btp_send_media_cp_ev(struct bt_conn *conn, uint8_t status,
334 				 const struct mpl_cmd *cmd)
335 {
336 	struct btp_mcp_media_cp_ev ev;
337 
338 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
339 
340 	ev.status = status;
341 	ev.opcode = cmd->opcode;
342 	ev.use_param = cmd->use_param;
343 	ev.param = sys_cpu_to_le32(cmd->param);
344 
345 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_MEDIA_CP_EV, &ev, sizeof(ev));
346 }
347 
btp_send_search_cp_ev(struct bt_conn * conn,uint8_t status,const struct mpl_search * search)348 static void btp_send_search_cp_ev(struct bt_conn *conn, uint8_t status,
349 				  const struct mpl_search *search)
350 {
351 	struct btp_mcp_search_cp_ev *ev;
352 	uint8_t param[SEARCH_LEN_MAX];
353 
354 	net_buf_simple_init(rx_ev_buf, 0);
355 
356 	ev = net_buf_simple_add(rx_ev_buf, sizeof(*ev));
357 
358 	bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn));
359 
360 	ev->status = status;
361 	ev->param_len = (uint8_t)search->search[0];
362 
363 	if (ev->param_len > (SEARCH_LEN_MAX - sizeof(ev->param_len))) {
364 		return;
365 	}
366 
367 	ev->search_type = search->search[1];
368 	strcpy(param, &search->search[2]);
369 	net_buf_simple_add_mem(rx_ev_buf, param, ev->param_len);
370 
371 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_SEARCH_CP_EV, ev, sizeof(*ev) + ev->param_len);
372 }
373 
btp_send_command_notifications_ev(struct bt_conn * conn,uint8_t status,const struct mpl_cmd_ntf * ntf)374 static void btp_send_command_notifications_ev(struct bt_conn *conn, uint8_t status,
375 					      const struct mpl_cmd_ntf *ntf)
376 {
377 	struct btp_mcp_cmd_ntf_ev ev;
378 
379 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
380 
381 	ev.status = status;
382 	ev.requested_opcode = ntf->requested_opcode;
383 	ev.result_code = ntf->result_code;
384 
385 	tester_event(BTP_SERVICE_ID_MCP, BTP_MCP_NTF_EV, &ev, sizeof(ev));
386 }
387 
btp_send_search_notifications_ev(struct bt_conn * conn,uint8_t status,uint8_t result_code)388 static void btp_send_search_notifications_ev(struct bt_conn *conn, uint8_t status,
389 					     uint8_t result_code)
390 {
391 	struct btp_scp_cmd_ntf_ev ev;
392 
393 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
394 
395 	ev.status = status;
396 	ev.result_code = result_code;
397 
398 	tester_event(BTP_SERVICE_ID_MCP, BTP_SCP_NTF_EV, &ev, sizeof(ev));
399 }
400 
mcc_discover_cb(struct bt_conn * conn,int err)401 static void mcc_discover_cb(struct bt_conn *conn, int err)
402 {
403 	struct mcs_instance_t *mcc_inst;
404 
405 	if (err) {
406 		LOG_DBG("Discovery failed (%d)", err);
407 	}
408 
409 	mcc_inst = lookup_inst_by_conn(conn);
410 
411 	svc_chrc_handles.gmcs_handles.player_name = mcc_inst->player_name_handle;
412 	svc_chrc_handles.gmcs_handles.icon_obj_id = mcc_inst->icon_obj_id_handle;
413 	svc_chrc_handles.gmcs_handles.icon_url = mcc_inst->icon_url_handle;
414 	svc_chrc_handles.gmcs_handles.track_changed = mcc_inst->track_changed_handle;
415 	svc_chrc_handles.gmcs_handles.track_title = mcc_inst->track_title_handle;
416 	svc_chrc_handles.gmcs_handles.track_duration = mcc_inst->track_duration_handle;
417 	svc_chrc_handles.gmcs_handles.track_position = mcc_inst->track_position_handle;
418 	svc_chrc_handles.gmcs_handles.playback_speed = mcc_inst->playback_speed_handle;
419 	svc_chrc_handles.gmcs_handles.seeking_speed = mcc_inst->seeking_speed_handle;
420 	svc_chrc_handles.gmcs_handles.segments_obj_id = mcc_inst->segments_obj_id_handle;
421 	svc_chrc_handles.gmcs_handles.current_track_obj_id = mcc_inst->current_track_obj_id_handle;
422 	svc_chrc_handles.gmcs_handles.next_track_obj_id = mcc_inst->next_track_obj_id_handle;
423 	svc_chrc_handles.gmcs_handles.current_group_obj_id = mcc_inst->current_group_obj_id_handle;
424 	svc_chrc_handles.gmcs_handles.parent_group_obj_id = mcc_inst->parent_group_obj_id_handle;
425 	svc_chrc_handles.gmcs_handles.playing_order = mcc_inst->playing_order_handle;
426 	svc_chrc_handles.gmcs_handles.playing_orders_supported =
427 		mcc_inst->playing_orders_supported_handle;
428 	svc_chrc_handles.gmcs_handles.media_state = mcc_inst->media_state_handle;
429 	svc_chrc_handles.gmcs_handles.cp = mcc_inst->cp_handle;
430 	svc_chrc_handles.gmcs_handles.opcodes_supported = mcc_inst->opcodes_supported_handle;
431 	svc_chrc_handles.gmcs_handles.search_results_obj_id =
432 		mcc_inst->search_results_obj_id_handle;
433 	svc_chrc_handles.gmcs_handles.scp = mcc_inst->scp_handle;
434 	svc_chrc_handles.gmcs_handles.content_control_id = mcc_inst->content_control_id_handle;
435 	svc_chrc_handles.ots_handles.feature = mcc_inst->otc.feature_handle;
436 	svc_chrc_handles.ots_handles.obj_name = mcc_inst->otc.obj_name_handle;
437 	svc_chrc_handles.ots_handles.obj_type = mcc_inst->otc.obj_type_handle;
438 	svc_chrc_handles.ots_handles.obj_size = mcc_inst->otc.obj_size_handle;
439 	svc_chrc_handles.ots_handles.obj_id = mcc_inst->otc.obj_id_handle;
440 	svc_chrc_handles.ots_handles.obj_properties = mcc_inst->otc.obj_properties_handle;
441 	svc_chrc_handles.ots_handles.obj_created = mcc_inst->otc.obj_created_handle;
442 	svc_chrc_handles.ots_handles.obj_modified = mcc_inst->otc.obj_modified_handle;
443 	svc_chrc_handles.ots_handles.oacp = mcc_inst->otc.oacp_handle;
444 	svc_chrc_handles.ots_handles.olcp = mcc_inst->otc.olcp_handle;
445 
446 	btp_send_mcp_found_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, svc_chrc_handles);
447 }
448 
mcc_read_track_duration_cb(struct bt_conn * conn,int err,int32_t dur)449 static void mcc_read_track_duration_cb(struct bt_conn *conn, int err, int32_t dur)
450 {
451 	LOG_DBG("MCC Read track duration cb (%d)", err);
452 
453 	btp_send_mcp_track_duration_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, dur);
454 }
455 
mcc_read_track_position_cb(struct bt_conn * conn,int err,int32_t pos)456 static void mcc_read_track_position_cb(struct bt_conn *conn, int err, int32_t pos)
457 {
458 	LOG_DBG("MCC Read track position cb (%d)", err);
459 
460 	btp_send_mcp_track_position_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, pos);
461 }
462 
mcc_set_track_position_cb(struct bt_conn * conn,int err,int32_t pos)463 static void mcc_set_track_position_cb(struct bt_conn *conn, int err, int32_t pos)
464 {
465 	LOG_DBG("MCC Set track position cb (%d)", err);
466 
467 	btp_send_mcp_track_position_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, pos);
468 }
469 
mcc_read_playback_speed_cb(struct bt_conn * conn,int err,int8_t speed)470 static void mcc_read_playback_speed_cb(struct bt_conn *conn, int err, int8_t speed)
471 {
472 	LOG_DBG("MCC read playback speed cb (%d)", err);
473 
474 	btp_send_mcp_playback_speed_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, speed);
475 }
476 
mcc_set_playback_speed_cb(struct bt_conn * conn,int err,int8_t speed)477 static void mcc_set_playback_speed_cb(struct bt_conn *conn, int err, int8_t speed)
478 {
479 	LOG_DBG("MCC set playback speed cb (%d)", err);
480 
481 	btp_send_mcp_playback_speed_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, speed);
482 }
483 
mcc_read_seeking_speed_cb(struct bt_conn * conn,int err,int8_t speed)484 static void mcc_read_seeking_speed_cb(struct bt_conn *conn, int err, int8_t speed)
485 {
486 	LOG_DBG("MCC read seeking speed cb (%d)", err);
487 
488 	btp_send_mcp_seeking_speed_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, speed);
489 }
490 
mcc_read_icon_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)491 static void mcc_read_icon_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
492 {
493 	LOG_DBG("MCC read Icon Object ID cb (%d)", err);
494 
495 	btp_send_mcp_icon_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
496 }
497 
mcc_read_next_track_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)498 static void mcc_read_next_track_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
499 {
500 	LOG_DBG("MCC read next track obj ID cb (%d)", err);
501 
502 	btp_send_mcp_next_track_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
503 }
504 
mcc_set_next_track_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)505 static void mcc_set_next_track_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
506 {
507 	LOG_DBG("MCC set next track obj ID cb (%d)", err);
508 
509 	btp_send_mcp_next_track_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
510 }
511 
mcc_read_parent_group_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)512 static void mcc_read_parent_group_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
513 {
514 	LOG_DBG("MCC read parent group obj ID cb (%d)", err);
515 
516 	btp_send_parent_group_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
517 }
518 
mcc_read_current_group_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)519 static void mcc_read_current_group_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
520 {
521 	LOG_DBG("MCC read current group obj ID cb (%d)", err);
522 
523 	btp_send_current_group_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
524 }
525 
mcc_set_current_group_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)526 static void mcc_set_current_group_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
527 {
528 	LOG_DBG("MCC read current group obj ID cb (%d)", err);
529 
530 	btp_send_current_group_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
531 }
532 
mcc_read_playing_order_cb(struct bt_conn * conn,int err,uint8_t order)533 static void mcc_read_playing_order_cb(struct bt_conn *conn, int err, uint8_t order)
534 {
535 	LOG_DBG("MCC read playing order cb (%d)", err);
536 
537 	btp_send_mcp_playing_order_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, order);
538 }
539 
mcc_set_playing_order_cb(struct bt_conn * conn,int err,uint8_t order)540 static void mcc_set_playing_order_cb(struct bt_conn *conn, int err, uint8_t order)
541 {
542 	LOG_DBG("MCC set playing order cb (%d)", err);
543 
544 	btp_send_mcp_playing_order_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, order);
545 }
546 
mcc_read_playing_orders_supported_cb(struct bt_conn * conn,int err,uint16_t orders)547 static void mcc_read_playing_orders_supported_cb(struct bt_conn *conn, int err, uint16_t orders)
548 {
549 	LOG_DBG("MCC set playing order cb (%d)", err);
550 
551 	btp_send_mcp_playing_orders_supported_ev(conn,
552 						 err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS,
553 						 orders);
554 }
555 
mcc_media_state_read_cb(struct bt_conn * conn,int err,uint8_t state)556 static void mcc_media_state_read_cb(struct bt_conn *conn, int err, uint8_t state)
557 {
558 	LOG_DBG("MCC media state read cb (%d)", err);
559 
560 	btp_send_mcp_media_state_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, state);
561 }
562 
mcc_opcodes_supported_cb(struct bt_conn * conn,int err,uint32_t opcodes)563 static void mcc_opcodes_supported_cb(struct bt_conn *conn, int err, uint32_t opcodes)
564 {
565 	LOG_DBG("MCC opcodes supported cb (%d)", err);
566 
567 	btp_send_mcp_opcodes_supported_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS,
568 					  opcodes);
569 }
570 
mcc_content_control_id_cb(struct bt_conn * conn,int err,uint8_t ccid)571 static void mcc_content_control_id_cb(struct bt_conn *conn, int err, uint8_t ccid)
572 {
573 	LOG_DBG("MCC Content control ID cb (%d)", err);
574 
575 	btp_send_mcp_content_control_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS,
576 					   ccid);
577 }
578 
mcc_segments_object_id_cb(struct bt_conn * conn,int err,uint64_t id)579 static void mcc_segments_object_id_cb(struct bt_conn *conn, int err, uint64_t id)
580 {
581 	LOG_DBG("MCC Segments Object ID cb (%d)", err);
582 
583 	btp_send_segments_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
584 }
585 
mcc_current_track_obj_id_read_cb(struct bt_conn * conn,int err,uint64_t id)586 static void mcc_current_track_obj_id_read_cb(struct bt_conn *conn, int err, uint64_t id)
587 {
588 	LOG_DBG("MCC Segments Object ID read cb (%d)", err);
589 
590 	btp_send_current_track_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
591 }
592 
mcc_current_track_obj_id_set_cb(struct bt_conn * conn,int err,uint64_t id)593 static void mcc_current_track_obj_id_set_cb(struct bt_conn *conn, int err, uint64_t id)
594 {
595 	LOG_DBG("MCC Segments Object ID set cb (%d)", err);
596 
597 	btp_send_current_track_obj_id_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, id);
598 }
599 
mcc_send_cmd_cb(struct bt_conn * conn,int err,const struct mpl_cmd * cmd)600 static void mcc_send_cmd_cb(struct bt_conn *conn, int err, const struct mpl_cmd *cmd)
601 {
602 	LOG_DBG("MCC Send Command cb (%d)", err);
603 
604 	btp_send_media_cp_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, cmd);
605 }
606 
mcc_send_search_cb(struct bt_conn * conn,int err,const struct mpl_search * search)607 static void mcc_send_search_cb(struct bt_conn *conn, int err, const struct mpl_search *search)
608 {
609 	LOG_DBG("MCC Send Search cb (%d)", err);
610 
611 	btp_send_search_cp_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, search);
612 }
613 
mcc_cmd_ntf_cb(struct bt_conn * conn,int err,const struct mpl_cmd_ntf * ntf)614 static void mcc_cmd_ntf_cb(struct bt_conn *conn, int err, const struct mpl_cmd_ntf *ntf)
615 {
616 	LOG_DBG("MCC Media Control Point Command Notify cb (%d)", err);
617 
618 	btp_send_command_notifications_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS, ntf);
619 }
620 
mcc_search_ntf_cb(struct bt_conn * conn,int err,uint8_t result_code)621 static void mcc_search_ntf_cb(struct bt_conn *conn, int err, uint8_t result_code)
622 {
623 	LOG_DBG("MCC Search Control Point Notify cb (%d)", err);
624 
625 	btp_send_search_notifications_ev(conn, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS,
626 					 result_code);
627 }
628 
629 static struct bt_mcc_cb mcp_cb = {
630 	.discover_mcs = mcc_discover_cb,
631 	.read_track_duration = mcc_read_track_duration_cb,
632 	.read_track_position = mcc_read_track_position_cb,
633 	.set_track_position = mcc_set_track_position_cb,
634 	.read_playback_speed = mcc_read_playback_speed_cb,
635 	.set_playback_speed = mcc_set_playback_speed_cb,
636 	.read_seeking_speed = mcc_read_seeking_speed_cb,
637 	.read_playing_order = mcc_read_playing_order_cb,
638 	.set_playing_order = mcc_set_playing_order_cb,
639 	.read_playing_orders_supported = mcc_read_playing_orders_supported_cb,
640 	.read_media_state = mcc_media_state_read_cb,
641 	.read_opcodes_supported = mcc_opcodes_supported_cb,
642 	.read_content_control_id = mcc_content_control_id_cb,
643 	.send_cmd = mcc_send_cmd_cb,
644 	.cmd_ntf = mcc_cmd_ntf_cb,
645 #ifdef CONFIG_BT_OTS_CLIENT
646 	.read_icon_obj_id = mcc_read_icon_obj_id_cb,
647 	.read_next_track_obj_id = mcc_read_next_track_obj_id_cb,
648 	.set_next_track_obj_id = mcc_set_next_track_obj_id_cb,
649 	.read_parent_group_obj_id = mcc_read_parent_group_obj_id_cb,
650 	.read_current_group_obj_id = mcc_read_current_group_obj_id_cb,
651 	.set_current_group_obj_id = mcc_set_current_group_obj_id_cb,
652 	.read_segments_obj_id = mcc_segments_object_id_cb,
653 	.read_current_track_obj_id = mcc_current_track_obj_id_read_cb,
654 	.set_current_track_obj_id = mcc_current_track_obj_id_set_cb,
655 	.send_search = mcc_send_search_cb,
656 	.search_ntf = mcc_search_ntf_cb,
657 #endif /* CONFIG_BT_OTS_CLIENT */
658 };
659 
mcp_supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)660 static uint8_t mcp_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp,
661 				      uint16_t *rsp_len)
662 {
663 	struct btp_mcp_read_supported_commands_rp *rp = rsp;
664 
665 	/* octet 0 */
666 	tester_set_bit(rp->data, BTP_MCP_READ_SUPPORTED_COMMANDS);
667 	tester_set_bit(rp->data, BTP_MCP_DISCOVER);
668 	tester_set_bit(rp->data, BTP_MCP_TRACK_DURATION_READ);
669 	tester_set_bit(rp->data, BTP_MCP_TRACK_POSITION_READ);
670 	tester_set_bit(rp->data, BTP_MCP_TRACK_POSITION_SET);
671 	tester_set_bit(rp->data, BTP_MCP_PLAYBACK_SPEED_READ);
672 	tester_set_bit(rp->data, BTP_MCP_PLAYBACK_SPEED_SET);
673 
674 	/* octet 1 */
675 	tester_set_bit(rp->data, BTP_MCP_SEEKING_SPEED_READ);
676 	tester_set_bit(rp->data, BTP_MCP_ICON_OBJ_ID_READ);
677 	tester_set_bit(rp->data, BTP_MCP_NEXT_TRACK_OBJ_ID_READ);
678 	tester_set_bit(rp->data, BTP_MCP_NEXT_TRACK_OBJ_ID_SET);
679 	tester_set_bit(rp->data, BTP_MCP_PARENT_GROUP_OBJ_ID_READ);
680 	tester_set_bit(rp->data, BTP_MCP_CURRENT_GROUP_OBJ_ID_READ);
681 	tester_set_bit(rp->data, BTP_MCP_CURRENT_GROUP_OBJ_ID_SET);
682 
683 	/* octet 2 */
684 	tester_set_bit(rp->data, BTP_MCP_PLAYING_ORDER_READ);
685 	tester_set_bit(rp->data, BTP_MCP_PLAYING_ORDER_SET);
686 	tester_set_bit(rp->data, BTP_MCP_PLAYING_ORDERS_SUPPORTED_READ);
687 	tester_set_bit(rp->data, BTP_MCP_MEDIA_STATE_READ);
688 	tester_set_bit(rp->data, BTP_MCP_OPCODES_SUPPORTED_READ);
689 	tester_set_bit(rp->data, BTP_MCP_CONTENT_CONTROL_ID_READ);
690 	tester_set_bit(rp->data, BTP_MCP_SEGMENTS_OBJ_ID_READ);
691 
692 	/* octet 3 */
693 	tester_set_bit(rp->data, BTP_MCP_CURRENT_TRACK_OBJ_ID_READ);
694 	tester_set_bit(rp->data, BTP_MCP_CURRENT_TRACK_OBJ_ID_SET);
695 	tester_set_bit(rp->data, BTP_MCP_CMD_SEND);
696 	tester_set_bit(rp->data, BTP_MCP_CMD_SEARCH);
697 
698 	*rsp_len = sizeof(*rp) + 1;
699 
700 	return BTP_STATUS_SUCCESS;
701 }
702 
mcp_discover(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)703 static uint8_t mcp_discover(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
704 {
705 	const struct btp_mcp_discover_cmd *cp = cmd;
706 	struct bt_conn *conn;
707 	int err;
708 
709 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
710 	if (!conn) {
711 		LOG_ERR("Unknown connection");
712 		return BTP_STATUS_FAILED;
713 	}
714 
715 	err = bt_mcc_discover_mcs(conn, true);
716 	if (err) {
717 		LOG_DBG("Discovery failed: %d", err);
718 		return BTP_STATUS_FAILED;
719 	}
720 
721 	return BTP_STATUS_SUCCESS;
722 }
723 
mcp_track_duration_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)724 static uint8_t mcp_track_duration_read(const void *cmd, uint16_t cmd_len, void *rsp,
725 				       uint16_t *rsp_len)
726 {
727 	const struct btp_mcp_track_duration_cmd *cp = cmd;
728 	struct bt_conn *conn;
729 	int err;
730 
731 	LOG_DBG("MCC Read track duration");
732 
733 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
734 	if (!conn) {
735 		LOG_ERR("Unknown connection");
736 		return BTP_STATUS_FAILED;
737 	}
738 
739 	err = bt_mcc_read_track_duration(conn);
740 	if (err) {
741 		return BTP_STATUS_FAILED;
742 	}
743 
744 	return BTP_STATUS_SUCCESS;
745 }
746 
mcp_track_position_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)747 static uint8_t mcp_track_position_read(const void *cmd, uint16_t cmd_len, void *rsp,
748 				       uint16_t *rsp_len)
749 {
750 	const struct btp_mcp_track_position_read_cmd *cp = cmd;
751 	struct bt_conn *conn;
752 	int err;
753 
754 	LOG_DBG("MCC Read track position");
755 
756 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
757 	if (!conn) {
758 		LOG_ERR("Unknown connection");
759 		return BTP_STATUS_FAILED;
760 	}
761 
762 	err = bt_mcc_read_track_position(conn);
763 	if (err) {
764 		return BTP_STATUS_FAILED;
765 	}
766 
767 	return BTP_STATUS_SUCCESS;
768 }
769 
mcp_track_position_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)770 static uint8_t mcp_track_position_set(const void *cmd, uint16_t cmd_len, void *rsp,
771 				      uint16_t *rsp_len)
772 {
773 	const struct btp_mcp_track_position_set_cmd *cp = cmd;
774 	uint32_t pos = sys_le32_to_cpu(cp->pos);
775 	struct bt_conn *conn;
776 	int err;
777 
778 	LOG_DBG("MCC Set track position");
779 
780 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
781 	if (!conn) {
782 		LOG_ERR("Unknown connection");
783 		return BTP_STATUS_FAILED;
784 	}
785 
786 	err = bt_mcc_set_track_position(conn, pos);
787 	if (err) {
788 		return BTP_STATUS_FAILED;
789 	}
790 
791 	return BTP_STATUS_SUCCESS;
792 }
793 
mcp_playback_speed_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)794 static uint8_t mcp_playback_speed_read(const void *cmd, uint16_t cmd_len, void *rsp,
795 				       uint16_t *rsp_len)
796 {
797 	const struct btp_mcp_playback_speed_read_cmd *cp = cmd;
798 	struct bt_conn *conn;
799 	int err;
800 
801 	LOG_DBG("MCC Read playback speed");
802 
803 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
804 	if (!conn) {
805 		LOG_ERR("Unknown connection");
806 		return BTP_STATUS_FAILED;
807 	}
808 
809 	err = bt_mcc_read_playback_speed(conn);
810 	if (err) {
811 		return BTP_STATUS_FAILED;
812 	}
813 
814 	return BTP_STATUS_SUCCESS;
815 }
816 
mcp_playback_speed_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)817 static uint8_t mcp_playback_speed_set(const void *cmd, uint16_t cmd_len, void *rsp,
818 				      uint16_t *rsp_len)
819 {
820 	const struct btp_mcp_playback_speed_set *cp = cmd;
821 	struct bt_conn *conn;
822 	int err;
823 
824 	LOG_DBG("MCC Set playback speed");
825 
826 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
827 	if (!conn) {
828 		LOG_ERR("Unknown connection");
829 		return BTP_STATUS_FAILED;
830 	}
831 
832 	err = bt_mcc_set_playback_speed(conn, cp->speed);
833 	if (err) {
834 		return BTP_STATUS_FAILED;
835 	}
836 
837 	return BTP_STATUS_SUCCESS;
838 }
839 
mcp_seeking_speed_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)840 static uint8_t mcp_seeking_speed_read(const void *cmd, uint16_t cmd_len, void *rsp,
841 				      uint16_t *rsp_len)
842 {
843 	const struct btp_mcp_seeking_speed_read_cmd *cp = cmd;
844 	struct bt_conn *conn;
845 	int err;
846 
847 	LOG_DBG("MCC Read seeking speed");
848 
849 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
850 	if (!conn) {
851 		LOG_ERR("Unknown connection");
852 		return BTP_STATUS_FAILED;
853 	}
854 
855 	err = bt_mcc_read_seeking_speed(conn);
856 	if (err) {
857 		return BTP_STATUS_FAILED;
858 	}
859 
860 	return BTP_STATUS_SUCCESS;
861 }
862 
mcp_read_icon_obj_id(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)863 static uint8_t mcp_read_icon_obj_id(const void *cmd, uint16_t cmd_len, void *rsp,
864 				    uint16_t *rsp_len)
865 {
866 	const struct btp_mcp_icon_obj_id_read_cmd *cp = cmd;
867 	struct bt_conn *conn;
868 	int err;
869 
870 	LOG_DBG("MCC Read Icon Object ID");
871 
872 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
873 	if (!conn) {
874 		LOG_ERR("Unknown connection");
875 		return BTP_STATUS_FAILED;
876 	}
877 
878 	err = bt_mcc_read_icon_obj_id(conn);
879 	if (err) {
880 		return BTP_STATUS_FAILED;
881 	}
882 
883 	return BTP_STATUS_SUCCESS;
884 }
885 
mcp_read_next_track_obj_id(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)886 static uint8_t mcp_read_next_track_obj_id(const void *cmd, uint16_t cmd_len, void *rsp,
887 					  uint16_t *rsp_len)
888 {
889 	const struct btp_mcp_next_track_obj_id_cmd *cp = cmd;
890 	struct bt_conn *conn;
891 	int err;
892 
893 	LOG_DBG("MCC Read Next Track Object ID");
894 
895 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
896 	if (!conn) {
897 		LOG_ERR("Unknown connection");
898 		return BTP_STATUS_FAILED;
899 	}
900 
901 	err = bt_mcc_read_next_track_obj_id(conn);
902 	if (err) {
903 		return BTP_STATUS_FAILED;
904 	}
905 
906 	return BTP_STATUS_SUCCESS;
907 }
908 
mcp_set_next_track_obj_id(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)909 static uint8_t mcp_set_next_track_obj_id(const void *cmd, uint16_t cmd_len, void *rsp,
910 					 uint16_t *rsp_len)
911 {
912 	const struct btp_mcp_set_next_track_obj_id_cmd *cp = cmd;
913 	uint64_t id = sys_get_le48(cp->id);
914 	struct bt_conn *conn;
915 	int err;
916 
917 	LOG_DBG("MCC Set Next Track Object ID");
918 
919 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
920 	if (!conn) {
921 		LOG_ERR("Unknown connection");
922 		return BTP_STATUS_FAILED;
923 	}
924 
925 	err = bt_mcc_set_next_track_obj_id(conn, id);
926 	if (err) {
927 		return BTP_STATUS_FAILED;
928 	}
929 
930 	return BTP_STATUS_SUCCESS;
931 }
932 
mcp_parent_group_obj_id_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)933 static uint8_t mcp_parent_group_obj_id_read(const void *cmd, uint16_t cmd_len, void *rsp,
934 					    uint16_t *rsp_len)
935 {
936 	const struct btp_mcp_parent_group_obj_id_read_cmd *cp = cmd;
937 	struct bt_conn *conn;
938 	int err;
939 
940 	LOG_DBG("MCC Read Parent Group Object ID");
941 
942 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
943 	if (!conn) {
944 		LOG_ERR("Unknown connection");
945 		return BTP_STATUS_FAILED;
946 	}
947 
948 	err = bt_mcc_read_parent_group_obj_id(conn);
949 	if (err) {
950 		return BTP_STATUS_FAILED;
951 	}
952 
953 	return BTP_STATUS_SUCCESS;
954 }
955 
mcp_current_group_obj_id_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)956 static uint8_t mcp_current_group_obj_id_read(const void *cmd, uint16_t cmd_len, void *rsp,
957 					     uint16_t *rsp_len)
958 {
959 	const struct btp_mcp_current_group_obj_id_read_cmd *cp = cmd;
960 	struct bt_conn *conn;
961 	int err;
962 
963 	LOG_DBG("MCC Read Current Group Object ID");
964 
965 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
966 	if (!conn) {
967 		LOG_ERR("Unknown connection");
968 		return BTP_STATUS_FAILED;
969 	}
970 
971 	err = bt_mcc_read_current_group_obj_id(conn);
972 	if (err) {
973 		return BTP_STATUS_FAILED;
974 	}
975 
976 	return BTP_STATUS_SUCCESS;
977 }
978 
mcp_set_current_group_obj_id(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)979 static uint8_t mcp_set_current_group_obj_id(const void *cmd, uint16_t cmd_len, void *rsp,
980 					    uint16_t *rsp_len)
981 {
982 	const struct btp_mcp_current_group_obj_id_set_cmd *cp = cmd;
983 	uint64_t id = sys_get_le48(cp->id);
984 	struct bt_conn *conn;
985 	int err;
986 
987 	LOG_DBG("MCC Set Next Track Object ID");
988 
989 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
990 	if (!conn) {
991 		LOG_ERR("Unknown connection");
992 		return BTP_STATUS_FAILED;
993 	}
994 
995 	err = bt_mcc_set_current_group_obj_id(conn, id);
996 	if (err) {
997 		return BTP_STATUS_FAILED;
998 	}
999 
1000 	return BTP_STATUS_SUCCESS;
1001 }
1002 
mcp_playing_order_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1003 static uint8_t mcp_playing_order_read(const void *cmd, uint16_t cmd_len, void *rsp,
1004 				      uint16_t *rsp_len)
1005 {
1006 	const struct btp_mcp_playing_order_read_cmd *cp = cmd;
1007 	struct bt_conn *conn;
1008 	int err;
1009 
1010 	LOG_DBG("MCC Read Playing Order");
1011 
1012 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1013 	if (!conn) {
1014 		LOG_ERR("Unknown connection");
1015 		return BTP_STATUS_FAILED;
1016 	}
1017 
1018 	err = bt_mcc_read_playing_order(conn);
1019 	if (err) {
1020 		return BTP_STATUS_FAILED;
1021 	}
1022 
1023 	return BTP_STATUS_SUCCESS;
1024 }
1025 
mcp_playing_order_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1026 static uint8_t mcp_playing_order_set(const void *cmd, uint16_t cmd_len, void *rsp,
1027 				     uint16_t *rsp_len)
1028 {
1029 	const struct btp_mcp_playing_order_set_cmd *cp = cmd;
1030 	struct bt_conn *conn;
1031 	int err;
1032 
1033 	LOG_DBG("MCC Set Playing Order");
1034 
1035 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1036 	if (!conn) {
1037 		LOG_ERR("Unknown connection");
1038 		return BTP_STATUS_FAILED;
1039 	}
1040 
1041 	err = bt_mcc_set_playing_order(conn, cp->order);
1042 	if (err) {
1043 		return BTP_STATUS_FAILED;
1044 	}
1045 
1046 	return BTP_STATUS_SUCCESS;
1047 }
1048 
mcp_playing_orders_supported_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1049 static uint8_t mcp_playing_orders_supported_read(const void *cmd, uint16_t cmd_len, void *rsp,
1050 						 uint16_t *rsp_len)
1051 {
1052 	const struct btp_mcp_playing_orders_supported_read_cmd *cp = cmd;
1053 	struct bt_conn *conn;
1054 	int err;
1055 
1056 	LOG_DBG("MCC Playing orders supported read");
1057 
1058 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1059 	if (!conn) {
1060 		LOG_ERR("Unknown connection");
1061 		return BTP_STATUS_FAILED;
1062 	}
1063 
1064 	err = bt_mcc_read_playing_orders_supported(conn);
1065 	if (err) {
1066 		return BTP_STATUS_FAILED;
1067 	}
1068 
1069 	return BTP_STATUS_SUCCESS;
1070 }
1071 
mcp_media_state_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1072 static uint8_t mcp_media_state_read(const void *cmd, uint16_t cmd_len, void *rsp,
1073 				    uint16_t *rsp_len)
1074 {
1075 	const struct btp_mcp_media_state_read_cmd *cp = cmd;
1076 	struct bt_conn *conn;
1077 	int err;
1078 
1079 	LOG_DBG("MCC Media State read");
1080 
1081 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1082 	if (!conn) {
1083 		LOG_ERR("Unknown connection");
1084 		return BTP_STATUS_FAILED;
1085 	}
1086 
1087 	err = bt_mcc_read_media_state(conn);
1088 	if (err) {
1089 		return BTP_STATUS_FAILED;
1090 	}
1091 
1092 	return BTP_STATUS_SUCCESS;
1093 }
1094 
mcp_opcodes_supported_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1095 static uint8_t mcp_opcodes_supported_read(const void *cmd, uint16_t cmd_len, void *rsp,
1096 					  uint16_t *rsp_len)
1097 {
1098 	const struct btp_mcp_opcodes_supported_read_cmd *cp = cmd;
1099 	struct bt_conn *conn;
1100 	int err;
1101 
1102 	LOG_DBG("MCC Supported opcodes read");
1103 
1104 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1105 	if (!conn) {
1106 		LOG_ERR("Unknown connection");
1107 		return BTP_STATUS_FAILED;
1108 	}
1109 
1110 	err = bt_mcc_read_opcodes_supported(conn);
1111 	if (err) {
1112 		return BTP_STATUS_FAILED;
1113 	}
1114 
1115 	return BTP_STATUS_SUCCESS;
1116 }
1117 
mcp_content_control_id_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1118 static uint8_t mcp_content_control_id_read(const void *cmd, uint16_t cmd_len, void *rsp,
1119 					   uint16_t *rsp_len)
1120 {
1121 	const struct btp_mcp_content_control_id_read_cmd *cp = cmd;
1122 	struct bt_conn *conn;
1123 	int err;
1124 
1125 	LOG_DBG("MCC Content Control ID read");
1126 
1127 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1128 	if (!conn) {
1129 		LOG_ERR("Unknown connection");
1130 		return BTP_STATUS_FAILED;
1131 	}
1132 
1133 	err = bt_mcc_read_content_control_id(conn);
1134 	if (err) {
1135 		return BTP_STATUS_FAILED;
1136 	}
1137 
1138 	return BTP_STATUS_SUCCESS;
1139 }
1140 
mcp_segments_obj_id_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1141 static uint8_t mcp_segments_obj_id_read(const void *cmd, uint16_t cmd_len, void *rsp,
1142 					uint16_t *rsp_len)
1143 {
1144 	const struct btp_mcp_segments_obj_id_read_cmd *cp = cmd;
1145 	struct bt_conn *conn;
1146 	int err;
1147 
1148 	LOG_DBG("MCC Track Segments Object ID read");
1149 
1150 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1151 	if (!conn) {
1152 		LOG_ERR("Unknown connection");
1153 		return BTP_STATUS_FAILED;
1154 	}
1155 
1156 	err = bt_mcc_read_segments_obj_id(conn);
1157 	if (err) {
1158 		return BTP_STATUS_FAILED;
1159 	}
1160 
1161 	return BTP_STATUS_SUCCESS;
1162 }
1163 
mcp_current_track_obj_id_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1164 static uint8_t mcp_current_track_obj_id_read(const void *cmd, uint16_t cmd_len, void *rsp,
1165 					     uint16_t *rsp_len)
1166 {
1167 	const struct btp_mcp_current_track_obj_id_read_cmd *cp = cmd;
1168 	struct bt_conn *conn;
1169 	int err;
1170 
1171 	LOG_DBG("MCC Current Track Object ID read");
1172 
1173 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1174 	if (!conn) {
1175 		LOG_ERR("Unknown connection");
1176 		return BTP_STATUS_FAILED;
1177 	}
1178 
1179 	err = bt_mcc_read_current_track_obj_id(conn);
1180 	if (err) {
1181 		return BTP_STATUS_FAILED;
1182 	}
1183 
1184 	return BTP_STATUS_SUCCESS;
1185 }
1186 
mcp_current_track_obj_id_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1187 static uint8_t mcp_current_track_obj_id_set(const void *cmd, uint16_t cmd_len, void *rsp,
1188 					    uint16_t *rsp_len)
1189 {
1190 	const struct btp_mcp_current_track_obj_id_set_cmd *cp = cmd;
1191 	uint64_t id = sys_get_le48(cp->id);
1192 	struct bt_conn *conn;
1193 	int err;
1194 
1195 	LOG_DBG("MCC Set Current Track Object ID");
1196 
1197 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1198 	if (!conn) {
1199 		LOG_ERR("Unknown connection");
1200 		return BTP_STATUS_FAILED;
1201 	}
1202 
1203 	err = bt_mcc_set_current_track_obj_id(conn, id);
1204 	if (err) {
1205 		return BTP_STATUS_FAILED;
1206 	}
1207 
1208 	return BTP_STATUS_SUCCESS;
1209 }
1210 
mcp_cmd_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1211 static uint8_t mcp_cmd_send(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
1212 {
1213 	const struct btp_mcp_send_cmd *cp = cmd;
1214 	struct mpl_cmd mcp_cmd;
1215 	struct bt_conn *conn;
1216 	int err;
1217 
1218 	LOG_DBG("MCC Send Command");
1219 
1220 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1221 	if (!conn) {
1222 		LOG_ERR("Unknown connection");
1223 		return BTP_STATUS_FAILED;
1224 	}
1225 
1226 	mcp_cmd.opcode = cp->opcode;
1227 	mcp_cmd.use_param = cp->use_param;
1228 	mcp_cmd.param = sys_le32_to_cpu(cp->param);
1229 
1230 	err = bt_mcc_send_cmd(conn, &mcp_cmd);
1231 	if (err) {
1232 		return BTP_STATUS_FAILED;
1233 	}
1234 
1235 	return BTP_STATUS_SUCCESS;
1236 }
1237 
mcp_cmd_search(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1238 static uint8_t mcp_cmd_search(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
1239 {
1240 	const struct btp_mcp_search_cmd *cp = cmd;
1241 	struct mpl_search search_items;
1242 	struct mpl_sci scp_cmd;
1243 	struct bt_conn *conn;
1244 	int err;
1245 
1246 	LOG_DBG("MCC Send Search Control Point Command");
1247 
1248 	if (cmd_len < sizeof(*cp) || cmd_len != sizeof(*cp) + cp->param_len) {
1249 		return BTP_STATUS_FAILED;
1250 	}
1251 
1252 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1253 	if (!conn) {
1254 		LOG_ERR("Unknown connection");
1255 		return BTP_STATUS_FAILED;
1256 	}
1257 
1258 	search_items.len = 0;
1259 	scp_cmd.type = cp->type;
1260 
1261 	if (scp_cmd.type == BT_MCS_SEARCH_TYPE_ONLY_TRACKS ||
1262 	    scp_cmd.type == BT_MCS_SEARCH_TYPE_ONLY_GROUPS) {
1263 		scp_cmd.len = sizeof(scp_cmd.type);
1264 
1265 		if (ARRAY_SIZE(search_items.search) < (sizeof(scp_cmd.len) +
1266 						       sizeof(scp_cmd.type))) {
1267 			return BTP_STATUS_FAILED;
1268 		}
1269 
1270 		memcpy(&search_items.search[search_items.len], &scp_cmd.len, sizeof(scp_cmd.len));
1271 		search_items.len += sizeof(scp_cmd.len);
1272 
1273 		memcpy(&search_items.search[search_items.len], &scp_cmd.type,
1274 		       sizeof(scp_cmd.type));
1275 		search_items.len += sizeof(scp_cmd.type);
1276 	} else {
1277 		if (cp->param_len >= (SEARCH_LEN_MAX - 1)) {
1278 			return BTP_STATUS_FAILED;
1279 		}
1280 
1281 		strcpy(scp_cmd.param, cp->param);
1282 		scp_cmd.len = sizeof(scp_cmd.type) + strlen(scp_cmd.param);
1283 
1284 		if (ARRAY_SIZE(search_items.search) < (sizeof(scp_cmd.len) + sizeof(scp_cmd.len) +
1285 						       strlen(scp_cmd.param))) {
1286 			return BTP_STATUS_FAILED;
1287 		}
1288 
1289 		memcpy(&search_items.search[search_items.len], &scp_cmd.len, sizeof(scp_cmd.len));
1290 		search_items.len += sizeof(scp_cmd.len);
1291 
1292 		memcpy(&search_items.search[search_items.len], &scp_cmd.type,
1293 		       sizeof(scp_cmd.type));
1294 		search_items.len += sizeof(scp_cmd.type);
1295 
1296 		strcpy(&search_items.search[search_items.len], scp_cmd.param);
1297 		search_items.len += strlen(scp_cmd.param);
1298 		search_items.search[search_items.len] = '\0';
1299 	}
1300 
1301 	err = bt_mcc_send_search(conn, &search_items);
1302 	if (err) {
1303 		return BTP_STATUS_FAILED;
1304 	}
1305 
1306 	return BTP_STATUS_SUCCESS;
1307 }
1308 
1309 static const struct btp_handler mcp_handlers[] = {
1310 	{
1311 		.opcode = BTP_MCP_READ_SUPPORTED_COMMANDS,
1312 		.index = BTP_INDEX_NONE,
1313 		.expect_len = 0,
1314 		.func = mcp_supported_commands,
1315 	},
1316 	{
1317 		.opcode = BTP_MCP_DISCOVER,
1318 		.expect_len = sizeof(struct btp_mcp_discover_cmd),
1319 		.func = mcp_discover,
1320 	},
1321 	{
1322 		.opcode = BTP_MCP_TRACK_DURATION_READ,
1323 		.expect_len = sizeof(struct btp_mcp_track_duration_cmd),
1324 		.func = mcp_track_duration_read,
1325 	},
1326 	{
1327 		.opcode = BTP_MCP_TRACK_POSITION_READ,
1328 		.expect_len = sizeof(struct btp_mcp_track_position_read_cmd),
1329 		.func = mcp_track_position_read,
1330 	},
1331 	{
1332 		.opcode = BTP_MCP_TRACK_POSITION_SET,
1333 		.expect_len = sizeof(struct btp_mcp_track_position_set_cmd),
1334 		.func = mcp_track_position_set,
1335 	},
1336 	{
1337 		.opcode = BTP_MCP_PLAYBACK_SPEED_READ,
1338 		.expect_len = sizeof(struct btp_mcp_playback_speed_read_cmd),
1339 		.func = mcp_playback_speed_read,
1340 	},
1341 	{
1342 		.opcode = BTP_MCP_PLAYBACK_SPEED_SET,
1343 		.expect_len = sizeof(struct btp_mcp_playback_speed_set),
1344 		.func = mcp_playback_speed_set,
1345 	},
1346 	{
1347 		.opcode = BTP_MCP_SEEKING_SPEED_READ,
1348 		.expect_len = sizeof(struct btp_mcp_seeking_speed_read_cmd),
1349 		.func = mcp_seeking_speed_read,
1350 	},
1351 	{
1352 		.opcode = BTP_MCP_ICON_OBJ_ID_READ,
1353 		.expect_len = sizeof(struct btp_mcp_icon_obj_id_read_cmd),
1354 		.func = mcp_read_icon_obj_id,
1355 	},
1356 	{
1357 		.opcode = BTP_MCP_NEXT_TRACK_OBJ_ID_READ,
1358 		.expect_len = sizeof(struct btp_mcp_next_track_obj_id_cmd),
1359 		.func = mcp_read_next_track_obj_id,
1360 	},
1361 	{
1362 		.opcode = BTP_MCP_NEXT_TRACK_OBJ_ID_SET,
1363 		.expect_len = sizeof(struct btp_mcp_set_next_track_obj_id_cmd),
1364 		.func = mcp_set_next_track_obj_id,
1365 	},
1366 	{
1367 		.opcode = BTP_MCP_PARENT_GROUP_OBJ_ID_READ,
1368 		.expect_len = sizeof(struct btp_mcp_parent_group_obj_id_read_cmd),
1369 		.func = mcp_parent_group_obj_id_read,
1370 	},
1371 	{
1372 		.opcode = BTP_MCP_CURRENT_GROUP_OBJ_ID_READ,
1373 		.expect_len = sizeof(struct btp_mcp_current_group_obj_id_read_cmd),
1374 		.func = mcp_current_group_obj_id_read,
1375 	},
1376 	{
1377 		.opcode = BTP_MCP_CURRENT_GROUP_OBJ_ID_SET,
1378 		.expect_len = sizeof(struct btp_mcp_current_group_obj_id_set_cmd),
1379 		.func = mcp_set_current_group_obj_id,
1380 	},
1381 	{
1382 		.opcode = BTP_MCP_PLAYING_ORDER_READ,
1383 		.expect_len = sizeof(struct btp_mcp_playing_order_read_cmd),
1384 		.func = mcp_playing_order_read,
1385 	},
1386 	{
1387 		.opcode = BTP_MCP_PLAYING_ORDER_SET,
1388 		.expect_len = sizeof(struct btp_mcp_playing_order_set_cmd),
1389 		.func = mcp_playing_order_set,
1390 	},
1391 	{
1392 		.opcode = BTP_MCP_PLAYING_ORDERS_SUPPORTED_READ,
1393 		.expect_len = sizeof(struct btp_mcp_playing_orders_supported_read_cmd),
1394 		.func = mcp_playing_orders_supported_read,
1395 	},
1396 	{
1397 		.opcode = BTP_MCP_MEDIA_STATE_READ,
1398 		.expect_len = sizeof(struct btp_mcp_media_state_read_cmd),
1399 		.func = mcp_media_state_read,
1400 	},
1401 	{
1402 		.opcode = BTP_MCP_OPCODES_SUPPORTED_READ,
1403 		.expect_len = sizeof(struct btp_mcp_opcodes_supported_read_cmd),
1404 		.func = mcp_opcodes_supported_read,
1405 	},
1406 	{
1407 		.opcode = BTP_MCP_CONTENT_CONTROL_ID_READ,
1408 		.expect_len = sizeof(struct btp_mcp_content_control_id_read_cmd),
1409 		.func = mcp_content_control_id_read,
1410 	},
1411 	{
1412 		.opcode = BTP_MCP_SEGMENTS_OBJ_ID_READ,
1413 		.expect_len = sizeof(struct btp_mcp_segments_obj_id_read_cmd),
1414 		.func = mcp_segments_obj_id_read,
1415 	},
1416 	{
1417 		.opcode = BTP_MCP_CURRENT_TRACK_OBJ_ID_READ,
1418 		.expect_len = sizeof(struct btp_mcp_current_track_obj_id_read_cmd),
1419 		.func = mcp_current_track_obj_id_read,
1420 	},
1421 	{
1422 		.opcode = BTP_MCP_CURRENT_TRACK_OBJ_ID_SET,
1423 		.expect_len = sizeof(struct btp_mcp_current_track_obj_id_set_cmd),
1424 		.func = mcp_current_track_obj_id_set,
1425 	},
1426 	{
1427 		.opcode = BTP_MCP_CMD_SEND,
1428 		.expect_len = sizeof(struct btp_mcp_send_cmd),
1429 		.func = mcp_cmd_send,
1430 	},
1431 	{
1432 		.opcode = BTP_MCP_CMD_SEARCH,
1433 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
1434 		.func = mcp_cmd_search,
1435 	},
1436 };
1437 
tester_init_mcp(void)1438 uint8_t tester_init_mcp(void)
1439 {
1440 	int err;
1441 
1442 	err = bt_mcc_init(&mcp_cb);
1443 	if (err) {
1444 		LOG_DBG("Failed to initialize Media Control Client: %d", err);
1445 		return BTP_STATUS_FAILED;
1446 	}
1447 
1448 	tester_register_command_handlers(BTP_SERVICE_ID_MCP, mcp_handlers,
1449 					 ARRAY_SIZE(mcp_handlers));
1450 
1451 	return BTP_STATUS_SUCCESS;
1452 }
1453 
tester_unregister_mcp(void)1454 uint8_t tester_unregister_mcp(void)
1455 {
1456 	return BTP_STATUS_SUCCESS;
1457 }
1458 
1459 /* Media Control Service */
mcs_supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1460 static uint8_t mcs_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp,
1461 				      uint16_t *rsp_len)
1462 {
1463 	struct btp_mcs_read_supported_commands_rp *rp = rsp;
1464 
1465 	/* octet 0 */
1466 	tester_set_bit(rp->data, BTP_MCS_READ_SUPPORTED_COMMANDS);
1467 	tester_set_bit(rp->data, BTP_MCS_CMD_SEND);
1468 	tester_set_bit(rp->data, BTP_MCS_CURRENT_TRACK_OBJ_ID_GET);
1469 	tester_set_bit(rp->data, BTP_MCS_NEXT_TRACK_OBJ_ID_GET);
1470 	tester_set_bit(rp->data, BTP_MCS_INACTIVE_STATE_SET);
1471 	tester_set_bit(rp->data, BTP_MCS_PARENT_GROUP_SET);
1472 
1473 	*rsp_len = sizeof(*rp) + 1;
1474 
1475 	return BTP_STATUS_SUCCESS;
1476 }
1477 
mcs_cmd_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1478 static uint8_t mcs_cmd_send(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
1479 {
1480 	const struct btp_mcs_send_cmd *cp = cmd;
1481 	struct mpl_cmd mcp_cmd;
1482 	int err;
1483 
1484 	LOG_DBG("MCS Send Command");
1485 
1486 	mcp_cmd.opcode = cp->opcode;
1487 	mcp_cmd.use_param = cp->use_param;
1488 	mcp_cmd.param = (cp->use_param != 0) ? sys_le32_to_cpu(cp->param) : 0;
1489 
1490 	err = media_proxy_ctrl_send_command(mcs_media_player, &mcp_cmd);
1491 	if (err) {
1492 		return BTP_STATUS_FAILED;
1493 	}
1494 
1495 	return BTP_STATUS_SUCCESS;
1496 }
1497 
mcs_next_track_obj_id_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1498 static uint8_t mcs_next_track_obj_id_get(const void *cmd, uint16_t cmd_len, void *rsp,
1499 					 uint16_t *rsp_len)
1500 {
1501 	struct btp_mcs_next_track_obj_id_rp *rp = rsp;
1502 	int err;
1503 
1504 	LOG_DBG("MCS Read Next Track Obj Id");
1505 
1506 	err = media_proxy_ctrl_get_next_track_id(mcs_media_player);
1507 	if (err) {
1508 		return BTP_STATUS_FAILED;
1509 	}
1510 
1511 	sys_put_le48(next_track_obj_id, rp->id);
1512 
1513 	*rsp_len = sizeof(*rp);
1514 
1515 	return BTP_STATUS_SUCCESS;
1516 }
1517 
mcs_current_track_obj_id_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1518 static uint8_t mcs_current_track_obj_id_get(const void *cmd, uint16_t cmd_len, void *rsp,
1519 					    uint16_t *rsp_len)
1520 {
1521 	struct btp_mcs_current_track_obj_id_rp *rp = rsp;
1522 	int err;
1523 
1524 	LOG_DBG("MCS Read Current Track Obj Id");
1525 
1526 	err = media_proxy_ctrl_get_current_track_id(mcs_media_player);
1527 	if (err) {
1528 		return BTP_STATUS_FAILED;
1529 	}
1530 
1531 	sys_put_le48(current_track_obj_id, rp->id);
1532 
1533 	*rsp_len = sizeof(*rp);
1534 
1535 	return BTP_STATUS_SUCCESS;
1536 }
1537 
mcs_parent_group_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1538 static uint8_t mcs_parent_group_set(const void *cmd, uint16_t cmd_len, void *rsp,
1539 				    uint16_t *rsp_len)
1540 {
1541 	int err;
1542 
1543 	LOG_DBG("MCS Set Current Group to be it's own parent");
1544 
1545 	err = media_proxy_ctrl_get_current_group_id(mcs_media_player);
1546 	if (err) {
1547 		return BTP_STATUS_FAILED;
1548 	}
1549 
1550 	/* Setting current group to be it's own parent */
1551 	mpl_test_unset_parent_group();
1552 
1553 	err = media_proxy_ctrl_get_parent_group_id(mcs_media_player);
1554 	if (err) {
1555 		return BTP_STATUS_FAILED;
1556 	}
1557 
1558 	if (current_id != parent_id) {
1559 		return BTP_STATUS_FAILED;
1560 	}
1561 
1562 	return BTP_STATUS_SUCCESS;
1563 }
1564 
mcs_inactive_state_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1565 static uint8_t mcs_inactive_state_set(const void *cmd, uint16_t cmd_len, void *rsp,
1566 				      uint16_t *rsp_len)
1567 {
1568 	struct btp_mcs_state_set_rp *rp = rsp;
1569 
1570 	LOG_DBG("MCS Set Media Player to inactive state");
1571 
1572 	mpl_test_media_state_set(MEDIA_PROXY_STATE_INACTIVE);
1573 
1574 	rp->state = media_player_state;
1575 
1576 	*rsp_len = sizeof(*rp);
1577 
1578 	return BTP_STATUS_SUCCESS;
1579 }
1580 
mcs_player_instance_cb(struct media_player * plr,int err)1581 static void mcs_player_instance_cb(struct media_player *plr, int err)
1582 {
1583 	mcs_media_player = plr;
1584 
1585 	LOG_DBG("Media PLayer Instance cb");
1586 }
1587 
mcs_command_send_cb(struct media_player * player,int err,const struct mpl_cmd * cmd)1588 static void mcs_command_send_cb(struct media_player *player, int err, const struct mpl_cmd *cmd)
1589 {
1590 	LOG_DBG("Media PLayer Send Command cb");
1591 }
1592 
mcs_current_track_obj_id_cb(struct media_player * player,int err,uint64_t id)1593 static void mcs_current_track_obj_id_cb(struct media_player *player, int err, uint64_t id)
1594 {
1595 	LOG_DBG("Media Player Current Track Object Id cb");
1596 
1597 	current_track_obj_id = id;
1598 }
1599 
mcs_next_track_obj_id_cb(struct media_player * player,int err,uint64_t id)1600 static void mcs_next_track_obj_id_cb(struct media_player *player, int err, uint64_t id)
1601 {
1602 	LOG_DBG("Media PLayer Next Track Object ID cb");
1603 
1604 	next_track_obj_id = id;
1605 }
1606 
mcs_media_state_cb(struct media_player * player,int err,uint8_t state)1607 static void mcs_media_state_cb(struct media_player *player, int err, uint8_t state)
1608 {
1609 	LOG_DBG("Media Player State cb");
1610 
1611 	media_player_state = state;
1612 }
1613 
mcs_current_group_id_cb(struct media_player * player,int err,uint64_t id)1614 static void mcs_current_group_id_cb(struct media_player *player, int err, uint64_t id)
1615 {
1616 	LOG_DBG("Media Player Current Group ID cb");
1617 
1618 	current_id = id;
1619 }
1620 
mcs_parent_group_id_cb(struct media_player * player,int err,uint64_t id)1621 static void mcs_parent_group_id_cb(struct media_player *player, int err, uint64_t id)
1622 {
1623 	LOG_DBG("Media Player Parent Group ID cb");
1624 
1625 	parent_id = id;
1626 }
1627 
1628 static struct media_proxy_ctrl_cbs mcs_cbs = {
1629 	.local_player_instance = mcs_player_instance_cb,
1630 	.command_send = mcs_command_send_cb,
1631 	.current_track_id_recv = mcs_current_track_obj_id_cb,
1632 	.next_track_id_recv = mcs_next_track_obj_id_cb,
1633 	.media_state_recv = mcs_media_state_cb,
1634 	.current_group_id_recv = mcs_current_group_id_cb,
1635 	.parent_group_id_recv = mcs_parent_group_id_cb,
1636 };
1637 
1638 static const struct btp_handler mcs_handlers[] = {
1639 	{
1640 		.opcode = BTP_MCS_READ_SUPPORTED_COMMANDS,
1641 		.index = BTP_INDEX_NONE,
1642 		.expect_len = 0,
1643 		.func = mcs_supported_commands,
1644 	},
1645 	{
1646 		.opcode = BTP_MCS_CMD_SEND,
1647 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
1648 		.func = mcs_cmd_send,
1649 	},
1650 	{
1651 		.opcode = BTP_MCS_CURRENT_TRACK_OBJ_ID_GET,
1652 		.expect_len = 0,
1653 		.func = mcs_current_track_obj_id_get,
1654 	},
1655 	{
1656 		.opcode = BTP_MCS_NEXT_TRACK_OBJ_ID_GET,
1657 		.expect_len = 0,
1658 		.func = mcs_next_track_obj_id_get,
1659 	},
1660 	{
1661 		.opcode = BTP_MCS_INACTIVE_STATE_SET,
1662 		.expect_len = 0,
1663 		.func = mcs_inactive_state_set,
1664 	},
1665 	{
1666 		.opcode = BTP_MCS_PARENT_GROUP_SET,
1667 		.expect_len = 0,
1668 		.func = mcs_parent_group_set,
1669 	},
1670 };
1671 
tester_init_mcs(void)1672 uint8_t tester_init_mcs(void)
1673 {
1674 	int err;
1675 
1676 	err = media_proxy_pl_init();
1677 	if (err) {
1678 		LOG_DBG("Failed to initialize Media Player: %d", err);
1679 		return BTP_STATUS_FAILED;
1680 	}
1681 
1682 	err = media_proxy_ctrl_register(&mcs_cbs);
1683 	if (err) {
1684 		return BTP_STATUS_FAILED;
1685 	}
1686 
1687 	tester_register_command_handlers(BTP_SERVICE_ID_GMCS, mcs_handlers,
1688 					 ARRAY_SIZE(mcs_handlers));
1689 
1690 	return BTP_STATUS_SUCCESS;
1691 }
1692 
tester_unregister_mcs(void)1693 uint8_t tester_unregister_mcs(void)
1694 {
1695 	return BTP_STATUS_SUCCESS;
1696 }
1697