| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 "host/ble_audio_broadcast_source.h" |
| #include "cmd_leaudio.h" |
| #include "btshell.h" |
| #include "console/console.h" |
| #include "errno.h" |
| |
| #if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) |
| int |
| cmd_leaudio_base_add(int argc, char **argv) |
| { |
| uint32_t presentation_delay; |
| uint8_t adv_instance; |
| int rc; |
| |
| rc = parse_arg_init(argc - 1, argv + 1); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| adv_instance = parse_arg_uint8("adv_instance", &rc); |
| if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { |
| console_printf("invalid advertising instance\n"); |
| return rc; |
| } |
| |
| presentation_delay = parse_arg_uint32("presentation_delay", &rc); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| return btshell_broadcast_base_add(adv_instance, presentation_delay); |
| } |
| |
| int |
| cmd_leaudio_big_sub_add(int argc, char **argv) |
| { |
| uint8_t adv_instance; |
| uint8_t codec_fmt; |
| uint16_t company_id; |
| uint16_t vendor_spec; |
| static uint8_t metadata[CMD_ADV_DATA_METADATA_MAX_SZ]; |
| unsigned int metadata_len; |
| static uint8_t codec_spec_cfg[CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ]; |
| unsigned int codec_spec_cfg_len; |
| int rc; |
| |
| rc = parse_arg_init(argc - 1, argv + 1); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| adv_instance = parse_arg_uint8("adv_instance", &rc); |
| if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { |
| console_printf("invalid advertising instance\n"); |
| return rc; |
| } |
| |
| codec_fmt = parse_arg_uint8("codec_fmt", &rc); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| company_id = parse_arg_uint16("company_id", &rc); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| vendor_spec = parse_arg_uint16("vendor_spec", &rc); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| rc = parse_arg_byte_stream("codec_spec_config", |
| CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ, |
| codec_spec_cfg, &codec_spec_cfg_len); |
| if (rc != 0 && rc != ENOENT) { |
| return rc; |
| } |
| |
| rc = parse_arg_byte_stream("metadata", CMD_ADV_DATA_METADATA_MAX_SZ, |
| metadata, &metadata_len); |
| if (rc != 0 && rc != ENOENT) { |
| return rc; |
| } |
| |
| return btshell_broadcast_big_sub_add(adv_instance, |
| codec_fmt, company_id, |
| vendor_spec, |
| metadata, metadata_len, |
| codec_spec_cfg, codec_spec_cfg_len); |
| } |
| |
| int |
| cmd_leaudio_bis_add(int argc, char **argv) |
| { |
| uint8_t adv_instance; |
| static uint8_t codec_spec_cfg[CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ]; |
| unsigned int codec_spec_cfg_len; |
| int rc; |
| |
| rc = parse_arg_init(argc - 1, argv + 1); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| adv_instance = parse_arg_uint8("adv_instance", &rc); |
| if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { |
| console_printf("invalid advertising instance\n"); |
| return rc; |
| } |
| |
| rc = parse_arg_byte_stream("codec_spec_config", |
| CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ, |
| codec_spec_cfg, &codec_spec_cfg_len); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| return btshell_broadcast_bis_add(adv_instance, codec_spec_cfg, |
| codec_spec_cfg_len); |
| } |
| |
| int |
| cmd_leaudio_broadcast_create(int argc, char **argv) |
| { |
| struct ble_iso_big_params big_params; |
| uint8_t adv_instance; |
| const char *name; |
| uint8_t extra_data[CMD_ADV_DATA_EXTRA_MAX_SZ]; |
| static uint8_t own_addr_type; |
| unsigned int extra_data_len; |
| struct ble_gap_periodic_adv_params periodic_params; |
| struct ble_gap_ext_adv_params extended_params = { |
| .scannable = 0, |
| .connectable = 0, |
| .primary_phy = BLE_HCI_LE_PHY_1M, |
| }; |
| int rc; |
| |
| rc = ble_hs_id_infer_auto(0, &own_addr_type); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| extended_params.own_addr_type = own_addr_type; |
| |
| rc = parse_arg_init(argc - 1, argv + 1); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| adv_instance = parse_arg_uint8("adv_instance", &rc); |
| if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { |
| console_printf("invalid advertising instance\n"); |
| return rc; |
| } |
| |
| extended_params.sid = adv_instance; |
| extended_params.itvl_min = parse_arg_uint8_dflt("ext_interval_min", |
| 0, &rc); |
| if (rc != 0 && rc != ENOENT) { |
| console_printf("invalid extended advertising interval (min)\n"); |
| return rc; |
| } |
| |
| extended_params.itvl_max = parse_arg_uint8_dflt("ext_interval_max", 0, |
| &rc); |
| if (rc != 0 && rc != ENOENT) { |
| console_printf("invalid extended advertising interval (max)\n"); |
| return rc; |
| } |
| |
| periodic_params.itvl_min = parse_arg_uint8_dflt("per_interval_min", 0, |
| &rc); |
| if (rc != 0 && rc != ENOENT) { |
| console_printf("invalid periodic advertising interval (min)\n"); |
| return rc; |
| } |
| |
| periodic_params.itvl_max = parse_arg_uint8_dflt("per_interval_max", 0, |
| &rc); |
| if (rc != 0 && rc != ENOENT) { |
| console_printf("invalid periodic advertising interval (max)\n"); |
| return rc; |
| } |
| |
| name = parse_arg_extract("name"); |
| |
| big_params.sdu_interval = parse_arg_uint32_bounds("sdu_interval", |
| 0x0000FF, 0x0FFFFF, |
| &rc); |
| if (rc != 0) { |
| console_printf("invalid SDU interval\n"); |
| return rc; |
| } |
| |
| big_params.max_sdu = parse_arg_uint16_bounds("max_sdu", 0x0001, 0x0FFF, |
| &rc); |
| if (rc != 0) { |
| console_printf("invalid max SDU size\n"); |
| return rc; |
| } |
| |
| big_params.max_transport_latency = parse_arg_uint16_bounds("max_latency", |
| 0x0005, 0x0FA0, |
| &rc); |
| if (rc != 0) { |
| console_printf("invalid max transport latency\n"); |
| return rc; |
| } |
| |
| big_params.rtn = parse_arg_uint8_bounds("rtn", 0x00, 0x1E, &rc); |
| if (rc != 0) { |
| console_printf("invalid RTN\n"); |
| return rc; |
| } |
| |
| big_params.phy = parse_arg_uint8_bounds("phy", 0, 2, &rc); |
| if (rc != 0) { |
| console_printf("invalid PHY\n"); |
| return rc; |
| } |
| |
| extended_params.secondary_phy = big_params.phy; |
| |
| big_params.packing = parse_arg_uint8_bounds_dflt("packing", 0, 1, 1, &rc); |
| if (rc != 0) { |
| console_printf("invalid packing\n"); |
| return rc; |
| } |
| |
| big_params.framing = parse_arg_uint8_bounds_dflt("framing", 0, 1, 0, &rc); |
| if (rc != 0) { |
| console_printf("invalid framing\n"); |
| return rc; |
| } |
| |
| big_params.encryption = parse_arg_uint8_bounds_dflt("encryption", 0, 1, 0, &rc); |
| if (rc != 0) { |
| console_printf("invalid encryption\n"); |
| return rc; |
| } |
| |
| if (big_params.encryption) { |
| big_params.broadcast_code = parse_arg_extract("broadcast_code"); |
| if (big_params.broadcast_code == NULL) { |
| console_printf("broadcast code missing\n"); |
| return ENOENT; |
| } |
| |
| if (strlen(big_params.broadcast_code) > 16) { |
| console_printf("broadcast code too long\n"); |
| return ENOENT; |
| } |
| } |
| |
| rc = parse_arg_byte_stream("extra_data", |
| CMD_ADV_DATA_EXTRA_MAX_SZ, |
| extra_data, &extra_data_len); |
| if (rc == ENOENT) { |
| extra_data_len = 0; |
| } else if (rc != 0) { |
| return rc; |
| } |
| |
| return btshell_broadcast_create(adv_instance, |
| &extended_params, |
| &periodic_params, |
| name, |
| big_params, |
| extra_data, |
| extra_data_len); |
| } |
| |
| int |
| cmd_leaudio_broadcast_destroy(int argc, char **argv) |
| { |
| uint8_t adv_instance; |
| int rc; |
| |
| rc = parse_arg_init(argc - 1, argv + 1); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| adv_instance = parse_arg_uint8("adv_instance", &rc); |
| if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { |
| console_printf("invalid advertising instance\n"); |
| return rc; |
| } |
| |
| return btshell_broadcast_destroy(adv_instance); |
| } |
| |
| int |
| cmd_leaudio_broadcast_update(int argc, char **argv) |
| { |
| uint8_t adv_instance; |
| uint8_t extra_data[CMD_ADV_DATA_EXTRA_MAX_SZ]; |
| unsigned int extra_data_len; |
| const char *name; |
| int rc; |
| |
| rc = parse_arg_init(argc - 1, argv + 1); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| adv_instance = parse_arg_uint8("adv_instance", &rc); |
| if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { |
| console_printf("invalid advertising instance\n"); |
| return rc; |
| } |
| |
| rc = parse_arg_byte_stream("extra_data", |
| CMD_ADV_DATA_EXTRA_MAX_SZ, |
| extra_data, &extra_data_len); |
| if (rc != 0 && rc != ENOENT) { |
| return rc; |
| } |
| |
| name = parse_arg_extract("name"); |
| |
| return btshell_broadcast_update(adv_instance, name, extra_data, extra_data_len); |
| } |
| |
| int |
| cmd_leaudio_broadcast_start(int argc, char **argv) |
| { |
| uint8_t adv_instance; |
| int rc; |
| |
| rc = parse_arg_init(argc - 1, argv + 1); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| adv_instance = parse_arg_uint8("adv_instance", &rc); |
| if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { |
| console_printf("invalid advertising instance\n"); |
| return rc; |
| } |
| |
| return btshell_broadcast_start(adv_instance); |
| } |
| |
| int |
| cmd_leaudio_broadcast_stop(int argc, char **argv) |
| { |
| uint8_t adv_instance; |
| int rc; |
| |
| rc = parse_arg_init(argc - 1, argv + 1); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| adv_instance = parse_arg_uint8("adv_instance", &rc); |
| if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { |
| console_printf("invalid advertising instance\n"); |
| return rc; |
| } |
| |
| return btshell_broadcast_stop(adv_instance); |
| } |
| #endif |