// Parse incoming messages from PHY1 void mqttsn_parser_phy1(MQ_t * pPHY1outBuf) { bool msg_from_gw = (memcmp(pPHY1outBuf->phy1addr, vMQTTSN.GatewayAddr, sizeof(PHY1_ADDR_t)) == 0); #ifdef MQTTSN_TRANSIT_ON_PHY1 // Transit messages on PHY1 if(!msg_from_gw && (vMQTTSN.Status == MQTTSN_STATUS_CONNECT)) { switch(pPHY1outBuf->mq.MsgType) { case MQTTSN_MSGTYP_SEARCHGW: if((pPHY1outBuf->mq.searchgw.Radius == (vMQTTSN.Radius + 1)) || (pPHY1outBuf->mq.searchgw.Radius == 0)) { vMQTTSN.tGWinfo1 = MQTTSN_T_GWINFO; } break; case MQTTSN_MSGTYP_ADVERTISE: case MQTTSN_MSGTYP_GWINFO: vMQTTSN.tGWinfo1 = 0; break; case MQTTSN_MSGTYP_CONNECT: case MQTTSN_MSGTYP_REGISTER: case MQTTSN_MSGTYP_REGACK: case MQTTSN_MSGTYP_PUBLISH: case MQTTSN_MSGTYP_PUBACK: case MQTTSN_MSGTYP_SUBSCRIBE: case MQTTSN_MSGTYP_PINGREQ: case MQTTSN_MSGTYP_DISCONNECT: case MQTTSN_MSGTYP_DHCPREQ: case MQTTSN_MSGTYP_FORWARD: { // Forward message on PHY1 from Remote Node to Gateway uint8_t Size = (MQTTSN_SIZEOF_MSG_FORWARD + sizeof(PHY1_ADDR_t) + 1); uint8_t Length = pPHY1outBuf->Length + Size; uint8_t pos; if(Length > sizeof(MQTTSN_MESSAGE_t)) break; // Don't use memcpy ! for(pos = (Length - 1); pos >= Size; pos--) pPHY1outBuf->raw[pos] = pPHY1outBuf->raw[pos - Size]; // Make forward message header pPHY1outBuf->Length = Length; pPHY1outBuf->mq.Length = Size; pPHY1outBuf->mq.MsgType = MQTTSN_MSGTYP_FORWARD; pPHY1outBuf->mq.forward.Ctrl = 0; // ?? TTL pPHY1outBuf->mq.forward.wNodeID[0] = 1; // PHY1 memcpy(&pPHY1outBuf->mq.forward.wNodeID[1], pPHY1outBuf->phy1addr, sizeof(PHY1_ADDR_t)); memcpy(pPHY1outBuf->phy1addr, vMQTTSN.GatewayAddr, sizeof(PHY1_ADDR_t)); PHY1_Send(pPHY1outBuf); } return; // Unknown, bad or unsupported message default: break; } mqFree(pPHY1outBuf); return; } #endif // MQTTSN_TRANSIT_ON_PHY1 switch(pPHY1outBuf->mq.MsgType) { // Advertise message from Gate, equivalent GWINFO case MQTTSN_MSGTYP_ADVERTISE: if(vMQTTSN.Status == MQTTSN_STATUS_SEARCHGW) { memcpy(vMQTTSN.GatewayAddr, pPHY1outBuf->phy1addr, sizeof(PHY1_ADDR_t)); vMQTTSN.GwId = pPHY1outBuf->mq.advertise.GwId; vMQTTSN.Radius = 1; vMQTTSN.Status = MQTTSN_STATUS_OFFLINE; vMQTTSN.Tretry = MQTTSN_T_ACCEL; vMQTTSN.Nretry = MQTTSN_N_RETRIES; } #ifdef PHY2_Send else if((vMQTTSN.Status == MQTTSN_STATUS_CONNECT) && msg_from_gw && (vMQTTSN.Radius == 1)) { vMQTTSN.tGWinfo1 = 0; vMQTTSN.tGWinfo2 = 0; PHY2_Send(pPHY1outBuf); return; } #endif break; // Search gateway request from another node case MQTTSN_MSGTYP_SEARCHGW: if(vMQTTSN.Status == MQTTSN_STATUS_SEARCHGW) { vMQTTSN.Tretry = MQTTSN_T_SEARCHGW; } break; // Gateway Info message case MQTTSN_MSGTYP_GWINFO: if(vMQTTSN.Status == MQTTSN_STATUS_SEARCHGW) { memcpy(vMQTTSN.GatewayAddr, pPHY1outBuf->phy1addr, sizeof(PHY1_ADDR_t)); vMQTTSN.GwId = pPHY1outBuf->mq.gwinfo.GwId; vMQTTSN.Status = MQTTSN_STATUS_OFFLINE; vMQTTSN.Tretry = MQTTSN_T_ACCEL; vMQTTSN.Nretry = MQTTSN_N_RETRIES; } else if(vMQTTSN.Status == MQTTSN_STATUS_CONNECT) { vMQTTSN.tGWinfo1 = 0; } break; // Connack message case MQTTSN_MSGTYP_CONNACK: if(msg_from_gw) { if(vMQTTSN.Status == MQTTSN_STATUS_OFFLINE) { if(pPHY1outBuf->mq.connack.ReturnCode == MQTTSN_RET_ACCEPTED) { vMQTTSN.Status = MQTTSN_STATUS_PRE_CONNECT; vMQTTSN.Tretry = (MQTTSN_T_KEEPALIVE * POLL_TMR_FREQ); vMQTTSN.Nretry = MQTTSN_N_RETRIES; } } // else // ToDo // Message lost, broker - gateway Problems, Connected another Node with same Address. // Potential dangerous } break; // Register Topic request case MQTTSN_MSGTYP_REGISTER: if(vMQTTSN.Status == MQTTSN_STATUS_CONNECT) { if(msg_from_gw) { pPHY1outBuf->mq.regack.ReturnCode = RegisterOD(&pPHY1outBuf->mq); pPHY1outBuf->Length = MQTTSN_SIZEOF_MSG_REGACK; pPHY1outBuf->mq.Length = MQTTSN_SIZEOF_MSG_REGACK; pPHY1outBuf->mq.MsgType = MQTTSN_MSGTYP_REGACK; PHY1_Send(pPHY1outBuf); return; } } break; // RegAck Answer case MQTTSN_MSGTYP_REGACK: if(msg_from_gw) { if((vMQTTSN.Status == MQTTSN_STATUS_PRE_CONNECT) || (vMQTTSN.Status == MQTTSN_STATUS_CONNECT)) { if((vMQTTSN.MsgType == MQTTSN_MSGTYP_REGISTER) && (vMQTTSN.pMessage->mq.regist.MsgId[0] == pPHY1outBuf->mq.regack.MsgId[0]) && (vMQTTSN.pMessage->mq.regist.MsgId[1] == pPHY1outBuf->mq.regack.MsgId[1])) { mqFree(vMQTTSN.pMessage); vMQTTSN.MsgType = MQTTSN_MSGTYP_PINGREQ; uint16_t index; if(pPHY1outBuf->mq.regack.ReturnCode == MQTTSN_RET_ACCEPTED) index = (pPHY1outBuf->mq.regack.TopicId[0]<<8) | pPHY1outBuf->mq.regack.TopicId[1]; else index = 0; RegAckOD(index); vMQTTSN.Tretry = (MQTTSN_T_KEEPALIVE * POLL_TMR_FREQ); vMQTTSN.Nretry = MQTTSN_N_RETRIES; } } } break; // Publish Topic request case MQTTSN_MSGTYP_PUBLISH: if(vMQTTSN.Status == MQTTSN_STATUS_CONNECT) { if(msg_from_gw) { uint8_t Flags = pPHY1outBuf->mq.publish.Flags; uint16_t TopicId = (pPHY1outBuf->mq.publish.TopicId[0]<<8) | pPHY1outBuf->mq.publish.TopicId[1]; uint16_t MsgId = (pPHY1outBuf->mq.publish.MsgId[0]<<8) | pPHY1outBuf->mq.publish.MsgId[1]; // Make PubAck message pPHY1outBuf->mq.puback.ReturnCode = WriteODpack( TopicId, Flags, (pPHY1outBuf->mq.Length - MQTTSN_SIZEOF_MSG_PUBLISH), (uint8_t *)pPHY1outBuf->mq.publish.Data); // ToDo Not Supported QOS2 if((Flags & MQTTSN_FL_QOS_MASK) == MQTTSN_FL_QOS1) // Need Ack { pPHY1outBuf->Length = MQTTSN_SIZEOF_MSG_PUBACK; pPHY1outBuf->mq.Length = MQTTSN_SIZEOF_MSG_PUBACK; pPHY1outBuf->mq.MsgType = MQTTSN_MSGTYP_PUBACK; pPHY1outBuf->mq.puback.TopicId[0] = TopicId>>8; pPHY1outBuf->mq.puback.TopicId[1] = TopicId & 0xFF; pPHY1outBuf->mq.puback.MsgId[0] = MsgId>>8; pPHY1outBuf->mq.puback.MsgId[1] = MsgId & 0xFF; PHY1_Send(pPHY1outBuf); return; } } } break; // PubAck Answer case MQTTSN_MSGTYP_PUBACK: if(msg_from_gw) { if((vMQTTSN.Status == MQTTSN_STATUS_CONNECT) || (vMQTTSN.Status == MQTTSN_STATUS_PRE_CONNECT)) { if((vMQTTSN.MsgType == MQTTSN_MSGTYP_PUBLISH) && (vMQTTSN.pMessage->mq.publish.MsgId[0] == pPHY1outBuf->mq.puback.MsgId[0]) && (vMQTTSN.pMessage->mq.publish.MsgId[1] == pPHY1outBuf->mq.puback.MsgId[1])) { mqFree(vMQTTSN.pMessage); vMQTTSN.MsgType = MQTTSN_MSGTYP_PINGREQ; vMQTTSN.Tretry = (MQTTSN_T_KEEPALIVE * POLL_TMR_FREQ); vMQTTSN.Nretry = MQTTSN_N_RETRIES; } } } break; // SubAck answer case MQTTSN_MSGTYP_SUBACK: if(msg_from_gw) { if(vMQTTSN.Status == MQTTSN_STATUS_PRE_CONNECT) { if((vMQTTSN.MsgType == MQTTSN_MSGTYP_SUBSCRIBE) && (vMQTTSN.pMessage->mq.subscribe.MsgId[0] == pPHY1outBuf->mq.suback.MsgId[0]) && (vMQTTSN.pMessage->mq.subscribe.MsgId[1] == pPHY1outBuf->mq.suback.MsgId[1])) { mqFree(vMQTTSN.pMessage); vMQTTSN.MsgType = MQTTSN_MSGTYP_PINGREQ; vMQTTSN.Status = MQTTSN_STATUS_CONNECT; vMQTTSN.Tretry = (MQTTSN_T_KEEPALIVE * POLL_TMR_FREQ); vMQTTSN.Nretry = MQTTSN_N_RETRIES; } } } break; // Ping Response case MQTTSN_MSGTYP_PINGRESP: if(vMQTTSN.Status == MQTTSN_STATUS_CONNECT) { if(msg_from_gw) { vMQTTSN.Tretry = (MQTTSN_T_KEEPALIVE * POLL_TMR_FREQ); vMQTTSN.Nretry = MQTTSN_N_RETRIES; } } break; // Disconnect Request case MQTTSN_MSGTYP_DISCONNECT: if(vMQTTSN.Status < MQTTSN_STATUS_OFFLINE) { vMQTTSN.Radius = 1; vMQTTSN.Tretry = 1; vMQTTSN.Nretry = MQTTSN_N_RETRIES; } else if(msg_from_gw) { vMQTTSN.Status = MQTTSN_STATUS_DISCONNECTED; vMQTTSN.Tretry = 1; vMQTTSN.Nretry = MQTTSN_N_RETRIES; } break; #ifdef MQTTSN_USE_DHCP // NOT STANDARD MESSAGE, DON'T USE WITH ANOTHER SYSTEMS // DHCP request from another node case MQTTSN_MSGTYP_DHCPREQ: if(vMQTTSN.Status == MQTTSN_STATUS_DHCP) vMQTTSN.Tretry = MQTTSN_T_SEARCHGW; break; // DHCP Response case MQTTSN_MSGTYP_DHCPRESP: if(vMQTTSN.Status == MQTTSN_STATUS_DHCP) { if(memcmp(pPHY1outBuf->mq.dhcpresp.MsgId, &vMQTTSN.MsgId, sizeof(vMQTTSN.MsgId)) == 0) // Own message { uint8_t Mask = 0; uint8_t * pData = pPHY1outBuf->mq.dhcpresp.addr; uint8_t Length = MQTTSN_SIZEOF_MSG_DHCPRESP; if(memcmp(PHY1_GetAddr(), &addr1_undef, sizeof(PHY1_ADDR_t)) == 0) { Length += sizeof(PHY1_ADDR_t); Mask = 1; } #ifdef PHY2_ADDR_t if(memcmp(PHY2_GetAddr(), &addr2_undef, sizeof(PHY2_ADDR_t))== 0) { Length += sizeof(PHY2_ADDR_t); Mask |= 2; } #endif // PHY2_ADDR_t if(pPHY1outBuf->mq.Length != Length) break; if(Mask & 1) { // Check, own address != Gateway Address if(memcmp(PHY1_GetAddr(), pData, sizeof(PHY1_ADDR_t)) == 0) break; WriteOD(PHY1_NodeId, MQTTSN_FL_TOPICID_PREDEF, sizeof(PHY1_ADDR_t), (uint8_t *)pData); pData += sizeof(PHY1_ADDR_t); } #ifdef PHY2_ADDR_t if(Mask & 2) { WriteOD(PHY2_NodeId, MQTTSN_FL_TOPICID_PREDEF, sizeof(PHY2_ADDR_t), (uint8_t *)pData); } #endif // PHY2_ADDR_t vMQTTSN.Status = MQTTSN_STATUS_DISCONNECTED; vMQTTSN.Tretry = 1; } } break; #endif // MQTTSN_USE_DHCP // Forward message #if ((defined MQTTSN_TRANSIT_ON_PHY1) || (defined PHY2_Send)) case MQTTSN_MSGTYP_FORWARD: if(vMQTTSN.Status == MQTTSN_STATUS_CONNECT) { if(msg_from_gw) // message from Gateway to Node { uint8_t Length = pPHY1outBuf->mq.Length; uint8_t phynr = pPHY1outBuf->mq.forward.wNodeID[0]; #ifdef MQTTSN_TRANSIT_ON_PHY1 // Direction: Gateway to Remote node on PHY1 if((phynr == 1) && (Length == (MQTTSN_SIZEOF_MSG_FORWARD + sizeof(PHY1_ADDR_t) + 1))) { memcpy(pPHY1outBuf->phy1addr, &pPHY1outBuf->mq.forward.wNodeID[1], sizeof(PHY1_ADDR_t)); // truncate header pPHY1outBuf->Length -= Length; memcpy(&pPHY1outBuf->raw[0], &pPHY1outBuf->raw[Length], pPHY1outBuf->Length); PHY1_Send(pPHY1outBuf); return; } #endif // MQTTSN_TRANSIT_ON_PHY1 #ifdef PHY2_Send // Direction Gateway to PHY2 if((phynr == 2) && (Length == (MQTTSN_SIZEOF_MSG_FORWARD + sizeof(PHY2_ADDR_t) + 1))) { memcpy(pPHY1outBuf->phy2addr, &pPHY1outBuf->mq.forward.wNodeID[1], sizeof(PHY2_ADDR_t)); // truncate header pPHY1outBuf->Length -= Length; memcpy(&pPHY1outBuf->raw[0], &pPHY1outBuf->raw[Length], pPHY1outBuf->Length); PHY2_Send(pPHY1outBuf); return; } #endif // PHY2_Send } } break; #endif // ((defined MQTTSN_TRANSIT_ON_PHY1) || (defined PHY2_Send)) // Unknown message type default: break; }
// Parse incoming messages from PHY1 void mqttsn_parser_phy1(MQ_t * pPHY1outBuf) { bool msg_from_gw = (memcmp(pPHY1outBuf->a.phy1addr, vMQ_GatewayAddr, sizeof(PHY1_ADDR_t)) == 0); e_MQTTSN_MSGTYPE_t MsgType = pPHY1outBuf->m.mq.MsgType; switch(MsgType) { case MQTTSN_MSGTYP_ADVERTISE: { if(vMQ_Status == MQTTSN_STATUS_SEARCHGW) { memcpy(vMQ_GatewayAddr, pPHY1outBuf->a.phy1addr, sizeof(PHY1_ADDR_t)); vMQ_GwId = pPHY1outBuf->m.mq.m.advertise.GwId; vMQ_Radius = 1; vMQ_Status = MQTTSN_STATUS_OFFLINE; vMQ_tRetry = MQTTSN_T_ACCEL; vMQ_nRetry = MQTTSN_N_RETRIES; } #if ((defined MQTTSN_USE_MESH) || (defined PHY2_Send)) else if(vMQ_Status == MQTTSN_STATUS_CONNECT) { if(msg_from_gw) { #ifdef PHY2_Send if(vMQ_Radius == 1) { #if (defined MQTTSN_USE_MESH) vMQ_tGWinfo1 = 0; #endif // (defined MQTTSN_USE_MESH) vMQ_tGWinfo2 = 0; // Set Destination - Broadcast memcpy(pPHY1outBuf->a.phy2addr, &addr2_broad, sizeof(PHY2_ADDR_t)); PHY2_Send(pPHY1outBuf); return; } #endif } #if (defined MQTTSN_USE_MESH) else vMQ_tGWinfo1 = 0; #endif // (defined MQTTSN_USE_MESH) } #endif // ((defined MQTTSN_USE_MESH) || (defined PHY2_Send)) break; } // Search gateway request from another node case MQTTSN_MSGTYP_SEARCHGW: { if(vMQ_Status == MQTTSN_STATUS_SEARCHGW) { vMQ_tRetry = MQTTSN_T_SEARCHGW; } #if (defined MQTTSN_USE_MESH) else if(vMQ_Status == MQTTSN_STATUS_CONNECT) { if((pPHY1outBuf->m.mq.m.searchgw.Radius == (vMQ_Radius + 1)) || (pPHY1outBuf->m.mq.m.searchgw.Radius == 0)) { vMQ_tGWinfo1 = MQTTSN_T_GWINFO; } } #endif // (defined MQTTSN_USE_MESH) break; } // Advertise message, equivalent GWINFO case MQTTSN_MSGTYP_GWINFO: { if(vMQ_Status == MQTTSN_STATUS_SEARCHGW) { memcpy(vMQ_GatewayAddr, pPHY1outBuf->a.phy1addr, sizeof(PHY1_ADDR_t)); vMQ_GwId = pPHY1outBuf->m.mq.m.gwinfo.GwId; vMQ_Status = MQTTSN_STATUS_OFFLINE; vMQ_tRetry = MQTTSN_T_ACCEL; vMQ_nRetry = MQTTSN_N_RETRIES; } #if (defined MQTTSN_USE_MESH) else if(vMQ_Status == MQTTSN_STATUS_CONNECT) { vMQ_tGWinfo1 = 0; } #endif // (defined MQTTSN_USE_MESH) break; } // Connect message from another node #ifdef MQTTSN_USE_MESH case MQTTSN_MSGTYP_CONNECT: { if(!msg_from_gw && (vMQ_Status == MQTTSN_STATUS_CONNECT)) { mqtts_forward_to_gate(pPHY1outBuf); return; } break; } #endif // MQTTSN_USE_MESH // Connack message case MQTTSN_MSGTYP_CONNACK: { if(msg_from_gw) { if(pPHY1outBuf->m.mq.m.connack.ReturnCode == MQTTSN_RET_ACCEPTED) { if(vMQ_Status == MQTTSN_STATUS_OFFLINE) { vMQ_Status = MQTTSN_STATUS_PRE_CONNECT; vMQ_tRetry = MQTTSN_T_SHORT; vMQ_nRetry = MQTTSN_N_RETRIES; } #ifdef ASLEEP else if(vMQ_Status == MQTTSN_STATUS_AWAKE) { vMQ_Status = MQTTSN_STATUS_CONNECT; vMQ_tRetry = 1; vMQ_nRetry = MQTTSN_N_RETRIES; } #endif // ASLEEP // else // ToDo // Message lost, broker - gateway Problems, // Connected another Node with same Address. // Potential dangerous } } break; } /* case MQTTSN_MSGTYP_WILLTOPICREQ: case MQTTSN_MSGTYP_WILLTOPIC: case MQTTSN_MSGTYP_WILLMSGREQ: case MQTTSN_MSGTYP_WILLMSG: */ // Register Topic request case MQTTSN_MSGTYP_REGISTER: { if(vMQ_Status == MQTTSN_STATUS_CONNECT) { if(msg_from_gw) { if(vMQ_MsgType == MQTTSN_MSGTYP_PINGREQ) { vMQ_tRetry = MQTTSN_T_SHORT; } pPHY1outBuf->m.mq.m.regack.ReturnCode = RegisterOD(&pPHY1outBuf->m.mq); pPHY1outBuf->Length = MQTTSN_SIZEOF_MSG_REGACK; pPHY1outBuf->m.mq.Length = MQTTSN_SIZEOF_MSG_REGACK; pPHY1outBuf->m.mq.MsgType = MQTTSN_MSGTYP_REGACK; PHY1_Send(pPHY1outBuf); } #ifdef MQTTSN_USE_MESH else { mqtts_forward_to_gate(pPHY1outBuf); } #endif // MQTTSN_USE_MESH return; } break; } // RegAck Answer case MQTTSN_MSGTYP_REGACK: { if(msg_from_gw) { if((vMQ_Status == MQTTSN_STATUS_PRE_CONNECT) || (vMQ_Status == MQTTSN_STATUS_CONNECT)) { if((vMQ_MsgType == MQTTSN_MSGTYP_REGISTER) && (vMQ_pMessage->m.mq.m.regist.MsgId[0] == pPHY1outBuf->m.mq.m.regack.MsgId[0]) && (vMQ_pMessage->m.mq.m.regist.MsgId[1] == pPHY1outBuf->m.mq.m.regack.MsgId[1])) { mqFree(vMQ_pMessage); vMQ_MsgType = MQTTSN_MSGTYP_PINGREQ; uint16_t index; if(pPHY1outBuf->m.mq.m.regack.ReturnCode == MQTTSN_RET_ACCEPTED) index = (pPHY1outBuf->m.mq.m.regack.TopicId[0]<<8) | pPHY1outBuf->m.mq.m.regack.TopicId[1]; else index = 0; RegAckOD(index); vMQ_tRetry = MQTTSN_T_SHORT; vMQ_nRetry = MQTTSN_N_RETRIES; } } } #ifdef MQTTSN_USE_MESH else if(vMQ_Status == MQTTSN_STATUS_CONNECT) { mqtts_forward_to_gate(pPHY1outBuf); return; } #endif // MQTTSN_USE_MESH break; } // Publish Topic request case MQTTSN_MSGTYP_PUBLISH: { if(msg_from_gw) { if((vMQ_Status == MQTTSN_STATUS_CONNECT) #ifdef ASLEEP || (vMQ_Status == MQTTSN_STATUS_AWAKE) #endif // ASLEEP ) { uint8_t Flags = pPHY1outBuf->m.mq.m.publish.Flags; uint16_t TopicId = (pPHY1outBuf->m.mq.m.publish.TopicId[0]<<8) | pPHY1outBuf->m.mq.m.publish.TopicId[1]; uint16_t MsgId = (pPHY1outBuf->m.mq.m.publish.MsgId[0]<<8) | pPHY1outBuf->m.mq.m.publish.MsgId[1]; if(((Flags & MQTTSN_FL_DUP) == 0) || (vMQ_oMsgId != MsgId)) { pPHY1outBuf->m.mq.m.puback.ReturnCode = WriteODpack( TopicId, Flags, (pPHY1outBuf->m.mq.Length - MQTTSN_SIZEOF_MSG_PUBLISH), (uint8_t *)pPHY1outBuf->m.mq.m.publish.Data); vMQ_oMsgId = MsgId; } // ToDo Not Supported QOS2 if((Flags & MQTTSN_FL_QOS_MASK) == MQTTSN_FL_QOS1) // Need Ack { if(vMQ_MsgType == MQTTSN_MSGTYP_PINGREQ) { vMQ_tRetry = MQTTSN_T_SHORT; } pPHY1outBuf->Length = MQTTSN_SIZEOF_MSG_PUBACK; pPHY1outBuf->m.mq.Length = MQTTSN_SIZEOF_MSG_PUBACK; pPHY1outBuf->m.mq.MsgType = MQTTSN_MSGTYP_PUBACK; pPHY1outBuf->m.mq.m.puback.TopicId[0] = TopicId>>8; pPHY1outBuf->m.mq.m.puback.TopicId[1] = TopicId & 0xFF; pPHY1outBuf->m.mq.m.puback.MsgId[0] = MsgId>>8; pPHY1outBuf->m.mq.m.puback.MsgId[1] = MsgId & 0xFF; PHY1_Send(pPHY1outBuf); return; } } } #ifdef MQTTSN_USE_MESH else if(vMQ_Status == MQTTSN_STATUS_CONNECT) { mqtts_forward_to_gate(pPHY1outBuf); return; } #endif // MQTTSN_USE_MESH break; }
uint8_t MQTTS_Parser(MQ_t * pBuf) { uint8_t tmp; switch(pBuf->mq.MsgType) { case MQTTS_MSGTYP_SEARCHGW: #ifdef GATEWAY // Local Answer pBuf->mq.Length = MQTTS_SIZEOF_MSG_GWINFO; pBuf->mq.MsgType = MQTTS_MSGTYP_GWINFO; pBuf->mq.m.gwinfo.GwId = rf_GetNodeID(); MQTTS_Push(pBuf); return 1; #else // !GATEWAY if(vMQTTS.Status == MQTTS_STATUS_SEARCHGW) { vMQTTS.Tretry = MQTTS_DEF_TSGW; vMQTTS.Nretry = MQTTS_DEF_NRETRY; } break; case MQTTS_MSGTYP_ADVERTISE: case MQTTS_MSGTYP_GWINFO: if(vMQTTS.Status == MQTTS_STATUS_SEARCHGW) { vMQTTS.GatewayID = pBuf->addr; vMQTTS.Status = MQTTS_STATUS_OFFLINE; vMQTTS.Tretry = 0; } break; #endif // GATEWAY case MQTTS_MSGTYP_CONNACK: if(vMQTTS.Status == MQTTS_STATUS_OFFLINE) { vMQTTS.pfCnt = POLL_TMR_FREQ - 1; if(pBuf->mq.m.connack.ReturnCode == MQTTS_RET_ACCEPTED) { vMQTTS.Status = MQTTS_STATUS_CONNECT; vMQTTS.Tretry = 0; vMQTTS.Nretry = MQTTS_DEF_NRETRY; vMQTTS.inMsgId = 0; // Publish Device Type if((vMQTTS.MsgID == 0) && (rf_GetNodeID() != 0xFF)) { pBuf->mq.Length = MQTTS_SIZEOF_CLIENTID - 1; ReadOD(objDeviceTyp, MQTTS_FL_TOPICID_PREDEF, &pBuf->mq.Length, (uint8_t *)&pBuf->mq.m.raw); MQTTS_Publish(objDeviceTyp, MQTTS_FL_QOS1 | MQTTS_FL_TOPICID_PREDEF, pBuf->mq.Length, (uint8_t *)&pBuf->mq.m.raw); } } else { MQTTS_Disconnect(); return 1; } } break; case MQTTS_MSGTYP_REGISTER: if(vMQTTS.Status < MQTTS_STATUS_CONNECT) break; tmp = mqtts_check_msgid(pBuf->mq.m.regist.MsgId); if(tmp == 0) // New message vMQTTS.ReturnCode = RegisterOD(pBuf); else if(tmp > 1) break; // Build RegAck Message pBuf->mq.Length = MQTTS_SIZEOF_MSG_REGACK; pBuf->mq.MsgType = MQTTS_MSGTYP_REGACK; pBuf->mq.m.regack.ReturnCode = vMQTTS.ReturnCode; MQTTS_Push(pBuf); return 1; case MQTTS_MSGTYP_REGACK: if((vMQTTS.Status == MQTTS_STATUS_CONNECT) && (vMQTTS.fBuf[vMQTTS.fTail]->mq.MsgType == MQTTS_MSGTYP_REGISTER)) { uint16_t index = 0; if(pBuf->mq.m.regack.ReturnCode == MQTTS_RET_ACCEPTED) index = SWAPWORD(pBuf->mq.m.regack.TopicId); RegAckOD(index); mqtts_inc_tail(); } break; case MQTTS_MSGTYP_PUBLISH: if((vMQTTS.Status != MQTTS_STATUS_CONNECT) #ifdef ASLEEP && (vMQTTS.Status !=MQTTS_STATUS_AWAKE) #endif // ASLEEP ) break; vMQTTS.pfCnt = (POLL_TMR_FREQ - 1); vMQTTS.Nretry = MQTTS_DEF_NRETRY; tmp = mqtts_check_msgid(pBuf->mq.m.publish.MsgId); if(tmp == 0) // New message { vMQTTS.ReturnCode = WriteOD(SWAPWORD(pBuf->mq.m.publish.TopicId), pBuf->mq.m.publish.Flags | 0x80, pBuf->mq.Length - MQTTS_SIZEOF_MSG_PUBLISH, (uint8_t *)&pBuf->mq.m.publish.Data); } else if((!(pBuf->mq.m.publish.Flags & MQTTS_FL_DUP)) || (tmp > 1)) break; uint8_t qos = pBuf->mq.m.publish.Flags & MQTTS_FL_QOS_MASK; if(qos == MQTTS_FL_QOS1) // Need Ack { pBuf->mq.Length = MQTTS_SIZEOF_MSG_PUBACK; pBuf->mq.MsgType = MQTTS_MSGTYP_PUBACK; pBuf->mq.m.puback.TopicId = pBuf->mq.m.publish.TopicId; pBuf->mq.m.puback.MsgId = pBuf->mq.m.publish.MsgId; pBuf->mq.m.puback.ReturnCode = vMQTTS.ReturnCode; MQTTS_Push(pBuf); return 1; } break; case MQTTS_MSGTYP_PUBACK: if((vMQTTS.Status == MQTTS_STATUS_CONNECT) && (vMQTTS.fBuf[vMQTTS.fTail]->mq.MsgType == MQTTS_MSGTYP_PUBLISH) && (vMQTTS.fBuf[vMQTTS.fTail]->mq.m.publish.MsgId == pBuf->mq.m.puback.MsgId)) mqtts_inc_tail(); break; case MQTTS_MSGTYP_SUBACK: if((vMQTTS.Status == MQTTS_STATUS_CONNECT) && (vMQTTS.fBuf[vMQTTS.fTail]->mq.MsgType == MQTTS_MSGTYP_SUBSCRIBE) && (vMQTTS.fBuf[vMQTTS.fTail]->mq.m.subscribe.MsgId == pBuf->mq.m.suback.MsgId)) mqtts_inc_tail(); break; case MQTTS_MSGTYP_PINGRESP: #ifdef ASLEEP if(vMQTTS.Status == MQTTS_STATUS_AWAKE) { vMQTTS.Status = MQTTS_STATUS_POST_AWAKE; } else #endif // ASLEEP if((vMQTTS.Status == MQTTS_STATUS_CONNECT) && (vMQTTS.tail == vMQTTS.head)) { vMQTTS.Tretry = MQTTS_DEF_KEEPALIVE; #ifdef ASLEEP if(vMQTTS.Tasleep != 0) { vMQTTS.Status = MQTTS_STATUS_POST_CONNECT; vMQTTS.pfCnt = 0; } #endif // ASLEEP } else break; vMQTTS.Nretry = MQTTS_DEF_NRETRY; vMQTTS.pfCnt = POLL_TMR_FREQ - 1; break; case MQTTS_MSGTYP_DISCONNECT: #ifdef ASLEEP if(vMQTTS.Status == MQTTS_STATUS_POST_CONNECT) { vMQTTS.Status = MQTTS_STATUS_PRE_ASLEEP; vMQTTS.pfCnt = POLL_TMR_FREQ - 1; break; } #endif // ASLEEP MQTTS_Disconnect(); return 1; } return 0; }