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