Example #1
0
void serDeleteOD(subidx_t * pSubidx)
{
    uint8_t port = pSubidx->Base / 10;
    
    uint8_t TxPin, RxPin;
    hal_uart_get_pins(port, &RxPin, &TxPin);

    if(extSerV[port] != NULL)
    {
        if(pSubidx->Type == ObjSerTx)
        {
            extSerV[port]->flags &= ~EXTSER_FLAG_TXEN;
        }
        else
        {
            extSerV[port]->flags &= ~EXTSER_FLAG_RXEN;

            if(extSerV[port]->pRxBuf != NULL)
            {
                mqFree(extSerV[port]->pRxBuf);
                extSerV[port]->pRxBuf = NULL;
            }
        }

        if((extSerV[port]->flags & (EXTSER_FLAG_TXEN | EXTSER_FLAG_RXEN)) == 0)
        {
            hal_uart_deinit(port);
            mqFree(extSerV[port]);
            extSerV[port] = NULL;
            
            dioRelease(TxPin);
            dioRelease(RxPin);
        }
    }
}
Example #2
0
void mqttsn_trace_msg(uint8_t Level, MQ_t * pMessage)
{
    if(pMessage == NULL)
        return;

    if(vMQ_Status != MQTTSN_STATUS_CONNECT)
    {
        mqFree(pMessage);
        return;
    }

    if(Level > lvlERROR)
        Level = lvlERROR;

    uint16_t TopicId = objLogD;
    TopicId += Level;
    mqttsn_new_msgid();

    pMessage->m.mq.MsgType = MQTTSN_MSGTYP_PUBLISH;
    pMessage->m.mq.publish.Flags = (MQTTSN_FL_QOS0 | MQTTSN_FL_TOPICID_PREDEF);
    pMessage->m.mq.publish.MsgId[0] = vMQ_MsgId>>8;
    pMessage->m.mq.publish.MsgId[1] = vMQ_MsgId & 0xFF;
    pMessage->m.mq.publish.TopicId[0] = TopicId>>8;
    pMessage->m.mq.publish.TopicId[1] = TopicId & 0xFF;
    pMessage->Length += MQTTSN_SIZEOF_MSG_PUBLISH;
    pMessage->m.mq.Length = pMessage->Length;
    memcpy(pMessage->phy1addr, vMQ_GatewayAddr, sizeof(PHY1_ADDR_t));
    PHY1_Send(pMessage);
}
Example #3
0
static void mqtts_forward_to_gate(MQ_t *pMsg)
{
    // Forward message on PHY1 from Remote Node to Gateway
    uint8_t Size = (MQTTSN_SIZEOF_MSG_FORWARD + sizeof(PHY1_ADDR_t) + 1);
    uint8_t Length = pMsg->Length + Size;
    uint8_t pos;

    if(Length > sizeof(MQTTSN_MESSAGE_t))
    {
        mqFree(pMsg);
        return;
    }

    // Don't use memcpy !
    for(pos = (Length - 1); pos >= Size; pos--)
        pMsg->m.raw[pos] = pMsg->m.raw[pos - Size];

    // Make forward message header
    pMsg->Length = Length;
    pMsg->m.mq.Length = Size;
    pMsg->m.mq.MsgType = MQTTSN_MSGTYP_FORWARD;
    pMsg->m.mq.m.forward.Ctrl = 0;   // ?? TTL
    pMsg->m.mq.m.forward.wNodeID[0] = 1;     // PHY1
    memcpy(&pMsg->m.mq.m.forward.wNodeID[1], pMsg->a.phy1addr, sizeof(PHY1_ADDR_t));
    memcpy(pMsg->a.phy1addr, vMQ_GatewayAddr, sizeof(PHY1_ADDR_t));
    PHY1_Send(pMsg);
}
Example #4
0
void UART_Send(void *pBuf)
{
    if(!mqEnqueue(&uart_tx_queue, pBuf))
        mqFree(pBuf);
    else
        uart_tx_task();
}
Example #5
0
static void uart_tx_task(void)
{
    static MQ_t   * pTx_buf = NULL;

    if(pTx_buf != NULL)
    {
        if(hal_uart_free(UART_PHY_PORT))
        {
            mqFree(pTx_buf);
            pTx_buf = NULL;
        }
    }

    if(uart_tx_queue.Size != 0)
    {
#ifdef LED_On
        LED_On();
#endif  //  LED_On
        if(hal_uart_free(UART_PHY_PORT))
        {
            pTx_buf = mqDequeue(&uart_tx_queue);
            // Paranoid check
            if(pTx_buf != NULL)
            {
                hal_uart_send(UART_PHY_PORT, (pTx_buf->Length + 1), &pTx_buf->Length);
            }
        }
    }
}
Example #6
0
void serInit()
{
    uint8_t port;
    
    for(port = 0; port < EXTSER_USED; port++)
    {
        hal_uart_deinit(port);
        if(extSerV[port] != NULL)
        {
            if(extSerV[port]->pTxBuf != NULL)
                mqFree(extSerV[port]->pTxBuf);

            mqFree(extSerV[port]);
            extSerV[port] = NULL;
        }
    }
}
Example #7
0
void UART_Init(void)
{
    MQ_t * pBuf;
    while((pBuf = mqDequeue(&uart_tx_queue)) != NULL)
        mqFree(pBuf);

    uint8_t Len = sizeof(UART_ADDR_t);
    ReadOD(UART_NODE_ID, MQTTSN_FL_TOPICID_PREDEF, &Len, (uint8_t *)&uart_addr);

    hal_uart_init_hw(UART_PHY_PORT, 4, 3);      // init uart 38400, Rx + Tx
}
Example #8
0
void hal_uart_deinit(uint8_t port)
{
    switch(port)
    {
#ifdef HAL_USE_USART0
        case HAL_USE_USART0:
            {
            UCSR0B = 0;
            UART0_PORT &= ~((1<<UART0_RX_PIN) | (1<<UART0_TX_PIN));
            UART0_DDR &= ~(1<<UART0_TX_PIN);
            }
            break;
#endif  //  HAL_USE_USART0
#ifdef HAL_USE_USART1
        case HAL_USE_USART1:
            {
            UCSR1B = 0;
            UART1_PORT &= ~((1<<UART1_RX_PIN) | (1<<UART1_TX_PIN));
            UART1_DDR &= ~(1<<UART1_TX_PIN);
            }
            break;
#endif  //  HAL_USE_USART1
#if (defined HAL_USE_USART2)
        case HAL_USE_USART2:
            {
            UCSR2B = 0;
            UART2_PORT &= ~((1<<UART2_RX_PIN) | (1<<UART2_TX_PIN));
            UART2_DDR &= ~(1<<UART2_TX_PIN);
            }
            break;
#endif  //  HAL_USE_USART2
#if (defined HAL_USE_USART3)
        case HAL_USE_USART3:
            {
            UCSR3B = 0;
            UART3_PORT &= ~((1<<UART3_RX_PIN) | (1<<UART3_TX_PIN));
            UART3_DDR &= ~(1<<UART3_TX_PIN);
            }
            break;
#endif  //  HAL_USE_USART3

        default:
            return;
    }

    if(hal_UARTv[port] != NULL)
    {
        mqFree(hal_UARTv[port]);
        hal_UARTv[port] = NULL;
    }
}
Example #9
0
void * UART_Get(void)
{
    uart_tx_task();
    
    // Rx Task
    static uint8_t  rx_pos = 0;
    static uint8_t  rx_len = 0;
    static MQ_t   * pRx_buf;
    static uint16_t rx_wd = 0;

    while(hal_uart_datardy(UART_PHY_PORT))
    {
        uint8_t data = hal_uart_get(UART_PHY_PORT);

        rx_wd = (HAL_get_ms() & 0xFFFF);

        if(rx_len == 0)
        {
            if((data >= 2) && (data < sizeof(MQTTSN_MESSAGE_t)))
            {
                pRx_buf = mqAlloc(sizeof(MQ_t));
                rx_len = data;
                rx_pos = 0;
            }
        }
        else
        {
            if(rx_pos < sizeof(MQTTSN_MESSAGE_t))
                pRx_buf->m.raw[rx_pos++] = data;

            if(rx_pos == rx_len)
            {
                memcpy(pRx_buf->a.phy1addr, (const void *)&uart_addr, sizeof(UART_ADDR_t));
                pRx_buf->Length = rx_len;
                rx_len = 0;
#ifdef LED_On
                LED_On();
#endif  //  LED_On
                return pRx_buf;
            }
        }
    }

    if((rx_len != 0) && (((HAL_get_ms() & 0xFFFF) - rx_wd) > 100))
    {
        rx_len = 0;
        mqFree(pRx_buf);
    }

    return NULL;
}
Example #10
0
void serProc(void)
{
    uint8_t port;

    for(port = 0; port < EXTSER_USED; port++)
    {
        if(extSerV[port] != NULL)
        {
            if(extSerV[port]->flags & EXTSER_FLAG_TXEN)
            {
                if((extSerV[port]->pTxBuf != NULL) && (hal_uart_free(port)))
                {
                    mqFree(extSerV[port]->pTxBuf);
                    extSerV[port]->pTxBuf = NULL;
                }
            }
            
            if(extSerV[port]->flags & EXTSER_FLAG_RXEN)
            {
                if(hal_uart_datardy(port))
                {
                    uint8_t tmphead = extSerV[port]->RxHead + 1;
                    if(tmphead >= sizeof(MQ_t))
                        tmphead = 0;

                    if(tmphead != extSerV[port]->RxTail)
                    {
                        extSerV[port]->pRxBuf[extSerV[port]->RxHead] = hal_uart_get(port);
                        extSerV[port]->RxHead = tmphead;
                        
                        uint8_t size;
                        
                        if(tmphead > extSerV[port]->RxTail)
                            size = tmphead - extSerV[port]->RxTail;
                        else
                            size = sizeof(MQ_t) - extSerV[port]->RxTail + tmphead;
                            
                        if(size < (sizeof(MQ_t)/2))
                            extSerV[port]->flags &= ~EXTSER_FLAG_RXRDY;
                        else
                            extSerV[port]->flags |= EXTSER_FLAG_RXRDY;
                    }
                }
            }
        }
    }
}
Example #11
0
static void uart_tx_task(void)
{
    static MQ_t   * pTx_buf = NULL;

    if(hal_uart_free(UART_PHY_PORT))
    {
        if(pTx_buf != NULL)
        {
            mqFree(pTx_buf);
            pTx_buf = NULL;
        }

        if(uart_tx_queue.Size != 0)
        {
            pTx_buf = mqDequeue(&uart_tx_queue);
            assert(pTx_buf != NULL);
            Activity(UART_PHY);
            hal_uart_send(UART_PHY_PORT, (pTx_buf->Length + 1), &pTx_buf->Length);
        }
    }
}
Example #12
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 #13
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 #14
0
void hal_uart_deinit(uint8_t port)
{
    switch(port)
    {
#if (defined HAL_USE_USART1)
        case HAL_USE_USART1:
            {
            USART1->CR1 &= ~USART_CR1_UE;               // Disable USART
            NVIC_DisableIRQ(USART1_IRQn);               // Disable USART IRQ

            RCC->APB2RSTR |= RCC_APB2RSTR_USART1RST;    // Reset USART
            RCC->APB2RSTR &= ~RCC_APB2RSTR_USART1RST;

            RCC->APB2ENR  &= ~RCC_APB2ENR_USART1EN;     // Disable UART1 Clock
#if (defined HAL_USE_ALT_USART1)
            hal_dio_gpio_cfg(GPIOB, GPIO_Pin_6 | GPIO_Pin_7, DIO_MODE_IN_FLOAT);
#else
            hal_dio_gpio_cfg(GPIOA, GPIO_Pin_9 | GPIO_Pin_10, DIO_MODE_IN_FLOAT);
#endif  //  HAL_USE_ALT_USART1
            }
            break;
#endif  //  USART1
#if (defined HAL_USE_USART2)
        case HAL_USE_USART2:
            {
            USART2->CR1 &= ~USART_CR1_UE;               // Disable USART
            NVIC_DisableIRQ(USART2_IRQn);               // Disable USART IRQ

            RCC->APB1RSTR |= RCC_APB1RSTR_USART2RST;    // Reset USART
            RCC->APB1RSTR &= ~RCC_APB1RSTR_USART2RST;

            RCC->APB1ENR   &= ~RCC_APB1ENR_USART2EN;    // Disable UART2 Clock
            
            hal_dio_gpio_cfg(GPIOA, GPIO_Pin_2 | GPIO_Pin_3, DIO_MODE_IN_FLOAT);
            }
            break;
#endif  //  USART2
#if (defined HAL_USE_USART3)
        case HAL_USE_USART3:
            {
            USART3->CR1 &= ~USART_CR1_UE;               // Disable USART
            NVIC_DisableIRQ(USART3_IRQn);               // Disable USART IRQ

            RCC->APB1RSTR |= RCC_APB1RSTR_USART3RST;    // Reset USART
            RCC->APB1RSTR &= ~RCC_APB1RSTR_USART3RST;

            RCC->APB1ENR   &= ~RCC_APB1ENR_USART3EN;    // Disable UART2 Clock
            
            hal_dio_gpio_cfg(GPIOB, GPIO_Pin_10 | GPIO_Pin_11, DIO_MODE_IN_FLOAT);
            }
            break;
#endif  //  USART3
#if (defined HAL_USE_UART4)
        case HAL_USE_UART4:
            {
            UART4->CR1 &= ~USART_CR1_UE;                // Disable USART
            NVIC_DisableIRQ(UART4_IRQn);                // Disable USART IRQ

            RCC->APB1RSTR |= RCC_APB1RSTR_UART4RST;     // Reset USART
            RCC->APB1RSTR &= ~RCC_APB1RSTR_UART4RST;

            RCC->APB1ENR   &= ~RCC_APB1ENR_UART4EN;     // Disable UART2 Clock
            
            hal_dio_gpio_cfg(GPIOA, GPIO_Pin_0 | GPIO_Pin_1, DIO_MODE_IN_FLOAT);
            }
            break;
#endif  //  UART4
        default:
            assert(0);
    }

    if(hal_UARTv[port] != NULL)
    {
        mqFree(hal_UARTv[port]);
        hal_UARTv[port] = NULL;
    }
}