Example #1
0
// 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;
    }
Example #2
0
// 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;
    }
Example #3
0
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;
}