mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-06 01:57:56 +00:00
Merge pull request #815 from michal-narajowski/mesh-blemesh-shell
New mesh app with shell support for testing X-Original-Commit: 2cf52d5bf0b83bf200d2ff5124270aa387ffcdb1
This commit is contained in:
@@ -373,7 +373,10 @@ static inline void k_sem_init(struct k_sem *sem, unsigned int initial_count,
|
||||
|
||||
static inline int k_sem_take(struct k_sem *sem, s32_t timeout)
|
||||
{
|
||||
return - os_sem_pend(sem, timeout);
|
||||
uint32_t ticks;
|
||||
|
||||
os_time_ms_to_ticks(timeout, &ticks);
|
||||
return - os_sem_pend(sem, ticks);
|
||||
}
|
||||
|
||||
static inline void k_sem_give(struct k_sem *sem)
|
||||
|
||||
@@ -39,3 +39,6 @@ pkg.deps.BLE_MESH_SHELL:
|
||||
pkg.req_apis:
|
||||
- log
|
||||
- stats
|
||||
|
||||
pkg.init:
|
||||
ble_mesh_shell_init: 1000
|
||||
|
||||
@@ -25,7 +25,7 @@ struct comp_data {
|
||||
struct os_mbuf *comp;
|
||||
};
|
||||
|
||||
static s32_t msg_timeout = K_SECONDS(2);
|
||||
static s32_t msg_timeout = K_SECONDS(5);
|
||||
|
||||
static struct bt_mesh_cfg_cli *cli;
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#include "foundation.h"
|
||||
#include "friend.h"
|
||||
|
||||
#define FRIEND_BUF_SIZE (BT_MESH_ADV_DATA_SIZE - BT_MESH_NET_HDR_LEN)
|
||||
|
||||
/* We reserve one extra buffer for each friendship, since we need to be able
|
||||
* to resend the last sent PDU, which sits separately outside of the queue.
|
||||
*/
|
||||
@@ -37,7 +35,7 @@
|
||||
|
||||
static os_membuf_t friend_buf_mem[OS_MEMPOOL_SIZE(
|
||||
FRIEND_BUF_COUNT,
|
||||
BT_MESH_ADV_DATA_SIZE + BT_MESH_ADV_USER_DATA_SIZE)];
|
||||
BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)];
|
||||
|
||||
struct os_mbuf_pool friend_os_mbuf_pool;
|
||||
static struct os_mempool friend_buf_mempool;
|
||||
|
||||
@@ -340,7 +340,9 @@ k_delayed_work_submit(struct k_delayed_work *w, uint32_t ms)
|
||||
{
|
||||
uint32_t ticks;
|
||||
|
||||
os_time_ms_to_ticks(ms, &ticks);
|
||||
if (os_time_ms_to_ticks(ms, &ticks) != 0) {
|
||||
assert(0);
|
||||
}
|
||||
os_callout_reset(&w->work, ticks);
|
||||
}
|
||||
|
||||
@@ -370,12 +372,12 @@ k_delayed_work_remaining_get (struct k_delayed_work *w)
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
t = os_callout_remaining_ticks(&w->work, os_cputime_get32());
|
||||
t = os_callout_remaining_ticks(&w->work, os_time_get());
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
/* We should return ms */
|
||||
return os_cputime_ticks_to_usecs(t) / 1000;
|
||||
return t / OS_TICKS_PER_SEC * 1000;
|
||||
}
|
||||
|
||||
int64_t k_uptime_get(void)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "foundation.h"
|
||||
#include "mesh/health_cli.h"
|
||||
|
||||
static s32_t msg_timeout = K_SECONDS(2);
|
||||
static s32_t msg_timeout = K_SECONDS(5);
|
||||
|
||||
static struct bt_mesh_health_cli *health_cli;
|
||||
|
||||
|
||||
@@ -246,10 +246,6 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov,
|
||||
bt_mesh_beacon_enable();
|
||||
#endif
|
||||
|
||||
#if (MYNEWT_VAL(BLE_MESH_SHELL))
|
||||
mesh_shell_init();
|
||||
#endif
|
||||
|
||||
#if (MYNEWT_VAL(BLE_MESH_PB_GATT))
|
||||
bt_mesh_proxy_prov_enable();
|
||||
#endif
|
||||
|
||||
+176
-17
@@ -21,15 +21,29 @@
|
||||
#include "mesh/mesh.h"
|
||||
#include "mesh/main.h"
|
||||
#include "mesh/glue.h"
|
||||
#include "mesh/testing.h"
|
||||
|
||||
/* Private includes for raw Network & Transport layer access */
|
||||
#include "net.h"
|
||||
#include "access.h"
|
||||
#include "mesh_priv.h"
|
||||
#include "lpn.h"
|
||||
#include "transport.h"
|
||||
#include "foundation.h"
|
||||
#include "testing.h"
|
||||
|
||||
/* This should be higher priority (lower value) than main task priority */
|
||||
#define BLE_MESH_SHELL_TASK_PRIO 126
|
||||
#define BLE_MESH_SHELL_STACK_SIZE 768
|
||||
|
||||
struct os_task mesh_shell_task;
|
||||
static struct os_eventq mesh_shell_queue;
|
||||
|
||||
#define CID_NVAL 0xffff
|
||||
#define CID_LOCAL 0x0002
|
||||
#define CID_VENDOR 0x05C3
|
||||
|
||||
/* Vendor Model data */
|
||||
#define VND_MODEL_ID_1 0x1234
|
||||
|
||||
/* Default net, app & dev key values, unless otherwise specified */
|
||||
static const u8_t default_key[16] = {
|
||||
@@ -91,7 +105,7 @@ static int fault_get_cur(struct bt_mesh_model *model, u8_t *test_id,
|
||||
printk("Sending current faults\n");
|
||||
|
||||
*test_id = 0x00;
|
||||
*company_id = CID_LOCAL;
|
||||
*company_id = CID_VENDOR;
|
||||
|
||||
get_faults(cur_faults, sizeof(cur_faults), faults, fault_count);
|
||||
|
||||
@@ -101,7 +115,7 @@ static int fault_get_cur(struct bt_mesh_model *model, u8_t *test_id,
|
||||
static int fault_get_reg(struct bt_mesh_model *model, u16_t cid,
|
||||
u8_t *test_id, u8_t *faults, u8_t *fault_count)
|
||||
{
|
||||
if (cid != CID_LOCAL) {
|
||||
if (cid != CID_VENDOR) {
|
||||
printk("Faults requested for unknown Company ID 0x%04x\n", cid);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -117,7 +131,7 @@ static int fault_get_reg(struct bt_mesh_model *model, u16_t cid,
|
||||
|
||||
static int fault_clear(struct bt_mesh_model *model, uint16_t cid)
|
||||
{
|
||||
if (cid != CID_LOCAL) {
|
||||
if (cid != CID_VENDOR) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -129,7 +143,7 @@ static int fault_clear(struct bt_mesh_model *model, uint16_t cid)
|
||||
static int fault_test(struct bt_mesh_model *model, uint8_t test_id,
|
||||
uint16_t cid)
|
||||
{
|
||||
if (cid != CID_LOCAL) {
|
||||
if (cid != CID_VENDOR) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -193,7 +207,7 @@ static struct bt_mesh_health_cli health_cli = {
|
||||
.current_status = health_current_status,
|
||||
};
|
||||
|
||||
static u8_t dev_uuid[16] = { 0xdd, 0xdd };
|
||||
static u8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
|
||||
|
||||
static struct bt_mesh_model root_models[] = {
|
||||
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
|
||||
@@ -202,12 +216,17 @@ static struct bt_mesh_model root_models[] = {
|
||||
BT_MESH_MODEL_HEALTH_CLI(&health_cli),
|
||||
};
|
||||
|
||||
static struct bt_mesh_model vnd_models[] = {
|
||||
BT_MESH_MODEL_VND(CID_VENDOR, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL,
|
||||
NULL),
|
||||
};
|
||||
|
||||
static struct bt_mesh_elem elements[] = {
|
||||
BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE),
|
||||
BT_MESH_ELEM(0, root_models, vnd_models),
|
||||
};
|
||||
|
||||
static const struct bt_mesh_comp comp = {
|
||||
.cid = CID_LOCAL,
|
||||
.cid = CID_VENDOR,
|
||||
.elem = elements,
|
||||
.elem_count = ARRAY_SIZE(elements),
|
||||
};
|
||||
@@ -545,18 +564,30 @@ struct shell_cmd_help cmd_lpn_help = {
|
||||
|
||||
#endif /* MESH_LOW_POWER */
|
||||
|
||||
static int check_addr_unassigned(uint8_t addr[BLE_DEV_ADDR_LEN])
|
||||
{
|
||||
return memcmp(addr, (uint8_t[BLE_DEV_ADDR_LEN]){0, 0, 0, 0, 0, 0},
|
||||
BLE_DEV_ADDR_LEN) == 0;
|
||||
}
|
||||
|
||||
static int cmd_init(int argc, char *argv[])
|
||||
{
|
||||
int err;
|
||||
ble_addr_t addr;
|
||||
|
||||
/* Use NRPA */
|
||||
err = ble_hs_id_gen_rnd(1, &addr);
|
||||
assert(err == 0);
|
||||
err = ble_hs_id_set_rnd(addr.val);
|
||||
assert(err == 0);
|
||||
if (check_addr_unassigned(MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR))) {
|
||||
/* Use NRPA */
|
||||
err = ble_hs_id_gen_rnd(1, &addr);
|
||||
assert(err == 0);
|
||||
err = ble_hs_id_set_rnd(addr.val);
|
||||
assert(err == 0);
|
||||
|
||||
err = bt_mesh_init(addr.type, &prov, &comp);
|
||||
}
|
||||
else {
|
||||
err = bt_mesh_init(0, &prov, &comp);
|
||||
}
|
||||
|
||||
err = bt_mesh_init(addr.type, &prov, &comp);
|
||||
if (err) {
|
||||
printk("Mesh initialization failed (err %d)\n", err);
|
||||
}
|
||||
@@ -783,6 +814,50 @@ static int cmd_rpl_clear(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_MESH_LOW_POWER)
|
||||
static int cmd_lpn_subscribe(int argc, char *argv[])
|
||||
{
|
||||
u16_t address;
|
||||
|
||||
if (argc < 2) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
address = strtoul(argv[1], NULL, 0);
|
||||
|
||||
printk("address 0x%04x", address);
|
||||
|
||||
bt_mesh_lpn_group_add(address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct shell_cmd_help cmd_lpn_subscribe_help = {
|
||||
NULL, "<addr>", NULL
|
||||
};
|
||||
|
||||
static int cmd_lpn_unsubscribe(int argc, char *argv[])
|
||||
{
|
||||
u16_t address;
|
||||
|
||||
if (argc < 2) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
address = strtoul(argv[1], NULL, 0);
|
||||
|
||||
printk("address 0x%04x", address);
|
||||
|
||||
bt_mesh_lpn_group_del(&address, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct shell_cmd_help cmd_lpn_unsubscribe_help = {
|
||||
NULL, "<addr>", NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
static int cmd_iv_update_test(int argc, char *argv[])
|
||||
{
|
||||
bool enable;
|
||||
@@ -2039,6 +2114,56 @@ struct shell_cmd_help cmd_del_fault_help = {
|
||||
NULL, "[Fault ID]", NULL
|
||||
};
|
||||
|
||||
static int cmd_print_credentials(int argc, char *argv[])
|
||||
{
|
||||
bt_test_print_credentials();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_comp_elem(struct bt_mesh_elem *elem,
|
||||
bool primary)
|
||||
{
|
||||
struct bt_mesh_model *mod;
|
||||
int i;
|
||||
|
||||
printk("Loc: %u\n", elem->loc);
|
||||
printk("Model count: %u\n", elem->model_count);
|
||||
printk("Vnd model count: %u\n", elem->vnd_model_count);
|
||||
|
||||
for (i = 0; i < elem->model_count; i++) {
|
||||
mod = &elem->models[i];
|
||||
printk(" Model: %u\n", i);
|
||||
printk(" ID: 0x%04x\n", mod->id);
|
||||
printk(" Opcode: 0x%08lx\n", mod->op->opcode);
|
||||
}
|
||||
|
||||
for (i = 0; i < elem->vnd_model_count; i++) {
|
||||
mod = &elem->vnd_models[i];
|
||||
printk(" Vendor model: %u\n", i);
|
||||
printk(" Company: 0x%04x\n", mod->vnd.company);
|
||||
printk(" ID: 0x%04x\n", mod->vnd.id);
|
||||
printk(" Opcode: 0x%08lx\n", mod->op->opcode);
|
||||
}
|
||||
}
|
||||
|
||||
static int cmd_print_composition_data(int argc, char *argv[])
|
||||
{
|
||||
const struct bt_mesh_comp *comp;
|
||||
int i;
|
||||
|
||||
comp = bt_mesh_comp_get();
|
||||
|
||||
printk("CID: %u\n", comp->cid);
|
||||
printk("PID: %u\n", comp->pid);
|
||||
printk("VID: %u\n", comp->vid);
|
||||
|
||||
for (i = 0; i < comp->elem_count; i++) {
|
||||
print_comp_elem(&comp->elem[i], i == 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct shell_cmd mesh_commands[] = {
|
||||
{ "init", cmd_init, NULL },
|
||||
{ "timeout", cmd_timeout, &cmd_timeout_help },
|
||||
@@ -2070,6 +2195,12 @@ static const struct shell_cmd mesh_commands[] = {
|
||||
{ "iv-update", cmd_iv_update, NULL },
|
||||
{ "iv-update-test", cmd_iv_update_test, &cmd_iv_update_test_help },
|
||||
{ "rpl-clear", cmd_rpl_clear, NULL },
|
||||
#if MYNEWT_VAL(BLE_MESH_LOW_POWER)
|
||||
{ "lpn-subscribe", cmd_lpn_subscribe, &cmd_lpn_subscribe_help },
|
||||
{ "lpn-unsubscribe", cmd_lpn_unsubscribe, &cmd_lpn_unsubscribe_help },
|
||||
#endif
|
||||
{ "print-credentials", cmd_print_credentials, NULL },
|
||||
{ "print-composition-data", cmd_print_composition_data, NULL },
|
||||
|
||||
/* Configuration Client Model operations */
|
||||
{ "get-comp", cmd_get_comp, &cmd_get_comp_help },
|
||||
@@ -2109,10 +2240,38 @@ static const struct shell_cmd mesh_commands[] = {
|
||||
{ NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
void mesh_shell_init(void)
|
||||
static void mesh_shell_thread(void *args)
|
||||
{
|
||||
health_pub_init();
|
||||
shell_register("mesh", mesh_commands);
|
||||
while (1) {
|
||||
os_eventq_run(&mesh_shell_queue);
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_mesh_shell_task_init(void)
|
||||
{
|
||||
os_stack_t *pstack;
|
||||
|
||||
pstack = malloc(sizeof(os_stack_t) * BLE_MESH_SHELL_STACK_SIZE);
|
||||
os_eventq_init(&mesh_shell_queue);
|
||||
|
||||
os_task_init(&mesh_shell_task, "mesh_sh", mesh_shell_thread, NULL,
|
||||
BLE_MESH_SHELL_TASK_PRIO, OS_WAIT_FOREVER, pstack,
|
||||
BLE_MESH_SHELL_STACK_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ble_mesh_shell_init(void)
|
||||
{
|
||||
#if !(MYNEWT_VAL(BLE_MESH_SHELL))
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Initialize health pub message */
|
||||
health_pub_init();
|
||||
|
||||
/* Shell and other mesh clients should use separate task to
|
||||
avoid deadlocks with mesh message processing queue */
|
||||
bt_mesh_shell_task_init();
|
||||
shell_evq_set(&mesh_shell_queue);
|
||||
shell_register("mesh", mesh_commands);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef __SHELL_H__
|
||||
#define __SHELL_H__
|
||||
|
||||
void mesh_shell_init(void);
|
||||
void ble_mesh_shell_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "console/console.h"
|
||||
#include "mesh/testing.h"
|
||||
#include "mesh/slist.h"
|
||||
#include "mesh/glue.h"
|
||||
@@ -84,3 +85,70 @@ void bt_test_mesh_trans_incomp_timer_exp(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bt_test_print_credentials(void)
|
||||
{
|
||||
int i;
|
||||
u8_t nid;
|
||||
const u8_t *enc;
|
||||
const u8_t *priv;
|
||||
struct bt_mesh_subnet *sub;
|
||||
struct bt_mesh_app_key *app_key;
|
||||
|
||||
console_printf("IV Index: %08lx\n", bt_mesh.iv_index);
|
||||
console_printf("Dev key: %s\n", bt_hex(bt_mesh.dev_key, 16));
|
||||
|
||||
for (i = 0; i < MYNEWT_VAL(BLE_MESH_SUBNET_COUNT); ++i)
|
||||
{
|
||||
if (bt_mesh.app_keys[i].net_idx == BT_MESH_KEY_UNUSED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sub = &bt_mesh.sub[i];
|
||||
|
||||
console_printf("Subnet: %d\n", i);
|
||||
console_printf("\tNetKeyIdx: %04x\n",
|
||||
sub->net_idx);
|
||||
console_printf("\tNetKey: %s\n",
|
||||
bt_hex(sub->keys[sub->kr_flag].net, 16));
|
||||
}
|
||||
|
||||
for (i = 0; i < MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT); ++i)
|
||||
{
|
||||
if (bt_mesh.app_keys[i].net_idx == BT_MESH_KEY_UNUSED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sub = &bt_mesh.sub[i];
|
||||
app_key = &bt_mesh.app_keys[i];
|
||||
|
||||
console_printf("AppKey: %d\n", i);
|
||||
console_printf("\tNetKeyIdx: %04x\n",
|
||||
app_key->net_idx);
|
||||
console_printf("\tAppKeyIdx: %04x\n",
|
||||
app_key->app_idx);
|
||||
console_printf("\tAppKey: %s\n",
|
||||
bt_hex(app_key->keys[sub->kr_flag].val, 16));
|
||||
}
|
||||
|
||||
for (i = 0; i < MYNEWT_VAL(BLE_MESH_SUBNET_COUNT); ++i)
|
||||
{
|
||||
if (bt_mesh.app_keys[i].net_idx == BT_MESH_KEY_UNUSED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (friend_cred_get(&bt_mesh.sub[i], BT_MESH_ADDR_UNASSIGNED,
|
||||
&nid, &enc, &priv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
console_printf("Friend cred: %d\n", i);
|
||||
console_printf("\tNetKeyIdx: %04x\n",
|
||||
bt_mesh.sub[i].net_idx);
|
||||
console_printf("\tNID: %02x\n", nid);
|
||||
console_printf("\tEncKey: %s\n",
|
||||
bt_hex(enc, 16));
|
||||
console_printf("\tPrivKey: %s\n",
|
||||
bt_hex(priv, 16));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,3 +20,4 @@ void bt_test_mesh_prov_invalid_bearer(u8_t opcode);
|
||||
void bt_test_mesh_net_recv(u8_t ttl, u8_t ctl, u16_t src, u16_t dst,
|
||||
const void *payload, size_t payload_len);
|
||||
void bt_test_mesh_trans_incomp_timer_exp(void);
|
||||
void bt_test_print_credentials(void);
|
||||
|
||||
Reference in New Issue
Block a user