Commit 8c3bbd07 authored by chen.weican's avatar chen.weican

【修改内容】1,增加gateway的配置文件;2,去掉kk_sub_tsl.c,同一改用kk_device_manage里的接口

【提交人】陈伟灿
parent a615faf9
...@@ -291,7 +291,6 @@ APPLICATION_FILES= \ ...@@ -291,7 +291,6 @@ APPLICATION_FILES= \
./ZB/kk_plat_ota.c\ ./ZB/kk_plat_ota.c\
./ZB/kk_rgb_hsl_convert.c\ ./ZB/kk_rgb_hsl_convert.c\
./kk_test.c\ ./kk_test.c\
./kk_sub_tsl.c\
./rpc_api/src/rpc_common.c\ ./rpc_api/src/rpc_common.c\
./rpc_api/src/rpc_onoff.c\ ./rpc_api/src/rpc_onoff.c\
./rpc_api/src/rpc_global_cmd.c\ ./rpc_api/src/rpc_global_cmd.c\
......
{
"productCode":"2",
"config":[
{
"identity":"NetChannelState",
"endpoint":1,
"cluster":"0x0000",
"attribute":"0x0000",
"reportFunc":"",
"controlFunc":"kk_permit_join"
}
]
}
\ No newline at end of file
...@@ -771,7 +771,6 @@ void kk_rpc_report_attribute(EmberEUI64 eui64, ...@@ -771,7 +771,6 @@ void kk_rpc_report_attribute(EmberEUI64 eui64,
{ {
int i,j,num,status; int i,j,num,status;
char macString[19] = {0}; char macString[19] = {0};
sub_dev_node_t *node = NULL;
char * pCode; char * pCode;
...@@ -788,8 +787,11 @@ void kk_rpc_report_attribute(EmberEUI64 eui64, ...@@ -788,8 +787,11 @@ void kk_rpc_report_attribute(EmberEUI64 eui64,
} }
void kk_device_gateway_add(EmberEUI64 eui64)
{
kk_device_config_map_add("2");
kk_device_table_add(eui64,0,"2",0);
}
#ifndef __KK_DEVICE_MANAGER_H #ifndef __KK_DEVICE_MANAGER_H
#define __KK_DEVICE_MANAGER_H #define __KK_DEVICE_MANAGER_H
#include "kk_test.h" #include "kk_test.h"
#include "kk_sub_tsl.h"
#include "kk_product_code.h" #include "kk_product_code.h"
#include "kk_zb_com.h" #include "kk_zb_com.h"
......
...@@ -138,8 +138,6 @@ void kk_device_table_add(EmberEUI64 mac,EmberNodeId nodeId,const char *productCo ...@@ -138,8 +138,6 @@ void kk_device_table_add(EmberEUI64 mac,EmberNodeId nodeId,const char *productCo
emberAfDebugPrint("mac:"); emberAfDebugPrint("mac:");
emberAfPrintBigEndianEui64(mac); emberAfPrintBigEndianEui64(mac);
kk_sub_tsl_add(mac,productCode);
if(kk_device_find_by_node(nodeId)!=NULL){ if(kk_device_find_by_node(nodeId)!=NULL){
emberAfDebugPrintln(" is already in device table!!!"); emberAfDebugPrintln(" is already in device table!!!");
kk_print_device_table(); kk_print_device_table();
......
...@@ -6,20 +6,19 @@ static void kk_msg_report(cJSON *data,char *msgtype,char *method,EmberEUI64 mac) ...@@ -6,20 +6,19 @@ static void kk_msg_report(cJSON *data,char *msgtype,char *method,EmberEUI64 mac)
static uint16_t msgid; static uint16_t msgid;
char msgIdString[10]= {0}; char msgIdString[10]= {0};
char macString[19] = {0}; char macString[19] = {0};
sub_dev_node_t *node = NULL;
int res = 0; int res = 0;
kk_device_table_s *dev =NULL;
rpc_eui64ToString(mac,macString); rpc_eui64ToString(mac,macString);
res = kk_sub_tsl_get_device_by_mac(macString, &node); dev = kk_device_find_by_mac(mac);
if (res != SUCCESS_RETURN) { if (dev == NULL) {
printf("[%s][%d]kk_rpc_send_message error!!!\n",__FUNCTION__,__LINE__); printf("[%s][%d]kk_msg_report error!!!\n",__FUNCTION__,__LINE__);
return; return;
} }
cJSON *info = rpc_cJSON_CreateObject(); cJSON *info = rpc_cJSON_CreateObject();
if(info != NULL){ if(info != NULL){
rpc_cJSON_AddStringToObject(info, "msgType",msgtype); rpc_cJSON_AddStringToObject(info, "msgType",msgtype);
rpc_cJSON_AddStringToObject(info, "productCode",node->productCode); rpc_cJSON_AddStringToObject(info, "productCode",dev->productCode);
rpc_cJSON_AddStringToObject(info, "deviceCode",macString); rpc_cJSON_AddStringToObject(info, "deviceCode",macString);
} }
cJSON *payload = rpc_cJSON_CreateObject(); cJSON *payload = rpc_cJSON_CreateObject();
...@@ -73,7 +72,6 @@ void kk_msg_report_dev_joined(EmberEUI64 mac,const char* productCode) ...@@ -73,7 +72,6 @@ void kk_msg_report_dev_joined(EmberEUI64 mac,const char* productCode)
rpc_cJSON_AddStringToObject(devicesJson, "deviceCode",macString); rpc_cJSON_AddStringToObject(devicesJson, "deviceCode",macString);
rpc_cJSON_AddStringToObject(devicesJson, "mac",macString); rpc_cJSON_AddStringToObject(devicesJson, "mac",macString);
kk_sub_tsl_add(mac,productCode);
emberAfGetEui64(localEui64); emberAfGetEui64(localEui64);
kk_msg_report_joined(devicesJson,localEui64); kk_msg_report_joined(devicesJson,localEui64);
} }
...@@ -82,22 +80,20 @@ void kk_msg_report_dev_leave(EmberEUI64 mac) ...@@ -82,22 +80,20 @@ void kk_msg_report_dev_leave(EmberEUI64 mac)
{ {
int res = 0; int res = 0;
cJSON* devicesJson; cJSON* devicesJson;
sub_dev_node_t *node = NULL;
EmberEUI64 localEui64 = {0}; EmberEUI64 localEui64 = {0};
char macString[KK_EUI64_STRING_LENGTH]; char macString[KK_EUI64_STRING_LENGTH];
kk_device_table_s *dev =NULL;
rpc_eui64ToString(mac,macString); rpc_eui64ToString(mac,macString);
res = kk_sub_tsl_get_device_by_mac(macString, &node); dev = kk_device_find_by_mac(mac);
if (res != SUCCESS_RETURN) { if (dev == NULL) {
emberAfDebugPrintln("[%s][%d]kk msg send error!!!\n",__FUNCTION__,__LINE__); emberAfDebugPrintln("[%s][%d]kk_msg_report_dev_leave error!!!\n",__FUNCTION__,__LINE__);
return; return;
} }
devicesJson = rpc_cJSON_CreateObject(); devicesJson = rpc_cJSON_CreateObject();
rpc_cJSON_AddStringToObject(devicesJson, "productCode",node->productCode); rpc_cJSON_AddStringToObject(devicesJson, "productCode",dev->productCode);
rpc_cJSON_AddStringToObject(devicesJson, "deviceCode",macString); rpc_cJSON_AddStringToObject(devicesJson, "deviceCode",macString);
emberAfGetEui64(localEui64); emberAfGetEui64(localEui64);
kk_msg_report_leave(devicesJson,localEui64); kk_msg_report_leave(devicesJson,localEui64);
kk_sub_tsl_delete(mac);
kk_device_table_delete(mac); kk_device_table_delete(mac);
kk_device_db_delete(mac); kk_device_db_delete(mac);
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include ".././jsonrpc/rpccJSON.h" #include ".././jsonrpc/rpccJSON.h"
#include "com_api.h" #include "com_api.h"
#include "kk_zb_com.h" #include "kk_zb_com.h"
#include "kk_sub_tsl.h"
#define KK_IPC_VERSION "1.0" #define KK_IPC_VERSION "1.0"
......
...@@ -111,7 +111,6 @@ void kk_tsl_report_attribute(EmberEUI64 eui64, ...@@ -111,7 +111,6 @@ void kk_tsl_report_attribute(EmberEUI64 eui64,
uint8_t *data) uint8_t *data)
{ {
int i,j,num,status; int i,j,num,status;
sub_dev_node_t *node = NULL;
int res = 0; int res = 0;
char macString[RPC_EUI64_STRING_LENGTH]; char macString[RPC_EUI64_STRING_LENGTH];
kk_device_table_s *dev; kk_device_table_s *dev;
......
...@@ -35,15 +35,13 @@ cJSON *kk_topo_change_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJS ...@@ -35,15 +35,13 @@ cJSON *kk_topo_change_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJS
} }
} }
} }
return rpc_cJSON_CreateNumber(res); return rpc_cJSON_CreateNumber(res);
error_return: error_return:
return rpc_cJSON_CreateNull(); return rpc_cJSON_CreateNull();
} }
int kk_tsl_utils_memtok(_IN_ char *input, _IN_ char *delimiter, _IN_ int index, _OU_ int *offset) int kk_tsl_utils_memtok( char *input, char *delimiter, int index, int *offset)
{ {
int item_index = 0; int item_index = 0;
int count = 0; int count = 0;
...@@ -103,7 +101,6 @@ cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJ ...@@ -103,7 +101,6 @@ cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJ
} }
item = &dev_info->item; item = &dev_info->item;
while(item!=NULL){ while(item!=NULL){
rev = kk_tsl_utils_memtok(item->identity,'.',2,&startIdx2); rev = kk_tsl_utils_memtok(item->identity,'.',2,&startIdx2);
if(!rev){ if(!rev){
kk_tsl_utils_memtok(item->identity,'.',1,&startIdx1); kk_tsl_utils_memtok(item->identity,'.',1,&startIdx1);
......
...@@ -24,7 +24,8 @@ void kk_rpc_test(void); ...@@ -24,7 +24,8 @@ void kk_rpc_test(void);
{"kk_tsl_set_colorlight_RGB_red",kk_tsl_set_colorlight_RGB_red},\ {"kk_tsl_set_colorlight_RGB_red",kk_tsl_set_colorlight_RGB_red},\
{"kk_tsl_set_colorlight_RGB_green",kk_tsl_set_colorlight_RGB_green},\ {"kk_tsl_set_colorlight_RGB_green",kk_tsl_set_colorlight_RGB_green},\
{"kk_tsl_set_colorlight_RGB_blue",kk_tsl_set_colorlight_RGB_blue},\ {"kk_tsl_set_colorlight_RGB_blue",kk_tsl_set_colorlight_RGB_blue},\
{"kk_tsl_set_colorlight_Brightness",kk_tsl_set_colorlight_Brightness},\ {"kk_tsl_set_colorlight_Brightness",kk_tsl_set_colorlight_Brightness},\
{"kk_permit_join",kk_permit_join},\
} }
#define KK_RPC_REPORT_FUNCTION_TABLE {\ #define KK_RPC_REPORT_FUNCTION_TABLE {\
......
#include "kk_sub_tsl.h"
typedef unsigned char EmberEUI64[8];
typedef struct {
void *mutex;
int sub_devid;
struct list_head dev_list;
} kk_sub_dev_ctx_t;
static kk_sub_dev_ctx_t g_sub_dev_mgr = {0};
static kk_sub_dev_ctx_t * _sub_dev_get_ctx(void)
{
return &g_sub_dev_mgr;
}
static void _sub_dev_mutex_lock(void)
{
kk_sub_dev_ctx_t *ctx = _sub_dev_get_ctx();
if (ctx->mutex) {
HAL_MutexLock(ctx->mutex);
}
}
static void _sub_dev_mutex_unlock(void)
{
kk_sub_dev_ctx_t *ctx = _sub_dev_get_ctx();
if (ctx->mutex) {
HAL_MutexUnlock(ctx->mutex);
}
}
int kk_tsl_init(EmberEUI64 mac)
{
int res = 0;
kk_sub_dev_ctx_t *ctx = _sub_dev_get_ctx();
ctx->mutex = HAL_MutexCreate();
if (ctx->mutex == NULL) {
return FAIL_RETURN;
}
ctx->sub_devid = 1;
INIT_LIST_HEAD(&ctx->dev_list);
kk_sub_tsl_add(mac,"2");
//usleep(1000000);
//kk_test();
return SUCCESS_RETURN;
}
static int _kk_tsl_check_exist(const char *deviceCode)
{
sub_dev_node_t *search_node = NULL;
kk_sub_dev_ctx_t *ctx = _sub_dev_get_ctx();
if(deviceCode == NULL){
return INVALID_PARAMETER;
}
list_for_each_entry(search_node, &ctx->dev_list, linked_list, sub_dev_node_t) {
if ( (strlen(search_node->deviceCode) == strlen(deviceCode)) &&
(memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
/* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */
return SUCCESS_RETURN;
}
}
return FAIL_RETURN;
}
int kk_sub_tsl_add(EmberEUI64 device_mac,const char *productCode)
{
sub_dev_node_t *node = NULL;
kk_sub_dev_ctx_t *ctx = _sub_dev_get_ctx();
char *tsl_str = NULL;
int res = 0;
char macString[19] = {0};
if(productCode == NULL)
{
return INVALID_PARAMETER;
}
rpc_eui64ToString(device_mac,macString);
if(_kk_tsl_check_exist(device_mac) == SUCCESS_RETURN){
return SUCCESS_RETURN;
}
node = malloc(sizeof(sub_dev_node_t));
if (node == NULL) {
return MEMORY_NOT_ENOUGH;
}
_sub_dev_mutex_lock();
memset(node,0,sizeof(sub_dev_node_t) );
memcpy(node->deviceCode, macString, strlen(macString));
memcpy(node->productCode, productCode, strlen(productCode));
INIT_LIST_HEAD(&node->linked_list);
list_add_tail(&node->linked_list, &ctx->dev_list);
_sub_dev_mutex_unlock();
return SUCCESS_RETURN;
}
int kk_sub_tsl_delete(EmberEUI64 device_mac)
{
sub_dev_node_t *node = NULL;
kk_sub_dev_ctx_t *ctx = _sub_dev_get_ctx();
char *tsl_str = NULL;
int res = 0;
char macString[19] = {0};
rpc_eui64ToString(device_mac,macString);
_sub_dev_mutex_lock();
res = kk_sub_tsl_get_device_by_mac(macString, &node);
if (res != SUCCESS_RETURN) {
_sub_dev_mutex_unlock();
return FAIL_RETURN;
}
list_del(&node->linked_list);
free(node);
node = NULL;
_sub_dev_mutex_unlock();
return SUCCESS_RETURN;
}
int kk_sub_tsl_get_device_by_mac(_IN_ const char *deviceCode , _OU_ sub_dev_node_t **node)
{
kk_sub_dev_ctx_t *ctx = _sub_dev_get_ctx();
sub_dev_node_t *search_node = NULL;
list_for_each_entry(search_node, &ctx->dev_list, linked_list, sub_dev_node_t) {
if ((strlen(search_node->deviceCode) == strlen(deviceCode)) &&
(memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
if (node) {
*node = search_node;
}
return SUCCESS_RETURN;
}
}
printf("Device Not Found, device_mac: %s\n", deviceCode);
return FAIL_RETURN;
}
#ifndef _KK_SUB_TSL_H_
#define _KK_SUB_TSL_H_
#include "kk_tsl_common.h"
#include "klist.h"
typedef struct {
char productCode[PRODUCT_TYPE_MAXLEN];
char deviceCode[DEVICE_CODE_MAXLEN];
struct list_head linked_list;
} sub_dev_node_t;
#endif
#include "kk_test.h" #include "kk_test.h"
#include "kk_sub_tsl.h"
static void kk_rpc_send_message(cJSON *data,char *msgtype,char *method,EmberEUI64 mac) static void kk_rpc_send_message(cJSON *data,char *msgtype,char *method,EmberEUI64 mac)
{ {
static uint16_t msgid; static uint16_t msgid;
char msgIdString[10]= {0}; char msgIdString[10]= {0};
char macString[19] = {0}; char macString[19] = {0};
sub_dev_node_t *node = NULL;
int res = 0; int res = 0;
kk_device_table_s *dev =NULL;
rpc_eui64ToString(mac,macString); rpc_eui64ToString(mac,macString);
res = kk_sub_tsl_get_device_by_mac(macString, &node); dev = kk_device_find_by_mac(mac);
if (res != SUCCESS_RETURN) { if (dev == NULL) {
printf("[%s][%d]kk_rpc_send_message error!!!\n",__FUNCTION__,__LINE__); printf("[%s][%d]kk_rpc_send_message error!!!\n",__FUNCTION__,__LINE__);
return; return;
} }
...@@ -19,7 +18,7 @@ static void kk_rpc_send_message(cJSON *data,char *msgtype,char *method,EmberEUI6 ...@@ -19,7 +18,7 @@ static void kk_rpc_send_message(cJSON *data,char *msgtype,char *method,EmberEUI6
cJSON *info = rpc_cJSON_CreateObject(); cJSON *info = rpc_cJSON_CreateObject();
if(info != NULL){ if(info != NULL){
rpc_cJSON_AddStringToObject(info, "msgType",msgtype); rpc_cJSON_AddStringToObject(info, "msgType",msgtype);
rpc_cJSON_AddStringToObject(info, "productCode",node->productCode); rpc_cJSON_AddStringToObject(info, "productCode",dev->productCode);
rpc_cJSON_AddStringToObject(info, "deviceCode",macString); rpc_cJSON_AddStringToObject(info, "deviceCode",macString);
} }
cJSON *payload = rpc_cJSON_CreateObject(); cJSON *payload = rpc_cJSON_CreateObject();
...@@ -70,22 +69,21 @@ void kk_rpc_reportLeftDevices(EmberEUI64 mac) ...@@ -70,22 +69,21 @@ void kk_rpc_reportLeftDevices(EmberEUI64 mac)
{ {
cJSON* devicesJson; cJSON* devicesJson;
char macString[RPC_EUI64_STRING_LENGTH]; char macString[RPC_EUI64_STRING_LENGTH];
sub_dev_node_t *node = NULL;
int res = 0; int res = 0;
EmberEUI64 gw_eui64 = {0}; EmberEUI64 gw_eui64 = {0};
kk_device_table_s *dev =NULL;
rpc_eui64ToString(mac,macString); rpc_eui64ToString(mac,macString);
res = kk_sub_tsl_get_device_by_mac(macString, &node); dev = kk_device_find_by_mac(mac);
if (res != SUCCESS_RETURN) { if (dev == NULL) {
printf("[%s][%d]kk_rpc_send_message error!!!\n",__FUNCTION__,__LINE__); printf("[%s][%d]kk_rpc_reportLeftDevices error!!!\n",__FUNCTION__,__LINE__);
return; return;
} }
devicesJson = rpc_cJSON_CreateObject(); devicesJson = rpc_cJSON_CreateObject();
rpc_cJSON_AddStringToObject(devicesJson, "productCode",node->productCode); rpc_cJSON_AddStringToObject(devicesJson, "productCode",dev->productCode);
rpc_cJSON_AddStringToObject(devicesJson, "deviceCode",macString); rpc_cJSON_AddStringToObject(devicesJson, "deviceCode",macString);
emberAfGetEui64(gw_eui64); emberAfGetEui64(gw_eui64);
kk_rpc_report_left_devices(devicesJson,gw_eui64); kk_rpc_report_left_devices(devicesJson,gw_eui64);
kk_sub_tsl_delete(mac);
kk_device_table_delete(mac); kk_device_table_delete(mac);
...@@ -109,7 +107,6 @@ void kk_rpc_reportDevices(EmberEUI64 mac,const char* productCode) ...@@ -109,7 +107,6 @@ void kk_rpc_reportDevices(EmberEUI64 mac,const char* productCode)
rpc_cJSON_AddStringToObject(devicesJson, "deviceCode",macString); rpc_cJSON_AddStringToObject(devicesJson, "deviceCode",macString);
rpc_cJSON_AddStringToObject(devicesJson, "mac",macString); rpc_cJSON_AddStringToObject(devicesJson, "mac",macString);
// //
kk_sub_tsl_add(mac,productCode);
emberAfGetEui64(eui64); emberAfGetEui64(eui64);
kk_rpc_report_devices(devicesJson,eui64); kk_rpc_report_devices(devicesJson,eui64);
} }
......
// Copyright 2016 Silicon Laboratories, Inc. *80* // Copyright 2016 Silicon Laboratories, Inc. *80*
#include PLATFORM_HEADER #include PLATFORM_HEADER
#ifdef EZSP_HOST #ifdef EZSP_HOST
// Includes needed for functions related to the EZSP host // Includes needed for functions related to the EZSP host
#include "stack/include/error.h" #include "stack/include/error.h"
#include "stack/include/ember-types.h" #include "stack/include/ember-types.h"
#include "app/util/ezsp/ezsp-protocol.h" #include "app/util/ezsp/ezsp-protocol.h"
#include "app/util/ezsp/ezsp.h" #include "app/util/ezsp/ezsp.h"
#include "app/util/ezsp/serial-interface.h" #include "app/util/ezsp/serial-interface.h"
#include "app/util/zigbee-framework/zigbee-device-common.h" #include "app/util/zigbee-framework/zigbee-device-common.h"
#else #else
#include "stack/include/ember.h" #include "stack/include/ember.h"
#endif #endif
#include "af.h" #include "af.h"
#include "af-main.h" #include "af-main.h"
#include "attribute-storage.h" #include "attribute-storage.h"
#include "common.h" #include "common.h"
#include "hal/hal.h" #include "hal/hal.h"
#include "app/util/serial/command-interpreter2.h" #include "app/util/serial/command-interpreter2.h"
#include "stack/include/event.h" #include "stack/include/event.h"
#include "app/framework/plugin/concentrator/source-route-host.h" #include "app/framework/plugin/concentrator/source-route-host.h"
#include "app/framework/plugin/device-table/device-table.h" #include "app/framework/plugin/device-table/device-table.h"
#include "app/framework/plugin/device-table/device-table-internal.h" #include "app/framework/plugin/device-table/device-table-internal.h"
#include "app/framework/util/util.h" #include "app/framework/util/util.h"
#include <stdlib.h> #include <stdlib.h>
#include <kk_test.h> #include <kk_test.h>
void emAfDeviceTableSave(void); void emAfDeviceTableSave(void);
void emAfDeviceTableLoad(void); void emAfDeviceTableLoad(void);
// Framework message send global data // Framework message send global data
extern uint8_t appZclBuffer[]; extern uint8_t appZclBuffer[];
extern uint16_t appZclBufferLen; extern uint16_t appZclBufferLen;
extern bool zclCmdIsBuilt; extern bool zclCmdIsBuilt;
extern EmberApsFrame globalApsFrame; extern EmberApsFrame globalApsFrame;
extern void emAfApsFrameEndpointSetup(uint8_t srcEndpoint, extern void emAfApsFrameEndpointSetup(uint8_t srcEndpoint,
uint8_t dstEndpoint); uint8_t dstEndpoint);
static EmberAfPluginDeviceTableEntry deviceTable[EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE]; static EmberAfPluginDeviceTableEntry deviceTable[EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE];
EmberStatus emberAfGetChildData(uint8_t index, EmberStatus emberAfGetChildData(uint8_t index,
EmberChildData *childData); EmberChildData *childData);
// Device discovery global declarations // Device discovery global declarations
void emAfDeviceTableInitiateRouteRepair(EmberNodeId nodeId); void emAfDeviceTableInitiateRouteRepair(EmberNodeId nodeId);
static void clearDeviceTableIndex(uint16_t index); static void clearDeviceTableIndex(uint16_t index);
EmberAfPluginDeviceTableEntry* emberAfDeviceTablePointer(void) EmberAfPluginDeviceTableEntry* emberAfDeviceTablePointer(void)
{ {
return deviceTable; return deviceTable;
} }
uint16_t emberAfDeviceTableGetNodeIdFromIndex(uint16_t index) uint16_t emberAfDeviceTableGetNodeIdFromIndex(uint16_t index)
{ {
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
return deviceTable[index].nodeId; return deviceTable[index].nodeId;
} }
uint8_t emAfDeviceTableGetFirstEndpointFromIndex(uint16_t index) uint8_t emAfDeviceTableGetFirstEndpointFromIndex(uint16_t index)
{ {
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
return deviceTable[index].endpoint; return deviceTable[index].endpoint;
} }
static void matchReverseEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) static void matchReverseEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
{ {
uint8_t i; uint8_t i;
for (i = 0; i < EUI64_SIZE; i++) { for (i = 0; i < EUI64_SIZE; i++) {
if (eui64a[i] != eui64b[(EUI64_SIZE - 1) - i]) { if (eui64a[i] != eui64b[(EUI64_SIZE - 1) - i]) {
return; return;
} }
} }
emberAfCorePrintln("MATCH_EUI: EUI matches backwards"); emberAfCorePrintln("MATCH_EUI: EUI matches backwards");
emberAfCorePrint("A:"); emberAfCorePrint("A:");
emAfDeviceTablePrintEUI64(eui64a); emAfDeviceTablePrintEUI64(eui64a);
emberAfCorePrint(" B:"); emberAfCorePrint(" B:");
emAfDeviceTablePrintEUI64(eui64b); emAfDeviceTablePrintEUI64(eui64b);
emberAfCorePrintln(""); emberAfCorePrintln("");
} }
static void checkNullEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) static void checkNullEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
{ {
uint8_t i; uint8_t i;
for (i = 0; i < EUI64_SIZE; i++) { for (i = 0; i < EUI64_SIZE; i++) {
if (eui64a[i] != 0xff if (eui64a[i] != 0xff
|| eui64b[i] != 0xff) { || eui64b[i] != 0xff) {
return; return;
} }
} }
emberAfCorePrintln("MatchEUI: two null EUI"); emberAfCorePrintln("MatchEUI: two null EUI");
} }
static bool matchEui64(EmberEUI64 a, EmberEUI64 b) static bool matchEui64(EmberEUI64 a, EmberEUI64 b)
{ {
checkNullEui64(a, b); checkNullEui64(a, b);
if (MEMCOMPARE(a, b, EUI64_SIZE) == 0) { if (MEMCOMPARE(a, b, EUI64_SIZE) == 0) {
return true; return true;
} else { } else {
// Test to see if the EUI64 is backwards // Test to see if the EUI64 is backwards
matchReverseEui64(a, b); matchReverseEui64(a, b);
return false; return false;
} }
} }
bool emberAfDeviceTableMatchEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) bool emberAfDeviceTableMatchEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
{ {
return matchEui64(eui64a, eui64b); return matchEui64(eui64a, eui64b);
} }
static void unsetEui64(EmberEUI64 eui64) static void unsetEui64(EmberEUI64 eui64)
{ {
uint8_t i; uint8_t i;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
eui64[i] = 0xff; eui64[i] = 0xff;
} }
} }
static void clearDeviceTableIndex(uint16_t index) static void clearDeviceTableIndex(uint16_t index)
{ {
uint8_t i; uint8_t i;
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
deviceTable[index].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; deviceTable[index].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
unsetEui64(deviceTable[index].eui64); unsetEui64(deviceTable[index].eui64);
deviceTable[index].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_NULL; deviceTable[index].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_NULL;
deviceTable[index].endpoint = 0; deviceTable[index].endpoint = 0;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; i++) {
deviceTable[index].clusterIds[i] = ZCL_NULL_CLUSTER_ID; deviceTable[index].clusterIds[i] = ZCL_NULL_CLUSTER_ID;
} }
deviceTable[index].clusterOutStartPosition = 0; deviceTable[index].clusterOutStartPosition = 0;
} }
void emAfPluginDeviceTableDeleteEntry(uint16_t index) void emAfPluginDeviceTableDeleteEntry(uint16_t index)
{ {
uint16_t currentIndex; uint16_t currentIndex;
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
currentIndex = index; currentIndex = index;
// Need to compute the next index before deleting the current one. Or else // Need to compute the next index before deleting the current one. Or else
// the call to next endpoint will yield a bogus result. // the call to next endpoint will yield a bogus result.
index = emAfDeviceTableFindNextEndpoint(index); index = emAfDeviceTableFindNextEndpoint(index);
clearDeviceTableIndex(currentIndex); clearDeviceTableIndex(currentIndex);
emberAfPluginDeviceTableIndexRemovedCallback(currentIndex); emberAfPluginDeviceTableIndexRemovedCallback(currentIndex);
} }
} }
void emAfDeviceTableInit(void) void emAfDeviceTableInit(void)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
clearDeviceTableIndex(i); clearDeviceTableIndex(i);
} }
} }
void emberAfDeviceTableClear(void) void emberAfDeviceTableClear(void)
{ {
emAfDeviceTableInit(); emAfDeviceTableInit();
emAfDeviceTableSave(); emAfDeviceTableSave();
//emberAfPluginDeviceTableClearedCallback(); //emberAfPluginDeviceTableClearedCallback();
} }
uint16_t emberAfDeviceTableGetIndexFromEui64AndEndpoint(EmberEUI64 eui64, uint16_t emberAfDeviceTableGetIndexFromEui64AndEndpoint(EmberEUI64 eui64,
uint8_t endpoint) uint8_t endpoint)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (matchEui64(deviceTable[i].eui64, eui64) if (matchEui64(deviceTable[i].eui64, eui64)
&& deviceTable[i].endpoint == endpoint) { && deviceTable[i].endpoint == endpoint) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
uint16_t emberAfDeviceTableGetNodeIdFromEui64(EmberEUI64 eui64) uint16_t emberAfDeviceTableGetNodeIdFromEui64(EmberEUI64 eui64)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (matchEui64(deviceTable[i].eui64, eui64) ) { if (matchEui64(deviceTable[i].eui64, eui64) ) {
return deviceTable[i].nodeId; return deviceTable[i].nodeId;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
} }
bool emberAfDeviceTableGetEui64FromNodeId(EmberNodeId emberNodeId, EmberEUI64 eui64) bool emberAfDeviceTableGetEui64FromNodeId(EmberNodeId emberNodeId, EmberEUI64 eui64)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == emberNodeId) { if (deviceTable[i].nodeId == emberNodeId) {
MEMCOPY(eui64, deviceTable[i].eui64, EUI64_SIZE); MEMCOPY(eui64, deviceTable[i].eui64, EUI64_SIZE);
return true; return true;
} }
} }
return false; return false;
} }
uint16_t emberAfDeviceTableGetIndexFromNodeId(EmberNodeId emberNodeId) uint16_t emberAfDeviceTableGetIndexFromNodeId(EmberNodeId emberNodeId)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == emberNodeId) { if (deviceTable[i].nodeId == emberNodeId) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
uint16_t emAfDeviceTableFindFreeDeviceTableIndex(void) uint16_t emAfDeviceTableFindFreeDeviceTableIndex(void)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) { if (deviceTable[i].nodeId == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
uint16_t emberAfDeviceTableGetEndpointFromNodeIdAndEndpoint(EmberNodeId emberNodeId, uint16_t emberAfDeviceTableGetEndpointFromNodeIdAndEndpoint(EmberNodeId emberNodeId,
uint8_t endpoint) uint8_t endpoint)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == emberNodeId if (deviceTable[i].nodeId == emberNodeId
&& deviceTable[i].endpoint == endpoint) { && deviceTable[i].endpoint == endpoint) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
void emAfDeviceTableCopyDeviceTableEntry(uint16_t fromIndex, uint16_t toIndex) void emAfDeviceTableCopyDeviceTableEntry(uint16_t fromIndex, uint16_t toIndex)
{ {
EmberAfPluginDeviceTableEntry* from = &(deviceTable[fromIndex]); EmberAfPluginDeviceTableEntry* from = &(deviceTable[fromIndex]);
EmberAfPluginDeviceTableEntry* to = &(deviceTable[toIndex]); EmberAfPluginDeviceTableEntry* to = &(deviceTable[toIndex]);
// make sure the fromIndex is in the valud range. // make sure the fromIndex is in the valud range.
assert(fromIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(fromIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
// make sure the fromIndex has a valid entry // make sure the fromIndex has a valid entry
assert(deviceTable[fromIndex].nodeId assert(deviceTable[fromIndex].nodeId
!= EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID); != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID);
// make sure the toIndex is in the valud range. // make sure the toIndex is in the valud range.
assert(toIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(toIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
MEMCOPY(to, from, sizeof(EmberAfPluginDeviceTableEntry)); MEMCOPY(to, from, sizeof(EmberAfPluginDeviceTableEntry));
} }
uint8_t emAfDeviceTableNumberOfEndpointsFromIndex(uint16_t index) uint8_t emAfDeviceTableNumberOfEndpointsFromIndex(uint16_t index)
{ {
uint8_t count = 0; uint8_t count = 0;
uint16_t currentNodeId = emberAfDeviceTableGetNodeIdFromIndex(index); uint16_t currentNodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == currentNodeId) { if (deviceTable[i].nodeId == currentNodeId) {
count++; count++;
} }
} }
return count; return count;
} }
static uint16_t findIndexFromNodeIdAndIndex(uint16_t nodeId, uint16_t index) static uint16_t findIndexFromNodeIdAndIndex(uint16_t nodeId, uint16_t index)
{ {
uint16_t i; uint16_t i;
for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (nodeId == emberAfDeviceTableGetNodeIdFromIndex(i)) { if (nodeId == emberAfDeviceTableGetNodeIdFromIndex(i)) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
static uint16_t findIndexFromEui64AndIndex(EmberEUI64 eui64, uint16_t index) static uint16_t findIndexFromEui64AndIndex(EmberEUI64 eui64, uint16_t index)
{ {
uint16_t i; uint16_t i;
for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (matchEui64(eui64, deviceTable[i].eui64)) { if (matchEui64(eui64, deviceTable[i].eui64)) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
uint16_t emAfDeviceTableFindFirstEndpointNodeId(uint16_t nodeId) uint16_t emAfDeviceTableFindFirstEndpointNodeId(uint16_t nodeId)
{ {
return findIndexFromNodeIdAndIndex(nodeId, 0); return findIndexFromNodeIdAndIndex(nodeId, 0);
} }
uint16_t emAfDeviceTableFindNextEndpoint(uint16_t index) uint16_t emAfDeviceTableFindNextEndpoint(uint16_t index)
{ {
return findIndexFromEui64AndIndex(deviceTable[index].eui64, return findIndexFromEui64AndIndex(deviceTable[index].eui64,
index + 1); index + 1);
} }
uint16_t emAfDeviceTableFindFirstEndpointIeee(EmberEUI64 eui64) uint16_t emAfDeviceTableFindFirstEndpointIeee(EmberEUI64 eui64)
{ {
return findIndexFromEui64AndIndex(eui64, 0); return findIndexFromEui64AndIndex(eui64, 0);
} }
uint16_t emberAfDeviceTableGetFirstIndexFromEui64(EmberEUI64 eui64) uint16_t emberAfDeviceTableGetFirstIndexFromEui64(EmberEUI64 eui64)
{ {
return emAfDeviceTableFindFirstEndpointIeee(eui64); return emAfDeviceTableFindFirstEndpointIeee(eui64);
} }
EmberAfStatus emAfDeviceTableAddNewEndpoint(uint16_t index, uint8_t newEndpoint) EmberAfStatus emAfDeviceTableAddNewEndpoint(uint16_t index, uint8_t newEndpoint)
{ {
uint16_t newIndex = emAfDeviceTableFindFreeDeviceTableIndex(); uint16_t newIndex = emAfDeviceTableFindFreeDeviceTableIndex();
if (newIndex == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { if (newIndex == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
return EMBER_ZCL_STATUS_FAILURE; return EMBER_ZCL_STATUS_FAILURE;
} }
emAfDeviceTableCopyDeviceTableEntry(index, newIndex); emAfDeviceTableCopyDeviceTableEntry(index, newIndex);
deviceTable[newIndex].endpoint = newEndpoint; deviceTable[newIndex].endpoint = newEndpoint;
return EMBER_ZCL_STATUS_SUCCESS; return EMBER_ZCL_STATUS_SUCCESS;
} }
uint16_t emAfDeviceTableFindIndexNodeIdEndpoint(uint16_t nodeId, uint16_t emAfDeviceTableFindIndexNodeIdEndpoint(uint16_t nodeId,
uint8_t endpoint) uint8_t endpoint)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == nodeId if (deviceTable[i].nodeId == nodeId
&& deviceTable[i].endpoint == endpoint) { && deviceTable[i].endpoint == endpoint) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
EmberAfPluginDeviceTableEntry *emberAfDeviceTableFindDeviceTableEntry(uint16_t index) EmberAfPluginDeviceTableEntry *emberAfDeviceTableFindDeviceTableEntry(uint16_t index)
{ {
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID); assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID);
return &(deviceTable[index]); return &(deviceTable[index]);
} }
void emAfDeviceTableUpdateNodeId(uint16_t currentNodeId, uint16_t newNodeId) void emAfDeviceTableUpdateNodeId(uint16_t currentNodeId, uint16_t newNodeId)
{ {
uint16_t index = emAfDeviceTableFindFirstEndpointNodeId(currentNodeId); uint16_t index = emAfDeviceTableFindFirstEndpointNodeId(currentNodeId);
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
deviceTable[index].nodeId = newNodeId; deviceTable[index].nodeId = newNodeId;
index = emAfDeviceTableFindNextEndpoint(index); index = emAfDeviceTableFindNextEndpoint(index);
} }
} }
void emAfDeviceTableUpdateDeviceState(uint16_t index, uint8_t newState) void emAfDeviceTableUpdateDeviceState(uint16_t index, uint8_t newState)
{ {
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
deviceTable[index].state = newState; deviceTable[index].state = newState;
index = emAfDeviceTableFindNextEndpoint(index); index = emAfDeviceTableFindNextEndpoint(index);
} }
} }
uint32_t emberAfDeviceTableTimeSinceLastMessage(uint16_t index) uint32_t emberAfDeviceTableTimeSinceLastMessage(uint16_t index)
{ {
uint32_t timeSinceLastMessage = halCommonGetInt32uMillisecondTick(); uint32_t timeSinceLastMessage = halCommonGetInt32uMillisecondTick();
timeSinceLastMessage -= deviceTable[index].lastMsgTimestamp; timeSinceLastMessage -= deviceTable[index].lastMsgTimestamp;
timeSinceLastMessage /= MILLISECOND_TICKS_PER_SECOND; timeSinceLastMessage /= MILLISECOND_TICKS_PER_SECOND;
return timeSinceLastMessage; return timeSinceLastMessage;
} }
// AF Framework callbacks. This is where the plugin implements the callbacks. // AF Framework callbacks. This is where the plugin implements the callbacks.
void emberAfPluginDeviceTableInitCallback(void) void emberAfPluginDeviceTableInitCallback(void)
{ {
emAfDeviceTableInit(); emAfDeviceTableInit();
// Load on Init // Load on Init
emAfDeviceTableLoad(); emAfDeviceTableLoad();
emberAfPluginDeviceTableInitialized(); emberAfPluginDeviceTableInitialized();
} }
void emberAfPluginDeviceTableStackStatusCallback(EmberStatus status) void emberAfPluginDeviceTableStackStatusCallback(EmberStatus status)
{ {
// If we leave the network, this plugin needs to clear out all of its device // If we leave the network, this plugin needs to clear out all of its device
// state. // state.
emberAfCorePrintln("%d %d", status, emberNetworkState()); emberAfCorePrintln("%d %d", status, emberNetworkState());
if (status == EMBER_NETWORK_DOWN if (status == EMBER_NETWORK_DOWN
&& emberNetworkState() == EMBER_NO_NETWORK) { && emberNetworkState() == EMBER_NO_NETWORK) {
emberAfCorePrintln("DeviceTable: Clear State"); emberAfCorePrintln("DeviceTable: Clear State");
emberAfDeviceTableClear(); emberAfDeviceTableClear();
//kk_device_table_clear(); //kk_device_table_clear();
} }
} }
// -------------------------------- // --------------------------------
// Save/Load the devices // Save/Load the devices
void emAfDeviceTableSave(void) void emAfDeviceTableSave(void)
{ {
#if defined(EZSP_HOST) && !defined(EMBER_TEST) #if defined(EZSP_HOST) && !defined(EMBER_TEST)
FILE *fp; FILE *fp;
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
uint8_t i; uint8_t i;
uint8_t j; uint8_t j;
// Save device table // Save device table
fp = fopen("devices.txt", "w"); fp = fopen("devices.txt", "w");
for (i = 0; for (i = 0;
i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE;
i++) { i++) {
if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) { if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) {
fprintf(fp, fprintf(fp,
"%x %x %x ", "%x %x %x ",
deviceTable[i].nodeId, deviceTable[i].nodeId,
deviceTable[i].endpoint, deviceTable[i].endpoint,
deviceTable[i].deviceId); deviceTable[i].deviceId);
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
fprintf(fp, "%x ", deviceTable[i].eui64[j]); fprintf(fp, "%x ", deviceTable[i].eui64[j]);
} }
for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) { for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) {
fprintf(fp, "%x ", deviceTable[i].clusterIds[j]); fprintf(fp, "%x ", deviceTable[i].clusterIds[j]);
} }
fprintf(fp, "%d ", deviceTable[i].clusterOutStartPosition); fprintf(fp, "%d ", deviceTable[i].clusterOutStartPosition);
} }
} }
// Write ffffffff to mark the end // Write ffffffff to mark the end
fprintf(fp, "\r\nffffffff\r\n"); fprintf(fp, "\r\nffffffff\r\n");
fclose(fp); fclose(fp);
#endif // defined(EZSP_HOST) && !defined(EMBER_TEST) #endif // defined(EZSP_HOST) && !defined(EMBER_TEST)
} }
void emAfDeviceTableLoad(void) void emAfDeviceTableLoad(void)
{ {
#if defined(EZSP_HOST) && !defined(EMBER_TEST) #if defined(EZSP_HOST) && !defined(EMBER_TEST)
uint16_t i; uint16_t i;
uint16_t j; uint16_t j;
FILE *fp; FILE *fp;
unsigned int data, data2, data3; unsigned int data, data2, data3;
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
fp = fopen("devices.txt", "r"); fp = fopen("devices.txt", "r");
if (!fp) { if (!fp) {
return; return;
} }
for (i = 0; for (i = 0;
i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE && feof(fp) == false; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE && feof(fp) == false;
i++) { i++) {
fscanf(fp, "%x %x %x", &data2, &data, &data3); fscanf(fp, "%x %x %x", &data2, &data, &data3);
deviceTable[i].endpoint = (uint8_t) data; deviceTable[i].endpoint = (uint8_t) data;
deviceTable[i].nodeId = (uint16_t) data2; deviceTable[i].nodeId = (uint16_t) data2;
deviceTable[i].deviceId = (uint16_t) data3; deviceTable[i].deviceId = (uint16_t) data3;
if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) { if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) {
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
fscanf(fp, "%x", &data); fscanf(fp, "%x", &data);
deviceTable[i].eui64[j] = (uint8_t) data; deviceTable[i].eui64[j] = (uint8_t) data;
} }
for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) { for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) {
fscanf(fp, "%x", &data); fscanf(fp, "%x", &data);
deviceTable[i].clusterIds[j] = (uint16_t) data; deviceTable[i].clusterIds[j] = (uint16_t) data;
} }
fscanf(fp, "%d", &data); fscanf(fp, "%d", &data);
deviceTable[i].clusterOutStartPosition = (uint16_t) data; deviceTable[i].clusterOutStartPosition = (uint16_t) data;
deviceTable[i].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_JOINED; deviceTable[i].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_JOINED;
//kk_sub_tsl_add(deviceTable[i].eui64,TEST_PRODUCT_CODE); }
}
deviceTable[i].lastMsgTimestamp = halCommonGetInt32uMillisecondTick();
deviceTable[i].lastMsgTimestamp = halCommonGetInt32uMillisecondTick(); }
}
fclose(fp);
fclose(fp);
// Set the rest of the device table to null.
// Set the rest of the device table to null. for (; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
for (; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { deviceTable[i].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
deviceTable[i].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; }
}
#endif // #if defined(EZSP_HOST) && !defined(EMBER_TEST)
#endif // #if defined(EZSP_HOST) && !defined(EMBER_TEST) }
}
// --------------------------------
// -------------------------------- // Message send section
// Message send section // Command to send the CIE IEEE address to the IAS Zone cluster
// Command to send the CIE IEEE address to the IAS Zone cluster void emAfDeviceTableSendCieAddressWrite(EmberNodeId nodeId, uint8_t endpoint)
void emAfDeviceTableSendCieAddressWrite(EmberNodeId nodeId, uint8_t endpoint) {
{ EmberEUI64 eui64;
EmberEUI64 eui64; uint8_t outgoingBuffer[15];
uint8_t outgoingBuffer[15]; uint32_t i;
uint32_t i;
emberAfGetEui64(eui64);
emberAfGetEui64(eui64);
globalApsFrame.options = EMBER_AF_DEFAULT_APS_OPTIONS;
globalApsFrame.options = EMBER_AF_DEFAULT_APS_OPTIONS; globalApsFrame.clusterId = ZCL_IAS_ZONE_CLUSTER_ID;
globalApsFrame.clusterId = ZCL_IAS_ZONE_CLUSTER_ID; globalApsFrame.sourceEndpoint = 0x01;
globalApsFrame.sourceEndpoint = 0x01; globalApsFrame.destinationEndpoint = endpoint;
globalApsFrame.destinationEndpoint = endpoint;
outgoingBuffer[0] = 0x00;
outgoingBuffer[0] = 0x00; outgoingBuffer[1] = emberAfNextSequence();
outgoingBuffer[1] = emberAfNextSequence(); outgoingBuffer[2] = ZCL_WRITE_ATTRIBUTES_COMMAND_ID;
outgoingBuffer[2] = ZCL_WRITE_ATTRIBUTES_COMMAND_ID; outgoingBuffer[3] = LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID);
outgoingBuffer[3] = LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID); outgoingBuffer[4] = HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID);
outgoingBuffer[4] = HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID); outgoingBuffer[5] = ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE;
outgoingBuffer[5] = ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE;
for (i = 0; i < 8; i++) {
for (i = 0; i < 8; i++) { outgoingBuffer[6 + i] = eui64[i];
outgoingBuffer[6 + i] = eui64[i]; }
}
emberAfSendUnicast(EMBER_OUTGOING_DIRECT,
emberAfSendUnicast(EMBER_OUTGOING_DIRECT, nodeId,
nodeId, &globalApsFrame,
&globalApsFrame, 14,
14, outgoingBuffer);
outgoingBuffer); }
}
void emberAfDeviceTableCliIndexSendWithEndpoint(uint16_t index,
void emberAfDeviceTableCliIndexSendWithEndpoint(uint16_t index, uint8_t endpoint)
uint8_t endpoint) {
{ EmberNodeId nodeId;
EmberNodeId nodeId; EmberStatus status;
EmberStatus status;
nodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
nodeId = emberAfDeviceTableGetNodeIdFromIndex(index); emAfApsFrameEndpointSetup(emberAfPrimaryEndpoint(), endpoint);
emAfApsFrameEndpointSetup(emberAfPrimaryEndpoint(), endpoint); status = emberAfSendUnicast(EMBER_OUTGOING_DIRECT,
status = emberAfSendUnicast(EMBER_OUTGOING_DIRECT, nodeId,
nodeId, &globalApsFrame,
&globalApsFrame, appZclBufferLen,
appZclBufferLen, appZclBuffer);
appZclBuffer);
zclCmdIsBuilt = false;
zclCmdIsBuilt = false; }
}
void emberAfDeviceTableCliIndexSend(uint16_t index)
void emberAfDeviceTableCliIndexSend(uint16_t index) {
{ uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index);
uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index); emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint);
emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint); }
}
void emberAfDeviceTableSend(EmberEUI64 eui64, uint8_t endpoint)
void emberAfDeviceTableSend(EmberEUI64 eui64, uint8_t endpoint) {
{ uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64);
uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64);
if (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
if (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint);
emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint); }
} }
}
void emberAfDeviceTableCommandIndexSendWithEndpoint(uint16_t index,
void emberAfDeviceTableCommandIndexSendWithEndpoint(uint16_t index, uint8_t endpoint)
uint8_t endpoint) {
{ EmberNodeId nodeId;
EmberNodeId nodeId; EmberStatus status;
EmberStatus status;
nodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
nodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
if (emberAfCurrentCommand() == NULL) {
if (emberAfCurrentCommand() == NULL) { emAfCommandApsFrame->sourceEndpoint = emberAfPrimaryEndpoint();
emAfCommandApsFrame->sourceEndpoint = emberAfPrimaryEndpoint(); } else {
} else { emAfCommandApsFrame->sourceEndpoint = emberAfCurrentEndpoint();
emAfCommandApsFrame->sourceEndpoint = emberAfCurrentEndpoint(); }
}
emAfCommandApsFrame->destinationEndpoint = endpoint;
emAfCommandApsFrame->destinationEndpoint = endpoint; emberAfCorePrintln("device table send with ep: 0x%2X, %d",
emberAfCorePrintln("device table send with ep: 0x%2X, %d", nodeId,
nodeId, endpoint);
endpoint); status = emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, nodeId);
status = emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, nodeId);
zclCmdIsBuilt = false;
zclCmdIsBuilt = false; }
}
void emberAfDeviceTableCommandIndexSend(uint16_t index)
void emberAfDeviceTableCommandIndexSend(uint16_t index) {
{ uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index);
uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index); emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint);
emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint); }
}
void emberAfDeviceTableCommandSendWithEndpoint(EmberEUI64 eui64,
void emberAfDeviceTableCommandSendWithEndpoint(EmberEUI64 eui64, uint8_t endpoint)
uint8_t endpoint) {
{ uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64);
uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64); emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint);
emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint); }
}
// ******************************************************************* // *******************************************************************
// * af-main-host.c // * af-main-host.c
// * // *
// * // *
// * Copyright 2007 by Ember Corporation. All rights reserved. *80* // * Copyright 2007 by Ember Corporation. All rights reserved. *80*
// ******************************************************************* // *******************************************************************
#include "app/framework/include/af.h" #include "app/framework/include/af.h"
// ZCL - ZigBee Cluster Library // ZCL - ZigBee Cluster Library
#include "app/framework/util/attribute-storage.h" #include "app/framework/util/attribute-storage.h"
#include "app/framework/util/util.h" #include "app/framework/util/util.h"
#include "app/framework/util/af-event.h" #include "app/framework/util/af-event.h"
// ZDO - ZigBee Device Object // ZDO - ZigBee Device Object
#include "app/util/zigbee-framework/zigbee-device-common.h" #include "app/util/zigbee-framework/zigbee-device-common.h"
#include "app/util/zigbee-framework/zigbee-device-host.h" #include "app/util/zigbee-framework/zigbee-device-host.h"
// Service discovery library // Service discovery library
#include "service-discovery.h" #include "service-discovery.h"
// Fragmentation // Fragmentation
#ifdef EMBER_AF_PLUGIN_FRAGMENTATION #ifdef EMBER_AF_PLUGIN_FRAGMENTATION
#include "app/framework/plugin/fragmentation/fragmentation.h" #include "app/framework/plugin/fragmentation/fragmentation.h"
#endif #endif
#include "app/framework/plugin/concentrator/source-route-host.h" #include "app/framework/plugin/concentrator/source-route-host.h"
// determines the number of in-clusters and out-clusters based on defines // determines the number of in-clusters and out-clusters based on defines
// in config.h // in config.h
#include "app/framework/util/af-main.h" #include "app/framework/util/af-main.h"
// Needed for zaTrustCenterSecurityPolicyInit() // Needed for zaTrustCenterSecurityPolicyInit()
#include "app/framework/security/af-security.h" #include "app/framework/security/af-security.h"
#ifdef GATEWAY_APP #ifdef GATEWAY_APP
#define COMMAND_INTERPRETER_SUPPORT #define COMMAND_INTERPRETER_SUPPORT
#include "app/util/gateway/gateway.h" #include "app/util/gateway/gateway.h"
#endif #endif
#include "app/util/security/security.h" // Trust Center Address Cache #include "app/util/security/security.h" // Trust Center Address Cache
#include "app/util/common/form-and-join.h" #include "app/util/common/form-and-join.h"
#include "app/framework/plugin/partner-link-key-exchange/partner-link-key-exchange.h" #include "app/framework/plugin/partner-link-key-exchange/partner-link-key-exchange.h"
#include "app/util/common/library.h" #include "app/util/common/library.h"
#include "app/framework/security/crypto-state.h" #include "app/framework/security/crypto-state.h"
#include "afv2-bookkeeping.h" #include "afv2-bookkeeping.h"
#include "yjq_ezsp.h" #include "yjq_ezsp.h"
#include "./rpc_api/inc/rpc_interface_parse.h" #include "./rpc_api/inc/rpc_interface_parse.h"
#include <pthread.h> #include <pthread.h>
pthread_mutex_t g_mutex_lock; pthread_mutex_t g_mutex_lock;
//#include <stdio.h> //#include <stdio.h>
// This is used to store the local EUI of the NCP when using // This is used to store the local EUI of the NCP when using
// fake certificates. // fake certificates.
// Fake certificates are constructed by setting the data to all F's // Fake certificates are constructed by setting the data to all F's
// but using the device's real IEEE in the cert. The Key establishment // but using the device's real IEEE in the cert. The Key establishment
// code requires access to the local IEEE to do this. // code requires access to the local IEEE to do this.
EmberEUI64 emLocalEui64; EmberEUI64 emLocalEui64;
// APP_SERIAL is set in the project files // APP_SERIAL is set in the project files
uint8_t serialPort = APP_SERIAL; uint8_t serialPort = APP_SERIAL;
typedef struct { typedef struct {
EmberNodeId nodeId; EmberNodeId nodeId;
EmberPanId panId; EmberPanId panId;
EmberNetworkStatus networkState; EmberNetworkStatus networkState;
uint8_t radioChannel; uint8_t radioChannel;
} NetworkCache; } NetworkCache;
static NetworkCache networkCache[EMBER_SUPPORTED_NETWORKS]; static NetworkCache networkCache[EMBER_SUPPORTED_NETWORKS];
#define UNKNOWN_NETWORK_STATE 0xFF #define UNKNOWN_NETWORK_STATE 0xFF
// the stack version that the NCP is running // the stack version that the NCP is running
static uint16_t ncpStackVer; static uint16_t ncpStackVer;
#if defined(EMBER_TEST) #if defined(EMBER_TEST)
#define EMBER_TEST_ASSERT(x) assert(x) #define EMBER_TEST_ASSERT(x) assert(x)
#else #else
#define EMBER_TEST_ASSERT(x) #define EMBER_TEST_ASSERT(x)
#endif #endif
#if defined(EMBER_AF_PLUGIN_CONCENTRATOR) #if defined(EMBER_AF_PLUGIN_CONCENTRATOR)
#define SOURCE_ROUTE_TABLE_SIZE EMBER_SOURCE_ROUTE_TABLE_SIZE #define SOURCE_ROUTE_TABLE_SIZE EMBER_SOURCE_ROUTE_TABLE_SIZE
#else #else
// Define a small size that will not consume much memory on NCP // Define a small size that will not consume much memory on NCP
#define SOURCE_ROUTE_TABLE_SIZE 2 #define SOURCE_ROUTE_TABLE_SIZE 2
#endif #endif
// ****************************************************************** // ******************************************************************
// Globals // Globals
// when this is set to true it means the NCP has reported a serious error // when this is set to true it means the NCP has reported a serious error
// and the host needs to reset and re-init the NCP // and the host needs to reset and re-init the NCP
static bool ncpNeedsResetAndInit = false; static bool ncpNeedsResetAndInit = false;
// Declarations related to idling // Declarations related to idling
#ifndef EMBER_TASK_COUNT #ifndef EMBER_TASK_COUNT
#define EMBER_TASK_COUNT (3) #define EMBER_TASK_COUNT (3)
#endif #endif
EmberTaskControl emTasks[EMBER_TASK_COUNT]; EmberTaskControl emTasks[EMBER_TASK_COUNT];
PGM uint8_t emTaskCount = EMBER_TASK_COUNT; PGM uint8_t emTaskCount = EMBER_TASK_COUNT;
#if defined (GATEWAY_APP) #if defined (GATEWAY_APP)
// Baud rate on the gateway application is meaningless, but we must // Baud rate on the gateway application is meaningless, but we must
// define it satisfy compilation. // define it satisfy compilation.
#define BAUD_RATE BAUD_115200 #define BAUD_RATE BAUD_115200
// Port 1 on the gateway application is used for CLI, while port 0 // Port 1 on the gateway application is used for CLI, while port 0
// is used for "raw" binary. We ignore what was set via App. Builder // is used for "raw" binary. We ignore what was set via App. Builder
// since only port 1 is used by the application. // since only port 1 is used by the application.
#undef APP_SERIAL #undef APP_SERIAL
#define APP_SERIAL 1 #define APP_SERIAL 1
#elif (EMBER_AF_BAUD_RATE == 300) #elif (EMBER_AF_BAUD_RATE == 300)
#define BAUD_RATE BAUD_300 #define BAUD_RATE BAUD_300
#elif (EMBER_AF_BAUD_RATE == 600) #elif (EMBER_AF_BAUD_RATE == 600)
#define BAUD_RATE BAUD_600 #define BAUD_RATE BAUD_600
#elif (EMBER_AF_BAUD_RATE == 900) #elif (EMBER_AF_BAUD_RATE == 900)
#define BAUD_RATE BAUD_900 #define BAUD_RATE BAUD_900
#elif (EMBER_AF_BAUD_RATE == 1200) #elif (EMBER_AF_BAUD_RATE == 1200)
#define BAUD_RATE BAUD_1200 #define BAUD_RATE BAUD_1200
#elif (EMBER_AF_BAUD_RATE == 2400) #elif (EMBER_AF_BAUD_RATE == 2400)
#define BAUD_RATE BAUD_2400 #define BAUD_RATE BAUD_2400
#elif (EMBER_AF_BAUD_RATE == 4800) #elif (EMBER_AF_BAUD_RATE == 4800)
#define BAUD_RATE BAUD_4800 #define BAUD_RATE BAUD_4800
#elif (EMBER_AF_BAUD_RATE == 9600) #elif (EMBER_AF_BAUD_RATE == 9600)
#define BAUD_RATE BAUD_9600 #define BAUD_RATE BAUD_9600
#elif (EMBER_AF_BAUD_RATE == 14400) #elif (EMBER_AF_BAUD_RATE == 14400)
#define BAUD_RATE BAUD_14400 #define BAUD_RATE BAUD_14400
#elif (EMBER_AF_BAUD_RATE == 19200) #elif (EMBER_AF_BAUD_RATE == 19200)
#define BAUD_RATE BAUD_19200 #define BAUD_RATE BAUD_19200
#elif (EMBER_AF_BAUD_RATE == 28800) #elif (EMBER_AF_BAUD_RATE == 28800)
#define BAUD_RATE BAUD_28800 #define BAUD_RATE BAUD_28800
#elif (EMBER_AF_BAUD_RATE == 38400) #elif (EMBER_AF_BAUD_RATE == 38400)
#define BAUD_RATE BAUD_38400 #define BAUD_RATE BAUD_38400
#elif (EMBER_AF_BAUD_RATE == 50000) #elif (EMBER_AF_BAUD_RATE == 50000)
#define BAUD_RATE BAUD_50000 #define BAUD_RATE BAUD_50000
#elif (EMBER_AF_BAUD_RATE == 57600) #elif (EMBER_AF_BAUD_RATE == 57600)
#define BAUD_RATE BAUD_57600 #define BAUD_RATE BAUD_57600
#elif (EMBER_AF_BAUD_RATE == 76800) #elif (EMBER_AF_BAUD_RATE == 76800)
#define BAUD_RATE BAUD_76800 #define BAUD_RATE BAUD_76800
#elif (EMBER_AF_BAUD_RATE == 100000) #elif (EMBER_AF_BAUD_RATE == 100000)
#define BAUD_RATE BAUD_100000 #define BAUD_RATE BAUD_100000
#elif (EMBER_AF_BAUD_RATE == 115200) #elif (EMBER_AF_BAUD_RATE == 115200)
#define BAUD_RATE BAUD_115200 #define BAUD_RATE BAUD_115200
#elif (EMBER_AF_BAUD_RATE == 230400) #elif (EMBER_AF_BAUD_RATE == 230400)
#define BAUD_RATE BAUD_230400 #define BAUD_RATE BAUD_230400
#elif (EMBER_AF_BAUD_RATE == 460800) #elif (EMBER_AF_BAUD_RATE == 460800)
#define BAUD_RATE BAUD_460800 #define BAUD_RATE BAUD_460800
#else #else
#error EMBER_AF_BAUD_RATE set to an invalid baud rate #error EMBER_AF_BAUD_RATE set to an invalid baud rate
#endif #endif
#define MAX_CLUSTER 58 #define MAX_CLUSTER 58
// We only get the sender EUI callback when the sender EUI is in the incoming // We only get the sender EUI callback when the sender EUI is in the incoming
// message. This keeps track of if the value in the variable is valid or not. // message. This keeps track of if the value in the variable is valid or not.
// This is set to VALID (true) when the callback happens and set to INVALID // This is set to VALID (true) when the callback happens and set to INVALID
// (false) at the end of IncomingMessageHandler. // (false) at the end of IncomingMessageHandler.
static bool currentSenderEui64IsValid; static bool currentSenderEui64IsValid;
static EmberEUI64 currentSenderEui64; static EmberEUI64 currentSenderEui64;
static EmberNodeId currentSender = EMBER_NULL_NODE_ID; static EmberNodeId currentSender = EMBER_NULL_NODE_ID;
static uint8_t currentBindingIndex = EMBER_NULL_BINDING; static uint8_t currentBindingIndex = EMBER_NULL_BINDING;
static uint8_t currentAddressIndex = EMBER_NULL_ADDRESS_TABLE_INDEX; static uint8_t currentAddressIndex = EMBER_NULL_ADDRESS_TABLE_INDEX;
#if defined(EMBER_TEST) && defined(EMBER_AF_PLUGIN_OTA_STORAGE_SIMPLE_EEPROM) #if defined(EMBER_TEST) && defined(EMBER_AF_PLUGIN_OTA_STORAGE_SIMPLE_EEPROM)
void emAfSetupFakeEepromForSimulation(void); void emAfSetupFakeEepromForSimulation(void);
#define SETUP_FAKE_EEPROM_FOR_SIMULATION() emAfSetupFakeEepromForSimulation() #define SETUP_FAKE_EEPROM_FOR_SIMULATION() emAfSetupFakeEepromForSimulation()
#else #else
#define SETUP_FAKE_EEPROM_FOR_SIMULATION() #define SETUP_FAKE_EEPROM_FOR_SIMULATION()
#endif #endif
#if defined(ZA_CLI_FULL) #if defined(ZA_CLI_FULL)
#define COMMAND_READER_INIT() emberCommandReaderInit() #define COMMAND_READER_INIT() emberCommandReaderInit()
#else #else
#define COMMAND_READER_INIT() #define COMMAND_READER_INIT()
#endif #endif
#if defined(MAIN_FUNCTION_HAS_STANDARD_ARGUMENTS) #if defined(MAIN_FUNCTION_HAS_STANDARD_ARGUMENTS)
#define APP_FRAMEWORK_MAIN_ARGUMENTS argc, argv #define APP_FRAMEWORK_MAIN_ARGUMENTS argc, argv
#else #else
#define APP_FRAMEWORK_MAIN_ARGUMENTS 0, NULL #define APP_FRAMEWORK_MAIN_ARGUMENTS 0, NULL
#endif #endif
static uint16_t cachedConfigIdValues[EZSP_CONFIG_ID_MAX + 1]; static uint16_t cachedConfigIdValues[EZSP_CONFIG_ID_MAX + 1];
static bool cacheConfigIdValuesAllowed = false; static bool cacheConfigIdValuesAllowed = false;
static uint8_t ezspSequenceNumber = 0; static uint8_t ezspSequenceNumber = 0;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Forward declarations // Forward declarations
#ifdef EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_DECLARATIONS #ifdef EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_DECLARATIONS
EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_DECLARATIONS EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_DECLARATIONS
#endif #endif
static void createEndpoint(uint8_t endpointIndex); static void createEndpoint(uint8_t endpointIndex);
static uint8_t ezspNextSequence(void); static uint8_t ezspNextSequence(void);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Functions // Functions
bool emberAfMemoryByteCompare(const uint8_t* pointer, uint8_t count, uint8_t byteValue) bool emberAfMemoryByteCompare(const uint8_t* pointer, uint8_t count, uint8_t byteValue)
{ {
uint8_t i; uint8_t i;
for (i = 0; i < count; i++, pointer++) { for (i = 0; i < count; i++, pointer++) {
if (*pointer != byteValue) { if (*pointer != byteValue) {
return false; return false;
} }
} }
return true; return true;
} }
static uint8_t ezspNextSequence(void) static uint8_t ezspNextSequence(void)
{ {
return ((++ezspSequenceNumber) & EMBER_AF_MESSAGE_TAG_MASK); return ((++ezspSequenceNumber) & EMBER_AF_MESSAGE_TAG_MASK);
} }
bool emberAfNcpNeedsReset(void) bool emberAfNcpNeedsReset(void)
{ {
return ncpNeedsResetAndInit; return ncpNeedsResetAndInit;
} }
// Because an EZSP call can be expensive in terms of bandwidth, // Because an EZSP call can be expensive in terms of bandwidth,
// we cache the node ID so it can be quickly retrieved by the host. // we cache the node ID so it can be quickly retrieved by the host.
EmberNodeId emberAfGetNodeId(void) EmberNodeId emberAfGetNodeId(void)
{ {
uint8_t networkIndex = emberGetCurrentNetwork(); uint8_t networkIndex = emberGetCurrentNetwork();
if (networkCache[networkIndex].nodeId == EMBER_NULL_NODE_ID) { if (networkCache[networkIndex].nodeId == EMBER_NULL_NODE_ID) {
networkCache[networkIndex].nodeId = emberGetNodeId();//yjq:the function useful networkCache[networkIndex].nodeId = emberGetNodeId();//yjq:the function useful
} }
return networkCache[networkIndex].nodeId; return networkCache[networkIndex].nodeId;
} }
EmberPanId emberAfGetPanId(void) EmberPanId emberAfGetPanId(void)
{ {
uint8_t networkIndex = emberGetCurrentNetwork(); uint8_t networkIndex = emberGetCurrentNetwork();
if (networkCache[networkIndex].panId == 0xFFFF) { if (networkCache[networkIndex].panId == 0xFFFF) {
EmberNodeType nodeType; EmberNodeType nodeType;
EmberNetworkParameters parameters; EmberNetworkParameters parameters;
emberAfGetNetworkParameters(&nodeType, &parameters); emberAfGetNetworkParameters(&nodeType, &parameters);
networkCache[networkIndex].panId = parameters.panId; networkCache[networkIndex].panId = parameters.panId;
} }
return networkCache[networkIndex].panId; return networkCache[networkIndex].panId;
} }
EmberNetworkStatus emberAfNetworkState(void) EmberNetworkStatus emberAfNetworkState(void)
{ {
uint8_t networkIndex = emberGetCurrentNetwork(); uint8_t networkIndex = emberGetCurrentNetwork();
if (networkCache[networkIndex].networkState == UNKNOWN_NETWORK_STATE) { if (networkCache[networkIndex].networkState == UNKNOWN_NETWORK_STATE) {
networkCache[networkIndex].networkState = emberNetworkState(); networkCache[networkIndex].networkState = emberNetworkState();
} }
return networkCache[networkIndex].networkState; return networkCache[networkIndex].networkState;
} }
uint8_t emberAfGetRadioChannel(void) uint8_t emberAfGetRadioChannel(void)
{ {
uint8_t networkIndex = emberGetCurrentNetwork(); uint8_t networkIndex = emberGetCurrentNetwork();
if (networkCache[networkIndex].radioChannel == 0xFF) { if (networkCache[networkIndex].radioChannel == 0xFF) {
EmberNodeType nodeType; EmberNodeType nodeType;
EmberNetworkParameters parameters; EmberNetworkParameters parameters;
emberAfGetNetworkParameters(&nodeType, &parameters); emberAfGetNetworkParameters(&nodeType, &parameters);
networkCache[networkIndex].radioChannel = parameters.radioChannel; networkCache[networkIndex].radioChannel = parameters.radioChannel;
} }
return networkCache[networkIndex].radioChannel; return networkCache[networkIndex].radioChannel;
} }
void emberAfGetMfgString(uint8_t* returnData) void emberAfGetMfgString(uint8_t* returnData)
{ {
static uint8_t mfgString[MFG_STRING_MAX_LENGTH]; static uint8_t mfgString[MFG_STRING_MAX_LENGTH];
static bool mfgStringRetrieved = false; static bool mfgStringRetrieved = false;
if (mfgStringRetrieved == false) { if (mfgStringRetrieved == false) {
ezspGetMfgToken(EZSP_MFG_STRING, mfgString); ezspGetMfgToken(EZSP_MFG_STRING, mfgString);
mfgStringRetrieved = true; mfgStringRetrieved = true;
} }
// NOTE: The MFG string is not NULL terminated. // NOTE: The MFG string is not NULL terminated.
MEMMOVE(returnData, mfgString, MFG_STRING_MAX_LENGTH); MEMMOVE(returnData, mfgString, MFG_STRING_MAX_LENGTH);
} }
void emAfClearNetworkCache(uint8_t networkIndex) void emAfClearNetworkCache(uint8_t networkIndex)
{ {
networkCache[networkIndex].nodeId = EMBER_NULL_NODE_ID; networkCache[networkIndex].nodeId = EMBER_NULL_NODE_ID;
networkCache[networkIndex].panId = 0xFFFF; networkCache[networkIndex].panId = 0xFFFF;
networkCache[networkIndex].networkState = UNKNOWN_NETWORK_STATE; networkCache[networkIndex].networkState = UNKNOWN_NETWORK_STATE;
networkCache[networkIndex].radioChannel = 0xFF; networkCache[networkIndex].radioChannel = 0xFF;
} }
// Some NCP's support a 'maximize packet buffer' call. If that doesn't // Some NCP's support a 'maximize packet buffer' call. If that doesn't
// work, slowly ratchet up the packet buffer count. // work, slowly ratchet up the packet buffer count.
static void setPacketBufferCount(void) static void setPacketBufferCount(void)
{ {
uint16_t value; uint16_t value;
EzspStatus ezspStatus; EzspStatus ezspStatus;
EzspStatus maxOutBufferStatus; EzspStatus maxOutBufferStatus;
maxOutBufferStatus maxOutBufferStatus
= ezspSetConfigurationValue(EZSP_CONFIG_PACKET_BUFFER_COUNT, = ezspSetConfigurationValue(EZSP_CONFIG_PACKET_BUFFER_COUNT,
EZSP_MAXIMIZE_PACKET_BUFFER_COUNT); EZSP_MAXIMIZE_PACKET_BUFFER_COUNT);
// We start from the default used by the NCP and increase up from there // We start from the default used by the NCP and increase up from there
// rather than use a hard coded default in the code. // rather than use a hard coded default in the code.
// This is more portable to different NCP hardware (i.e. 357 vs. 260). // This is more portable to different NCP hardware (i.e. 357 vs. 260).
ezspStatus = ezspGetConfigurationValue(EZSP_CONFIG_PACKET_BUFFER_COUNT, ezspStatus = ezspGetConfigurationValue(EZSP_CONFIG_PACKET_BUFFER_COUNT,
&value); &value);
if (maxOutBufferStatus == EZSP_SUCCESS) { if (maxOutBufferStatus == EZSP_SUCCESS) {
emberAfAppPrintln("NCP supports maxing out packet buffers"); emberAfAppPrintln("NCP supports maxing out packet buffers");
goto setPacketBufferCountDone; goto setPacketBufferCountDone;
} }
while (ezspStatus == EZSP_SUCCESS) { while (ezspStatus == EZSP_SUCCESS) {
value++; value++;
ezspStatus = ezspSetConfigurationValue(EZSP_CONFIG_PACKET_BUFFER_COUNT, ezspStatus = ezspSetConfigurationValue(EZSP_CONFIG_PACKET_BUFFER_COUNT,
value); value);
} }
setPacketBufferCountDone: setPacketBufferCountDone:
emberAfAppPrintln("Ezsp Config: set packet buffers to %d", emberAfAppPrintln("Ezsp Config: set packet buffers to %d",
maxOutBufferStatus == EZSP_SUCCESS maxOutBufferStatus == EZSP_SUCCESS
? value ? value
: (value - 1)); : (value - 1));
emberAfAppFlush(); emberAfAppFlush();
} }
// initialize the network co-processor (NCP) // initialize the network co-processor (NCP)
void emAfResetAndInitNCP(void) void emAfResetAndInitNCP(void)
{ {
uint8_t ep; uint8_t ep;
EzspStatus ezspStatus; EzspStatus ezspStatus;
bool memoryAllocation; bool memoryAllocation;
uint16_t seed0, seed1; uint16_t seed0, seed1;
emberAfPreNcpResetCallback(); emberAfPreNcpResetCallback();
// ezspInit resets the NCP by calling halNcpHardReset on a SPI host or // ezspInit resets the NCP by calling halNcpHardReset on a SPI host or
// ashResetNcp on a UART host // ashResetNcp on a UART host
ezspStatus = ezspInit(); ezspStatus = ezspInit();
if (ezspStatus != EZSP_SUCCESS) { if (ezspStatus != EZSP_SUCCESS) {
emberAfCorePrintln("ERROR: ezspForceReset 0x%x", ezspStatus); emberAfCorePrintln("ERROR: ezspForceReset 0x%x", ezspStatus);
emberAfCoreFlush(); emberAfCoreFlush();
//assert(false); //assert(false);
printf("[%s][%d]\n",__FUNCTION__,__LINE__); printf("[%s][%d]\n",__FUNCTION__,__LINE__);
return; return;
} }
// send the version command before any other commands // send the version command before any other commands
emAfCliVersionCommand(); emAfCliVersionCommand();
emSecureEzspInit(); emSecureEzspInit();
// The random number generator on the host needs to be seeded with some // The random number generator on the host needs to be seeded with some
// random data, which we can get from the NCP. // random data, which we can get from the NCP.
ezspGetRandomNumber(&seed0); ezspGetRandomNumber(&seed0);
ezspGetRandomNumber(&seed1); ezspGetRandomNumber(&seed1);
halStackSeedRandom(((uint32_t)seed1 << 16) | (uint32_t)seed0); halStackSeedRandom(((uint32_t)seed1 << 16) | (uint32_t)seed0);
// set the source route table size // set the source route table size
emberAfSetEzspConfigValue(EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE, emberAfSetEzspConfigValue(EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE,
SOURCE_ROUTE_TABLE_SIZE, SOURCE_ROUTE_TABLE_SIZE,
"source route table size"); "source route table size");
emberAfSetEzspConfigValue(EZSP_CONFIG_SECURITY_LEVEL, emberAfSetEzspConfigValue(EZSP_CONFIG_SECURITY_LEVEL,
EMBER_SECURITY_LEVEL, EMBER_SECURITY_LEVEL,
"security level"); "security level");
// set the address table size // set the address table size
emberAfSetEzspConfigValue(EZSP_CONFIG_ADDRESS_TABLE_SIZE, emberAfSetEzspConfigValue(EZSP_CONFIG_ADDRESS_TABLE_SIZE,
EMBER_AF_PLUGIN_ADDRESS_TABLE_SIZE, EMBER_AF_PLUGIN_ADDRESS_TABLE_SIZE,
"address table size"); "address table size");
// set the trust center address cache size // set the trust center address cache size
emberAfSetEzspConfigValue(EZSP_CONFIG_TRUST_CENTER_ADDRESS_CACHE_SIZE, emberAfSetEzspConfigValue(EZSP_CONFIG_TRUST_CENTER_ADDRESS_CACHE_SIZE,
EMBER_AF_PLUGIN_ADDRESS_TABLE_TRUST_CENTER_CACHE_SIZE, EMBER_AF_PLUGIN_ADDRESS_TABLE_TRUST_CENTER_CACHE_SIZE,
"TC addr cache"); "TC addr cache");
// the stack profile is defined in the config file // the stack profile is defined in the config file
emberAfSetEzspConfigValue(EZSP_CONFIG_STACK_PROFILE, emberAfSetEzspConfigValue(EZSP_CONFIG_STACK_PROFILE,
EMBER_STACK_PROFILE, EMBER_STACK_PROFILE,
"stack profile"); "stack profile");
// BUG 14222: If stack profile is 2 (ZigBee Pro), we need to enforce // BUG 14222: If stack profile is 2 (ZigBee Pro), we need to enforce
// the standard stack configuration values for that feature set. // the standard stack configuration values for that feature set.
if ( EMBER_STACK_PROFILE == 2 ) { if ( EMBER_STACK_PROFILE == 2 ) {
// MAC indirect timeout should be 7.68 secs // MAC indirect timeout should be 7.68 secs
emberAfSetEzspConfigValue(EZSP_CONFIG_INDIRECT_TRANSMISSION_TIMEOUT, emberAfSetEzspConfigValue(EZSP_CONFIG_INDIRECT_TRANSMISSION_TIMEOUT,
7680, 7680,
"MAC indirect TX timeout"); "MAC indirect TX timeout");
// Max hops should be 2 * nwkMaxDepth, where nwkMaxDepth is 15 // Max hops should be 2 * nwkMaxDepth, where nwkMaxDepth is 15
emberAfSetEzspConfigValue(EZSP_CONFIG_MAX_HOPS, emberAfSetEzspConfigValue(EZSP_CONFIG_MAX_HOPS,
30, 30,
"max hops"); "max hops");
} }
emberAfSetEzspConfigValue(EZSP_CONFIG_TX_POWER_MODE, emberAfSetEzspConfigValue(EZSP_CONFIG_TX_POWER_MODE,
EMBER_AF_TX_POWER_MODE, EMBER_AF_TX_POWER_MODE,
"tx power mode"); "tx power mode");
emberAfSetEzspConfigValue(EZSP_CONFIG_SUPPORTED_NETWORKS, emberAfSetEzspConfigValue(EZSP_CONFIG_SUPPORTED_NETWORKS,
EMBER_SUPPORTED_NETWORKS, EMBER_SUPPORTED_NETWORKS,
"supported networks"); "supported networks");
// allow other devices to modify the binding table // allow other devices to modify the binding table
emberAfSetEzspPolicy(EZSP_BINDING_MODIFICATION_POLICY, emberAfSetEzspPolicy(EZSP_BINDING_MODIFICATION_POLICY,
EZSP_CHECK_BINDING_MODIFICATIONS_ARE_VALID_ENDPOINT_CLUSTERS, EZSP_CHECK_BINDING_MODIFICATIONS_ARE_VALID_ENDPOINT_CLUSTERS,
"binding modify", "binding modify",
"allow for valid endpoints & clusters only"); "allow for valid endpoints & clusters only");
// return message tag and message contents in ezspMessageSentHandler() // return message tag and message contents in ezspMessageSentHandler()
emberAfSetEzspPolicy(EZSP_MESSAGE_CONTENTS_IN_CALLBACK_POLICY, emberAfSetEzspPolicy(EZSP_MESSAGE_CONTENTS_IN_CALLBACK_POLICY,
EZSP_MESSAGE_TAG_AND_CONTENTS_IN_CALLBACK, EZSP_MESSAGE_TAG_AND_CONTENTS_IN_CALLBACK,
"message content in msgSent", "message content in msgSent",
"return"); "return");
{ {
uint8_t value[2]; uint8_t value[2];
value[0] = LOW_BYTE(EMBER_AF_INCOMING_BUFFER_LENGTH); value[0] = LOW_BYTE(EMBER_AF_INCOMING_BUFFER_LENGTH);
value[1] = HIGH_BYTE(EMBER_AF_INCOMING_BUFFER_LENGTH); value[1] = HIGH_BYTE(EMBER_AF_INCOMING_BUFFER_LENGTH);
emberAfSetEzspValue(EZSP_VALUE_MAXIMUM_INCOMING_TRANSFER_SIZE, emberAfSetEzspValue(EZSP_VALUE_MAXIMUM_INCOMING_TRANSFER_SIZE,
2, // value length 2, // value length
value, value,
"maximum incoming transfer size"); "maximum incoming transfer size");
value[0] = LOW_BYTE(EMBER_AF_MAXIMUM_SEND_PAYLOAD_LENGTH); value[0] = LOW_BYTE(EMBER_AF_MAXIMUM_SEND_PAYLOAD_LENGTH);
value[1] = HIGH_BYTE(EMBER_AF_MAXIMUM_SEND_PAYLOAD_LENGTH); value[1] = HIGH_BYTE(EMBER_AF_MAXIMUM_SEND_PAYLOAD_LENGTH);
emberAfSetEzspValue(EZSP_VALUE_MAXIMUM_OUTGOING_TRANSFER_SIZE, emberAfSetEzspValue(EZSP_VALUE_MAXIMUM_OUTGOING_TRANSFER_SIZE,
2, // value length 2, // value length
value, value,
"maximum outgoing transfer size"); "maximum outgoing transfer size");
} }
// Set the manufacturing code. This is defined by ZigBee document 053874r10 // Set the manufacturing code. This is defined by ZigBee document 053874r10
// Ember's ID is 0x1002 and is the default, but this can be overridden in App Builder. // Ember's ID is 0x1002 and is the default, but this can be overridden in App Builder.
emberSetManufacturerCode(EMBER_AF_MANUFACTURER_CODE); emberSetManufacturerCode(EMBER_AF_MANUFACTURER_CODE);
// Call the plugin and user-specific NCP inits. This is when configuration // Call the plugin and user-specific NCP inits. This is when configuration
// that affects table sizes should occur, which means it must happen before // that affects table sizes should occur, which means it must happen before
// setPacketBufferCount. // setPacketBufferCount.
memoryAllocation = true; memoryAllocation = true;
#ifdef EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_CALLS #ifdef EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_CALLS
EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_CALLS EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_CALLS
#endif #endif
emberAfNcpInitCallback(memoryAllocation); emberAfNcpInitCallback(memoryAllocation);
setPacketBufferCount(); setPacketBufferCount();
// Call the plugin and user-specific NCP inits again. This is where non- // Call the plugin and user-specific NCP inits again. This is where non-
// sizing configuration should occur. // sizing configuration should occur.
memoryAllocation = false; memoryAllocation = false;
#ifdef EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_CALLS #ifdef EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_CALLS
EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_CALLS EMBER_AF_GENERATED_PLUGIN_NCP_INIT_FUNCTION_CALLS
#endif #endif
emberAfNcpInitCallback(memoryAllocation); emberAfNcpInitCallback(memoryAllocation);
// create endpoints // create endpoints
for ( ep = 0; ep < emberAfEndpointCount(); ep++ ) { for ( ep = 0; ep < emberAfEndpointCount(); ep++ ) {
createEndpoint(ep); createEndpoint(ep);
} }
EM_AF_NETWORK_INIT(); EM_AF_NETWORK_INIT();
MEMSET(cachedConfigIdValues, 0xFF, ((EZSP_CONFIG_ID_MAX + 1) * sizeof(uint16_t))); MEMSET(cachedConfigIdValues, 0xFF, ((EZSP_CONFIG_ID_MAX + 1) * sizeof(uint16_t)));
cacheConfigIdValuesAllowed = true; cacheConfigIdValuesAllowed = true;
// Set the localEui64 global // Set the localEui64 global
ezspGetEui64(emLocalEui64); ezspGetEui64(emLocalEui64);
// Initialize messageSentCallbacks table // Initialize messageSentCallbacks table
emAfInitializeMessageSentCallbackArray(); emAfInitializeMessageSentCallbackArray();
} }
// ******************************************************************* // *******************************************************************
// ******************************************************************* // *******************************************************************
// The main() loop and the application's contribution. // The main() loop and the application's contribution.
void emberAfMainInit(void) void emberAfMainInit(void)
{ {
} }
int emberAfMain(MAIN_FUNCTION_PARAMETERS) int emberAfMain(MAIN_FUNCTION_PARAMETERS)
{ {
SETUP_FAKE_EEPROM_FOR_SIMULATION(); SETUP_FAKE_EEPROM_FOR_SIMULATION();
//Initialize the hal //Initialize the hal
halInit(); halInit();
INTERRUPTS_ON(); // Safe to enable interrupts at this point INTERRUPTS_ON(); // Safe to enable interrupts at this point
{ {
int returnCode; int returnCode;
if (emberAfMainStartCallback(&returnCode, if (emberAfMainStartCallback(&returnCode,
APP_FRAMEWORK_MAIN_ARGUMENTS)) { //get serial port info APP_FRAMEWORK_MAIN_ARGUMENTS)) { //get serial port info
return returnCode; return returnCode;
} }
} }
kk_print("*******************123****************\r\n"); kk_print("*******************123****************\r\n");
kk_print_info("\r\n-----hello world![%s:%s]-----\r\n",__DATE__,__TIME__); kk_print_info("\r\n-----hello world![%s:%s]-----\r\n",__DATE__,__TIME__);
kk_print_version(); kk_print_version();
emberSerialInit(APP_SERIAL, BAUD_RATE, PARITY_NONE, 1); //fock child process emberSerialInit(APP_SERIAL, BAUD_RATE, PARITY_NONE, 1); //fock child process
emberAfAppPrintln("Reset info: %d (%p)", emberAfAppPrintln("Reset info: %d (%p)",
halGetResetInfo(), halGetResetInfo(),
halGetResetString()); halGetResetString());
int ret = pthread_mutex_init(&g_mutex_lock, NULL); int ret = pthread_mutex_init(&g_mutex_lock, NULL);
if (ret != 0) { if (ret != 0) {
printf("mutex init failed\n"); printf("mutex init failed\n");
return -1; return -1;
} }
/*int pid=fork(); /*int pid=fork();
if(pid==0){ if(pid==0){
rpcInterfaceParse(); rpcInterfaceParse();
}*/ }*/
emberAfCoreFlush(); emberAfCoreFlush();
// This will initialize the stack of networks maintained by the framework, // This will initialize the stack of networks maintained by the framework,
// including setting the default network. // including setting the default network.
emAfInitializeNetworkIndexStack(); emAfInitializeNetworkIndexStack();
// We must initialize the endpoint information first so // We must initialize the endpoint information first so
// that they are correctly added by emAfResetAndInitNCP() // that they are correctly added by emAfResetAndInitNCP()
emberAfEndpointConfigure(); emberAfEndpointConfigure();
// initialize the network co-processor (NCP) // initialize the network co-processor (NCP)
emAfResetAndInitNCP(); emAfResetAndInitNCP();
printf("[%s][%d]\n",__FUNCTION__,__LINE__); printf("[%s][%d]\n",__FUNCTION__,__LINE__);
EmberEUI64 eui64; EmberEUI64 eui64;
emberAfGetEui64(eui64); emberAfGetEui64(eui64);
emberAfCorePrintln("~~~~~~~~~~~~~~~~~~~~~NCP MAC:"); emberAfCorePrintln("~~~~~~~~~~~~~~~~~~~~~NCP MAC:");
emberAfPrintBigEndianEui64(eui64); emberAfPrintBigEndianEui64(eui64);
kk_network_check(); kk_network_check();
kk_tsl_init(eui64); kk_device_gateway_add(eui64);
pthread_t tid; pthread_t tid;
//pthread_create(&tid, NULL, rpcInterfaceParse, NULL); //pthread_create(&tid, NULL, rpcInterfaceParse, NULL);
pthread_create(&tid, NULL, ipcHandle, NULL); pthread_create(&tid, NULL, ipcHandle, NULL);
// initialize the ZCL framework ,(plug in) ,mqtt init is here // initialize the ZCL framework ,(plug in) ,mqtt init is here
emAfInit(); emAfInit();
COMMAND_READER_INIT(); COMMAND_READER_INIT();
// main loop // main loop
while (true) { while (true) {
halResetWatchdog(); // Periodically reset the watchdog. halResetWatchdog(); // Periodically reset the watchdog.
// see if the NCP has anything waiting to send us // see if the NCP has anything waiting to send us
ezspTick(); ezspTick();
while (ezspCallbackPending()) { while (ezspCallbackPending()) {
ezspCallback(); ezspCallback();
} }
// check if we have hit an EZSP Error and need to reset and init the NCP // check if we have hit an EZSP Error and need to reset and init the NCP
if (ncpNeedsResetAndInit) { if (ncpNeedsResetAndInit) {
ncpNeedsResetAndInit = false; ncpNeedsResetAndInit = false;
// re-initialize the NCP // re-initialize the NCP
emAfResetAndInitNCP(); emAfResetAndInitNCP();
} }
// Wait until ECC operations are done. Don't allow any of the clusters // Wait until ECC operations are done. Don't allow any of the clusters
// to send messages as the NCP is busy doing ECC // to send messages as the NCP is busy doing ECC
if (emAfIsCryptoOperationInProgress()) { if (emAfIsCryptoOperationInProgress()) {
continue; continue;
} }
// let the ZCL Utils run - this should go after ezspTick // let the ZCL Utils run - this should go after ezspTick
emAfTick(); emAfTick();
emberSerialBufferTick(); emberSerialBufferTick();
emberAfRunEvents(); emberAfRunEvents();
#if defined(ZA_CLI_FULL) #if defined(ZA_CLI_FULL)
if (emberProcessCommandInput(APP_SERIAL)) if (emberProcessCommandInput(APP_SERIAL))
{ {
#if !defined GATEWAY_APP #if !defined GATEWAY_APP
// Gateway app. has its own way of handling the command-line prompt. // Gateway app. has its own way of handling the command-line prompt.
emberAfGuaranteedPrint("%p>", ZA_PROMPT); emberAfGuaranteedPrint("%p>", ZA_PROMPT);
#endif #endif
} }
#endif #endif
#if defined(EMBER_TEST) #if defined(EMBER_TEST)
if (1) { if (1) {
// Simulation only // Simulation only
uint32_t timeToNextEventMax = emberMsToNextStackEvent(); uint32_t timeToNextEventMax = emberMsToNextStackEvent();
timeToNextEventMax = emberAfMsToNextEvent(timeToNextEventMax); timeToNextEventMax = emberAfMsToNextEvent(timeToNextEventMax);
simulatedTimePassesMs(timeToNextEventMax); simulatedTimePassesMs(timeToNextEventMax);
} }
#endif #endif
// After each interation through the main loop, our network index stack // After each interation through the main loop, our network index stack
// should be empty and we should be on the default network index again. // should be empty and we should be on the default network index again.
emAfAssertNetworkIndexStackIsEmpty(); emAfAssertNetworkIndexStackIsEmpty();
} }
return 0; return 0;
} }
// ****************************************************************** // ******************************************************************
// binding // binding
// ****************************************************************** // ******************************************************************
EmberStatus emberAfSendEndDeviceBind(uint8_t endpoint) EmberStatus emberAfSendEndDeviceBind(uint8_t endpoint)
{ {
EmberStatus status; EmberStatus status;
EmberEUI64 eui; EmberEUI64 eui;
uint8_t inClusterCount, outClusterCount; uint8_t inClusterCount, outClusterCount;
EmberAfClusterId clusterList[MAX_CLUSTER]; EmberAfClusterId clusterList[MAX_CLUSTER];
EmberAfClusterId *inClusterList; EmberAfClusterId *inClusterList;
EmberAfClusterId *outClusterList; EmberAfClusterId *outClusterList;
EmberAfProfileId profileId; EmberAfProfileId profileId;
EmberApsOption options = ((EMBER_AF_DEFAULT_APS_OPTIONS EmberApsOption options = ((EMBER_AF_DEFAULT_APS_OPTIONS
| EMBER_APS_OPTION_SOURCE_EUI64) | EMBER_APS_OPTION_SOURCE_EUI64)
& ~EMBER_APS_OPTION_RETRY); & ~EMBER_APS_OPTION_RETRY);
uint8_t index = emberAfIndexFromEndpoint(endpoint); uint8_t index = emberAfIndexFromEndpoint(endpoint);
if (index == 0xFF) { if (index == 0xFF) {
return EMBER_INVALID_ENDPOINT; return EMBER_INVALID_ENDPOINT;
} }
status = emberAfPushEndpointNetworkIndex(endpoint); status = emberAfPushEndpointNetworkIndex(endpoint);
if (status != EMBER_SUCCESS) { if (status != EMBER_SUCCESS) {
return status; return status;
} }
emberAfGetEui64(eui); emberAfGetEui64(eui);
emberAfZdoPrintln("send %x %2x ", endpoint, options); emberAfZdoPrintln("send %x %2x ", endpoint, options);
inClusterList = clusterList; inClusterList = clusterList;
inClusterCount = emberAfGetClustersFromEndpoint(endpoint, inClusterCount = emberAfGetClustersFromEndpoint(endpoint,
inClusterList, inClusterList,
MAX_CLUSTER, MAX_CLUSTER,
true); // server? true); // server?
outClusterList = clusterList + inClusterCount; outClusterList = clusterList + inClusterCount;
outClusterCount = emberAfGetClustersFromEndpoint(endpoint, outClusterCount = emberAfGetClustersFromEndpoint(endpoint,
outClusterList, outClusterList,
(MAX_CLUSTER (MAX_CLUSTER
- inClusterCount), - inClusterCount),
false); // server? false); // server?
profileId = emberAfProfileIdFromIndex(index); profileId = emberAfProfileIdFromIndex(index);
status = ezspEndDeviceBindRequest(emberAfGetNodeId(), status = ezspEndDeviceBindRequest(emberAfGetNodeId(),
eui, eui,
endpoint, endpoint,
profileId, profileId,
inClusterCount, // cluster in count inClusterCount, // cluster in count
outClusterCount, // cluster out count outClusterCount, // cluster out count
inClusterList, // list of input clusters inClusterList, // list of input clusters
outClusterList, // list of output clusters outClusterList, // list of output clusters
options); options);
emberAfZdoPrintln("done: %x.", status); emberAfZdoPrintln("done: %x.", status);
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
return status; return status;
} }
// ********************************************************************** // **********************************************************************
// this function sets an EZSP config value and prints out the results to // this function sets an EZSP config value and prints out the results to
// the serial output // the serial output
// ********************************************************************** // **********************************************************************
EzspStatus emberAfSetEzspConfigValue(EzspConfigId configId, EzspStatus emberAfSetEzspConfigValue(EzspConfigId configId,
uint16_t value, uint16_t value,
PGM_P configIdName) PGM_P configIdName)
{ {
EzspStatus ezspStatus = ezspSetConfigurationValue(configId, value); EzspStatus ezspStatus = ezspSetConfigurationValue(configId, value);
emberAfAppFlush(); emberAfAppFlush();
emberAfAppPrint("Ezsp Config: set %p to 0x%2x:", configIdName, value); emberAfAppPrint("Ezsp Config: set %p to 0x%2x:", configIdName, value);
emberAfAppDebugExec(emAfPrintStatus("set", ezspStatus)); emberAfAppDebugExec(emAfPrintStatus("set", ezspStatus));
emberAfAppFlush(); emberAfAppFlush();
emberAfAppPrintln(""); emberAfAppPrintln("");
emberAfAppFlush(); emberAfAppFlush();
// If this fails, odds are the simulated NCP doesn't have enough // If this fails, odds are the simulated NCP doesn't have enough
// memory allocated to it. // memory allocated to it.
EMBER_TEST_ASSERT(ezspStatus == EZSP_SUCCESS); EMBER_TEST_ASSERT(ezspStatus == EZSP_SUCCESS);
return ezspStatus; return ezspStatus;
} }
// ********************************************************************** // **********************************************************************
// this function sets an EZSP policy and prints out the results to // this function sets an EZSP policy and prints out the results to
// the serial output // the serial output
// ********************************************************************** // **********************************************************************
EzspStatus emberAfSetEzspPolicy(EzspPolicyId policyId, EzspStatus emberAfSetEzspPolicy(EzspPolicyId policyId,
EzspDecisionId decisionId, EzspDecisionId decisionId,
PGM_P policyName, PGM_P policyName,
PGM_P decisionName) PGM_P decisionName)
{ {
EzspStatus ezspStatus = ezspSetPolicy(policyId, EzspStatus ezspStatus = ezspSetPolicy(policyId,
decisionId); decisionId);
emberAfAppPrint("Ezsp Policy: set %p to \"%p\":", emberAfAppPrint("Ezsp Policy: set %p to \"%p\":",
policyName, policyName,
decisionName); decisionName);
emberAfAppDebugExec(emAfPrintStatus("set", emberAfAppDebugExec(emAfPrintStatus("set",
ezspStatus)); ezspStatus));
emberAfAppPrintln(""); emberAfAppPrintln("");
emberAfAppFlush(); emberAfAppFlush();
return ezspStatus; return ezspStatus;
} }
// ********************************************************************** // **********************************************************************
// this function sets an EZSP value and prints out the results to // this function sets an EZSP value and prints out the results to
// the serial output // the serial output
// ********************************************************************** // **********************************************************************
EzspStatus emberAfSetEzspValue(EzspValueId valueId, EzspStatus emberAfSetEzspValue(EzspValueId valueId,
uint8_t valueLength, uint8_t valueLength,
uint8_t *value, uint8_t *value,
PGM_P valueName) PGM_P valueName)
{ {
EzspStatus ezspStatus = ezspSetValue(valueId, valueLength, value); EzspStatus ezspStatus = ezspSetValue(valueId, valueLength, value);
emberAfAppPrint("Ezsp Value : set %p to ", valueName); emberAfAppPrint("Ezsp Value : set %p to ", valueName);
// print the value based on the length of the value // print the value based on the length of the value
// for length 1/2/4 bytes, fetch int of that length and promote to 32 bits for printing // for length 1/2/4 bytes, fetch int of that length and promote to 32 bits for printing
switch (valueLength) { switch (valueLength) {
case 1: case 1:
emberAfAppPrint("0x%4x:", (uint32_t)(*value)); emberAfAppPrint("0x%4x:", (uint32_t)(*value));
break; break;
case 2: case 2:
emberAfAppPrint("0x%4x:", (uint32_t)(*((uint16_t *)value))); emberAfAppPrint("0x%4x:", (uint32_t)(*((uint16_t *)value)));
break; break;
case 4: case 4:
emberAfAppPrint("0x%4x:", (uint32_t)(*((uint32_t *)value))); emberAfAppPrint("0x%4x:", (uint32_t)(*((uint32_t *)value)));
break; break;
default: default:
emberAfAppPrint("{val of len %x}:", valueLength); emberAfAppPrint("{val of len %x}:", valueLength);
break; break;
} }
emberAfAppDebugExec(emAfPrintStatus("set", ezspStatus)); emberAfAppDebugExec(emAfPrintStatus("set", ezspStatus));
emberAfAppPrintln(""); emberAfAppPrintln("");
emberAfAppFlush(); emberAfAppFlush();
return ezspStatus; return ezspStatus;
} }
// ****************************************************************** // ******************************************************************
// setup endpoints and clusters for responding to ZDO requests // setup endpoints and clusters for responding to ZDO requests
// ****************************************************************** // ******************************************************************
// //
// Creates the endpoint for 260 by calling ezspAddEndpoint() // Creates the endpoint for 260 by calling ezspAddEndpoint()
// //
static void createEndpoint(uint8_t endpointIndex) static void createEndpoint(uint8_t endpointIndex)
{ {
uint16_t clusterList[MAX_CLUSTER]; uint16_t clusterList[MAX_CLUSTER];
uint16_t *inClusterList; uint16_t *inClusterList;
uint16_t *outClusterList; uint16_t *outClusterList;
uint8_t endpoint = emberAfEndpointFromIndex(endpointIndex); uint8_t endpoint = emberAfEndpointFromIndex(endpointIndex);
uint8_t inClusterCount; uint8_t inClusterCount;
uint8_t outClusterCount; uint8_t outClusterCount;
{ {
EmberStatus status = emberAfPushEndpointNetworkIndex(endpoint); EmberStatus status = emberAfPushEndpointNetworkIndex(endpoint);
if (status != EMBER_SUCCESS) { if (status != EMBER_SUCCESS) {
emberAfAppPrintln("Error in creating endpoint %d: 0x%x", endpoint, status); emberAfAppPrintln("Error in creating endpoint %d: 0x%x", endpoint, status);
return; return;
} }
} }
// Lay out clusters in the arrays. // Lay out clusters in the arrays.
inClusterList = clusterList; inClusterList = clusterList;
inClusterCount = emberAfGetClustersFromEndpoint(endpoint, inClusterList, MAX_CLUSTER, true); inClusterCount = emberAfGetClustersFromEndpoint(endpoint, inClusterList, MAX_CLUSTER, true);
outClusterList = clusterList + inClusterCount; outClusterList = clusterList + inClusterCount;
outClusterCount = emberAfGetClustersFromEndpoint(endpoint, outClusterList, (MAX_CLUSTER - inClusterCount), false); outClusterCount = emberAfGetClustersFromEndpoint(endpoint, outClusterList, (MAX_CLUSTER - inClusterCount), false);
// Call EZSP function with data. // Call EZSP function with data.
{ {
EzspStatus status = ezspAddEndpoint(endpoint, EzspStatus status = ezspAddEndpoint(endpoint,
emberAfProfileIdFromIndex(endpointIndex), emberAfProfileIdFromIndex(endpointIndex),
emberAfDeviceIdFromIndex(endpointIndex), emberAfDeviceIdFromIndex(endpointIndex),
emberAfDeviceVersionFromIndex(endpointIndex), emberAfDeviceVersionFromIndex(endpointIndex),
inClusterCount, inClusterCount,
outClusterCount, outClusterCount,
(uint16_t *)inClusterList, (uint16_t *)inClusterList,
(uint16_t *)outClusterList); (uint16_t *)outClusterList);
if (status == EZSP_SUCCESS) { if (status == EZSP_SUCCESS) {
emberAfAppPrintln("Ezsp Endpoint %d added, profile 0x%2x, in clusters: %d, out clusters %d", emberAfAppPrintln("Ezsp Endpoint %d added, profile 0x%2x, in clusters: %d, out clusters %d",
endpoint, endpoint,
emberAfProfileIdFromIndex(endpointIndex), emberAfProfileIdFromIndex(endpointIndex),
inClusterCount, inClusterCount,
outClusterCount); outClusterCount);
} else { } else {
emberAfAppPrintln("Error in creating endpoint %d: 0x%x", endpoint, status); emberAfAppPrintln("Error in creating endpoint %d: 0x%x", endpoint, status);
} }
} }
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
} }
// ******************************************************************* // *******************************************************************
// Handlers required to use the Ember Stack. // Handlers required to use the Ember Stack.
// Called when the stack status changes, usually as a result of an // Called when the stack status changes, usually as a result of an
// attempt to form, join, or leave a network. // attempt to form, join, or leave a network.
void ezspStackStatusHandler(EmberStatus status) void ezspStackStatusHandler(EmberStatus status)
{ {
emberAfPushCallbackNetworkIndex(); emberAfPushCallbackNetworkIndex();
emAfStackStatusHandler(status); emAfStackStatusHandler(status);
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
} }
EmberNodeId emberGetSender(void) EmberNodeId emberGetSender(void)
{ {
return currentSender; return currentSender;
} }
uint8_t emberAfGetBindingIndex(void) uint8_t emberAfGetBindingIndex(void)
{ {
return currentBindingIndex; return currentBindingIndex;
} }
uint8_t emberAfGetAddressIndex(void) uint8_t emberAfGetAddressIndex(void)
{ {
return currentAddressIndex; return currentAddressIndex;
} }
// This is not called if the incoming message did not contain the EUI64 of // This is not called if the incoming message did not contain the EUI64 of
// the sender. // the sender.
void ezspIncomingSenderEui64Handler(EmberEUI64 senderEui64) void ezspIncomingSenderEui64Handler(EmberEUI64 senderEui64)
{ {
// current sender is now valid // current sender is now valid
MEMMOVE(currentSenderEui64, senderEui64, EUI64_SIZE); MEMMOVE(currentSenderEui64, senderEui64, EUI64_SIZE);
currentSenderEui64IsValid = true; currentSenderEui64IsValid = true;
} }
EmberStatus emberGetSenderEui64(EmberEUI64 senderEui64) EmberStatus emberGetSenderEui64(EmberEUI64 senderEui64)
{ {
// if the current sender EUI is valid then copy it in and send it back // if the current sender EUI is valid then copy it in and send it back
if (currentSenderEui64IsValid) { if (currentSenderEui64IsValid) {
MEMMOVE(senderEui64, currentSenderEui64, EUI64_SIZE); MEMMOVE(senderEui64, currentSenderEui64, EUI64_SIZE);
return EMBER_SUCCESS; return EMBER_SUCCESS;
} }
// in the not valid case just return error // in the not valid case just return error
return EMBER_ERR_FATAL; return EMBER_ERR_FATAL;
} }
// //
// ****************************************************************** // ******************************************************************
void ezspIncomingMessageHandler(EmberIncomingMessageType type, void ezspIncomingMessageHandler(EmberIncomingMessageType type,
EmberApsFrame *apsFrame, EmberApsFrame *apsFrame,
uint8_t lastHopLqi, uint8_t lastHopLqi,
int8_t lastHopRssi, int8_t lastHopRssi,
EmberNodeId sender, EmberNodeId sender,
uint8_t bindingIndex, uint8_t bindingIndex,
uint8_t addressIndex, uint8_t addressIndex,
uint8_t messageLength, uint8_t messageLength,
uint8_t *messageContents) uint8_t *messageContents)
{ {
uint8_t sourceRouteOverhead; uint8_t sourceRouteOverhead;
emberAfPushCallbackNetworkIndex(); emberAfPushCallbackNetworkIndex();
// The following code caches valid Source Route overheads sent pro actively // The following code caches valid Source Route overheads sent pro actively
// by the NCP and uses it once to calculate the overhead for a target, after // by the NCP and uses it once to calculate the overhead for a target, after
// which it gets cleared. // which it gets cleared.
sourceRouteOverhead = getSourceRouteOverhead(messageLength); sourceRouteOverhead = getSourceRouteOverhead(messageLength);
emberAfSetSourceRouteOverheadCallback(sender, sourceRouteOverhead); emberAfSetSourceRouteOverheadCallback(sender, sourceRouteOverhead);
currentSender = sender; currentSender = sender;
currentBindingIndex = bindingIndex; currentBindingIndex = bindingIndex;
currentAddressIndex = addressIndex; currentAddressIndex = addressIndex;
emAfIncomingMessageHandler(type, emAfIncomingMessageHandler(type,
apsFrame, apsFrame,
lastHopLqi, lastHopLqi,
lastHopRssi, lastHopRssi,
messageLength, messageLength,
messageContents); messageContents);
currentSenderEui64IsValid = false; currentSenderEui64IsValid = false;
currentSender = EMBER_NULL_NODE_ID; currentSender = EMBER_NULL_NODE_ID;
currentBindingIndex = EMBER_NULL_BINDING; currentBindingIndex = EMBER_NULL_BINDING;
currentAddressIndex = EMBER_NULL_ADDRESS_TABLE_INDEX; currentAddressIndex = EMBER_NULL_ADDRESS_TABLE_INDEX;
// Invalidate the sourceRouteOverhead cached at the end of the current incomingMessageHandler // Invalidate the sourceRouteOverhead cached at the end of the current incomingMessageHandler
emberAfSetSourceRouteOverheadCallback(sender, EZSP_SOURCE_ROUTE_OVERHEAD_UNKNOWN); emberAfSetSourceRouteOverheadCallback(sender, EZSP_SOURCE_ROUTE_OVERHEAD_UNKNOWN);
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
} }
// Called when a message we sent is acked by the destination or when an // Called when a message we sent is acked by the destination or when an
// ack fails to arrive after several retransmissions. // ack fails to arrive after several retransmissions.
void ezspMessageSentHandler(EmberOutgoingMessageType type, void ezspMessageSentHandler(EmberOutgoingMessageType type,
uint16_t indexOrDestination, uint16_t indexOrDestination,
EmberApsFrame *apsFrame, EmberApsFrame *apsFrame,
uint8_t messageTag, uint8_t messageTag,
EmberStatus status, EmberStatus status,
uint8_t messageLength, uint8_t messageLength,
uint8_t *messageContents) uint8_t *messageContents)
{ {
emberAfPushCallbackNetworkIndex(); emberAfPushCallbackNetworkIndex();
#ifdef EMBER_AF_PLUGIN_FRAGMENTATION #ifdef EMBER_AF_PLUGIN_FRAGMENTATION
if (emAfFragmentationMessageSent(apsFrame, status)) { if (emAfFragmentationMessageSent(apsFrame, status)) {
goto kickout; goto kickout;
} }
#endif //EMBER_AF_PLUGIN_FRAGMENTATION #endif //EMBER_AF_PLUGIN_FRAGMENTATION
emAfMessageSentHandler(type, emAfMessageSentHandler(type,
indexOrDestination, indexOrDestination,
apsFrame, apsFrame,
status, status,
messageLength, messageLength,
messageContents, messageContents,
messageTag); messageTag);
goto kickout; // silence a warning when not using fragmentation goto kickout; // silence a warning when not using fragmentation
kickout: kickout:
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
} }
void emberChildJoinHandler(uint8_t index, bool joining) void emberChildJoinHandler(uint8_t index, bool joining)
{ {
} }
// This is called when an EZSP error is reported // This is called when an EZSP error is reported
void ezspErrorHandler(EzspStatus status) void ezspErrorHandler(EzspStatus status)
{ {
emberAfCorePrintln("ERROR: ezspErrorHandler 0x%x", status); emberAfCorePrintln("ERROR: ezspErrorHandler 0x%x", status);
emberAfCoreFlush(); emberAfCoreFlush();
// Rather than detect whether or not we can recover from the error, // Rather than detect whether or not we can recover from the error,
// we just flag the NCP for reboot. // we just flag the NCP for reboot.
// Do not reset if this is a decryption failure, as we ignored the packet. // Do not reset if this is a decryption failure, as we ignored the packet.
if (status != EZSP_ERROR_SECURITY_PARAMETERS_INVALID) { if (status != EZSP_ERROR_SECURITY_PARAMETERS_INVALID) {
ncpNeedsResetAndInit = true; ncpNeedsResetAndInit = true;
} }
} }
EmberStatus emberAfEzspSetSourceRoute(EmberNodeId id) EmberStatus emberAfEzspSetSourceRoute(EmberNodeId id)
{ {
#ifdef EZSP_APPLICATION_HAS_ROUTE_RECORD_HANDLER #ifdef EZSP_APPLICATION_HAS_ROUTE_RECORD_HANDLER
uint16_t relayList[ZA_MAX_HOPS]; uint16_t relayList[ZA_MAX_HOPS];
uint8_t relayCount; uint8_t relayCount;
if (emberFindSourceRoute(id, &relayCount, relayList) if (emberFindSourceRoute(id, &relayCount, relayList)
&& ezspSetSourceRoute(id, relayCount, relayList) != EMBER_SUCCESS) { && ezspSetSourceRoute(id, relayCount, relayList) != EMBER_SUCCESS) {
return EMBER_SOURCE_ROUTE_FAILURE; return EMBER_SOURCE_ROUTE_FAILURE;
} }
#endif #endif
return EMBER_SUCCESS; return EMBER_SUCCESS;
} }
EmberStatus emAfSend(EmberOutgoingMessageType type, EmberStatus emAfSend(EmberOutgoingMessageType type,
uint16_t indexOrDestination, uint16_t indexOrDestination,
EmberApsFrame *apsFrame, EmberApsFrame *apsFrame,
uint8_t messageLength, uint8_t messageLength,
uint8_t *message, uint8_t *message,
uint8_t *messageTag, uint8_t *messageTag,
EmberNodeId alias, EmberNodeId alias,
uint8_t sequence) uint8_t sequence)
{ {
EmberStatus status; EmberStatus status;
*messageTag = ezspNextSequence(); *messageTag = ezspNextSequence();
switch (type) { switch (type) {
case EMBER_OUTGOING_DIRECT: case EMBER_OUTGOING_DIRECT:
case EMBER_OUTGOING_VIA_ADDRESS_TABLE: case EMBER_OUTGOING_VIA_ADDRESS_TABLE:
case EMBER_OUTGOING_VIA_BINDING: case EMBER_OUTGOING_VIA_BINDING:
{ {
status = emberAfEzspSetSourceRoute(indexOrDestination); status = emberAfEzspSetSourceRoute(indexOrDestination);
if (status == EMBER_SUCCESS) { if (status == EMBER_SUCCESS) {
status = ezspSendUnicast(type, status = ezspSendUnicast(type,
indexOrDestination, indexOrDestination,
apsFrame, apsFrame,
*messageTag, *messageTag,
(uint8_t)messageLength, (uint8_t)messageLength,
message, message,
&apsFrame->sequence); &apsFrame->sequence);
} }
break; break;
} }
case EMBER_OUTGOING_MULTICAST: case EMBER_OUTGOING_MULTICAST:
{ {
status = ezspSendMulticast(apsFrame, status = ezspSendMulticast(apsFrame,
ZA_MAX_HOPS, // hops ZA_MAX_HOPS, // hops
ZA_MAX_HOPS, // nonmember radius ZA_MAX_HOPS, // nonmember radius
*messageTag, *messageTag,
messageLength, messageLength,
message, message,
&apsFrame->sequence); &apsFrame->sequence);
break; break;
} }
case EMBER_OUTGOING_MULTICAST_WITH_ALIAS: case EMBER_OUTGOING_MULTICAST_WITH_ALIAS:
{ {
status = ezspSendMulticastWithAlias(apsFrame, status = ezspSendMulticastWithAlias(apsFrame,
apsFrame->radius, //radius apsFrame->radius, //radius
apsFrame->radius, //nonmember radius apsFrame->radius, //nonmember radius
alias, alias,
sequence, sequence,
*messageTag, *messageTag,
messageLength, messageLength,
message, message,
&apsFrame->sequence); &apsFrame->sequence);
break; break;
} }
case EMBER_OUTGOING_BROADCAST: case EMBER_OUTGOING_BROADCAST:
{ {
status = ezspSendBroadcast(indexOrDestination, status = ezspSendBroadcast(indexOrDestination,
apsFrame, apsFrame,
ZA_MAX_HOPS, // radius ZA_MAX_HOPS, // radius
*messageTag, *messageTag,
messageLength, messageLength,
message, message,
&apsFrame->sequence); &apsFrame->sequence);
break; break;
} }
case EMBER_OUTGOING_BROADCAST_WITH_ALIAS: case EMBER_OUTGOING_BROADCAST_WITH_ALIAS:
status = ezspProxyBroadcast(alias, status = ezspProxyBroadcast(alias,
indexOrDestination, indexOrDestination,
sequence, sequence,
apsFrame, apsFrame,
apsFrame->radius, // radius apsFrame->radius, // radius
*messageTag, *messageTag,
messageLength, messageLength,
message, message,
&apsFrame->sequence); &apsFrame->sequence);
break; break;
default: default:
status = EMBER_BAD_ARGUMENT; status = EMBER_BAD_ARGUMENT;
} }
return status; return status;
} }
// Platform dependent interface to get various stack parameters. // Platform dependent interface to get various stack parameters.
void emberAfGetEui64(EmberEUI64 returnEui64) void emberAfGetEui64(EmberEUI64 returnEui64)
{ {
MEMCOPY(returnEui64, emLocalEui64, EUI64_SIZE); MEMCOPY(returnEui64, emLocalEui64, EUI64_SIZE);
} }
EmberStatus emberAfGetNetworkParameters(EmberNodeType* nodeType, EmberStatus emberAfGetNetworkParameters(EmberNodeType* nodeType,
EmberNetworkParameters* parameters) EmberNetworkParameters* parameters)
{ {
return ezspGetNetworkParameters(nodeType, parameters); return ezspGetNetworkParameters(nodeType, parameters);
} }
EmberStatus emberAfGetNodeType(EmberNodeType *nodeType) EmberStatus emberAfGetNodeType(EmberNodeType *nodeType)
{ {
EmberNetworkParameters parameters; EmberNetworkParameters parameters;
return ezspGetNetworkParameters(nodeType, &parameters); return ezspGetNetworkParameters(nodeType, &parameters);
} }
// This will cache all config items to make sure repeated calls do not // This will cache all config items to make sure repeated calls do not
// go all the way to the NCP. // go all the way to the NCP.
uint8_t emberAfGetNcpConfigItem(EzspConfigId id) uint8_t emberAfGetNcpConfigItem(EzspConfigId id)
{ {
// In case we can't cache config items yet, we need a temp // In case we can't cache config items yet, we need a temp
// variable to store the retrieved EZSP config ID. // variable to store the retrieved EZSP config ID.
uint16_t temp = 0xFFFF; uint16_t temp = 0xFFFF;
uint16_t *configItemPtr = &temp; uint16_t *configItemPtr = &temp;
bool cacheValid; bool cacheValid;
EMBER_TEST_ASSERT(id <= EZSP_CONFIG_ID_MAX); EMBER_TEST_ASSERT(id <= EZSP_CONFIG_ID_MAX);
cacheValid = (cacheConfigIdValuesAllowed cacheValid = (cacheConfigIdValuesAllowed
&& id <= EZSP_CONFIG_ID_MAX); && id <= EZSP_CONFIG_ID_MAX);
if (cacheValid) { if (cacheValid) {
configItemPtr = &(cachedConfigIdValues[id]); configItemPtr = &(cachedConfigIdValues[id]);
} }
if (*configItemPtr == 0xFFFF if (*configItemPtr == 0xFFFF
&& EZSP_SUCCESS != ezspGetConfigurationValue(id, && EZSP_SUCCESS != ezspGetConfigurationValue(id,
configItemPtr)) { configItemPtr)) {
// We return a 0 size (for tables) on error to prevent code from using the // We return a 0 size (for tables) on error to prevent code from using the
// invalid value of 0xFFFF. This is particularly necessary for loops that // invalid value of 0xFFFF. This is particularly necessary for loops that
// iterate over all indexes. // iterate over all indexes.
return 0; return 0;
} }
return (uint8_t)(*configItemPtr); return (uint8_t)(*configItemPtr);
} }
EmberStatus emberAfGetSourceRouteTableEntry( EmberStatus emberAfGetSourceRouteTableEntry(
uint8_t index, uint8_t index,
EmberNodeId *destination, EmberNodeId *destination,
uint8_t *closerIndex) uint8_t *closerIndex)
{ {
return ezspGetSourceRouteTableEntry(index, return ezspGetSourceRouteTableEntry(index,
destination, destination,
closerIndex); closerIndex);
} }
uint8_t emberAfGetSourceRouteTableFilledSize(void) uint8_t emberAfGetSourceRouteTableFilledSize(void)
{ {
return ezspGetSourceRouteTableFilledSize(); return ezspGetSourceRouteTableFilledSize();
} }
uint8_t emberAfGetSourceRouteTableTotalSize(void) uint8_t emberAfGetSourceRouteTableTotalSize(void)
{ {
return ezspGetSourceRouteTableTotalSize(); return ezspGetSourceRouteTableTotalSize();
} }
EmberStatus emberAfGetChildData(uint8_t index, EmberStatus emberAfGetChildData(uint8_t index,
EmberChildData *childData) EmberChildData *childData)
{ {
return ezspGetChildData(index, return ezspGetChildData(index,
childData); childData);
} }
uint8_t emberAfGetChildTableSize(void) uint8_t emberAfGetChildTableSize(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_MAX_END_DEVICE_CHILDREN); return emberAfGetNcpConfigItem(EZSP_CONFIG_MAX_END_DEVICE_CHILDREN);
} }
uint8_t emberAfGetKeyTableSize(void) uint8_t emberAfGetKeyTableSize(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_KEY_TABLE_SIZE); return emberAfGetNcpConfigItem(EZSP_CONFIG_KEY_TABLE_SIZE);
} }
uint8_t emberAfGetAddressTableSize(void) uint8_t emberAfGetAddressTableSize(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_ADDRESS_TABLE_SIZE); return emberAfGetNcpConfigItem(EZSP_CONFIG_ADDRESS_TABLE_SIZE);
} }
uint8_t emberAfGetBindingTableSize(void) uint8_t emberAfGetBindingTableSize(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_BINDING_TABLE_SIZE); return emberAfGetNcpConfigItem(EZSP_CONFIG_BINDING_TABLE_SIZE);
} }
uint8_t emberAfGetNeighborTableSize(void) uint8_t emberAfGetNeighborTableSize(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_NEIGHBOR_TABLE_SIZE); return emberAfGetNcpConfigItem(EZSP_CONFIG_NEIGHBOR_TABLE_SIZE);
} }
uint8_t emberAfGetRouteTableSize(void) uint8_t emberAfGetRouteTableSize(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_ROUTE_TABLE_SIZE); return emberAfGetNcpConfigItem(EZSP_CONFIG_ROUTE_TABLE_SIZE);
} }
uint8_t emberAfGetSecurityLevel(void) uint8_t emberAfGetSecurityLevel(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_SECURITY_LEVEL); return emberAfGetNcpConfigItem(EZSP_CONFIG_SECURITY_LEVEL);
} }
uint8_t emberAfGetStackProfile(void) uint8_t emberAfGetStackProfile(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_STACK_PROFILE); return emberAfGetNcpConfigItem(EZSP_CONFIG_STACK_PROFILE);
} }
uint8_t emberAfGetSleepyMulticastConfig(void) uint8_t emberAfGetSleepyMulticastConfig(void)
{ {
return emberAfGetNcpConfigItem(EZSP_CONFIG_SEND_MULTICASTS_TO_SLEEPY_ADDRESS); return emberAfGetNcpConfigItem(EZSP_CONFIG_SEND_MULTICASTS_TO_SLEEPY_ADDRESS);
} }
// On the System-on-a-chip this function is provided by the stack. // On the System-on-a-chip this function is provided by the stack.
// Here is a copy for the host based applications. // Here is a copy for the host based applications.
void emberReverseMemCopy(uint8_t* dest, const uint8_t* src, uint16_t length) void emberReverseMemCopy(uint8_t* dest, const uint8_t* src, uint16_t length)
{ {
uint16_t i; uint16_t i;
uint16_t j = (length - 1); uint16_t j = (length - 1);
for ( i = 0; i < length; i++) { for ( i = 0; i < length; i++) {
dest[i] = src[j]; dest[i] = src[j];
j--; j--;
} }
} }
// ****************************************************************** // ******************************************************************
// Functions called by the Serial Command Line Interface (CLI) // Functions called by the Serial Command Line Interface (CLI)
// ****************************************************************** // ******************************************************************
// ***************************** // *****************************
// emAfCliVersionCommand // emAfCliVersionCommand
// //
// version <no arguments> // version <no arguments>
// ***************************** // *****************************
void emAfCliVersionCommand(void) void emAfCliVersionCommand(void)
{ {
// Note that NCP == Network Co-Processor // Note that NCP == Network Co-Processor
EmberVersion versionStruct; EmberVersion versionStruct;
// the EZSP protocol version that the NCP is using // the EZSP protocol version that the NCP is using
uint8_t ncpEzspProtocolVer; uint8_t ncpEzspProtocolVer;
// the stackType that the NCP is running // the stackType that the NCP is running
uint8_t ncpStackType; uint8_t ncpStackType;
// the EZSP protocol version that the Host is running // the EZSP protocol version that the Host is running
// we are the host so we set this value // we are the host so we set this value
uint8_t hostEzspProtocolVer = EZSP_PROTOCOL_VERSION; uint8_t hostEzspProtocolVer = EZSP_PROTOCOL_VERSION;
// send the Host version number to the NCP. The NCP returns the EZSP // send the Host version number to the NCP. The NCP returns the EZSP
// version that the NCP is running along with the stackType and stackVersion // version that the NCP is running along with the stackType and stackVersion
ncpEzspProtocolVer = ezspVersion(hostEzspProtocolVer, ncpEzspProtocolVer = ezspVersion(hostEzspProtocolVer,
&ncpStackType, &ncpStackType,
&ncpStackVer); &ncpStackVer);
// verify that the stack type is what is expected // verify that the stack type is what is expected
if (ncpStackType != EZSP_STACK_TYPE_MESH) { if (ncpStackType != EZSP_STACK_TYPE_MESH) {
emberAfAppPrint("ERROR: stack type 0x%x is not expected!", emberAfAppPrint("ERROR: stack type 0x%x is not expected!",
ncpStackType); ncpStackType);
assert(false); assert(false);
} }
// verify that the NCP EZSP Protocol version is what is expected // verify that the NCP EZSP Protocol version is what is expected
if (ncpEzspProtocolVer != EZSP_PROTOCOL_VERSION) { if (ncpEzspProtocolVer != EZSP_PROTOCOL_VERSION) {
emberAfAppPrint("ERROR: NCP EZSP protocol version of 0x%x does not match Host version 0x%x\r\n", emberAfAppPrint("ERROR: NCP EZSP protocol version of 0x%x does not match Host version 0x%x\r\n",
ncpEzspProtocolVer, ncpEzspProtocolVer,
hostEzspProtocolVer); hostEzspProtocolVer);
assert(false); assert(false);
} }
emberAfAppPrint("ezsp ver 0x%x stack type 0x%x ", emberAfAppPrint("ezsp ver 0x%x stack type 0x%x ",
ncpEzspProtocolVer, ncpStackType); ncpEzspProtocolVer, ncpStackType);
if (EZSP_SUCCESS != ezspGetVersionStruct(&versionStruct)) { if (EZSP_SUCCESS != ezspGetVersionStruct(&versionStruct)) {
// NCP has Old style version number // NCP has Old style version number
emberAfAppPrintln("stack ver [0x%2x]", ncpStackVer); emberAfAppPrintln("stack ver [0x%2x]", ncpStackVer);
kk_set_ezsp_version_info(hostEzspProtocolVer,ncpEzspProtocolVer,ncpStackType,ncpStackVer,NULL); kk_set_ezsp_version_info(hostEzspProtocolVer,ncpEzspProtocolVer,ncpStackType,ncpStackVer,NULL);
} else { } else {
// NCP has new style version number // NCP has new style version number
emAfParseAndPrintVersion(versionStruct); emAfParseAndPrintVersion(versionStruct);
kk_set_ezsp_version_info(hostEzspProtocolVer,ncpEzspProtocolVer,ncpStackType,ncpStackVer,&versionStruct); kk_set_ezsp_version_info(hostEzspProtocolVer,ncpEzspProtocolVer,ncpStackType,ncpStackVer,&versionStruct);
} }
emberAfAppFlush(); emberAfAppFlush();
} }
uint8_t emAfGetPacketBufferFreeCount(void) uint8_t emAfGetPacketBufferFreeCount(void)
{ {
uint8_t freeCount; uint8_t freeCount;
uint8_t valueLength = 1; uint8_t valueLength = 1;
ezspGetValue(EZSP_VALUE_FREE_BUFFERS, ezspGetValue(EZSP_VALUE_FREE_BUFFERS,
&valueLength, &valueLength,
&freeCount); &freeCount);
return freeCount; return freeCount;
} }
uint8_t emAfGetPacketBufferTotalCount(void) uint8_t emAfGetPacketBufferTotalCount(void)
{ {
uint16_t value; uint16_t value;
ezspGetConfigurationValue(EZSP_CONFIG_PACKET_BUFFER_COUNT, ezspGetConfigurationValue(EZSP_CONFIG_PACKET_BUFFER_COUNT,
&value); &value);
return (uint8_t)value; return (uint8_t)value;
} }
// WARNING: This function executes in ISR context // WARNING: This function executes in ISR context
void halNcpIsAwakeIsr(bool isAwake) void halNcpIsAwakeIsr(bool isAwake)
{ {
if (isAwake) { if (isAwake) {
emberAfNcpIsAwakeIsrCallback(); emberAfNcpIsAwakeIsrCallback();
} else { } else {
// If we got indication that the NCP failed to wake up // If we got indication that the NCP failed to wake up
// there is not much that can be done. We will reset the // there is not much that can be done. We will reset the
// host (which in turn will reset the NCP) and that will // host (which in turn will reset the NCP) and that will
// hopefully bring things back in sync. // hopefully bring things back in sync.
assert(0); assert(0);
} }
} }
void ezspNetworkFoundHandler(EmberZigbeeNetwork *networkFound, void ezspNetworkFoundHandler(EmberZigbeeNetwork *networkFound,
uint8_t lqi, uint8_t lqi,
int8_t rssi) int8_t rssi)
{ {
emberAfPushCallbackNetworkIndex(); emberAfPushCallbackNetworkIndex();
#ifdef EMBER_AF_PLUGIN_FORM_AND_JOIN #ifdef EMBER_AF_PLUGIN_FORM_AND_JOIN
if (!emberFormAndJoinNetworkFoundHandler(networkFound, lqi, rssi)) if (!emberFormAndJoinNetworkFoundHandler(networkFound, lqi, rssi))
#endif #endif
emberAfNetworkFoundCallback(networkFound, lqi, rssi); emberAfNetworkFoundCallback(networkFound, lqi, rssi);
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
} }
void ezspScanCompleteHandler(uint8_t channel, EmberStatus status) void ezspScanCompleteHandler(uint8_t channel, EmberStatus status)
{ {
emberAfPushCallbackNetworkIndex(); emberAfPushCallbackNetworkIndex();
#ifdef EMBER_AF_PLUGIN_FORM_AND_JOIN #ifdef EMBER_AF_PLUGIN_FORM_AND_JOIN
if (!emberFormAndJoinScanCompleteHandler(channel, status)) if (!emberFormAndJoinScanCompleteHandler(channel, status))
#endif #endif
emberAfScanCompleteCallback(channel, status); emberAfScanCompleteCallback(channel, status);
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
} }
void ezspEnergyScanResultHandler(uint8_t channel, int8_t rssi) void ezspEnergyScanResultHandler(uint8_t channel, int8_t rssi)
{ {
emberAfPushCallbackNetworkIndex(); emberAfPushCallbackNetworkIndex();
#ifdef EMBER_AF_PLUGIN_FORM_AND_JOIN #ifdef EMBER_AF_PLUGIN_FORM_AND_JOIN
if (!emberFormAndJoinEnergyScanResultHandler(channel, rssi)) if (!emberFormAndJoinEnergyScanResultHandler(channel, rssi))
#endif #endif
emberAfEnergyScanResultCallback(channel, rssi); emberAfEnergyScanResultCallback(channel, rssi);
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
} }
void ezspUnusedPanIdFoundHandler(EmberPanId panId, uint8_t channel) void ezspUnusedPanIdFoundHandler(EmberPanId panId, uint8_t channel)
{ {
emberAfPushCallbackNetworkIndex(); emberAfPushCallbackNetworkIndex();
#ifdef EMBER_AF_PLUGIN_FORM_AND_JOIN #ifdef EMBER_AF_PLUGIN_FORM_AND_JOIN
if (!emberFormAndJoinUnusedPanIdFoundHandler(panId, channel)) if (!emberFormAndJoinUnusedPanIdFoundHandler(panId, channel))
#endif #endif
emberAfUnusedPanIdFoundCallback(panId, channel); emberAfUnusedPanIdFoundCallback(panId, channel);
emberAfPopNetworkIndex(); emberAfPopNetworkIndex();
} }
void emAfPrintEzspEndpointFlags(uint8_t endpoint) void emAfPrintEzspEndpointFlags(uint8_t endpoint)
{ {
EzspEndpointFlags flags; EzspEndpointFlags flags;
EzspStatus status = ezspGetEndpointFlags(endpoint, EzspStatus status = ezspGetEndpointFlags(endpoint,
&flags); &flags);
if (status != EZSP_SUCCESS) { if (status != EZSP_SUCCESS) {
emberAfCorePrint("Error retrieving EZSP endpoint flags."); emberAfCorePrint("Error retrieving EZSP endpoint flags.");
} else { } else {
emberAfCorePrint("- EZSP Endpoint flags: 0x%2X", flags); emberAfCorePrint("- EZSP Endpoint flags: 0x%2X", flags);
} }
} }
void emSetAddDelay(uint8_t delay) void emSetAddDelay(uint8_t delay)
{ {
//XXXEZSP //XXXEZSP
} }
void ezspZigbeeKeyEstablishmentHandler(EmberEUI64 partner, void ezspZigbeeKeyEstablishmentHandler(EmberEUI64 partner,
EmberKeyStatus status) EmberKeyStatus status)
{ {
// This function is generated. // This function is generated.
emAfZigbeeKeyEstablishment(partner, status); emAfZigbeeKeyEstablishment(partner, status);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment