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;
|
canid_t id;
|
||||||
//datagram_t packet;
|
//datagram_t packet;
|
||||||
bool res=false;
|
bool res=false;
|
||||||
|
id.subjId=0;
|
||||||
id.deviceId=getIdByMac(mac); //Retrieved controllerID
|
id.deviceId=getIdByMac(mac); //Retrieved controllerID
|
||||||
if (!id.deviceId) return false;
|
if (!id.deviceId) return false;
|
||||||
|
aJsonObject * config=getConfbyID(id.deviceId);
|
||||||
|
if (config) id.subjId=getCRC(config); //CRC16 of remote config
|
||||||
|
|
||||||
id.reserve=0;
|
id.reserve=0;
|
||||||
id.status=1; //response
|
id.status=1; //response
|
||||||
id.payloadType=payloadType::lookupMAC;
|
id.payloadType=payloadType::lookupMAC;
|
||||||
|
|
||||||
id.subjId=200; //CRC16 of remote config
|
|
||||||
|
|
||||||
|
|
||||||
debugSerial<<("CAN: Send remote ID")<<endl;
|
debugSerial<<("CAN: Send remote ID")<<endl;
|
||||||
res = write (id.id,(datagram_t*)mac,6);
|
res = write (id.id,(datagram_t*)mac,6);
|
||||||
@@ -152,6 +156,11 @@ return res;
|
|||||||
|
|
||||||
bool canDriver::begin()
|
bool canDriver::begin()
|
||||||
{
|
{
|
||||||
|
if (!root) return false;
|
||||||
|
canConfigObj = aJson.getObjectItem(root, "can");
|
||||||
|
if (!canConfigObj) return false;
|
||||||
|
canRemoteConfigObj= aJson.getObjectItem(canConfigObj, "conf");
|
||||||
|
|
||||||
controllerId = getMyId();
|
controllerId = getMyId();
|
||||||
|
|
||||||
if (!ready) // not reInitialization
|
if (!ready) // not reInitialization
|
||||||
@@ -419,7 +428,7 @@ if (id.status){
|
|||||||
case payloadType::itemCommand:
|
case payloadType::itemCommand:
|
||||||
{
|
{
|
||||||
if (len!=8) return false;
|
if (len!=8) return false;
|
||||||
aJsonObject *confObj = findConfbyID(id.deviceId);
|
aJsonObject *confObj = getConfbyID(id.deviceId);
|
||||||
if (confObj)
|
if (confObj)
|
||||||
{
|
{
|
||||||
debugSerial<<F("CAN: status received for dev ")<<id.deviceId<<endl;
|
debugSerial<<F("CAN: status received for dev ")<<id.deviceId<<endl;
|
||||||
@@ -434,7 +443,7 @@ if (id.status){
|
|||||||
ic.cmd = packet->cmd;
|
ic.cmd = packet->cmd;
|
||||||
ic.param = packet->param;
|
ic.param = packet->param;
|
||||||
|
|
||||||
debugSerial<<F("CAN: item ")<<it.itemArr->name;
|
debugSerial<<F("CAN: item ")<<it.itemArr->name<<" ";
|
||||||
ic.debugOut();
|
ic.debugOut();
|
||||||
|
|
||||||
if (ic.isCommand()) flags |= FLAG_COMMAND;
|
if (ic.isCommand()) flags |= FLAG_COMMAND;
|
||||||
@@ -456,9 +465,17 @@ if (id.status){
|
|||||||
case canState::MACLookup:
|
case canState::MACLookup:
|
||||||
if ((id.payloadType == payloadType::lookupMAC))
|
if ((id.payloadType == payloadType::lookupMAC))
|
||||||
{
|
{
|
||||||
debugSerial<<"\nCAN: Got Controller addr: "<<id.deviceId<<endl;
|
if (canConfigObj && (id.subjId == getCRC(canConfigObj))) ///?
|
||||||
controllerId=id.deviceId;
|
{
|
||||||
state = canState::ReadConfig;
|
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;
|
return true;
|
||||||
|
|
||||||
@@ -511,7 +528,7 @@ else //Requests
|
|||||||
else if ((id.payloadType == payloadType::configFrame) && (id.subjId == 0xFFFF))
|
else if ((id.payloadType == payloadType::configFrame) && (id.subjId == 0xFFFF))
|
||||||
{
|
{
|
||||||
debugSerial<<F("CAN: Requested conf for dev#")<<id.deviceId<<endl;
|
debugSerial<<F("CAN: Requested conf for dev#")<<id.deviceId<<endl;
|
||||||
aJsonObject * remoteConfObj = findConfbyID(id.deviceId);
|
aJsonObject * remoteConfObj = getConfbyID(id.deviceId);
|
||||||
if (remoteConfObj)
|
if (remoteConfObj)
|
||||||
{
|
{
|
||||||
infoSerial<<F("CAN: Sending conf for dev#")<<id.deviceId<<endl;
|
infoSerial<<F("CAN: Sending conf for dev#")<<id.deviceId<<endl;
|
||||||
@@ -531,26 +548,17 @@ return false;
|
|||||||
|
|
||||||
uint8_t canDriver::getMyId()
|
uint8_t canDriver::getMyId()
|
||||||
{
|
{
|
||||||
if (!root) return 0;
|
if (!canConfigObj) return 0;
|
||||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
aJsonObject * addrObj = aJson.getObjectItem(canConfigObj, "addr");
|
||||||
if (!canObj) return 0;
|
|
||||||
|
|
||||||
aJsonObject * addrObj = aJson.getObjectItem(canObj, "addr");
|
|
||||||
if (addrObj && (addrObj->type == aJson_Int)) return addrObj->valueint;
|
if (addrObj && (addrObj->type == aJson_Int)) return addrObj->valueint;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
aJsonObject * canDriver::findConfbyID(uint8_t devId)
|
aJsonObject * canDriver::getConfbyID(uint8_t devId)
|
||||||
{
|
{
|
||||||
if (!root) return NULL;
|
if (!canConfigObj) return NULL;
|
||||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
if (!canRemoteConfigObj) return NULL;
|
||||||
if (!canObj) return NULL;
|
aJsonObject * remoteConfObj=canRemoteConfigObj->child;
|
||||||
|
|
||||||
aJsonObject * remoteConfObj = aJson.getObjectItem(canObj, "conf");
|
|
||||||
|
|
||||||
if (!remoteConfObj) return NULL;
|
|
||||||
remoteConfObj=remoteConfObj->child;
|
|
||||||
while (remoteConfObj)
|
while (remoteConfObj)
|
||||||
{
|
{
|
||||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||||
@@ -564,30 +572,77 @@ while (remoteConfObj)
|
|||||||
return NULL;
|
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)
|
uint8_t canDriver::getIdByMac(macAddress mac)
|
||||||
{
|
{
|
||||||
char macStr[19];
|
char macStr[19];
|
||||||
uint8_t strptr = 0;
|
uint8_t strptr = 0;
|
||||||
|
|
||||||
if (!root) return 0;
|
if (!canRemoteConfigObj) return 0;
|
||||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
memset(macStr,0,sizeof(macStr));
|
||||||
if (!canObj) return 0;
|
for (byte i = 0; i < 6; i++)
|
||||||
aJsonObject * confObj = aJson.getObjectItem(canObj, "conf");
|
{
|
||||||
if (!confObj) return 0;
|
SetBytes(&mac[i],1,&macStr[strptr]);
|
||||||
|
strptr+=2;
|
||||||
memset(macStr,0,sizeof(macStr));
|
if (i < 5) macStr[strptr++]=':';
|
||||||
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++]=':';
|
|
||||||
}
|
|
||||||
debugSerial<<F("CAN: Searching devId for ")<<macStr<<endl;
|
debugSerial<<F("CAN: Searching devId for ")<<macStr<<endl;
|
||||||
aJsonObject * remoteConfObj = aJson.getObjectItem(confObj, macStr);
|
aJsonObject * remoteConfObj = aJson.getObjectItem(canRemoteConfigObj, macStr);
|
||||||
|
|
||||||
if (!remoteConfObj) return 0;
|
if (!remoteConfObj) return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ Error
|
|||||||
class canDriver
|
class canDriver
|
||||||
{
|
{
|
||||||
public:
|
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();
|
uint8_t getMyId();
|
||||||
bool sendStatus(uint16_t itemNum, itemCmd cmd, int subItem = NO_SUBITEM);
|
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 );
|
bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status=false, int subItemID=NO_SUBITEM );
|
||||||
@@ -133,16 +133,22 @@ bool sendRemoteID(macAddress mac);
|
|||||||
bool begin();
|
bool begin();
|
||||||
void Poll();
|
void Poll();
|
||||||
bool processPacket(canid_t id, datagram_t *packet, uint8_t len, bool rtr=false);
|
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);
|
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 getControllerID(){return controllerId;};
|
||||||
uint8_t getIdByMac(macAddress mac);
|
uint8_t getIdByMac(macAddress mac);
|
||||||
|
aJsonObject * canConfigObj;
|
||||||
|
aJsonObject * canRemoteConfigObj;
|
||||||
datagram_t RXpacket;
|
datagram_t RXpacket;
|
||||||
canid_t RXid;
|
canid_t RXid;
|
||||||
uint8_t RXlen;
|
uint8_t RXlen;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
aJsonObject * findConfbyID(uint8_t devId);
|
aJsonObject * getConfbyID(uint8_t devId);
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_STM32)
|
#if defined(ARDUINO_ARCH_STM32)
|
||||||
CAN_message_t CAN_RX_msg;
|
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= 0; //Truncate subItem string
|
||||||
suffix++;
|
suffix++;
|
||||||
suffixCode = txt2subItem(suffix);
|
suffixCode = txt2subItem(suffix);
|
||||||
debugSerial<<F("suffixCode:")<<suffixCode<<endl;
|
// debugSerial<<F("suffixCode:")<<suffixCode<<endl;
|
||||||
// myhome/dev/item/sub.....Item/suffix
|
// myhome/dev/item/sub.....Item/suffix
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -684,7 +684,7 @@ long int Item::limitSetValue()
|
|||||||
|
|
||||||
|
|
||||||
// myhome/dev/item/subItem
|
// myhome/dev/item/subItem
|
||||||
int Item::Ctrl(char * payload, char * subItem)
|
int Item::Ctrl(char * payload, char * subItem, int remoteID)
|
||||||
{
|
{
|
||||||
if (!payload) return 0;
|
if (!payload) return 0;
|
||||||
int fr = freeRam();
|
int fr = freeRam();
|
||||||
@@ -709,13 +709,16 @@ if (suffixCode == S_RAW)
|
|||||||
{ itemCmd ic;
|
{ itemCmd ic;
|
||||||
ic.Str(payload);
|
ic.Str(payload);
|
||||||
ic.setSuffix(suffixCode);
|
ic.setSuffix(suffixCode);
|
||||||
|
if (remoteID) return remoteCtrl(ic,remoteID,subItem);
|
||||||
return Ctrl(ic,subItem);
|
return Ctrl(ic,subItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool authorized = false;
|
bool authorized = false;
|
||||||
char * authPos = strchr(payload,'@');
|
char * authToken = NULL;
|
||||||
|
char * authPos = strchr(payload,'@'); //token@command
|
||||||
if (authPos)
|
if (authPos)
|
||||||
{
|
{
|
||||||
|
authToken = payload;
|
||||||
*authPos=0;
|
*authPos=0;
|
||||||
authorized = checkToken(payload,authPos+1);
|
authorized = checkToken(payload,authPos+1);
|
||||||
payload=authPos+1;
|
payload=authPos+1;
|
||||||
@@ -782,7 +785,7 @@ st.setSuffix(suffixCode);
|
|||||||
default: errorSerial<<F("Wrong paylad")<<endl;
|
default: errorSerial<<F("Wrong paylad")<<endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (remoteID) return remoteCtrl(st,remoteID,subItem,authToken);
|
||||||
return Ctrl(st,subItem,true,authorized);
|
return Ctrl(st,subItem,true,authorized);
|
||||||
} //Void command
|
} //Void command
|
||||||
break;
|
break;
|
||||||
@@ -806,7 +809,7 @@ st.setSuffix(suffixCode);
|
|||||||
case 4: st.RGBW(Par[0],Par[1],Par[2],Par[3]);
|
case 4: st.RGBW(Par[0],Par[1],Par[2],Par[3]);
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
if (remoteID) return remoteCtrl(st,remoteID,subItem,authToken);
|
||||||
return Ctrl(st,subItem,true,authorized);
|
return Ctrl(st,subItem,true,authorized);
|
||||||
}
|
}
|
||||||
case CMD_UP:
|
case CMD_UP:
|
||||||
@@ -815,18 +818,40 @@ st.setSuffix(suffixCode);
|
|||||||
itemCmd Par0 = getNumber((char **) &payload);
|
itemCmd Par0 = getNumber((char **) &payload);
|
||||||
Par0.Cmd(cmd);
|
Par0.Cmd(cmd);
|
||||||
Par0.setSuffix(suffixCode);
|
Par0.setSuffix(suffixCode);
|
||||||
|
if (remoteID) return remoteCtrl(Par0,remoteID,subItem,authToken);
|
||||||
return Ctrl(Par0, subItem,true,authorized);
|
return Ctrl(Par0, subItem,true,authorized);
|
||||||
}
|
}
|
||||||
default: //some known command
|
default: //some known command
|
||||||
{
|
{
|
||||||
int32_t intParam = getIntFromStr((char **) &payload);
|
int32_t intParam = getIntFromStr((char **) &payload);
|
||||||
if (intParam) st.Int(intParam);
|
if (intParam) st.Int(intParam);
|
||||||
|
if (remoteID) return remoteCtrl(st,remoteID,NULL,authToken);
|
||||||
return Ctrl(st,NULL, true, authorized);
|
return Ctrl(st,NULL, true, authorized);
|
||||||
}
|
}
|
||||||
} //ctrl
|
} //ctrl
|
||||||
return 0;
|
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
|
// Recursive function with small stack consumption
|
||||||
// if cmd defined - execute Ctrl for any group members recursively
|
// 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
|
// else performs Activity check for group members and return true if any member is active
|
||||||
@@ -1663,7 +1688,7 @@ int Item::isActive() {
|
|||||||
itemCmd st;
|
itemCmd st;
|
||||||
int val = 0;
|
int val = 0;
|
||||||
|
|
||||||
debugSerial<<itemArr->name<<F(" ");
|
debugSerial<<F("ACTIVE:")<<itemArr->name<<F(" ");
|
||||||
if (!isValid())
|
if (!isValid())
|
||||||
{
|
{
|
||||||
debugSerial<<F(" invalid")<<endl;
|
debugSerial<<F(" invalid")<<endl;
|
||||||
@@ -1841,7 +1866,8 @@ int Item::SendStatus(int sendFlags) {
|
|||||||
st.debugOut();
|
st.debugOut();
|
||||||
|
|
||||||
#ifdef CANDRV
|
#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
|
#endif
|
||||||
|
|
||||||
if (sendFlags & FLAG_COMMAND)
|
if (sendFlags & FLAG_COMMAND)
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ class Item
|
|||||||
void Stop();
|
void Stop();
|
||||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
|
//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(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);
|
int getArg(short n=0);
|
||||||
float getFloatArg(short n=0);
|
float getFloatArg(short n=0);
|
||||||
short getArgCount();
|
short getArgCount();
|
||||||
|
|||||||
@@ -434,8 +434,10 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
|
|||||||
|
|
||||||
short pfxlen = 0;
|
short pfxlen = 0;
|
||||||
char * itemName = NULL;
|
char * itemName = NULL;
|
||||||
char * subItem = NULL;
|
|
||||||
char savedTopic[MQTT_TOPIC_LENGTH] = "";
|
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.
|
// in Retaining status - trying to restore previous state from retained output topic. Retained input topics are not relevant.
|
||||||
if (lanStatus == RETAINING_COLLECTING)
|
if (lanStatus == RETAINING_COLLECTING)
|
||||||
@@ -455,17 +457,39 @@ if (lanStatus == RETAINING_COLLECTING)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else forLocal = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pfxlen=inTopic(topic,T_DEV);
|
pfxlen=inTopic(topic,T_DEV);
|
||||||
if (!pfxlen) pfxlen = inTopic(topic,T_BCST);
|
if (!pfxlen) pfxlen = inTopic(topic,T_BCST);
|
||||||
else // Personal device topic
|
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) {
|
if (!pfxlen) {
|
||||||
debugSerial<<F("Skipping..")<<endl;
|
// debugSerial<<F("Skipping..")<<endl;
|
||||||
return;// -3;
|
return;// -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,13 +497,16 @@ else
|
|||||||
// debugSerial<<itemName<<endl;
|
// debugSerial<<itemName<<endl;
|
||||||
if(!strcmp_P(itemName,CMDTOPIC_P) && payload && (strlen((char*) payload)>1)) {
|
if(!strcmp_P(itemName,CMDTOPIC_P) && payload && (strlen((char*) payload)>1)) {
|
||||||
mqttClient.deleteTopic(topic);
|
mqttClient.deleteTopic(topic);
|
||||||
cmd_parse((char *)payload);
|
if (forLocal)((char *)payload);
|
||||||
|
//TODO implement for remote
|
||||||
return;// -4;
|
return;// -4;
|
||||||
}
|
}
|
||||||
//if (itemName[0]=='$') return;// -6; //Skipping homie stuff
|
//if (itemName[0]=='$') return;// -6; //Skipping homie stuff
|
||||||
if (strrchr(topic,'$')) return;
|
if (strrchr(topic,'$')) return;
|
||||||
|
|
||||||
Item item(itemName);
|
|
||||||
|
/*
|
||||||
|
Item item(itemName);
|
||||||
if (item.isValid() && (item.Ctrl((char *)payload)>0) && savedTopic[0] && lanStatus != RETAINING_COLLECTING)
|
if (item.isValid() && (item.Ctrl((char *)payload)>0) && savedTopic[0] && lanStatus != RETAINING_COLLECTING)
|
||||||
|
|
||||||
//if (lanStatus != RETAINING_COLLECTING && (mqttClient.isRetained()))
|
//if (lanStatus != RETAINING_COLLECTING && (mqttClient.isRetained()))
|
||||||
@@ -487,7 +514,36 @@ else
|
|||||||
debugSerial<<F("MQTT: Complete. Remove topic ")<<savedTopic<<endl;
|
debugSerial<<F("MQTT: Complete. Remove topic ")<<savedTopic<<endl;
|
||||||
mqttClient.deleteTopic(savedTopic);
|
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;
|
return;// -7;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,12 +769,17 @@ lan_status lanLoop() {
|
|||||||
setTopic(buf,sizeof(buf),T_OUT);
|
setTopic(buf,sizeof(buf),T_OUT);
|
||||||
strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics
|
strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics
|
||||||
mqttClient.unsubscribe(buf);
|
mqttClient.unsubscribe(buf);
|
||||||
|
|
||||||
|
#ifdef CANDRV
|
||||||
|
setTopic(buf,sizeof(buf),T_ROOT);
|
||||||
|
LHCAN.subscribeTopics(buf,sizeof(buf));
|
||||||
|
#endif
|
||||||
|
|
||||||
onMQTTConnect();
|
onMQTTConnect();
|
||||||
|
|
||||||
#ifdef CRYPT
|
#ifdef CRYPT
|
||||||
//setTopic(buf,sizeof(buf),T_OUT);
|
setTopic(buf,sizeof(buf),T_ROOT);
|
||||||
strncpy(buf, "+/+/$salt", sizeof(buf)); // Only on separated cmd/val topics
|
strncat(buf, "+/$salt", sizeof(buf)); // Only on separated cmd/val topics
|
||||||
mqttClient.subscribe(buf);
|
mqttClient.subscribe(buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2733,7 +2794,6 @@ LHCAN.upTime(ut);
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if not defined (NOIP)
|
|
||||||
void setupMacAddress() {
|
void setupMacAddress() {
|
||||||
//Check MAC, stored in NVRAM
|
//Check MAC, stored in NVRAM
|
||||||
|
|
||||||
@@ -2765,12 +2825,7 @@ if (!sysConf.getMAC()) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
printMACAddress();
|
printMACAddress();
|
||||||
|
|
||||||
#ifdef CANDRV
|
|
||||||
// LHCAN.lookupMAC();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
//#endif //NOIP
|
|
||||||
|
|
||||||
void setupCmdArduino() {
|
void setupCmdArduino() {
|
||||||
//cmdInit(uint32_t(SERIAL_BAUD));
|
//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); /////
|
strncat_P(buf,inTopic,buflen); /////
|
||||||
break;
|
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;
|
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(debugSerial))
|
||||||
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ using namespace ios;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum topicType {
|
enum topicType {
|
||||||
|
T_ROOT = 4,
|
||||||
T_DEV = 1,
|
T_DEV = 1,
|
||||||
T_BCST= 2,
|
T_BCST= 2,
|
||||||
T_OUT = 3
|
T_OUT = 3
|
||||||
@@ -80,4 +81,24 @@ int str2regSize(char * str);
|
|||||||
bool checkToken(char * token, char * data);
|
bool checkToken(char * token, char * data);
|
||||||
bool isProtectedPin(short pin);
|
bool isProtectedPin(short pin);
|
||||||
bool i2cReset();
|
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