Commit 1699fe75 authored by 黄振令's avatar 黄振令

【修改内容】1.解决设备上报格式错误

【提交人】huang.zhenling
parent bbbee50e
...@@ -7,13 +7,15 @@ extern kk_tsl_zigbee_map_t g_tsl_zigbee_map []; ...@@ -7,13 +7,15 @@ extern kk_tsl_zigbee_map_t g_tsl_zigbee_map [];
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]; char msgIdString[10]= {0};
char macString[19] = {0};
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",""); rpc_cJSON_AddStringToObject(info, "productCode","24");
rpc_cJSON_AddStringToObject(info, "deviceCode",""); rpc_eui64ToString(mac,macString);
rpc_cJSON_AddStringToObject(info, "deviceCode",macString);
} }
cJSON *payload = rpc_cJSON_CreateObject(); cJSON *payload = rpc_cJSON_CreateObject();
if(payload != NULL){ if(payload != NULL){
...@@ -64,8 +66,8 @@ void kk_rpc_reportDevices(kk_report_device_s device) ...@@ -64,8 +66,8 @@ void kk_rpc_reportDevices(kk_report_device_s device)
rpc_cJSON_AddAppVersionToObject(devicesJson,device.AppVersion); rpc_cJSON_AddAppVersionToObject(devicesJson,device.AppVersion);
rpc_cJSON_AddStringToObject(devicesJson, "deviceType","1"); rpc_cJSON_AddStringToObject(devicesJson, "deviceType","1");
rpc_cJSON_AddStringToObject(devicesJson, "deviceCode","2"); rpc_cJSON_AddStringToObject(devicesJson, "deviceCode","2");
rpc_cJSON_AddStringToObject(devicesJson, "productType",TEST_PRODUCT_CODE); rpc_cJSON_AddStringToObject(devicesJson, "productType","3");
rpc_cJSON_AddStringToObject(devicesJson, "productCode","4"); rpc_cJSON_AddStringToObject(devicesJson, "productCode",TEST_PRODUCT_CODE);
kk_sub_tsl_add(device.mac,TEST_PRODUCT_CODE); kk_sub_tsl_add(device.mac,TEST_PRODUCT_CODE);
kk_rpc_report_devices(devicesJson,device.mac); kk_rpc_report_devices(devicesJson,device.mac);
} }
......
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
#include "RPC_API.h" #include "RPC_API.h"
#define KK_REPORT_DEVICE_JOINED_TYPE "/thing/topo/add" #define KK_REPORT_DEVICE_JOINED_TYPE "/thing/topo/add"
#define KK_REPORT_ATTRIBUTE_TYPE "/thing/service/property/report" #define KK_REPORT_ATTRIBUTE_TYPE "/thing/event/property/post"
#define KK_IPC_VERSION "1.0" #define KK_IPC_VERSION "1.0"
#define KK_REPORT_DEVICE_JOINED_METHOD "thing.topo.add" #define KK_REPORT_DEVICE_JOINED_METHOD "thing.topo.add"
#define KK_REPORT_DEVICE_LEAVE_METHOD "thing.topo.leave" #define KK_REPORT_DEVICE_LEAVE_METHOD "thing.topo.leave"
#define KK_REPORT_ATTRIBUTE_METHOD "thing.service.property.report" #define KK_REPORT_ATTRIBUTE_METHOD "thing.event.property.post"
#define KK_READ_ATTRIBUTE_METHOD "thing.service.property.get" #define KK_READ_ATTRIBUTE_METHOD "thing.service.property.get"
#define TEST_PRODUCT_CODE "24" #define TEST_PRODUCT_CODE "24"
......
...@@ -346,7 +346,7 @@ int addGW_and_getIP(char* ip){ ...@@ -346,7 +346,7 @@ int addGW_and_getIP(char* ip){
close(sk_recv); close(sk_recv);
return -1; return -1;
} }
printf("addGW_and_getIP allan ==============\n");
char info[] = "{\"msgtype\":\"/thing/topo/add\",\"productType\":\"gw\",\"productCode\":\"2\",\"deviceCode\":\"1122334455667788\"}"; char info[] = "{\"msgtype\":\"/thing/topo/add\",\"productType\":\"gw\",\"productCode\":\"2\",\"deviceCode\":\"1122334455667788\"}";
char payload[] = "{\"msgId\":\"1\",\"version\":\"1.0\",\"params\":{\"deviceCode\":\"1122334455667788\",\"productCode\":\"2\",\"mac\":\"1122334455667788\"}}"; char payload[] = "{\"msgId\":\"1\",\"version\":\"1.0\",\"params\":{\"deviceCode\":\"1122334455667788\",\"productCode\":\"2\",\"mac\":\"1122334455667788\"}}";
cJSON* root = cJSON_CreateObject(); cJSON* root = cJSON_CreateObject();
...@@ -356,7 +356,7 @@ int addGW_and_getIP(char* ip){ ...@@ -356,7 +356,7 @@ int addGW_and_getIP(char* ip){
cJSON_AddItemToObject(root, "payload",payloadObj); cJSON_AddItemToObject(root, "payload",payloadObj);
char* outbuf = cJSON_Print(root); char* outbuf = cJSON_Print(root);
cJSON_Delete(root); cJSON_Delete(root);
printf("addGW_and_getIP allan ===========111111===\n");
while (1) while (1)
{ {
if ((iSendbytes = sendto(sock, outbuf, strlen(outbuf)+1, 0, (struct sockaddr*)&Addrto, sizeof(struct sockaddr))) == -1) if ((iSendbytes = sendto(sock, outbuf, strlen(outbuf)+1, 0, (struct sockaddr*)&Addrto, sizeof(struct sockaddr))) == -1)
......
// 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>
void emAfDeviceTableSave(void);
void emAfDeviceTableLoad(void);
void emAfDeviceTableSave(void);
// Framework message send global data void emAfDeviceTableLoad(void);
extern uint8_t appZclBuffer[];
extern uint16_t appZclBufferLen; // Framework message send global data
extern bool zclCmdIsBuilt; extern uint8_t appZclBuffer[];
extern EmberApsFrame globalApsFrame; extern uint16_t appZclBufferLen;
extern bool zclCmdIsBuilt;
extern void emAfApsFrameEndpointSetup(uint8_t srcEndpoint, extern EmberApsFrame globalApsFrame;
uint8_t dstEndpoint);
extern void emAfApsFrameEndpointSetup(uint8_t srcEndpoint,
static EmberAfPluginDeviceTableEntry deviceTable[EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE]; uint8_t dstEndpoint);
EmberStatus emberAfGetChildData(uint8_t index, static EmberAfPluginDeviceTableEntry deviceTable[EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE];
EmberChildData *childData);
EmberStatus emberAfGetChildData(uint8_t index,
// Device discovery global declarations EmberChildData *childData);
void emAfDeviceTableInitiateRouteRepair(EmberNodeId nodeId);
static void clearDeviceTableIndex(uint16_t index); // Device discovery global declarations
void emAfDeviceTableInitiateRouteRepair(EmberNodeId nodeId);
EmberAfPluginDeviceTableEntry* emberAfDeviceTablePointer(void) static void clearDeviceTableIndex(uint16_t index);
{
return deviceTable; EmberAfPluginDeviceTableEntry* emberAfDeviceTablePointer(void)
} {
return deviceTable;
uint16_t emberAfDeviceTableGetNodeIdFromIndex(uint16_t index) }
{
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); uint16_t emberAfDeviceTableGetNodeIdFromIndex(uint16_t index)
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); {
return deviceTable[index].nodeId; EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
} assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
return deviceTable[index].nodeId;
uint8_t emAfDeviceTableGetFirstEndpointFromIndex(uint16_t index) }
{
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); uint8_t emAfDeviceTableGetFirstEndpointFromIndex(uint16_t index)
return deviceTable[index].endpoint; {
} assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
return deviceTable[index].endpoint;
static void matchReverseEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) }
{
uint8_t i; static void matchReverseEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
{
for (i = 0; i < EUI64_SIZE; i++) { uint8_t i;
if (eui64a[i] != eui64b[(EUI64_SIZE - 1) - i]) {
return; for (i = 0; i < EUI64_SIZE; i++) {
} if (eui64a[i] != eui64b[(EUI64_SIZE - 1) - i]) {
} return;
}
emberAfCorePrintln("MATCH_EUI: EUI matches backwards"); }
emberAfCorePrint("A:"); emberAfCorePrintln("MATCH_EUI: EUI matches backwards");
emAfDeviceTablePrintEUI64(eui64a);
emberAfCorePrint(" B:"); emberAfCorePrint("A:");
emAfDeviceTablePrintEUI64(eui64b); emAfDeviceTablePrintEUI64(eui64a);
emberAfCorePrintln(""); emberAfCorePrint(" B:");
} emAfDeviceTablePrintEUI64(eui64b);
emberAfCorePrintln("");
static void checkNullEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) }
{
uint8_t i; static void checkNullEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
for (i = 0; i < EUI64_SIZE; i++) { {
if (eui64a[i] != 0xff uint8_t i;
|| eui64b[i] != 0xff) { for (i = 0; i < EUI64_SIZE; i++) {
return; if (eui64a[i] != 0xff
} || eui64b[i] != 0xff) {
} return;
}
emberAfCorePrintln("MatchEUI: two null EUI"); }
}
emberAfCorePrintln("MatchEUI: two null EUI");
static bool matchEui64(EmberEUI64 a, EmberEUI64 b) }
{
checkNullEui64(a, b); static bool matchEui64(EmberEUI64 a, EmberEUI64 b)
{
if (MEMCOMPARE(a, b, EUI64_SIZE) == 0) { checkNullEui64(a, b);
return true;
} else { if (MEMCOMPARE(a, b, EUI64_SIZE) == 0) {
// Test to see if the EUI64 is backwards return true;
matchReverseEui64(a, b); } else {
// Test to see if the EUI64 is backwards
return false; matchReverseEui64(a, b);
}
} return false;
}
bool emberAfDeviceTableMatchEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) }
{
return matchEui64(eui64a, eui64b); bool emberAfDeviceTableMatchEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
} {
return matchEui64(eui64a, eui64b);
static void unsetEui64(EmberEUI64 eui64) }
{
uint8_t i; static void unsetEui64(EmberEUI64 eui64)
for (i = 0; i < 8; i++) { {
eui64[i] = 0xff; uint8_t i;
} for (i = 0; i < 8; i++) {
} eui64[i] = 0xff;
}
static void clearDeviceTableIndex(uint16_t index) }
{
uint8_t i; static void clearDeviceTableIndex(uint16_t index)
{
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); uint8_t i;
deviceTable[index].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
unsetEui64(deviceTable[index].eui64);
deviceTable[index].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_NULL; deviceTable[index].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
deviceTable[index].endpoint = 0; unsetEui64(deviceTable[index].eui64);
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; i++) { deviceTable[index].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_NULL;
deviceTable[index].clusterIds[i] = ZCL_NULL_CLUSTER_ID; deviceTable[index].endpoint = 0;
} for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; i++) {
deviceTable[index].clusterOutStartPosition = 0; deviceTable[index].clusterIds[i] = ZCL_NULL_CLUSTER_ID;
} }
deviceTable[index].clusterOutStartPosition = 0;
void emAfPluginDeviceTableDeleteEntry(uint16_t index) }
{
uint16_t currentIndex; void emAfPluginDeviceTableDeleteEntry(uint16_t index)
{
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { uint16_t currentIndex;
currentIndex = index;
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
// Need to compute the next index before deleting the current one. Or else currentIndex = index;
// the call to next endpoint will yield a bogus result.
index = emAfDeviceTableFindNextEndpoint(index); // Need to compute the next index before deleting the current one. Or else
// the call to next endpoint will yield a bogus result.
clearDeviceTableIndex(currentIndex); index = emAfDeviceTableFindNextEndpoint(index);
emberAfPluginDeviceTableIndexRemovedCallback(currentIndex);
} clearDeviceTableIndex(currentIndex);
} emberAfPluginDeviceTableIndexRemovedCallback(currentIndex);
}
void emAfDeviceTableInit(void) }
{
uint16_t i; void emAfDeviceTableInit(void)
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
clearDeviceTableIndex(i); uint16_t i;
} for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
} clearDeviceTableIndex(i);
}
void emberAfDeviceTableClear(void) }
{
emAfDeviceTableInit(); void emberAfDeviceTableClear(void)
emAfDeviceTableSave(); {
//emberAfPluginDeviceTableClearedCallback(); emAfDeviceTableInit();
} emAfDeviceTableSave();
//emberAfPluginDeviceTableClearedCallback();
uint16_t emberAfDeviceTableGetIndexFromEui64AndEndpoint(EmberEUI64 eui64, }
uint8_t endpoint)
{ uint16_t emberAfDeviceTableGetIndexFromEui64AndEndpoint(EmberEUI64 eui64,
uint16_t i; uint8_t endpoint)
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
if (matchEui64(deviceTable[i].eui64, eui64) uint16_t i;
&& deviceTable[i].endpoint == endpoint) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
return i; if (matchEui64(deviceTable[i].eui64, eui64)
} && deviceTable[i].endpoint == endpoint) {
} 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 i; uint16_t emberAfDeviceTableGetNodeIdFromEui64(EmberEUI64 eui64)
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
if (matchEui64(deviceTable[i].eui64, eui64) ) { uint16_t i;
return deviceTable[i].nodeId; for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
} if (matchEui64(deviceTable[i].eui64, eui64) ) {
} 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) }
{
uint16_t i; bool emberAfDeviceTableGetEui64FromNodeId(EmberNodeId emberNodeId, EmberEUI64 eui64)
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
if (deviceTable[i].nodeId == emberNodeId) { uint16_t i;
MEMCOPY(eui64, deviceTable[i].eui64, EUI64_SIZE); for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
return true; if (deviceTable[i].nodeId == emberNodeId) {
} MEMCOPY(eui64, deviceTable[i].eui64, EUI64_SIZE);
} return true;
return false; }
} }
return false;
uint16_t emberAfDeviceTableGetIndexFromNodeId(EmberNodeId emberNodeId) }
{
uint16_t i; uint16_t emberAfDeviceTableGetIndexFromNodeId(EmberNodeId emberNodeId)
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
if (deviceTable[i].nodeId == emberNodeId) { uint16_t i;
return i; for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
} if (deviceTable[i].nodeId == emberNodeId) {
} return i;
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
uint16_t emAfDeviceTableFindFreeDeviceTableIndex(void) }
{
uint16_t i; uint16_t emAfDeviceTableFindFreeDeviceTableIndex(void)
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) { uint16_t i;
return 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) {
} return i;
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
uint16_t emberAfDeviceTableGetEndpointFromNodeIdAndEndpoint(EmberNodeId emberNodeId, }
uint8_t endpoint)
{ uint16_t emberAfDeviceTableGetEndpointFromNodeIdAndEndpoint(EmberNodeId emberNodeId,
uint16_t i; uint8_t endpoint)
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
if (deviceTable[i].nodeId == emberNodeId uint16_t i;
&& deviceTable[i].endpoint == endpoint) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
return i; if (deviceTable[i].nodeId == emberNodeId
} && deviceTable[i].endpoint == endpoint) {
} 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) }
{
EmberAfPluginDeviceTableEntry* from = &(deviceTable[fromIndex]); void emAfDeviceTableCopyDeviceTableEntry(uint16_t fromIndex, uint16_t toIndex)
EmberAfPluginDeviceTableEntry* to = &(deviceTable[toIndex]); {
EmberAfPluginDeviceTableEntry* from = &(deviceTable[fromIndex]);
// make sure the fromIndex is in the valud range. EmberAfPluginDeviceTableEntry* to = &(deviceTable[toIndex]);
assert(fromIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
// make sure the fromIndex is in the valud range.
// make sure the fromIndex has a valid entry assert(fromIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
assert(deviceTable[fromIndex].nodeId
!= EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID); // make sure the fromIndex has a valid entry
assert(deviceTable[fromIndex].nodeId
// make sure the toIndex is in the valud range. != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID);
assert(toIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
// make sure the toIndex is in the valud range.
MEMCOPY(to, from, sizeof(EmberAfPluginDeviceTableEntry)); assert(toIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
}
MEMCOPY(to, from, sizeof(EmberAfPluginDeviceTableEntry));
uint8_t emAfDeviceTableNumberOfEndpointsFromIndex(uint16_t index) }
{
uint8_t count = 0; uint8_t emAfDeviceTableNumberOfEndpointsFromIndex(uint16_t index)
uint16_t currentNodeId = emberAfDeviceTableGetNodeIdFromIndex(index); {
uint16_t i; uint8_t count = 0;
uint16_t currentNodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { uint16_t i;
if (deviceTable[i].nodeId == currentNodeId) {
count++; for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
} if (deviceTable[i].nodeId == currentNodeId) {
} count++;
return count; }
} }
return count;
static uint16_t findIndexFromNodeIdAndIndex(uint16_t nodeId, uint16_t index) }
{
uint16_t i; static uint16_t findIndexFromNodeIdAndIndex(uint16_t nodeId, uint16_t index)
for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
if (nodeId == emberAfDeviceTableGetNodeIdFromIndex(i)) { uint16_t i;
return i; for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
} if (nodeId == emberAfDeviceTableGetNodeIdFromIndex(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) }
{
uint16_t i; static uint16_t findIndexFromEui64AndIndex(EmberEUI64 eui64, uint16_t index)
for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
if (matchEui64(eui64, deviceTable[i].eui64)) { uint16_t i;
return i; for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
} if (matchEui64(eui64, deviceTable[i].eui64)) {
} return i;
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
uint16_t emAfDeviceTableFindFirstEndpointNodeId(uint16_t nodeId) }
{
return findIndexFromNodeIdAndIndex(nodeId, 0); uint16_t emAfDeviceTableFindFirstEndpointNodeId(uint16_t nodeId)
} {
return findIndexFromNodeIdAndIndex(nodeId, 0);
uint16_t emAfDeviceTableFindNextEndpoint(uint16_t index) }
{
return findIndexFromEui64AndIndex(deviceTable[index].eui64, uint16_t emAfDeviceTableFindNextEndpoint(uint16_t index)
index + 1); {
} return findIndexFromEui64AndIndex(deviceTable[index].eui64,
index + 1);
uint16_t emAfDeviceTableFindFirstEndpointIeee(EmberEUI64 eui64) }
{
return findIndexFromEui64AndIndex(eui64, 0); uint16_t emAfDeviceTableFindFirstEndpointIeee(EmberEUI64 eui64)
} {
return findIndexFromEui64AndIndex(eui64, 0);
uint16_t emberAfDeviceTableGetFirstIndexFromEui64(EmberEUI64 eui64) }
{
return emAfDeviceTableFindFirstEndpointIeee(eui64); uint16_t emberAfDeviceTableGetFirstIndexFromEui64(EmberEUI64 eui64)
} {
return emAfDeviceTableFindFirstEndpointIeee(eui64);
EmberAfStatus emAfDeviceTableAddNewEndpoint(uint16_t index, uint8_t newEndpoint) }
{
uint16_t newIndex = emAfDeviceTableFindFreeDeviceTableIndex(); EmberAfStatus emAfDeviceTableAddNewEndpoint(uint16_t index, uint8_t newEndpoint)
{
if (newIndex == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { uint16_t newIndex = emAfDeviceTableFindFreeDeviceTableIndex();
return EMBER_ZCL_STATUS_FAILURE;
} if (newIndex == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
return EMBER_ZCL_STATUS_FAILURE;
emAfDeviceTableCopyDeviceTableEntry(index, newIndex); }
deviceTable[newIndex].endpoint = newEndpoint; emAfDeviceTableCopyDeviceTableEntry(index, newIndex);
return EMBER_ZCL_STATUS_SUCCESS; deviceTable[newIndex].endpoint = newEndpoint;
}
return EMBER_ZCL_STATUS_SUCCESS;
uint16_t emAfDeviceTableFindIndexNodeIdEndpoint(uint16_t nodeId, }
uint8_t endpoint)
{ uint16_t emAfDeviceTableFindIndexNodeIdEndpoint(uint16_t nodeId,
uint16_t i; uint8_t endpoint)
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { {
if (deviceTable[i].nodeId == nodeId uint16_t i;
&& deviceTable[i].endpoint == endpoint) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
return i; if (deviceTable[i].nodeId == nodeId
} && deviceTable[i].endpoint == endpoint) {
} return i;
}
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; }
}
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
EmberAfPluginDeviceTableEntry *emberAfDeviceTableFindDeviceTableEntry(uint16_t index) }
{
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID); EmberAfPluginDeviceTableEntry *emberAfDeviceTableFindDeviceTableEntry(uint16_t index)
return &(deviceTable[index]); {
} assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID);
return &(deviceTable[index]);
void emAfDeviceTableUpdateNodeId(uint16_t currentNodeId, uint16_t newNodeId) }
{
uint16_t index = emAfDeviceTableFindFirstEndpointNodeId(currentNodeId); void emAfDeviceTableUpdateNodeId(uint16_t currentNodeId, uint16_t newNodeId)
{
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { uint16_t index = emAfDeviceTableFindFirstEndpointNodeId(currentNodeId);
deviceTable[index].nodeId = newNodeId;
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
index = emAfDeviceTableFindNextEndpoint(index); deviceTable[index].nodeId = newNodeId;
}
} index = emAfDeviceTableFindNextEndpoint(index);
}
void emAfDeviceTableUpdateDeviceState(uint16_t index, uint8_t newState) }
{
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { void emAfDeviceTableUpdateDeviceState(uint16_t index, uint8_t newState)
deviceTable[index].state = newState; {
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
index = emAfDeviceTableFindNextEndpoint(index); deviceTable[index].state = newState;
}
} index = emAfDeviceTableFindNextEndpoint(index);
}
uint32_t emberAfDeviceTableTimeSinceLastMessage(uint16_t index) }
{
uint32_t timeSinceLastMessage = halCommonGetInt32uMillisecondTick(); uint32_t emberAfDeviceTableTimeSinceLastMessage(uint16_t index)
{
timeSinceLastMessage -= deviceTable[index].lastMsgTimestamp; uint32_t timeSinceLastMessage = halCommonGetInt32uMillisecondTick();
timeSinceLastMessage /= MILLISECOND_TICKS_PER_SECOND;
timeSinceLastMessage -= deviceTable[index].lastMsgTimestamp;
return timeSinceLastMessage; timeSinceLastMessage /= MILLISECOND_TICKS_PER_SECOND;
}
return timeSinceLastMessage;
// AF Framework callbacks. This is where the plugin implements the callbacks. }
void emberAfPluginDeviceTableInitCallback(void)
{ // AF Framework callbacks. This is where the plugin implements the callbacks.
emAfDeviceTableInit(); void emberAfPluginDeviceTableInitCallback(void)
{
// Load on Init emAfDeviceTableInit();
emAfDeviceTableLoad();
// Load on Init
emberAfPluginDeviceTableInitialized(); emAfDeviceTableLoad();
}
emberAfPluginDeviceTableInitialized();
void emberAfPluginDeviceTableStackStatusCallback(EmberStatus status) }
{
// If we leave the network, this plugin needs to clear out all of its device void emberAfPluginDeviceTableStackStatusCallback(EmberStatus status)
// state. {
// If we leave the network, this plugin needs to clear out all of its device
emberAfCorePrintln("%d %d", status, emberNetworkState()); // state.
if (status == EMBER_NETWORK_DOWN emberAfCorePrintln("%d %d", status, emberNetworkState());
&& emberNetworkState() == EMBER_NO_NETWORK) {
emberAfCorePrintln("DeviceTable: Clear State"); if (status == EMBER_NETWORK_DOWN
&& emberNetworkState() == EMBER_NO_NETWORK) {
emberAfDeviceTableClear(); emberAfCorePrintln("DeviceTable: Clear State");
}
} emberAfDeviceTableClear();
}
// -------------------------------- }
// Save/Load the devices
void emAfDeviceTableSave(void) // --------------------------------
{ // Save/Load the devices
#if defined(EZSP_HOST) && !defined(EMBER_TEST) void emAfDeviceTableSave(void)
FILE *fp; {
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); #if defined(EZSP_HOST) && !defined(EMBER_TEST)
uint8_t i; FILE *fp;
uint8_t j; EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
uint8_t i;
// Save device table uint8_t j;
fp = fopen("devices.txt", "w");
// Save device table
for (i = 0; fp = fopen("devices.txt", "w");
i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE;
i++) { for (i = 0;
if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) { i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE;
fprintf(fp, i++) {
"%x %x %x ", if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) {
deviceTable[i].nodeId, fprintf(fp,
deviceTable[i].endpoint, "%x %x %x ",
deviceTable[i].deviceId); deviceTable[i].nodeId,
for (j = 0; j < 8; j++) { deviceTable[i].endpoint,
fprintf(fp, "%x ", deviceTable[i].eui64[j]); deviceTable[i].deviceId);
} for (j = 0; j < 8; j++) {
for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) { fprintf(fp, "%x ", deviceTable[i].eui64[j]);
fprintf(fp, "%x ", deviceTable[i].clusterIds[j]); }
} for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) {
fprintf(fp, "%d ", deviceTable[i].clusterOutStartPosition); fprintf(fp, "%x ", deviceTable[i].clusterIds[j]);
} }
} fprintf(fp, "%d ", deviceTable[i].clusterOutStartPosition);
}
// Write ffffffff to mark the end }
fprintf(fp, "\r\nffffffff\r\n");
fclose(fp); // Write ffffffff to mark the end
fprintf(fp, "\r\nffffffff\r\n");
#endif // defined(EZSP_HOST) && !defined(EMBER_TEST) fclose(fp);
}
#endif // defined(EZSP_HOST) && !defined(EMBER_TEST)
void emAfDeviceTableLoad(void) }
{
#if defined(EZSP_HOST) && !defined(EMBER_TEST) void emAfDeviceTableLoad(void)
uint16_t i; {
uint16_t j; #if defined(EZSP_HOST) && !defined(EMBER_TEST)
FILE *fp; uint16_t i;
unsigned int data, data2, data3; uint16_t j;
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); FILE *fp;
unsigned int data, data2, data3;
fp = fopen("devices.txt", "r"); EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
if (!fp) { fp = fopen("devices.txt", "r");
return;
} if (!fp) {
return;
for (i = 0; }
i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE && feof(fp) == false;
i++) { for (i = 0;
i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE && feof(fp) == false;
fscanf(fp, "%x %x %x", &data2, &data, &data3); i++) {
deviceTable[i].endpoint = (uint8_t) data;
deviceTable[i].nodeId = (uint16_t) data2; fscanf(fp, "%x %x %x", &data2, &data, &data3);
deviceTable[i].deviceId = (uint16_t) data3; deviceTable[i].endpoint = (uint8_t) data;
deviceTable[i].nodeId = (uint16_t) data2;
if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) { deviceTable[i].deviceId = (uint16_t) data3;
for (j = 0; j < 8; j++) {
fscanf(fp, "%x", &data); if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) {
deviceTable[i].eui64[j] = (uint8_t) data; for (j = 0; j < 8; j++) {
} fscanf(fp, "%x", &data);
for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) { deviceTable[i].eui64[j] = (uint8_t) data;
fscanf(fp, "%x", &data); }
deviceTable[i].clusterIds[j] = (uint16_t) data; for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) {
} fscanf(fp, "%x", &data);
fscanf(fp, "%d", &data); deviceTable[i].clusterIds[j] = (uint16_t) data;
deviceTable[i].clusterOutStartPosition = (uint16_t) data; }
fscanf(fp, "%d", &data);
deviceTable[i].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_JOINED; deviceTable[i].clusterOutStartPosition = (uint16_t) data;
kk_sub_tsl_add(deviceTable[i].eui64,"3");
} 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); }
// Set the rest of the device table to null. fclose(fp);
for (; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
deviceTable[i].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; // Set the rest of the device table to null.
} for (; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
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
// Command to send the CIE IEEE address to the IAS Zone cluster // --------------------------------
void emAfDeviceTableSendCieAddressWrite(EmberNodeId nodeId, uint8_t endpoint) // Message send section
{ // Command to send the CIE IEEE address to the IAS Zone cluster
EmberEUI64 eui64; void emAfDeviceTableSendCieAddressWrite(EmberNodeId nodeId, uint8_t endpoint)
uint8_t outgoingBuffer[15]; {
uint32_t i; EmberEUI64 eui64;
uint8_t outgoingBuffer[15];
emberAfGetEui64(eui64); uint32_t i;
globalApsFrame.options = EMBER_AF_DEFAULT_APS_OPTIONS; emberAfGetEui64(eui64);
globalApsFrame.clusterId = ZCL_IAS_ZONE_CLUSTER_ID;
globalApsFrame.sourceEndpoint = 0x01; globalApsFrame.options = EMBER_AF_DEFAULT_APS_OPTIONS;
globalApsFrame.destinationEndpoint = endpoint; globalApsFrame.clusterId = ZCL_IAS_ZONE_CLUSTER_ID;
globalApsFrame.sourceEndpoint = 0x01;
outgoingBuffer[0] = 0x00; globalApsFrame.destinationEndpoint = endpoint;
outgoingBuffer[1] = emberAfNextSequence();
outgoingBuffer[2] = ZCL_WRITE_ATTRIBUTES_COMMAND_ID; outgoingBuffer[0] = 0x00;
outgoingBuffer[3] = LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID); outgoingBuffer[1] = emberAfNextSequence();
outgoingBuffer[4] = HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID); outgoingBuffer[2] = ZCL_WRITE_ATTRIBUTES_COMMAND_ID;
outgoingBuffer[5] = ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE; outgoingBuffer[3] = LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID);
outgoingBuffer[4] = HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID);
for (i = 0; i < 8; i++) { outgoingBuffer[5] = ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE;
outgoingBuffer[6 + i] = eui64[i];
} for (i = 0; i < 8; i++) {
outgoingBuffer[6 + i] = eui64[i];
emberAfSendUnicast(EMBER_OUTGOING_DIRECT, }
nodeId,
&globalApsFrame, emberAfSendUnicast(EMBER_OUTGOING_DIRECT,
14, nodeId,
outgoingBuffer); &globalApsFrame,
} 14,
outgoingBuffer);
void emberAfDeviceTableCliIndexSendWithEndpoint(uint16_t index, }
uint8_t endpoint)
{ void emberAfDeviceTableCliIndexSendWithEndpoint(uint16_t index,
EmberNodeId nodeId; uint8_t endpoint)
EmberStatus status; {
EmberNodeId nodeId;
nodeId = emberAfDeviceTableGetNodeIdFromIndex(index); EmberStatus status;
emAfApsFrameEndpointSetup(emberAfPrimaryEndpoint(), endpoint);
status = emberAfSendUnicast(EMBER_OUTGOING_DIRECT, nodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
nodeId, emAfApsFrameEndpointSetup(emberAfPrimaryEndpoint(), endpoint);
&globalApsFrame, status = emberAfSendUnicast(EMBER_OUTGOING_DIRECT,
appZclBufferLen, nodeId,
appZclBuffer); &globalApsFrame,
appZclBufferLen,
zclCmdIsBuilt = false; appZclBuffer);
}
zclCmdIsBuilt = false;
void emberAfDeviceTableCliIndexSend(uint16_t index) }
{
uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index); void emberAfDeviceTableCliIndexSend(uint16_t index)
emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint); {
} uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index);
emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint);
void emberAfDeviceTableSend(EmberEUI64 eui64, uint8_t endpoint) }
{
uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64); void emberAfDeviceTableSend(EmberEUI64 eui64, uint8_t endpoint)
{
if (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64);
emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint);
} if (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
} emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint);
}
void emberAfDeviceTableCommandIndexSendWithEndpoint(uint16_t index, }
uint8_t endpoint)
{ void emberAfDeviceTableCommandIndexSendWithEndpoint(uint16_t index,
EmberNodeId nodeId; uint8_t endpoint)
EmberStatus status; {
EmberNodeId nodeId;
nodeId = emberAfDeviceTableGetNodeIdFromIndex(index); EmberStatus status;
if (emberAfCurrentCommand() == NULL) { nodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
emAfCommandApsFrame->sourceEndpoint = emberAfPrimaryEndpoint();
} else { if (emberAfCurrentCommand() == NULL) {
emAfCommandApsFrame->sourceEndpoint = emberAfCurrentEndpoint(); emAfCommandApsFrame->sourceEndpoint = emberAfPrimaryEndpoint();
} } else {
emAfCommandApsFrame->sourceEndpoint = emberAfCurrentEndpoint();
emAfCommandApsFrame->destinationEndpoint = endpoint; }
emberAfCorePrintln("device table send with ep: 0x%2X, %d",
nodeId, emAfCommandApsFrame->destinationEndpoint = endpoint;
endpoint); emberAfCorePrintln("device table send with ep: 0x%2X, %d",
status = emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, nodeId); nodeId,
endpoint);
zclCmdIsBuilt = false; status = emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, nodeId);
}
zclCmdIsBuilt = false;
void emberAfDeviceTableCommandIndexSend(uint16_t index) }
{
uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index); void emberAfDeviceTableCommandIndexSend(uint16_t index)
emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint); {
} uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index);
emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint);
void emberAfDeviceTableCommandSendWithEndpoint(EmberEUI64 eui64, }
uint8_t endpoint)
{ void emberAfDeviceTableCommandSendWithEndpoint(EmberEUI64 eui64,
uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64); uint8_t endpoint)
emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint); {
} uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64);
emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint);
}
......
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