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); } } }
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); }
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); }
void UART_Send(void *pBuf) { if(!mqEnqueue(&uart_tx_queue, pBuf)) mqFree(pBuf); else uart_tx_task(); }
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); } } } }
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; } } }
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 }
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; } }
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; }
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; } } } } } }
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); } } }
// 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; }
// 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; }
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; } }