* Copyright (C) 2022 Xiaomi Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bluetooth.h"
#include "bt_adapter.h"
#include "bt_lea_mcs.h"
#include "bt_tools.h"
static int le_mcs_add(void* handle, int argc, char* argv[]);
static int le_mcs_remove(void* handle, int argc, char* argv[]);
static int mcs_media_state_changed(void* handle, int argc, char* argv[]);
static int mcs_set_media_player_info(void* handle, int argc, char* argv[]);
static int mcs_media_control_response(void* handle, int argc, char* argv[]);
static int mcs_playing_order_changed(void* handle, int argc, char* argv[]);
static int mcs_playback_speed_changed(void* handle, int argc, char* argv[]);
static int mcs_seeking_speed_changed(void* handle, int argc, char* argv[]);
static int mcs_track_title_changed(void* handle, int argc, char* argv[]);
static int mcs_track_duration_changed(void* handle, int argc, char* argv[]);
static int mcs_track_position_changed(void* handle, int argc, char* argv[]);
static int mcs_current_track_changed(void* handle, int argc, char* argv[]);
static int mcs_next_track_changed(void* handle, int argc, char* argv[]);
static int mcs_current_group_changed(void* handle, int argc, char* argv[]);
static int mcs_parent_group_changed(void* handle, int argc, char* argv[]);
static bt_command_t g_lea_mcs_tables[] = {
{ "add", le_mcs_add, 0, "MCS instance add param: <NULL>" },
{ "remove", le_mcs_remove, 0, "MCS instance remove param: <NULL>" },
{ "mediastatechanged", mcs_media_state_changed, 0, "MCS notify media state param: <state>" },
{ "setmediaplayer", mcs_set_media_player_info, 0, "set media player info param: <NULL>" },
{ "mediacontrolrsp", mcs_media_control_response, 0, "notify media control point process result param: <result>" },
{ "playingorderchanged", mcs_playing_order_changed, 0, "MCS notify playing order changed param: <order>" },
{ "playbackspeedchanged", mcs_playback_speed_changed, 0, "MCS notify playback speed changed param: <speed>" },
{ "seekingspeedchanged", mcs_seeking_speed_changed, 0, "MCS notify seeking speed changed param: <speed>" },
{ "tracktitlechanged", mcs_track_title_changed, 0, "MCS notify track title changed param: <title>" },
{ "trackdurationchanged", mcs_track_duration_changed, 0, "MCS notify track duration changed param: <duration>" },
{ "trackpositionchanged", mcs_track_position_changed, 0, "MCS notify track position changed param: <position>" },
{ "currenttrackchanged", mcs_current_track_changed, 0, "MCS notify current track changed param: <track_id[6] six octets>" },
{ "nexttrackchanged", mcs_next_track_changed, 0, "MCS notify next track changed param: <track_id[6] six octets>" },
{ "currentgroupchanged", mcs_current_group_changed, 0, "MCS notify current group changed param: <group_id[6] six octets>" },
{ "parentgroupchanged", mcs_parent_group_changed, 0, "MCS notify parent group changed param: <group_id[6] six octets>" },
};
static void* mcs_callbacks = NULL;
static void usage(void)
{
printf("Usage:\n");
printf("\taddress: peer device address like 00:01:02:03:04:05\n");
printf("Commands:\n");
for (int i = 0; i < ARRAY_SIZE(g_lea_mcs_tables); i++) {
printf("\t%-8s\t%s\n", g_lea_mcs_tables[i].cmd, g_lea_mcs_tables[i].help);
}
}
static int le_mcs_add(void* handle, int argc, char* argv[])
{
if (bt_lea_mcs_service_add(handle) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int le_mcs_remove(void* handle, int argc, char* argv[])
{
if (bt_lea_mcs_service_remove(handle) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_media_state_changed(void* handle, int argc, char* argv[])
{
if (argc < 1)
return CMD_PARAM_NOT_ENOUGH;
lea_adpt_mcs_media_state_t state = atoi(argv[0]);
if (bt_lea_mcs_media_state_changed(handle, state) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_set_media_player_info(void* handle, int argc, char* argv[])
{
if (bt_lea_mcs_set_media_player_info(handle) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_media_control_response(void* handle, int argc, char* argv[])
{
if (argc < 1)
return CMD_PARAM_NOT_ENOUGH;
lea_adpt_mcs_media_control_result_t result = atoi(argv[0]);
if (bt_lea_mcs_media_control_point_response(handle, result) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_playing_order_changed(void* handle, int argc, char* argv[])
{
if (argc < 1)
return CMD_PARAM_NOT_ENOUGH;
uint8_t order = atoi(argv[0]);
if (bt_lea_mcs_playing_order_changed(handle, order) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_playback_speed_changed(void* handle, int argc, char* argv[])
{
if (argc < 1)
return CMD_PARAM_NOT_ENOUGH;
uint8_t speed = atoi(argv[0]);
if (bt_lea_mcs_playback_speed_changed(handle, speed) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_seeking_speed_changed(void* handle, int argc, char* argv[])
{
if (argc < 1)
return CMD_PARAM_NOT_ENOUGH;
uint8_t speed = atoi(argv[0]);
if (bt_lea_mcs_seeking_speed_changed(handle, speed) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_track_title_changed(void* handle, int argc, char* argv[])
{
if (argc < 1)
return CMD_PARAM_NOT_ENOUGH;
uint8_t* title = (uint8_t*)strdup(argv[0]);
if (bt_lea_mcs_track_title_changed(handle, title) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_track_duration_changed(void* handle, int argc, char* argv[])
{
if (argc < 1)
return CMD_PARAM_NOT_ENOUGH;
uint8_t duration = atoi(argv[0]);
if (bt_lea_mcs_track_duration_changed(handle, duration) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_track_position_changed(void* handle, int argc, char* argv[])
{
if (argc < 1)
return CMD_PARAM_NOT_ENOUGH;
int32_t position = atoi(argv[0]);
if (bt_lea_mcs_track_position_changed(handle, position) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_current_track_changed(void* handle, int argc, char* argv[])
{
if (argc != 6)
return CMD_PARAM_NOT_ENOUGH;
lea_object_id track_id;
for (int i = 0; i <= 5; i++) {
track_id[i] = strtol(argv[i], NULL, 16);
}
if (bt_lea_mcs_current_track_change(handle, track_id) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_next_track_changed(void* handle, int argc, char* argv[])
{
if (argc != 6)
return CMD_PARAM_NOT_ENOUGH;
lea_object_id track_id;
for (int i = 0; i <= 5; i++) {
track_id[i] = strtol(argv[i], NULL, 16);
}
if (bt_lea_mcs_next_track_changed(handle, track_id) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_current_group_changed(void* handle, int argc, char* argv[])
{
if (argc != 6)
return CMD_PARAM_NOT_ENOUGH;
lea_object_id group_id;
for (int i = 0; i <= 5; i++) {
group_id[i] = strtol(argv[i], NULL, 16);
}
if (bt_lea_mcs_current_group_changed(handle, group_id) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static int mcs_parent_group_changed(void* handle, int argc, char* argv[])
{
if (argc != 6)
return CMD_PARAM_NOT_ENOUGH;
lea_object_id group_id;
for (int i = 0; i <= 5; i++) {
group_id[i] = strtol(argv[i], NULL, 16);
}
if (bt_lea_mcs_parent_group_changed(handle, group_id) != BT_STATUS_SUCCESS)
return CMD_ERROR;
return CMD_OK;
}
static void lea_mcs_test_callback(void* cookie, uint8_t event)
{
printf("lea_mcs_test_callback");
}
static const lea_mcs_callbacks_t lea_mcs_cbs = {
sizeof(lea_mcs_cbs),
lea_mcs_test_callback,
};
int lea_mcs_commond_init(void* handle)
{
mcs_callbacks = bt_lea_mcs_register_callbacks(handle, &lea_mcs_cbs);
return CMD_OK;
}
void lea_mcs_commond_uninit(void* handle)
{
bt_status_t ret;
bt_lea_mcs_unregister_callbacks(handle, mcs_callbacks);
ret = bluetooth_stop_service(handle, PROFILE_LEAUDIO_MCS);
if (ret != BT_STATUS_SUCCESS) {
PRINT("%s, failed ret:%d", __func__, ret);
}
}
int lea_mcs_command_exec(void* handle, int argc, char* argv[])
{
int ret = CMD_USAGE_FAULT;
if (argc > 0)
ret = execute_command_in_table(handle, g_lea_mcs_tables, ARRAY_SIZE(g_lea_mcs_tables), argc, argv);
if (ret < 0)
usage();
return ret;
}