Implementations for network related CLI commands.
License#
Copyright 2018 Silicon Laboratories Inc. www.silabs.com
The licensor of this software is Silicon Laboratories Inc. Your use of this software is governed by the terms of Silicon Labs Master Software License Agreement (MSLA) available at www.silabs.com/about-us/legal/master-software-license-agreement. This software is distributed to you in Source Code format and is governed by the sections of the MSLA applicable to Source Code.
/***************************************************************************/
#include "app/framework/include/af.h"
#include "app/framework/util/af-main.h"
#include "app/framework/util/util.h"
#include "app/util/serial/command-interpreter2.h"
#include "app/util/zigbee-framework/zigbee-device-common.h"
#include "network-cli.h"
// emberFindAndRejoinNetworkWithReason
#ifdef EZSP_HOST
#include "app/util/ezsp/ezsp.h"
#else
#include "stack/include/network-formation.h"
#endif
//------------------------------------------------------------------------------
void networkJoinCommand(void);
void networkRejoinCommand(void);
void networkFormCommand(void);
void networkExtendedPanIdCommand(void);
void networkLeaveCommand(void);
void networkPermitJoinCommand(void);
void findJoinableNetworkCommand(void);
void findUnusedPanIdCommand(void);
void networkChangeChannelCommand(void);
void networkSetCommand(void);
void networkIdCommand(void);
void networkMultiPhyStartCommand(void);
void networkMultiPhyStopCommand(void);
void networkChangeChildTimeoutOptionMaskCommand(void);
void changeKeepAliveModeCommand(void);
void networkCheckPjoinCommand(void);
// TODO: Gate this again when we have the mechanism for doing so
// with the generated CLI.
//#if defined(EMBER_AF_TC_SWAP_OUT_TEST)
void networkInitCommand(void);
//#endif
#define EMBER_AF_DOXYGEN_CLI__NETWORK_COMMANDS
#ifndef EMBER_AF_GENERATE_CLI
// Form and join library commands.
static EmberCommandEntry findCommands[] = {
{ "joinable", findJoinableNetworkCommand, "" },
{ "unused", findUnusedPanIdCommand, "" },
{ NULL },
};
EmberCommandEntry networkCommands[] = {
{ "form", networkFormCommand, "usv" },
{ "join", networkJoinCommand, "usvu*" },
{ "rejoin", networkRejoinCommand, "uw" },
{ "leave", networkLeaveCommand, "" },
{ "isopen", networkCheckPjoinCommand, "" },
{ "pjoin", networkPermitJoinCommand, "u" },
{ "broad-pjoin", networkPermitJoinCommand, "u" },
{ "extpanid", networkExtendedPanIdCommand, "b" },
{ "find", NULL, (const char *)findCommands },
emberCommandEntryAction("id",
networkIdCommand,
"",
"Print the current network IDs"),
{ "change-channel", networkChangeChannelCommand, "u" },
{ "multi-phy-start", networkMultiPhyStartCommand, "uusu*" },
{ "multi-phy-stop", networkMultiPhyStopCommand, "" },
#if defined(EMBER_AF_TC_SWAP_OUT_TEST)
// Do not document this command.
{ "init", networkInitCommand, "" },
#endif
{ "set", networkSetCommand, "u" },
{ "change-keep-alive-mode", changeKeepAliveModeCommand, "u" },
{ "timeout-option-mask", networkChangeChildTimeoutOptionMaskCommand, "v" },
{ NULL }
};
#endif // EMBER_AF_GENERATE_CLI
uint8_t emAfCliNetworkIndex = EMBER_AF_DEFAULT_NETWORK_INDEX;
#ifdef EMBER_AF_PLUGIN_TEST_HARNESS_Z3
extern EmberEventControl emZigbeeLeaveEvent;
#endif
//------------------------------------------------------------------------------
void initNetworkParams(EmberNetworkParameters *networkParams)
{
MEMSET(networkParams, 0, sizeof(EmberNetworkParameters));
emberAfGetFormAndJoinExtendedPanIdCallback(networkParams->extendedPanId);
networkParams->radioChannel = (uint8_t)emberUnsignedCommandArgument(0);
networkParams->radioTxPower = (int8_t)emberSignedCommandArgument(1);
networkParams->panId = (uint16_t)emberUnsignedCommandArgument(2);
if (emberCommandArgumentCount() > 3) {
// Map the channel page into the channel, if present.
// Page bits: 7, 6, 5 channel bits: 4...0
uint8_t page = (uint8_t)emberUnsignedCommandArgument(3);
networkParams->radioChannel = (uint8_t)((page << 5) | (networkParams->radioChannel & 0x1F));
}
}
// network join <channel> <power> <panid>
void networkJoinCommand(void)
{
EmberStatus status;
EmberNetworkParameters networkParams = { 0 };
initNetworkParams(&networkParams);
status = emberAfJoinNetwork(&networkParams);
UNUSED_VAR(status);
emberAfAppPrintln("%p 0x%x", "join", status);
}
// network rejoin <haveCurrentNetworkKey:1>
void networkRejoinCommand(void)
{
bool haveCurrentNetworkKey = (bool)emberUnsignedCommandArgument(0);
uint32_t channelMask = (uint32_t)emberUnsignedCommandArgument(1);
if (channelMask == 0) {
channelMask = EMBER_ALL_802_15_4_CHANNELS_MASK;
}
EmberStatus status = emberFindAndRejoinNetworkWithReason(haveCurrentNetworkKey,
channelMask,
EMBER_AF_REJOIN_DUE_TO_CLI_COMMAND);
emberAfAppPrintln("%p 0x%x", "rejoin", status);
}
void networkRejoinDiffDeviceTypeCommand(void)
{
bool haveCurrentNetworkKey = (uint8_t)emberUnsignedCommandArgument(0);
uint32_t channelMask = (uint32_t)emberUnsignedCommandArgument(1);
uint8_t emberNodeType = (uint8_t)emberUnsignedCommandArgument(2);
EmberStatus status = emberFindAndRejoinNetworkWithNodeType(haveCurrentNetworkKey,
channelMask,
emberNodeType);
emberAfAppPrintln("%p 0x%x", "rejoinDiffDeviceType", status);
}
// network form <channel> <power> <panid>
void networkFormCommand(void)
{
#ifdef EMBER_AF_HAS_COORDINATOR_NETWORK
EmberStatus status;
EmberNetworkParameters networkParams;
initNetworkParams(&networkParams);
status = emberAfFormNetwork(&networkParams);
emberAfAppPrintln("%p 0x%x", "form", status);
emberAfAppFlush();
#else
emberAfAppPrintln("only coordinators can form");
#endif
}
// network extpanid <8 BYTES>
void networkExtendedPanIdCommand(void)
{
emberCopyBigEndianEui64Argument(0, emAfExtendedPanId);
emberAfSetFormAndJoinExtendedPanIdCallback(emAfExtendedPanId);
emberAfAppPrint("ext. PAN ID: ");
emberAfAppDebugExec(emberAfPrintBigEndianEui64(emAfExtendedPanId));
emberAfAppPrintln("");
}
// network leave
void networkLeaveCommand(void)
{
EmberStatus status;
status = emberLeaveNetwork();
#ifdef EMBER_AF_PLUGIN_TEST_HARNESS_Z3
// Complete the leave immediately without the usual delay.
emberEventControlSetActive(emZigbeeLeaveEvent);
#endif
UNUSED_VAR(status);
emberAfAppPrintln("%p 0x%x", "leave", status);
}
// check pjoin status
void networkCheckPjoinCommand(void)
{
uint8_t open_duration = emberAfGetOpenNetworkDurationSec();
if (open_duration > 0) {
emberAfAppPrintln("NWK open: %u sec", open_duration);
} else {
emberAfAppPrintln("NWK closed");
}
}
// network pjoin <time>
// network broad-pjoin <time>
void networkPermitJoinCommand(void)
{
uint8_t duration = (uint8_t)emberUnsignedCommandArgument(0);
emAfPermitJoin(duration,
('b'
== emberStringCommandArgument(-1,
NULL)[0])); // broadcast permit join?
}
void findJoinableNetworkCommand(void)
{
EmberStatus status = emberAfStartSearchForJoinableNetwork();
emberAfCorePrintln("find joinable: 0x%X", status);
}
void findUnusedPanIdCommand(void)
{
EmberStatus status = emberAfFindUnusedPanIdAndForm();
emberAfCorePrintln("find unused: 0x%X", status);
}
void networkChangeChannelCommand(void)
{
uint8_t channel = (uint8_t)emberUnsignedCommandArgument(0);
EmberStatus status = emberChannelChangeRequest(channel);
emberAfAppPrintln("Changing to channel %d: 0x%X",
channel,
status);
}
// TODO: Put gating back in after we have a mechanism in place to do so
// for the generated CLI.
//#if defined(EMBER_AF_TC_SWAP_OUT_TEST)
void networkInitCommand(void)
{
EmberNetworkInitStruct networkInitStruct = {
EMBER_AF_CUSTOM_NETWORK_INIT_OPTIONS // EmberNetworkInitBitmask value
};
EmberStatus status = emberNetworkInit(&networkInitStruct);
emberAfAppPrintln("Network Init returned: 0x%X", status);
}
//#endif
void networkSetCommand(void)
{
uint8_t index = (uint8_t)emberUnsignedCommandArgument(0);
if (EMBER_SUPPORTED_NETWORKS <= index) {
emberAfCorePrintln("invalid network index");
return;
}
emAfCliNetworkIndex = index;
}
void networkIdCommand(void)
{
EmberEUI64 eui64;
emberAfGetEui64(eui64);
emberAfCorePrint("Short ID: 0x%2X, EUI64: ", emberAfGetNodeId());
emberAfPrintBigEndianEui64(eui64);
emberAfCorePrintln(", Pan ID: 0x%2X", emberAfGetPanId());
}
void networkMultiPhyStartCommand(void)
{
EmberStatus status;
uint8_t page = emberUnsignedCommandArgument(0);
uint8_t channel = emberUnsignedCommandArgument(1);
int8_t power = (int8_t)emberSignedCommandArgument(2);
uint8_t optionsMask = 0;
if (emberCommandArgumentCount() > 3) {
optionsMask = (uint8_t) emberUnsignedCommandArgument(3);
}
status = emberMultiPhyStart(PHY_INDEX_PRO2PLUS, page, channel, power, optionsMask);
if (status == EMBER_SUCCESS) {
emberAfCorePrintln("Started multi-phy interface");
} else {
emberAfCorePrintln("Failed to %s %s 0x%X",
"start",
"multi-phy interface",
status);
}
}
void networkMultiPhyStopCommand(void)
{
uint8_t status = emberMultiPhyStop(PHY_INDEX_PRO2PLUS);
if (status == EMBER_SUCCESS) {
emberAfCorePrintln("Terminated %s 0x%X",
"multi-phy interface",
status);
} else {
emberAfCorePrintln("Failed to %s %s 0x%X",
"stop",
"multi-phy interface",
status);
}
}
/* ToDo: keep or remove? needed for testing. no ezsp support. */
void changeKeepAliveModeCommand(void)
{
uint8_t keepAliveMode = emberUnsignedCommandArgument(0);
if (!emberSetKeepAliveMode(keepAliveMode)) {
emberAfAppPrintln("Keep alive support enabled.");
} else {
emberAfAppPrintln("failed to set keep alive mode.");
}
}
void networkChangeChildTimeoutOptionMaskCommand(void)
{
uint16_t mask = (uint16_t)emberUnsignedCommandArgument(0);
if (!emberSetChildTimeoutOptionMask(mask)) {
emberAfAppPrintln("successfully set the child timeout option mask.");
} else {
emberAfAppPrintln("failed to set the child timeout option mask.");
}
}
Macros#
#define
EMBER_AF_DOXYGEN_CLI__NETWORK_COMMANDS
network form <channel> <power> <panid>
Functions#
void
networkJoinCommand(void)
void
networkRejoinCommand(void)
void
networkFormCommand(void)
void
void
networkLeaveCommand(void)
void
networkPermitJoinCommand(void)
void
void
findUnusedPanIdCommand(void)
void
void
networkSetCommand(void)
void
networkIdCommand(void)
void
void
void
void
networkCheckPjoinCommand(void)
void
networkInitCommand(void)
void
initNetworkParams(EmberNetworkParameters *networkParams)
void
Variable Documentation#
emAfCliNetworkIndex#
uint8_t emAfCliNetworkIndex
Referenced by emberCommandActionHandler , and networkSetCommand
Function Documentation#
networkJoinCommand#
void networkJoinCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
References emberAfJoinNetwork , and initNetworkParams
networkRejoinCommand#
void networkRejoinCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
References EMBER_AF_REJOIN_DUE_TO_CLI_COMMAND , and EMBER_ALL_802_15_4_CHANNELS_MASK
networkFormCommand#
void networkFormCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
References emberAfFormNetwork , and initNetworkParams
networkExtendedPanIdCommand#
void networkExtendedPanIdCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
networkLeaveCommand#
void networkLeaveCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
networkPermitJoinCommand#
void networkPermitJoinCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
findJoinableNetworkCommand#
void findJoinableNetworkCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
findUnusedPanIdCommand#
void findUnusedPanIdCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
networkChangeChannelCommand#
void networkChangeChannelCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
networkSetCommand#
void networkSetCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
networkIdCommand#
void networkIdCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
networkMultiPhyStartCommand#
void networkMultiPhyStartCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
References EMBER_SUCCESS , and PHY_INDEX_PRO2PLUS
networkMultiPhyStopCommand#
void networkMultiPhyStopCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
References EMBER_SUCCESS , and PHY_INDEX_PRO2PLUS
networkChangeChildTimeoutOptionMaskCommand#
void networkChangeChildTimeoutOptionMaskCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
changeKeepAliveModeCommand#
void changeKeepAliveModeCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
networkCheckPjoinCommand#
void networkCheckPjoinCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
networkInitCommand#
void networkInitCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
initNetworkParams#
void initNetworkParams (EmberNetworkParameters * networkParams)
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
EmberNetworkParameters * | N/A | networkParams |
References emberAfGetFormAndJoinExtendedPanIdCallback , EmberNetworkParameters::extendedPanId , EmberNetworkParameters::panId , EmberNetworkParameters::radioChannel , and EmberNetworkParameters::radioTxPower
Referenced by networkFormCommand , and networkJoinCommand
networkRejoinDiffDeviceTypeCommand#
void networkRejoinDiffDeviceTypeCommand (void )
Parameters
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |