mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
MQTT->CAN proxy. CRC16 for CAN config
This commit is contained in:
@@ -131,15 +131,19 @@ bool canDriver::sendRemoteID(macAddress mac)
|
||||
{
|
||||
canid_t id;
|
||||
//datagram_t packet;
|
||||
bool res=false;
|
||||
bool res=false;
|
||||
id.subjId=0;
|
||||
id.deviceId=getIdByMac(mac); //Retrieved controllerID
|
||||
if (!id.deviceId) return false;
|
||||
aJsonObject * config=getConfbyID(id.deviceId);
|
||||
if (config) id.subjId=getCRC(config); //CRC16 of remote config
|
||||
|
||||
id.reserve=0;
|
||||
id.status=1; //response
|
||||
id.payloadType=payloadType::lookupMAC;
|
||||
|
||||
id.subjId=200; //CRC16 of remote config
|
||||
|
||||
|
||||
|
||||
debugSerial<<("CAN: Send remote ID")<<endl;
|
||||
res = write (id.id,(datagram_t*)mac,6);
|
||||
@@ -152,6 +156,11 @@ return res;
|
||||
|
||||
bool canDriver::begin()
|
||||
{
|
||||
if (!root) return false;
|
||||
canConfigObj = aJson.getObjectItem(root, "can");
|
||||
if (!canConfigObj) return false;
|
||||
canRemoteConfigObj= aJson.getObjectItem(canConfigObj, "conf");
|
||||
|
||||
controllerId = getMyId();
|
||||
|
||||
if (!ready) // not reInitialization
|
||||
@@ -419,7 +428,7 @@ if (id.status){
|
||||
case payloadType::itemCommand:
|
||||
{
|
||||
if (len!=8) return false;
|
||||
aJsonObject *confObj = findConfbyID(id.deviceId);
|
||||
aJsonObject *confObj = getConfbyID(id.deviceId);
|
||||
if (confObj)
|
||||
{
|
||||
debugSerial<<F("CAN: status received for dev ")<<id.deviceId<<endl;
|
||||
@@ -434,7 +443,7 @@ if (id.status){
|
||||
ic.cmd = packet->cmd;
|
||||
ic.param = packet->param;
|
||||
|
||||
debugSerial<<F("CAN: item ")<<it.itemArr->name;
|
||||
debugSerial<<F("CAN: item ")<<it.itemArr->name<<" ";
|
||||
ic.debugOut();
|
||||
|
||||
if (ic.isCommand()) flags |= FLAG_COMMAND;
|
||||
@@ -456,9 +465,17 @@ if (id.status){
|
||||
case canState::MACLookup:
|
||||
if ((id.payloadType == payloadType::lookupMAC))
|
||||
{
|
||||
debugSerial<<"\nCAN: Got Controller addr: "<<id.deviceId<<endl;
|
||||
controllerId=id.deviceId;
|
||||
state = canState::ReadConfig;
|
||||
if (canConfigObj && (id.subjId == getCRC(canConfigObj))) ///?
|
||||
{
|
||||
infoSerial << (F("Valid config already onboard")) << endl;
|
||||
state = canState::Idle;
|
||||
}
|
||||
else
|
||||
{
|
||||
infoSerial<<"\nCAN: Got Controller addr: "<<id.deviceId<<endl;
|
||||
state = canState::ReadConfig;
|
||||
controllerId=id.deviceId;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -511,7 +528,7 @@ else //Requests
|
||||
else if ((id.payloadType == payloadType::configFrame) && (id.subjId == 0xFFFF))
|
||||
{
|
||||
debugSerial<<F("CAN: Requested conf for dev#")<<id.deviceId<<endl;
|
||||
aJsonObject * remoteConfObj = findConfbyID(id.deviceId);
|
||||
aJsonObject * remoteConfObj = getConfbyID(id.deviceId);
|
||||
if (remoteConfObj)
|
||||
{
|
||||
infoSerial<<F("CAN: Sending conf for dev#")<<id.deviceId<<endl;
|
||||
@@ -531,26 +548,17 @@ return false;
|
||||
|
||||
uint8_t canDriver::getMyId()
|
||||
{
|
||||
if (!root) return 0;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return 0;
|
||||
|
||||
aJsonObject * addrObj = aJson.getObjectItem(canObj, "addr");
|
||||
if (!canConfigObj) return 0;
|
||||
aJsonObject * addrObj = aJson.getObjectItem(canConfigObj, "addr");
|
||||
if (addrObj && (addrObj->type == aJson_Int)) return addrObj->valueint;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
aJsonObject * canDriver::findConfbyID(uint8_t devId)
|
||||
aJsonObject * canDriver::getConfbyID(uint8_t devId)
|
||||
{
|
||||
if (!root) return NULL;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return NULL;
|
||||
|
||||
aJsonObject * remoteConfObj = aJson.getObjectItem(canObj, "conf");
|
||||
|
||||
if (!remoteConfObj) return NULL;
|
||||
remoteConfObj=remoteConfObj->child;
|
||||
if (!canConfigObj) return NULL;
|
||||
if (!canRemoteConfigObj) return NULL;
|
||||
aJsonObject * remoteConfObj=canRemoteConfigObj->child;
|
||||
while (remoteConfObj)
|
||||
{
|
||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||
@@ -564,30 +572,77 @@ while (remoteConfObj)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aJsonObject * canDriver::findConfbyName(char* devName, int * devAddr)
|
||||
{
|
||||
if (!canRemoteConfigObj && !devName) return NULL;
|
||||
aJsonObject * remoteConfObj=canRemoteConfigObj->child;
|
||||
while (remoteConfObj)
|
||||
{
|
||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||
if (remoteCanObj)
|
||||
{
|
||||
aJsonObject * nameObj = aJson.getObjectItem(remoteCanObj, "name");
|
||||
if (nameObj && (nameObj->type == aJson_String) && nameObj->valuestring && (strncasecmp(nameObj->valuestring,devName,strlen(nameObj->valuestring)) == 0))
|
||||
{
|
||||
if (devAddr)
|
||||
{
|
||||
aJsonObject * addrObj = aJson.getObjectItem(remoteCanObj, "addr");
|
||||
if (addrObj && (addrObj->type == aJson_Int)) *devAddr=addrObj->valueint;
|
||||
}
|
||||
return remoteConfObj;
|
||||
}
|
||||
}
|
||||
remoteConfObj=remoteConfObj->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if not defined (NOIP)
|
||||
extern PubSubClient mqttClient;
|
||||
|
||||
bool canDriver::subscribeTopics(char * root, size_t buflen)
|
||||
{
|
||||
if (!root) return false;
|
||||
if (!canRemoteConfigObj) return false;
|
||||
|
||||
int rootLen = strlen(root);
|
||||
|
||||
aJsonObject * remoteConfObj=canRemoteConfigObj->child;
|
||||
while (remoteConfObj)
|
||||
{
|
||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||
if (remoteCanObj)
|
||||
{
|
||||
aJsonObject * addrObj = aJson.getObjectItem(remoteCanObj, "name");
|
||||
if (addrObj && (addrObj->type == aJson_String) && addrObj->valuestring)
|
||||
{
|
||||
strncpy(root+rootLen, addrObj->valuestring, buflen-rootLen-1);
|
||||
strncat(root+rootLen, "/", buflen-rootLen-1);
|
||||
strncat(root+rootLen, "#", buflen-rootLen-1);
|
||||
debugSerial.println(root);
|
||||
mqttClient.subscribe(root);
|
||||
}
|
||||
}
|
||||
remoteConfObj=remoteConfObj->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t canDriver::getIdByMac(macAddress mac)
|
||||
{
|
||||
char macStr[19];
|
||||
uint8_t strptr = 0;
|
||||
char macStr[19];
|
||||
uint8_t strptr = 0;
|
||||
|
||||
if (!root) return 0;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return 0;
|
||||
aJsonObject * confObj = aJson.getObjectItem(canObj, "conf");
|
||||
if (!confObj) return 0;
|
||||
|
||||
memset(macStr,0,sizeof(macStr));
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
// if (mac[i]<16) macStr[strptr++]='0';
|
||||
|
||||
SetBytes(&mac[i],1,&macStr[strptr]);
|
||||
strptr+=2;
|
||||
|
||||
if (i < 5) macStr[strptr++]=':';
|
||||
}
|
||||
if (!canRemoteConfigObj) return 0;
|
||||
memset(macStr,0,sizeof(macStr));
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
SetBytes(&mac[i],1,&macStr[strptr]);
|
||||
strptr+=2;
|
||||
if (i < 5) macStr[strptr++]=':';
|
||||
}
|
||||
debugSerial<<F("CAN: Searching devId for ")<<macStr<<endl;
|
||||
aJsonObject * remoteConfObj = aJson.getObjectItem(confObj, macStr);
|
||||
aJsonObject * remoteConfObj = aJson.getObjectItem(canRemoteConfigObj, macStr);
|
||||
|
||||
if (!remoteConfObj) return 0;
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ Error
|
||||
class canDriver
|
||||
{
|
||||
public:
|
||||
canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::stateUnknown;};
|
||||
canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::stateUnknown;canConfigObj=NULL;canRemoteConfigObj=NULL;};
|
||||
uint8_t getMyId();
|
||||
bool sendStatus(uint16_t itemNum, itemCmd cmd, int subItem = NO_SUBITEM);
|
||||
bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status=false, int subItemID=NO_SUBITEM );
|
||||
@@ -134,15 +134,21 @@ bool begin();
|
||||
void Poll();
|
||||
bool processPacket(canid_t id, datagram_t *packet, uint8_t len, bool rtr=false);
|
||||
bool write(uint32_t msg_id, datagram_t * buf = NULL, uint8_t size=0);
|
||||
aJsonObject * findConfbyName(char* devName, int * devAddr=NULL);
|
||||
#if not defined (NOIP)
|
||||
bool subscribeTopics(char * root, size_t buflen);
|
||||
#endif
|
||||
|
||||
uint8_t getControllerID(){return controllerId;};
|
||||
uint8_t getIdByMac(macAddress mac);
|
||||
|
||||
aJsonObject * canConfigObj;
|
||||
aJsonObject * canRemoteConfigObj;
|
||||
datagram_t RXpacket;
|
||||
canid_t RXid;
|
||||
uint8_t RXlen;
|
||||
|
||||
private:
|
||||
aJsonObject * findConfbyID(uint8_t devId);
|
||||
aJsonObject * getConfbyID(uint8_t devId);
|
||||
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
CAN_message_t CAN_RX_msg;
|
||||
|
||||
@@ -649,7 +649,7 @@ if (suffix = strrchr(*psubItem, '/')) //Trying to retrieve right part
|
||||
*suffix= 0; //Truncate subItem string
|
||||
suffix++;
|
||||
suffixCode = txt2subItem(suffix);
|
||||
debugSerial<<F("suffixCode:")<<suffixCode<<endl;
|
||||
// debugSerial<<F("suffixCode:")<<suffixCode<<endl;
|
||||
// myhome/dev/item/sub.....Item/suffix
|
||||
}
|
||||
else
|
||||
@@ -684,7 +684,7 @@ long int Item::limitSetValue()
|
||||
|
||||
|
||||
// myhome/dev/item/subItem
|
||||
int Item::Ctrl(char * payload, char * subItem)
|
||||
int Item::Ctrl(char * payload, char * subItem, int remoteID)
|
||||
{
|
||||
if (!payload) return 0;
|
||||
int fr = freeRam();
|
||||
@@ -709,13 +709,16 @@ if (suffixCode == S_RAW)
|
||||
{ itemCmd ic;
|
||||
ic.Str(payload);
|
||||
ic.setSuffix(suffixCode);
|
||||
if (remoteID) return remoteCtrl(ic,remoteID,subItem);
|
||||
return Ctrl(ic,subItem);
|
||||
}
|
||||
|
||||
bool authorized = false;
|
||||
char * authPos = strchr(payload,'@');
|
||||
char * authToken = NULL;
|
||||
char * authPos = strchr(payload,'@'); //token@command
|
||||
if (authPos)
|
||||
{
|
||||
authToken = payload;
|
||||
*authPos=0;
|
||||
authorized = checkToken(payload,authPos+1);
|
||||
payload=authPos+1;
|
||||
@@ -782,7 +785,7 @@ st.setSuffix(suffixCode);
|
||||
default: errorSerial<<F("Wrong paylad")<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (remoteID) return remoteCtrl(st,remoteID,subItem,authToken);
|
||||
return Ctrl(st,subItem,true,authorized);
|
||||
} //Void command
|
||||
break;
|
||||
@@ -806,7 +809,7 @@ st.setSuffix(suffixCode);
|
||||
case 4: st.RGBW(Par[0],Par[1],Par[2],Par[3]);
|
||||
default:;
|
||||
}
|
||||
|
||||
if (remoteID) return remoteCtrl(st,remoteID,subItem,authToken);
|
||||
return Ctrl(st,subItem,true,authorized);
|
||||
}
|
||||
case CMD_UP:
|
||||
@@ -815,18 +818,40 @@ st.setSuffix(suffixCode);
|
||||
itemCmd Par0 = getNumber((char **) &payload);
|
||||
Par0.Cmd(cmd);
|
||||
Par0.setSuffix(suffixCode);
|
||||
if (remoteID) return remoteCtrl(Par0,remoteID,subItem,authToken);
|
||||
return Ctrl(Par0, subItem,true,authorized);
|
||||
}
|
||||
default: //some known command
|
||||
{
|
||||
int32_t intParam = getIntFromStr((char **) &payload);
|
||||
if (intParam) st.Int(intParam);
|
||||
if (remoteID) return remoteCtrl(st,remoteID,NULL,authToken);
|
||||
return Ctrl(st,NULL, true, authorized);
|
||||
}
|
||||
} //ctrl
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Item::remoteCtrl(itemCmd cmd, int remoteID, char* subItem, char * authToken)
|
||||
{
|
||||
#ifdef CANDRV
|
||||
// Retrieve remote item id
|
||||
if (!itemArr) return 0;
|
||||
aJsonObject * itemHandler = itemArr->child;
|
||||
if (!itemHandler || itemHandler->type!=aJson_Array) return 0;
|
||||
aJsonObject * itemIdObj=aJson.getArrayItem(itemHandler,1);
|
||||
if (itemIdObj->type != aJson_Int) return 0;
|
||||
|
||||
//Retrieve target controller ID
|
||||
if (!remoteID) return 0;
|
||||
|
||||
//TODO - translate subItem & auth token
|
||||
short subitemNum = NO_SUBITEM;
|
||||
return LHCAN.sendCommand(remoteID,itemIdObj->valueint,cmd,false,subitemNum);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Recursive function with small stack consumption
|
||||
// if cmd defined - execute Ctrl for any group members recursively
|
||||
// else performs Activity check for group members and return true if any member is active
|
||||
@@ -1663,7 +1688,7 @@ int Item::isActive() {
|
||||
itemCmd st;
|
||||
int val = 0;
|
||||
|
||||
debugSerial<<itemArr->name<<F(" ");
|
||||
debugSerial<<F("ACTIVE:")<<itemArr->name<<F(" ");
|
||||
if (!isValid())
|
||||
{
|
||||
debugSerial<<F(" invalid")<<endl;
|
||||
@@ -1841,7 +1866,8 @@ int Item::SendStatus(int sendFlags) {
|
||||
st.debugOut();
|
||||
|
||||
#ifdef CANDRV
|
||||
if (!(sendFlags & FLAG_NOT_SEND_CAN)) LHCAN.sendStatus(getCanNum(itemArr->child),st, getSubitemId(subItem));
|
||||
if (!(sendFlags & FLAG_NOT_SEND_CAN))
|
||||
LHCAN.sendStatus(getCanNum(itemArr->child),(sendFlags & FLAG_SEND_DELAYED)?st.setSuffix(S_DELAYED):st, getSubitemId(subItem));
|
||||
#endif
|
||||
|
||||
if (sendFlags & FLAG_COMMAND)
|
||||
|
||||
@@ -117,8 +117,8 @@ class Item
|
||||
void Stop();
|
||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool allowRecursion = true, bool authorized=false);
|
||||
int Ctrl(char * payload, char * subItem=NULL);
|
||||
|
||||
int Ctrl(char * payload, char * subItem=NULL, int remoteID = 0);
|
||||
int remoteCtrl(itemCmd cmd, int remoteID, char* subItem=NULL, char * authToken=NULL);
|
||||
int getArg(short n=0);
|
||||
float getFloatArg(short n=0);
|
||||
short getArgCount();
|
||||
|
||||
@@ -434,8 +434,10 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
|
||||
short pfxlen = 0;
|
||||
char * itemName = NULL;
|
||||
char * subItem = NULL;
|
||||
char savedTopic[MQTT_TOPIC_LENGTH] = "";
|
||||
bool forLocal=false;
|
||||
aJsonObject * remoteConfig = NULL;
|
||||
int remoteID=0;
|
||||
|
||||
// in Retaining status - trying to restore previous state from retained output topic. Retained input topics are not relevant.
|
||||
if (lanStatus == RETAINING_COLLECTING)
|
||||
@@ -455,17 +457,39 @@ if (lanStatus == RETAINING_COLLECTING)
|
||||
}
|
||||
return;
|
||||
}
|
||||
else forLocal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfxlen=inTopic(topic,T_DEV);
|
||||
if (!pfxlen) pfxlen = inTopic(topic,T_BCST);
|
||||
else // Personal device topic
|
||||
strncpy(savedTopic,topic,sizeof(savedTopic)-1);
|
||||
strncpy(savedTopic,topic,sizeof(savedTopic)-1); //Save topic to delete after exec
|
||||
|
||||
if (pfxlen) forLocal=true;
|
||||
|
||||
#ifdef CANDRV
|
||||
else //Nor local or bcst name, try can names
|
||||
{
|
||||
pfxlen=inTopic(topic,T_ROOT); //check root
|
||||
if (pfxlen)
|
||||
{
|
||||
remoteConfig = LHCAN.findConfbyName(topic+pfxlen,&remoteID);
|
||||
if (remoteConfig)
|
||||
{
|
||||
while(*(topic+pfxlen) && *(topic+pfxlen)!='/') pfxlen++; //skip controller name
|
||||
if (*(topic+pfxlen)=='/') pfxlen++;
|
||||
debugSerial<<F("MQTT: remote command Item:")<<topic+pfxlen<<endl;
|
||||
strncpy(savedTopic,topic,sizeof(savedTopic)-1); //Save topic to delete after exec
|
||||
}
|
||||
else pfxlen=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!pfxlen) {
|
||||
debugSerial<<F("Skipping..")<<endl;
|
||||
// debugSerial<<F("Skipping..")<<endl;
|
||||
return;// -3;
|
||||
}
|
||||
|
||||
@@ -473,12 +497,15 @@ else
|
||||
// debugSerial<<itemName<<endl;
|
||||
if(!strcmp_P(itemName,CMDTOPIC_P) && payload && (strlen((char*) payload)>1)) {
|
||||
mqttClient.deleteTopic(topic);
|
||||
cmd_parse((char *)payload);
|
||||
if (forLocal)((char *)payload);
|
||||
//TODO implement for remote
|
||||
return;// -4;
|
||||
}
|
||||
//if (itemName[0]=='$') return;// -6; //Skipping homie stuff
|
||||
if (strrchr(topic,'$')) return;
|
||||
|
||||
|
||||
/*
|
||||
Item item(itemName);
|
||||
if (item.isValid() && (item.Ctrl((char *)payload)>0) && savedTopic[0] && lanStatus != RETAINING_COLLECTING)
|
||||
|
||||
@@ -487,7 +514,36 @@ else
|
||||
debugSerial<<F("MQTT: Complete. Remove topic ")<<savedTopic<<endl;
|
||||
mqttClient.deleteTopic(savedTopic);
|
||||
}
|
||||
*/
|
||||
|
||||
bool succeeded = false;
|
||||
|
||||
if (forLocal)
|
||||
{
|
||||
Item item(itemName);
|
||||
if (item.isValid()) //Local item
|
||||
{
|
||||
if (item.Ctrl((char *)payload)>0) succeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CANDRV
|
||||
if (remoteConfig)
|
||||
{
|
||||
aJsonObject * remoteItems = aJson.getObjectItem(remoteConfig,"items");
|
||||
if (remoteItems)
|
||||
{
|
||||
Item remoteItem(itemName,remoteItems);
|
||||
if (remoteItem.Ctrl((char *)payload,NULL,remoteID)>0) succeeded = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (succeeded && savedTopic[0] && lanStatus != RETAINING_COLLECTING)
|
||||
{
|
||||
debugSerial<<F("MQTT: Complete. Remove topic ")<<savedTopic<<endl;
|
||||
mqttClient.deleteTopic(savedTopic);
|
||||
}
|
||||
return;// -7;
|
||||
}
|
||||
|
||||
@@ -714,11 +770,16 @@ lan_status lanLoop() {
|
||||
strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics
|
||||
mqttClient.unsubscribe(buf);
|
||||
|
||||
#ifdef CANDRV
|
||||
setTopic(buf,sizeof(buf),T_ROOT);
|
||||
LHCAN.subscribeTopics(buf,sizeof(buf));
|
||||
#endif
|
||||
|
||||
onMQTTConnect();
|
||||
|
||||
#ifdef CRYPT
|
||||
//setTopic(buf,sizeof(buf),T_OUT);
|
||||
strncpy(buf, "+/+/$salt", sizeof(buf)); // Only on separated cmd/val topics
|
||||
setTopic(buf,sizeof(buf),T_ROOT);
|
||||
strncat(buf, "+/$salt", sizeof(buf)); // Only on separated cmd/val topics
|
||||
mqttClient.subscribe(buf);
|
||||
#endif
|
||||
|
||||
@@ -2733,7 +2794,6 @@ LHCAN.upTime(ut);
|
||||
#endif
|
||||
}
|
||||
|
||||
//#if not defined (NOIP)
|
||||
void setupMacAddress() {
|
||||
//Check MAC, stored in NVRAM
|
||||
|
||||
@@ -2765,12 +2825,7 @@ if (!sysConf.getMAC()) {
|
||||
#endif
|
||||
}
|
||||
printMACAddress();
|
||||
|
||||
#ifdef CANDRV
|
||||
// LHCAN.lookupMAC();
|
||||
#endif
|
||||
}
|
||||
//#endif //NOIP
|
||||
|
||||
void setupCmdArduino() {
|
||||
//cmdInit(uint32_t(SERIAL_BAUD));
|
||||
|
||||
@@ -531,9 +531,12 @@ if (_l2 && _l2->type == aJson_String) strncat(buf,_l2->valuestring,buflen);
|
||||
strncat_P(buf,inTopic,buflen); /////
|
||||
break;
|
||||
}
|
||||
strncat(buf,"/",buflen);
|
||||
if (suffix) strncat(buf,suffix,buflen);
|
||||
|
||||
if (tt!=T_ROOT)
|
||||
{
|
||||
strncat(buf,"/",buflen);
|
||||
if (suffix) strncat(buf,suffix,buflen);
|
||||
}
|
||||
return buf;
|
||||
|
||||
}
|
||||
@@ -975,6 +978,14 @@ return true;
|
||||
|
||||
|
||||
|
||||
uint16_t getCRC(aJsonObject * in)
|
||||
{
|
||||
if (!in) return 0;
|
||||
CRCStream crcStream;
|
||||
aJsonStream aJsonCrcStream = aJsonStream(&crcStream);
|
||||
aJson.print(in,&aJsonCrcStream);
|
||||
return crcStream.getCRC16();
|
||||
}
|
||||
|
||||
#pragma message(VAR_NAME_VALUE(debugSerial))
|
||||
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
||||
|
||||
@@ -38,6 +38,7 @@ using namespace ios;
|
||||
#endif
|
||||
|
||||
enum topicType {
|
||||
T_ROOT = 4,
|
||||
T_DEV = 1,
|
||||
T_BCST= 2,
|
||||
T_OUT = 3
|
||||
@@ -80,4 +81,24 @@ int str2regSize(char * str);
|
||||
bool checkToken(char * token, char * data);
|
||||
bool isProtectedPin(short pin);
|
||||
bool i2cReset();
|
||||
uint16_t getCRC(aJsonObject * in);
|
||||
|
||||
#include "util/crc16_.h"
|
||||
class CRCStream : public Stream
|
||||
{
|
||||
public:
|
||||
CRCStream() : CRC16(0xFFFF){}
|
||||
uint16_t CRC16;
|
||||
uint16_t getCRC16() {return CRC16;}
|
||||
|
||||
// Stream methods
|
||||
virtual int available(){return 0;};
|
||||
virtual int read(){return 0;};
|
||||
virtual int peek(){return 0;};
|
||||
|
||||
virtual void flush(){};
|
||||
// Print methods
|
||||
virtual size_t write(uint8_t c) {CRC16 = crc16_update(CRC16, c);};
|
||||
virtual int availableForWrite(){return 1;};
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user