// Returns false if XNCP is not the right software and doesn't support our // custom EZSP frames, true if it does. static bool checkXncpSoftware(void) { uint16_t manufacturerId; uint16_t versionNumber; EmberStatus status; status = ezspGetXncpInfo(&manufacturerId, &versionNumber); if (status != EMBER_SUCCESS) { emberAfCorePrintln("Error: XNCP test harness software not present on NCP."); return false; } else if (manufacturerId != EMBER_MANUFACTURER_ID || versionNumber != EMBER_XNCP_TEST_HARNESS_VERSION_NUMBER) { emberAfCorePrintln("Error: Wrong XNCP software loaded on NCP."); emberAfCorePrintln(" Wanted Manuf ID: 0x%2X, Version: 0x%2X", EMBER_MANUFACTURER_ID, EMBER_XNCP_TEST_HARNESS_VERSION_NUMBER); emberAfCorePrintln(" Got Manuf ID: 0x%2X, Version: 0x%2X", manufacturerId, versionNumber); return false; } return true; }
bool emberAfPreZDOMessageReceivedCallback(EmberNodeId sender, EmberApsFrame* apsFrame, uint8_t* message, uint16_t length) { if (!enabled) { return false; } if (apsFrame->clusterId == END_DEVICE_ANNOUNCE) { EmberEUI64 tempEui64; MEMMOVE(tempEui64, &(message[DEVICE_ANNOUNCE_EUI64_OFFSET]), EUI64_SIZE); // If the device already exists, this call won't overwrite it and will // leave its status alone. Maybe it rejoined and we already know about, // in which case we won't bother re-interrogating it. const EmberAfDeviceInfo* device = emberAfPluginDeviceDatabaseAdd(tempEui64, message[DEVICE_ANNOUNCE_CAPABILITIES_OFFSET]); if (device == NULL) { emberAfCorePrint("Error: %p failed to add device to database: ", PLUGIN_NAME); emberAfPrintLittleEndianEui64(tempEui64); emberAfCorePrintln(""); } else { if (device->status == EMBER_AF_DEVICE_DISCOVERY_STATUS_NEW) { emberAfCorePrint("%p added device to database: ", PLUGIN_NAME); emberAfPrintLittleEndianEui64(tempEui64); emberAfCorePrintln(", capabilities: 0x%X", device->capabilities); scheduleEvent(WITH_DELAY); } } return true; } return false; }
void tryToJoinNetwork(void) { EmberNetworkParameters networkParams; EmberStatus status; EmberNodeType nodeType; MEMSET(&networkParams, 0, sizeof(EmberNetworkParameters)); networkParams.panId = getNextCandidate(); if (networkParams.panId == EMBER_AF_INVALID_PAN_ID) { debugPrintln("No networks to join on channel %d", emAfPluginNetworkSteeringCurrentChannel); gotoNextChannel(); return; } emberAfCorePrintln("%p joining 0x%2x", PLUGIN_NAME, networkParams.panId); networkParams.radioChannel = emAfPluginNetworkSteeringCurrentChannel; networkParams.radioTxPower = emberAfPluginNetworkSteeringGetPowerForRadioChannelCallback(emAfPluginNetworkSteeringCurrentChannel); nodeType = emberAfPluginNetworkSteeringGetNodeTypeCallback(emAfPluginNetworkSteeringState); status = emberJoinNetwork(nodeType, &networkParams); emAfPluginNetworkSteeringJoinAttempts++; if (EMBER_SUCCESS != status) { emberAfCorePrintln("Error: %p could not attempt join: 0x%X", PLUGIN_NAME, status); cleanupAndStop(status); return; } }
void gotoNextChannel(void) { EmberAfPluginScanDispatchScanData scanData; EmberStatus status; emAfPluginNetworkSteeringCurrentChannel = getNextChannel(); if (emAfPluginNetworkSteeringCurrentChannel == 0) { debugPrintln("No more channels"); tryNextMethod(); return; } clearPanIdCandidates(); scanData.scanType = EMBER_ACTIVE_SCAN; scanData.channelMask = BIT32(emAfPluginNetworkSteeringCurrentChannel); scanData.duration = EMBER_AF_PLUGIN_NETWORK_STEERING_SCAN_DURATION; scanData.handler = scanResultsHandler; status = emberAfPluginScanDispatchScheduleScan(&scanData); if (EMBER_SUCCESS != status) { emberAfCorePrintln("Error: %p start scan failed: 0x%X", PLUGIN_NAME, status); cleanupAndStop(status); } else { emberAfCorePrintln("Starting scan on channel %d", emAfPluginNetworkSteeringCurrentChannel); } }
static bool addPanIdCandidate(uint16_t panId) { uint16_t* panIdPointer = emAfPluginNetworkSteeringGetStoredPanIdPointer(0); if (panIdPointer == NULL) { emberAfCorePrintln("Error: %p could not get memory pointer for stored PAN IDs", PLUGIN_NAME); return false; } uint8_t maxNetworks = emAfPluginNetworkSteeringGetMaxPossiblePanIds(); uint8_t i; for (i = 0; i < maxNetworks; i++) { if (panId == *panIdPointer) { // We already know about this PAN, no point in recording it twice. debugPrintln("Ignoring duplicate PAN ID 0x%2X", panId); return true; } else if (*panIdPointer == EMBER_AF_INVALID_PAN_ID) { *panIdPointer = panId; debugPrintln("Stored PAN ID 0x%2X", *panIdPointer); return true; } panIdPointer++; } if (!printedMaxPanIdsWarning) { emberAfCorePrintln("Warning: %p Max PANs reached (%d)", PLUGIN_NAME, maxNetworks); printedMaxPanIdsWarning = true; } return true; }
static EmberStatus stateMachineRun(void) { EmberStatus status = EMBER_SUCCESS; emberAfCorePrintln("%p State: %p", PLUGIN_NAME, emAfPluginNetworkSteeringStateNames[emAfPluginNetworkSteeringState]); if ((status = setupSecurity()) != EMBER_SUCCESS) { emberAfCorePrintln("Error: %p could not setup security: 0x%X", PLUGIN_NAME, status); return tryNextMethod(); } switch (emAfPluginNetworkSteeringState) { case EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_SCAN_PRIMARY_INSTALL_CODE: case EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_SCAN_PRIMARY_CENTRALIZED: case EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_SCAN_PRIMARY_DISTRIBUTED: currentChannelMask = emAfPluginNetworkSteeringPrimaryChannelMask; break; default: currentChannelMask = emAfPluginNetworkSteeringSecondaryChannelMask; break; } debugPrintln("Channel Mask: 0x%4X", currentChannelMask); gotoNextChannel(); return status; }
void emberAfPluginButtonJoiningButton0EventHandler(void) { emberEventControlSetInactive(buttonEvent0); if (buttonPressDurationMs >= BUTTON_HOLD_DURATION_MS) { emberAfCorePrintln("Leaving network due to button press."); emberLeaveNetwork(); return; } if (emberAfNetworkState() == EMBER_JOINED_NETWORK) { emberAfBroadcastPermitJoin(PERMIT_JOIN_TIMEOUT); } else if (emberAfNetworkState() == EMBER_NO_NETWORK) { #ifdef EMBER_AF_HAS_COORDINATOR_NETWORK emberAfCorePrintln("%p: nwk down: do form", "button0"); emberAfFindUnusedPanIdAndForm(); #else emberAfCorePrintln("%p: nwk down: do join", "button0"); emberAfStartSearchForJoinableNetwork(); #endif } }
void emberAfPluginConcentratorSetRouterBehaviorCommand(void) { EmberAfPluginConcentratorRouterBehavior behavior = (EmberAfPluginConcentratorRouterBehavior)emberUnsignedCommandArgument(0); if (behavior > EMBER_AF_PLUGIN_CONCENTRATOR_ROUTER_BEHAVIOR_MAX) { emberAfCorePrintln("Illegal concentrator router behavior: 0x%X", behavior); } else { emberAfPluginConcentratorSetRouterBehavior(behavior); emberAfCorePrintln("Set concentrator router behavior to: 0x%X", behavior); } }
void emberAfPluginAddressTableLookupCommand(void) { uint8_t index; EmberEUI64 entry; emberCopyEui64Argument(0, entry); index = emberAfPluginAddressTableLookupByEui64(entry); if (index == EMBER_NULL_ADDRESS_TABLE_INDEX) emberAfCorePrintln("Entry not found"); else emberAfCorePrintln("Found entry at position 0x%x", index); }
void emberAfPluginAddressTableRemoveCommand(void) { EmberStatus status; EmberEUI64 entry; emberCopyEui64Argument(0, entry); status = emberAfPluginAddressTableRemoveEntry(entry); if (status == EMBER_SUCCESS) { emberAfCorePrintln("Entry removed"); } else { emberAfCorePrintln("Entry removal failed"); } }
void printEvents(void) { uint8_t i = 0; uint32_t nowMS32 = halCommonGetInt32uMillisecondTick(); while (emAfEvents[i].control != NULL) { emberAfCorePrint("%p : ", emAfEventStrings[i]); if (emAfEvents[i].control->status == EMBER_EVENT_INACTIVE) { emberAfCorePrintln("inactive"); } else { emberAfCorePrintln("%l ms", emAfEvents[i].control->timeToExecute - nowMS32); } i++; } }
void emberAfPluginAddressTableAddCommand(void) { uint8_t index; EmberEUI64 entry; emberCopyEui64Argument(0, entry); index = emberAfPluginAddressTableAddEntry(entry); if (index == EMBER_NULL_ADDRESS_TABLE_INDEX) { emberAfCorePrintln("Table full, entry not added"); } else { emberAfCorePrintln("Entry added at position 0x%x", index); } }
/** @brief Pairing Complete * * This function is called by the RF4CE ZRC plugin when the push-button * pairing operation completes. If status is ::EMBER_SUCCESS, pairing was * successful and pairingIndex indicates the index in the pairing table for * the remote node while eui64, vendorInfo, and applicationInfo contain * information about the remote node itself. Otherwise, status indicates the * reason for failure and the other arguments are meaningless. * * @param status The status of the push-button pairing operation. Ver.: * always * @param pairingIndex The index of the pairing entry. Ver.: always * @param eui64 The ::EmberEUI64 of the remote node. Ver.: always * @param vendorInfo The vendor information of the remote node. Ver.: always * @param applicationInfo The application information of the remote node. * Ver.: always */ void emberAfPluginRf4ceZrc11PairingCompleteCallback(EmberStatus status, int8u pairingIndex, const EmberEUI64 eui64, const EmberRf4ceVendorInfo *vendorInfo, const EmberRf4ceApplicationInfo *applicationInfo) { if (status == EMBER_SUCCESS) { emberAfCorePrintln("Pairing %p: 0x%x", "complete", pairingIndex); halPlayTune_P(happyTune, TRUE); } else { emberAfCorePrintln("Pairing %p: 0x%x", "failed", status); halPlayTune_P(sadTune, TRUE); } halClearLed(LED); }
static void setupPrice(bool onSale) { const uint8_t* label = (onSale ? salePriceLabel : normalPriceLabel); uint8_t labelSize = (onSale ? sizeof(salePriceLabel) : sizeof(normalPriceLabel)); MEMSET(myPrice.rateLabel, 0, ZCL_PRICE_CLUSTER_MAXIMUM_RATE_LABEL_LENGTH + 1); MEMMOVE(myPrice.rateLabel, label, labelSize); myPrice.price = (onSale ? salePrice : normalPrice); // One of the few times '%s' is appropriate. We are using a RAM string // %p is used for all CONST strings (which is the norm) emberAfCorePrintln("%s", myPrice.rateLabel); // This print assumes 2 digit prices less than 1 dollar emberAfCorePrintln("Price: $0.%d/kwh\n", myPrice.price); }
// plugin test-harness z3 beacon beacon-req void emAfPluginTestHarnessZ3BeaconBeaconReqCommand(void) { EmberNetworkParameters networkParameters; EmberStatus status; #ifdef EZSP_HOST EmberNodeType nodeType; status = ezspGetNetworkParameters(&nodeType, &networkParameters); #else status = emberGetNetworkParameters(&networkParameters); #endif if (status == EMBER_SUCCESS) { status = emberStartScan(EMBER_ACTIVE_SCAN, BIT32(networkParameters.radioChannel), 2); // scan duration, whatever } else { // We probably are not on a network, so try to use the network-steering // channels. extern uint32_t emAfPluginNetworkSteeringPrimaryChannelMask; status = emberStartScan(EMBER_ACTIVE_SCAN, emAfPluginNetworkSteeringPrimaryChannelMask, 2); // scan duration, whatever } emberAfCorePrintln("%p: %p: 0x%X", TEST_HARNESS_Z3_PRINT_NAME, "Beacon request", status); }
static void networkFoundCallback(EmberZigbeeNetwork *networkFound, uint8_t lqi, int8_t rssi) { emAfPluginNetworkSteeringTotalBeacons++; if (!(networkFound->allowingJoin && networkFound->stackProfile == REQUIRED_STACK_PROFILE)) { return; } debugPrint("%p nwk found ch: %d, panID 0x%2X, xpan: ", PLUGIN_NAME, networkFound->channel, networkFound->panId); debugExec(emberAfPrintBigEndianEui64(networkFound->extendedPanId)); debugPrintln(""); if (!addPanIdCandidate(networkFound->panId)) { emberAfCorePrintln("Error: %p could not add candidate network.", PLUGIN_NAME); cleanupAndStop(EMBER_ERR_FATAL); return; } }
static void resetOrAdvanceApsFrameCounter(bool advance) { uint8_t customEzspMessage[1]; uint8_t reply[1]; uint8_t replyLength; EmberStatus status; customEzspMessage[0] = (advance ? EMBER_XNCP_TEST_HARNESS_COMMAND_ADVANCE_APS_FRAME_COUNTER : EMBER_XNCP_TEST_HARNESS_COMMAND_RESET_APS_FRAME_COUNTER); if (!checkXncpSoftware()) { return; } status = ezspCustomFrame(1, // length of custom EZSP message customEzspMessage, &replyLength, reply); emberAfCorePrintln("%p APS Frame counter: %p (0x%X)", (advance ? "Advancing" : "Reset"), ((status == EMBER_SUCCESS) ? "Success" : "FAILED"), status); }
bool emberAfPluginDeviceDatabaseSetEndpoints(const EmberEUI64 eui64, const uint8_t* endpointList, uint8_t endpointCount) { EmberAfDeviceInfo* device = findDeviceByEui64(eui64); if (device == NULL) { emberAfCorePrint("Error: %p cannot add endpoints. No such device in database: "); emberAfPrintLittleEndianEui64(eui64); emberAfCorePrintln(""); return false; } // Clear all existing endpoints so there is no leftover clusters or endpoints. MEMSET(device->endpoints, 0xFF, sizeof(EmberAfEndpointInfoStruct) * EMBER_AF_MAX_ENDPOINTS_PER_DEVICE); device->endpointCount = (endpointCount < EMBER_AF_MAX_ENDPOINTS_PER_DEVICE ? endpointCount : EMBER_AF_MAX_ENDPOINTS_PER_DEVICE); uint8_t i; for (i = 0; i < device->endpointCount; i++) { device->endpoints[i].endpoint = *endpointList; device->endpoints[i].clusterCount = 0; endpointList++; } return true; }
bool emberAfPluginUpdateTcLinkKeyStatusCallback(EmberKeyStatus keyStatus) { if (emAfPluginNetworkSteeringStateUpdateTclk()) { emberAfCorePrintln("%p: %p: 0x%X", PLUGIN_NAME, "Trust center link key update status", keyStatus); switch(keyStatus) { case EMBER_TRUST_CENTER_LINK_KEY_ESTABLISHED: // Success! But we should still wait to make sure we verify the key. emAfPluginNetworkSteeringStateSetVerifyTclk(); emberEventControlSetDelayMS(finishSteeringEvent, VERIFY_KEY_TIMEOUT_MS); return false; case EMBER_TRUST_CENTER_IS_PRE_R21: case EMBER_VERIFY_LINK_KEY_SUCCESS: // If the trust center is pre-r21, then we don't update the link key. // If the key status is that the link key has been verified, then we // have successfully updated our trust center link key and we are done! emAfPluginNetworkSteeringStateClearVerifyTclk(); emberEventControlSetDelayMS(finishSteeringEvent, randomJitterMS()); break; default: // Failure! emberLeaveNetwork(); cleanupAndStop(EMBER_NO_LINK_KEY_RECEIVED); } emAfPluginNetworkSteeringStateClearUpdateTclk(); } return true; }
EmberStatus emberAfPluginNetworkSteeringStart(void) { EmberStatus status = EMBER_INVALID_CALL; if (emAfProIsCurrentNetwork() && (emAfPluginNetworkSteeringState == EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_NONE)) { if (emberAfNetworkState() == EMBER_NO_NETWORK) { emAfPluginNetworkSteeringState = EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_SCAN_PRIMARY_INSTALL_CODE; // Stop any previous trust center link key update. emberAfPluginUpdateTcLinkKeyStop(); status = stateMachineRun(); } else { status = emberAfPermitJoin(EMBER_AF_PLUGIN_NETWORK_STEERING_COMMISSIONING_TIME_S, true); // Broadcast permit join? } } emberAfCorePrintln("%p: %p: 0x%X", emAfNetworkSteeringPluginName, "Start", status); return status; }
/** @brief User Control Repeated * * This function is called by the RF4CE ZRC plugin when a User Control * Repeated message is received by the device. * * @param commandCode The HDMI CEC operand [UI Command]. Ver.: always * @param commandPayload The additional operands, if any, required by the HDMI * CEC command. Ver.: always * @param commandPayloadLength The length of the command payload in bytes. * Ver.: always */ void emberAfPluginRf4ceZrc11UserControlRepeatedCallback(EmberAfRf4ceUserControlCode commandCode, const int8u *commandPayload, int8u commandPayloadLength) { emberAfCorePrint("Repeated 0x%x {", commandCode); emberAfCorePrintBuffer(commandPayload, commandPayloadLength, FALSE); emberAfCorePrintln("}"); }
void ALIAS(emberGetGlobalAddressReturn)(const EmberIpv6Address *address, uint32_t preferredLifetime, uint32_t validLifetime, uint8_t addressFlags) { emberAfCorePrint("global address: "); emberAfCoreDebugExec(emberAfPrintIpv6Address(address)); emberAfCorePrintln(""); }
void ALIAS(emberGetGlobalPrefixReturn)(uint8_t borderRouterFlags, const uint8_t *prefix, uint8_t domainId, uint32_t preferredLifetime, uint32_t validLifetime) { emberAfCorePrint("global prefix: "); emberAfCoreDebugExec(emberAfPrintIpv6Prefix((const EmberIpv6Prefix *)prefix)); emberAfCorePrintln(""); }
void emberAfPluginButtonJoiningPressButton(uint8_t button) { // We don't bother to check the button press both times // since the only reason it fails is invalid button. // No point in doing that twice. bool result = buttonPress(button, BUTTON_PRESSED); buttonPress(button, BUTTON_RELEASED); if (!result) { emberAfCorePrintln("Invalid button %d", button); } }
void enableDisableEndpoint(void) { uint8_t endpoint = (uint8_t)emberUnsignedCommandArgument(0); bool enable = (emberCurrentCommand->name[0] == 'e' ? true : false); if (!emberAfEndpointEnableDisable(endpoint, enable)) { emberAfCorePrintln("Error: Unknown endpoint."); } }
void emberAfPluginNetworkSteeringFinishSteeringEventHandler(void) { EmberStatus status; emberEventControlSetInactive(finishSteeringEvent); if (emAfPluginNetworkSteeringStateVerifyTclk()) { // If we get here, then we have failed to verify the TCLK. Therefore, // we leave the network. emberAfPluginUpdateTcLinkKeyStop(); emberLeaveNetwork(); emberAfCorePrintln("%p: %p", PLUGIN_NAME, "Key verification failed. Leaving network"); cleanupAndStop(EMBER_ERR_FATAL); } else if (emAfPluginNetworkSteeringStateUpdateTclk()) { // Start the process to update the TC link key. We will set another event // for the broadcast permit join. status = emberAfPluginUpdateTcLinkKeyStart(); emberAfCorePrintln("%p: %p: 0x%X", PLUGIN_NAME, "Starting update trust center link key process", status); if (status != EMBER_SUCCESS) { emberLeaveNetwork(); cleanupAndStop(status); } } else { // Broadcast permit join to extend the network. // We are done! status = emberAfPermitJoin(EMBER_AF_PLUGIN_NETWORK_STEERING_COMMISSIONING_TIME_S, true); // Broadcast permit join? emberAfCorePrintln("%p: %p: 0x%X", PLUGIN_NAME, "Broadcasting permit join", status); cleanupAndStop(status); } }
static void sendActiveEndpointRequest(const EmberAfDeviceInfo* device) { debugPrintln("%p initiating active endpoint requset for: 0x%2X", PLUGIN_NAME, currentNodeId); EmberStatus status = emberAfFindActiveEndpoints(currentNodeId, serviceDiscoveryCallback); if (status != EMBER_SUCCESS) { emberAfCorePrintln("Error: %p failed to initiate Active EP request (0x%X)", PLUGIN_NAME, status); noteFailedDiscovery(device); scheduleEvent(WITH_DELAY); } else { // Don't schedule event, since service discovery returns the results via callback. emberAfPluginDeviceDatabaseSetStatus(device->eui64, EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_ENDPOINTS); } }
static void cleanupAndStop(EmberStatus status) { emberAfCorePrintln("%p Stop. Cleaning up.", PLUGIN_NAME); emberAfPluginNetworkSteeringCompleteCallback(status, emAfPluginNetworkSteeringTotalBeacons, emAfPluginNetworkSteeringJoinAttempts, emAfPluginNetworkSteeringState); emAfPluginNetworkSteeringClearStoredPanIds(); emAfPluginNetworkSteeringState = EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_NONE; emAfPluginNetworkSteeringPanIdIndex = 0; emAfPluginNetworkSteeringJoinAttempts = 0; emAfPluginNetworkSteeringTotalBeacons = 0; }
void endpointPrint(void) { uint8_t i; for (i = 0; i < emberAfEndpointCount(); i++) { emberAfCorePrint("EP %d: %p ", emAfEndpoints[i].endpoint, (emberAfEndpointIndexIsEnabled(i) ? "Enabled" : "Disabled")); emAfPrintEzspEndpointFlags(emAfEndpoints[i].endpoint); emberAfCorePrintln(""); } }
bool emberAfPluginDeviceDatabaseSetClustersForEndpoint(const EmberEUI64 eui64, const EmberAfClusterList* clusterList) { EmberAfDeviceInfo* device = findDeviceByEui64(eui64); uint8_t index = emberAfPluginDeviceDatabaseGetIndexFromEndpoint(clusterList->endpoint, eui64); if (index == 0xFF) { emberAfCorePrintln("Error: %p endpoint %d does not exist for device.", PLUGIN_NAME, clusterList->endpoint); return false; } uint8_t doServer; device->endpoints[index].profileId = clusterList->profileId; device->endpoints[index].deviceId = clusterList->deviceId; device->endpoints[index].clusterCount = clusterList->inClusterCount + clusterList->outClusterCount; if (device->endpoints[index].clusterCount > EMBER_AF_MAX_CLUSTERS_PER_ENDPOINT) { emberAfCorePrintln("%p too many clusters (%d) for endpoint. Limiting to %d", PLUGIN_NAME, device->endpoints[index].clusterCount, EMBER_AF_MAX_CLUSTERS_PER_ENDPOINT); device->endpoints[index].clusterCount = EMBER_AF_MAX_CLUSTERS_PER_ENDPOINT; } uint8_t deviceClusterIndex = 0; for (doServer = 0; doServer < 2; doServer++) { uint8_t clusterPointerIndex; uint8_t count = (doServer ? clusterList->inClusterCount : clusterList->outClusterCount); const uint16_t* clusterPointer = (doServer ? clusterList->inClusterList : clusterList->outClusterList); for (clusterPointerIndex = 0; (clusterPointerIndex < count) && (deviceClusterIndex < device->endpoints[index].clusterCount); clusterPointerIndex++) { device->endpoints[index].clusters[deviceClusterIndex].clusterId = clusterPointer[clusterPointerIndex]; device->endpoints[index].clusters[deviceClusterIndex].server = (doServer ? true : false); deviceClusterIndex++; } } return true; }