apps: Add DTM shell application

This application provides shell interface for Bluetooth DTM. It also
provides few extra commands useful for testing (TX power configuration,
antenna selection, unmodulated carrier).
This commit is contained in:
Szymon Janc
2023-07-10 17:05:46 +02:00
parent 4953755ee5
commit 3bd6e5b15b
5 changed files with 1073 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
# 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.
pkg.name: apps/dtm
pkg.type: app
pkg.description: "Bluetooth DTM shell application"
pkg.author: "Apache Mynewt <[email protected]>"
pkg.homepage: "https://mynewt.apache.org/"
pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/shell"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-mcumgr/cmd/img_mgmt"
- "@mcuboot/boot/bootutil"
+425
View File
@@ -0,0 +1,425 @@
/*
* 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 "os/mynewt.h"
#include <console/console.h>
#include <parse.h>
#include <shell/shell.h>
#include "nimble/ble.h"
#include "nimble/nimble_opt.h"
#include "host/ble_hs.h"
#include "host/ble_dtm.h"
#include <img_mgmt/img_mgmt.h>
#include <bootutil/image.h>
static const struct kv_pair phy_opts[] = {
{ "1M", 0x01 },
{ "2M", 0x02 },
{ "coded", 0x03 },
{ NULL }
};
static const struct kv_pair modulation_index_opts[] = {
{ "standard", 0x00 },
{ "stable", 0x01 },
{ NULL }
};
static int
cmd_rx_test(int argc, char **argv)
{
struct ble_dtm_rx_params params;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
params.channel = parse_arg_uint8("channel", &rc);
if ((rc != 0) || (params.channel > 39)) {
console_printf("invalid channel\n");
return rc;
}
params.phy = parse_arg_kv_dflt("phy", phy_opts, 0x01, &rc);
if (rc != 0) {
console_printf("invalid 'phy' parameter\n");
return rc;
}
params.modulation_index = parse_arg_kv_dflt("modulation_index",
modulation_index_opts, 0x00, &rc);
if (rc != 0) {
console_printf("invalid 'modulation_index' parameter\n");
return rc;
}
rc = ble_dtm_rx_start(&params);
if (rc) {
console_printf("failed to start RX test\n");
return rc;
}
console_printf("RX test started\n");
return 0;
}
static int
cmd_tx_test(int argc, char **argv)
{
struct ble_dtm_tx_params params;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
params.channel = parse_arg_uint8("channel", &rc);
if ((rc != 0) || (params.channel > 39)) {
console_printf("invalid channel\n");
return rc;
}
params.phy = parse_arg_kv_dflt("phy", phy_opts, 0x01, &rc);
if (rc != 0) {
console_printf("invalid 'phy' parameter\n");
return rc;
}
params.payload = parse_arg_uint8("payload", &rc);
if ((rc != 0) || ((params.payload > 7))) {
console_printf("invalid 'payload' parameter\n");
return rc;
}
params.test_data_len = parse_arg_uint8_dflt("data_length", 0, &rc);
if (rc != 0) {
console_printf("invalid 'data_length' parameter\n");
return rc;
}
rc = ble_dtm_tx_start(&params);
if (rc) {
console_printf("failed to start TX test\n");
return rc;
}
console_printf("TX test started\n");
return 0;
}
static int
cmd_stop_test(int argc, char **argv)
{
uint16_t num_packets;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
rc = ble_dtm_stop(&num_packets);
if (rc) {
console_printf("failed to stop test\n");
return rc;
}
console_printf("Test stopped (%u packets)\n", num_packets);
return 0;
}
static int
cmd_tx_power(int argc, char **argv)
{
struct ble_hci_vs_set_tx_pwr_cp cmd;
struct ble_hci_vs_set_tx_pwr_rp rsp;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
cmd.tx_power = parse_arg_long_bounds_dflt("power",
-127, 127, 127, &rc);
if (rc != 0) {
console_printf("invalid 'power' parameter\n");
return rc;
}
rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_TX_PWR, &cmd, sizeof(cmd),
&rsp, sizeof(rsp));
if (rc) {
console_printf("failed to set TX power\n");
return rc;
}
console_printf("TX power set to %d dBm\n", rsp.tx_power);
return 0;
}
static int
cmd_set_antenna(int argc, char **argv)
{
struct ble_hci_vs_set_antenna_cp cmd;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
cmd.antenna = parse_arg_uint8_dflt("antenna", 0, &rc);
if (rc != 0 || ((cmd.antenna > 2))) {
console_printf("invalid 'antenna' parameter\n");
return rc;
}
rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_ANTENNA, &cmd, sizeof(cmd),
NULL, 0);
if (rc) {
console_printf("failed to set antenna\n");
return rc;
}
console_printf("Antenna set to %u\n", cmd.antenna);
return 0;
}
#define BLE_HCI_OCF_VS_TEST_CARRIER (0x0020)
static bool tx_carrier_running = false;
static int
cmd_tx_carrier(int argc, char **argv)
{
uint8_t cmd[2];
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
if (tx_carrier_running) {
console_printf("TX carrier already started\n");
return 0;
}
cmd[0] = 1;
cmd[1] = parse_arg_uint8("channel", &rc);
if ((rc != 0) || (cmd[1] > 39)) {
console_printf("invalid channel\n");
return rc;
}
rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_TEST_CARRIER, &cmd, sizeof(cmd),
NULL, 0);
if (rc) {
console_printf("failed to start TX carrier\n");
return rc;
}
console_printf("TX carrier started\n");
tx_carrier_running = true;
return 0;
}
static int
cmd_stop_carrier(int argc, char **argv)
{
uint8_t cmd[2];
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
if (!tx_carrier_running) {
console_printf("TX carrier not started\n");
return 0;
}
cmd[0] = 0;
cmd[1] = 0;
rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_TEST_CARRIER, &cmd, sizeof(cmd),
NULL, 0);
if (rc) {
console_printf("failed to stop TX carrier\n");
return rc;
}
console_printf("TX carrier stopped\n");
tx_carrier_running = false;
return 0;
}
static const struct shell_param cmd_rx_test_params[] = {
{"channel", "RX channel, usage: =[0-39]"},
{"phy", "usage: =[1M|2M], default: 1M"},
{"modulation_index", "usage: =[standard|stable], default=standard"},
{NULL}
};
static const struct shell_cmd_help cmd_rx_test_help = {
.summary = "start DTM RX test",
.usage = NULL,
.params = cmd_rx_test_params,
};
static const struct shell_param cmd_tx_test_params[] = {
{"channel", "RX channel, usage: =[0-39]"},
{"phy", "usage: =[1M|2M], default: 1M"},
{"data_length", "usage: =[0-255], default: 0"},
{"payload", "usage: =[0-7]"},
{NULL}
};
static const struct shell_cmd_help cmd_tx_test_help = {
.summary = "start DTM TX test",
.usage = NULL,
.params = cmd_tx_test_params,
};
static const struct shell_cmd_help cmd_stop_test_help = {
.summary = "stop DTM test",
.usage = NULL,
.params = NULL,
};
static const struct shell_param cmd_tx_power_params[] = {
{"power", "usage: =[-127-127], default: 127"},
{NULL}
};
static const struct shell_cmd_help cmd_tx_power_help = {
.summary = "set TX power",
.usage = NULL,
.params = cmd_tx_power_params,
};
static const struct shell_param cmd_set_antenna_params[] = {
{"antenna", "usage: =[0,1,2], default: 0"},
{NULL}
};
static const struct shell_cmd_help cmd_set_antenna_help = {
.summary = "set active antenna ",
.usage = NULL,
.params = cmd_set_antenna_params,
};
static const struct shell_param cmd_tx_carrier_params[] = {
{"channel", "TX channel, usage: =[0-39]"},
{NULL}
};
static const struct shell_cmd_help cmd_tx_carrier_help = {
.summary = "TX unmodulated carrier",
.usage = NULL,
.params = cmd_tx_carrier_params,
};
static const struct shell_cmd_help cmd_stop_carrier_help = {
.summary = "stop TX unmodulated carrier",
.usage = NULL,
.params = NULL,
};
static const struct shell_cmd dtm_commands[] = {
{
.sc_cmd = "rx-test",
.sc_cmd_func = cmd_rx_test,
.help = &cmd_rx_test_help,
},
{
.sc_cmd = "tx-test",
.sc_cmd_func = cmd_tx_test,
.help = &cmd_tx_test_help,
},
{
.sc_cmd = "stop-test",
.sc_cmd_func = cmd_stop_test,
.help = &cmd_stop_test_help,
},
{
.sc_cmd = "tx-power",
.sc_cmd_func = cmd_tx_power,
.help = &cmd_tx_power_help,
},
{
.sc_cmd = "set-antenna",
.sc_cmd_func = cmd_set_antenna,
.help = &cmd_set_antenna_help,
},
{
.sc_cmd = "tx-carrier",
.sc_cmd_func = cmd_tx_carrier,
.help = &cmd_tx_carrier_help,
},
{
.sc_cmd = "stop-carrier",
.sc_cmd_func = cmd_stop_carrier,
.help = &cmd_stop_carrier_help,
},
{ }
};
static void
on_sync(void)
{
console_printf("Host and controller synced\n");
}
static void
on_reset(int reason)
{
console_printf("Error: Resetting state; reason=%d\n", reason);
}
int
main(void)
{
struct image_version the_version;
char prompt[50];
sysinit();
img_mgmt_read_info(0, &the_version, NULL, NULL);
snprintf(prompt, sizeof(prompt), "dtm_%u.%u.%u",
the_version.iv_major, the_version.iv_minor, the_version.iv_revision);
/* Initialize the NimBLE host configuration. */
ble_hs_cfg.reset_cb = on_reset;
ble_hs_cfg.sync_cb = on_sync;
shell_register(prompt, dtm_commands);
shell_register_default_module(prompt);
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
return 0;
}
+529
View File
@@ -0,0 +1,529 @@
/*
* 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 <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <ctype.h>
#include <parse.h>
#include "console/console.h"
#define CMD_MAX_ARGS 16
static char *cmd_args[CMD_MAX_ARGS][2];
static int cmd_num_args;
int
parse_arg_find_idx(const char *key)
{
int i;
for (i = 0; i < cmd_num_args; i++) {
if (strcmp(cmd_args[i][0], key) == 0) {
return i;
}
}
return -1;
}
char *
parse_arg_peek(const char *key)
{
int i;
for (i = 0; i < cmd_num_args; i++) {
if (strcmp(cmd_args[i][0], key) == 0) {
return cmd_args[i][1];
}
}
return NULL;
}
char *
parse_arg_extract(const char *key)
{
int i;
for (i = 0; i < cmd_num_args; i++) {
if (strcmp(cmd_args[i][0], key) == 0) {
/* Erase parameter. */
cmd_args[i][0][0] = '\0';
return cmd_args[i][1];
}
}
return NULL;
}
/**
* Determines which number base to use when parsing the specified numeric
* string. This just avoids base '0' so that numbers don't get interpreted as
* octal.
*/
static int
parse_arg_long_base(char *sval)
{
if (sval[0] == '0' && sval[1] == 'x') {
return 0;
} else {
return 10;
}
}
long
parse_long_bounds(char *sval, long min, long max, int *out_status)
{
char *endptr;
long lval;
lval = strtol(sval, &endptr, parse_arg_long_base(sval));
if (sval[0] != '\0' && *endptr == '\0' &&
lval >= min && lval <= max) {
*out_status = 0;
return lval;
}
*out_status = EINVAL;
return 0;
}
long
parse_arg_long_bounds_peek(char *name, long min, long max, int *out_status)
{
char *sval;
sval = parse_arg_peek(name);
if (sval == NULL) {
*out_status = ENOENT;
return 0;
}
return parse_long_bounds(sval, min, max, out_status);
}
long
parse_arg_long_bounds(char *name, long min, long max, int *out_status)
{
char *sval;
sval = parse_arg_extract(name);
if (sval == NULL) {
*out_status = ENOENT;
return 0;
}
return parse_long_bounds(sval, min, max, out_status);
}
long
parse_arg_long_bounds_dflt(char *name, long min, long max,
long dflt, int *out_status)
{
long val;
int rc;
val = parse_arg_long_bounds(name, min, max, &rc);
if (rc == ENOENT) {
rc = 0;
val = dflt;
}
*out_status = rc;
return val;
}
uint64_t
parse_arg_uint64_bounds(char *name, uint64_t min, uint64_t max, int *out_status)
{
char *endptr;
char *sval;
uint64_t lval;
sval = parse_arg_extract(name);
if (sval == NULL) {
*out_status = ENOENT;
return 0;
}
lval = strtoull(sval, &endptr, parse_arg_long_base(sval));
if (sval[0] != '\0' && *endptr == '\0' &&
lval >= min && lval <= max) {
*out_status = 0;
return lval;
}
*out_status = EINVAL;
return 0;
}
long
parse_arg_long(char *name, int *out_status)
{
return parse_arg_long_bounds(name, LONG_MIN, LONG_MAX, out_status);
}
uint8_t
parse_arg_bool(char *name, int *out_status)
{
return parse_arg_long_bounds(name, 0, 1, out_status);
}
uint8_t
parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status)
{
return parse_arg_long_bounds_dflt(name, 0, 1, dflt, out_status);
}
uint8_t
parse_arg_uint8(char *name, int *out_status)
{
return parse_arg_long_bounds(name, 0, UINT8_MAX, out_status);
}
uint16_t
parse_arg_uint16(char *name, int *out_status)
{
return parse_arg_long_bounds(name, 0, UINT16_MAX, out_status);
}
uint16_t
parse_arg_uint16_peek(char *name, int *out_status)
{
return parse_arg_long_bounds_peek(name, 0, UINT16_MAX, out_status);
}
uint32_t
parse_arg_uint32(char *name, int *out_status)
{
return parse_arg_uint64_bounds(name, 0, UINT32_MAX, out_status);
}
uint64_t
parse_arg_uint64(char *name, int *out_status)
{
return parse_arg_uint64_bounds(name, 0, UINT64_MAX, out_status);
}
uint8_t
parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status)
{
uint8_t val;
int rc;
val = parse_arg_uint8(name, &rc);
if (rc == ENOENT) {
val = dflt;
rc = 0;
}
*out_status = rc;
return val;
}
uint16_t
parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status)
{
uint16_t val;
int rc;
val = parse_arg_uint16(name, &rc);
if (rc == ENOENT) {
val = dflt;
rc = 0;
}
*out_status = rc;
return val;
}
uint32_t
parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status)
{
uint32_t val;
int rc;
val = parse_arg_uint32(name, &rc);
if (rc == ENOENT) {
val = dflt;
rc = 0;
}
*out_status = rc;
return val;
}
static uint32_t
parse_time_unit_mult(const char *str)
{
if (!strcasecmp(str, "us")) {
return 1;
} else if (!strcasecmp(str, "ms")) {
return 1000;
} else if (!strcasecmp(str, "s")) {
return 1000000;
}
return 0;
}
static uint32_t
parse_time_us(const char *str, int *out_status)
{
uint32_t val = 0;
uint32_t val_div = 1;
uint32_t val_mult = 1;
uint32_t val_us;
while (isdigit((unsigned char)*str)) {
val *= 10;
val += *str - '0';
str++;
}
if (*str == '.') {
str++;
while (isdigit((unsigned char)*str)) {
val *= 10;
val += *str - '0';
val_div *= 10;
str++;
}
}
val_mult = parse_time_unit_mult(str);
if (val_mult == 0) {
*out_status = EINVAL;
return 0;
}
if (val_mult > val_div) {
val_us = val * (val_mult / val_div);
} else {
val_us = val * (val_div / val_mult);
}
*out_status = 0;
return val_us;
}
uint32_t
parse_arg_time_dflt(char *name, int step_us, uint32_t dflt, int *out_status)
{
const char *arg;
uint32_t val;
int rc;
arg = parse_arg_peek(name);
if (!arg) {
*out_status = 0;
return dflt;
}
val = parse_time_us(arg, &rc);
if (rc) {
val = parse_arg_uint32(name, &rc);
if (rc == ENOENT) {
*out_status = 0;
return dflt;
}
} else {
val /= step_us;
parse_arg_extract(name);
}
*out_status = rc;
return val;
}
const struct kv_pair *
parse_kv_find(const struct kv_pair *kvs, char *name)
{
const struct kv_pair *kv;
int i;
for (i = 0; kvs[i].key != NULL; i++) {
kv = kvs + i;
if (strcmp(name, kv->key) == 0) {
return kv;
}
}
return NULL;
}
int
parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status)
{
const struct kv_pair *kv;
char *sval;
sval = parse_arg_extract(name);
if (sval == NULL) {
*out_status = ENOENT;
return -1;
}
kv = parse_kv_find(kvs, sval);
if (kv == NULL) {
*out_status = EINVAL;
return -1;
}
*out_status = 0;
return kv->val;
}
int
parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val,
int *out_status)
{
int val;
int rc;
val = parse_arg_kv(name, kvs, &rc);
if (rc == ENOENT) {
rc = 0;
val = def_val;
}
*out_status = rc;
return val;
}
static int
parse_arg_byte_stream_delim(char *sval, char *delims, int max_len,
uint8_t *dst, int *out_len)
{
unsigned long ul;
char *endptr;
char *token;
int i;
char *tok_ptr;
i = 0;
for (token = strtok_r(sval, delims, &tok_ptr);
token != NULL;
token = strtok_r(NULL, delims, &tok_ptr)) {
if (i >= max_len) {
return EINVAL;
}
ul = strtoul(token, &endptr, 16);
if (sval[0] == '\0' || *endptr != '\0' || ul > UINT8_MAX) {
return -1;
}
dst[i] = ul;
i++;
}
*out_len = i;
return 0;
}
int
parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len)
{
char *sval;
sval = parse_arg_extract(name);
if (sval == NULL) {
return ENOENT;
}
return parse_arg_byte_stream_delim(sval, ":-", max_len, dst, out_len);
}
int
parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len,
uint8_t *dst, int *out_len)
{
char *sval;
sval = parse_arg_extract(name);
if (sval == NULL) {
return ENOENT;
}
return parse_arg_byte_stream_delim(sval, separator, max_len, dst, out_len);
}
int
parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len)
{
int actual_len;
int rc;
rc = parse_arg_byte_stream(name, len, dst, &actual_len);
if (rc != 0) {
return rc;
}
if (actual_len != len) {
return EINVAL;
}
return 0;
}
int
parse_arg_all(int argc, char **argv)
{
char *key;
char *val;
int i;
char *tok_ptr;
cmd_num_args = 0;
for (i = 0; i < argc; i++) {
key = strtok_r(argv[i], "=", &tok_ptr);
val = strtok_r(NULL, "=", &tok_ptr);
if (key != NULL && val != NULL) {
if (strlen(key) == 0) {
console_printf("Error: invalid argument: %s\n", argv[i]);
return -1;
}
if (cmd_num_args >= CMD_MAX_ARGS) {
console_printf("Error: too many arguments");
return -1;
}
cmd_args[cmd_num_args][0] = key;
cmd_args[cmd_num_args][1] = val;
cmd_num_args++;
}
}
return 0;
}
+58
View File
@@ -0,0 +1,58 @@
/*
* 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.
*/
#ifndef PARSE_H
#define PARSE_H
#include <inttypes.h>
struct kv_pair {
char *key;
int val;
};
uint32_t parse_arg_time_dflt(char *name, int step, uint32_t dflt, int *out_status);
const struct kv_pair *parse_kv_find(const struct kv_pair *kvs, char *name);
int parse_arg_find_idx(const char *key);
char *parse_arg_extract(const char *key);
long parse_arg_long_bounds(char *name, long min, long max, int *out_status);
long parse_arg_long_bounds_dflt(char *name, long min, long max,
long dflt, int *out_status);
uint64_t parse_arg_uint64_bounds(char *name, uint64_t min,
uint64_t max, int *out_status);
long parse_arg_long(char *name, int *staus);
uint8_t parse_arg_bool(char *name, int *status);
uint8_t parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status);
uint8_t parse_arg_uint8(char *name, int *status);
uint8_t parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status);
uint16_t parse_arg_uint16(char *name, int *status);
uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status);
uint32_t parse_arg_uint32(char *name, int *out_status);
uint32_t parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status);
uint64_t parse_arg_uint64(char *name, int *out_status);
int parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status);
int parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val,
int *out_status);
int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len);
int parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len,
uint8_t *dst, int *out_len);
int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len);
int parse_arg_all(int argc, char **argv);
#endif
+28
View File
@@ -0,0 +1,28 @@
# 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.
syscfg.vals:
# Enable the shell task.
SHELL_TASK: 1
SHELL_CMD_HELP: 1
CONSOLE_HISTORY: ram
CONSOLE_HISTORY_RAM_HISTORY_SIZE: 50
BLE_LL_DTM: 1
BLE_LL_DTM_EXTENSIONS: 1
BLE_LL_CFG_FEAT_LE_2M_PHY: 1
BLE_LL_CFG_FEAT_LE_CODED_PHY: 1