4.4. Operating as a Router

Linux作为路由器的配置
本文介绍了如何通过配置Linux系统来实现路由器功能,包括IP包转发、状态无关的NAT、透明代理及伪装等网络技术。文章重点讲解了sysctl设置net.ipv4.ip_forward的重要性,并说明了如何针对不同接口定制转发行为。

4.4. Operating as a Router

Operating as a router allows a linux machine to accept packets on one interface and transmit them on another. This is the nature of a router. The process of accepting and transmitting IP packets is known as forwarding. IP forwarding is a requirement for many of the networking techniques identified here. Stateless NAT and firewalling, transparent proxying and masquerading all require the support of IP forwarding in order to function correctly.

The sysctl net/ipv4/ip_forward toggles the IP forwarding functionality on a linux box. Note that setting this sysctl alters other routing-related sysctl entries, so it is wise to set this first, and then alter other entries. Frequently, an administrator will forget this simple and crucial detail when configuring a new machine to operate as a router only to be frustrated at the simple error.

The sysctl net/ipv4/conf/$DEV/forward defaults to the value of net/ipv4/ip_forward, but can be independently modified. In order to allow forwarding of packets between two interfaces while prohibiting such behaviour on a third interface, this sysctl can be employed.

#ifndef __USART_H #define __USART_H #include "stdio.h" #include "sys.h" #define USART_REC_LEN 200 //֨ӥخճޓ˕ؖޚ˽ 200 #define EN_USART1_RX 1 //ʹŜè1é/޻ֹè0éԮࠚ1ޓ˕ extern u8 USART_RX_BUF[USART_REC_LEN]; //ޓ˕ۺԥ,خճUSART_REC_LENٶؖޚ.ĩؖޚΪۻѐػ extern u16 USART_RX_STA; //ޓ˕״̬Ҫ݇ //ɧڻЫԮࠚא׏ޓ˕ìȫһҪעˍӔЂ۪֨ӥ void uart1_init(u32 bound); void uart2_init(u32 bound); #endif #include "sys.h" #include "usart.h" #include "gizwits_product.h" #if 1 #pragma import(__use_no_semihosting) //Ҫ׼ࠢѨҪք֧Ԗگ˽ struct __FILE { int handle; }; FILE __stdout; //֨ӥ_sys_exit()ӔҜĢʹԃѫ׷ܺģʽ void _sys_exit(int x) { x = x; } //ט֨ӥfputcگ˽ int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0);//ѭ۷ע̍,ֱսע̍Ϊҏ USART1->DR = (u8) ch; return ch; } #endif #if EN_USART1_RX //ɧڻʹŜ‹ޓ˕ //Ԯࠚ1א׏ؾϱԌѲ //עӢ,ׁȡUSARTx->SRŜҜĢĪĻǤĮքխϳ u8 USART_RX_BUF[USART_REC_LEN]; //ޓ˕ۺԥ,خճUSART_REC_LENٶؖޚ. //ޓ˕״̬ //bit15ì ޓ˕ΪԉҪ־ //bit14ì ޓ˕ս0x0d //bit13~0ì ޓ˕սքԐЧؖޚ˽Ŀ u16 USART_RX_STA=0; //ޓ˕״̬Ҫ݇ void uart1_init(u32 bound){ //GPIO׋ࠚʨ׃ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //ʹŜUSART1ìGPIOAʱד //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //شԃΆάˤԶ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.9 //USART1_RX GPIOA.10Եʼۯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//ءࠕˤɫ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.10 //Usart1 NVIC Ƥ׃ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ȀռԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //ؓԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨրʹŜ NVIC_Init(&NVIC_InitStructure); //ٹߝָ֨քӎ˽ԵʼۯVIC݄զǷ //USART Եʼۯʨ׃ USART_InitStructure.USART_BaudRate = bound;//ԮࠚҨ͘Ê USART_InitStructure.USART_WordLength = USART_WordLength_8b;//ؖӤΪ8λ˽ߝٱʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//һٶֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ϞǦżУҩλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ϞӲݾ˽ߝ·࠘׆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˕עģʽ USART_Init(USART1, &USART_InitStructure); //ԵʼۯԮࠚ1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//ߪǴԮࠚޓ˜א׏ USART_Cmd(USART1, ENABLE); //ʹŜԮࠚ1 } void uart2_init(u32 bound){ //GPIO׋ࠚʨ׃ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //ʹŜUSART2ìGPIOAʱד RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //شԃΆάˤԶ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.9 //USART1_RX GPIOA.10Եʼۯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//ءࠕˤɫ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.10 //Usart1 NVIC Ƥ׃ NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ȀռԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //ؓԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨրʹŜ NVIC_Init(&NVIC_InitStructure); //ٹߝָ֨քӎ˽ԵʼۯVIC݄զǷ //USART Եʼۯʨ׃ USART_InitStructure.USART_BaudRate = bound;//ԮࠚҨ͘Ê USART_InitStructure.USART_WordLength = USART_WordLength_8b;//ؖӤΪ8λ˽ߝٱʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//һٶֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ϞǦżУҩλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ϞӲݾ˽ߝ·࠘׆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˕עģʽ USART_Init(USART2, &USART_InitStructure); //ԵʼۯԮࠚ1 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//ߪǴԮࠚޓ˜א׏ USART_Cmd(USART2, ENABLE); //ʹŜԮࠚ1 } void USART1_IRQHandler(void) //Ԯࠚ1א׏ؾϱԌѲ { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //ޓ˕א׏(ޓ˕սք˽ߝҘѫˇ0x0d 0x0aޡβ) { USART_ClearITPendingBit(USART1,USART_IT_RXNE); Res =USART_ReceiveData(USART1); //ׁȡޓ˕սք˽ߝ } } void USART2_IRQHandler(void) //Ԯࠚ2א׏ؾϱԌѲ { u8 Res; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //ޓ˕א׏(ޓ˕սք˽ߝҘѫˇ0x0d 0x0aޡβ) { USART_ClearITPendingBit(USART2,USART_IT_RXNE); Res =USART_ReceiveData(USART2); //ׁȡޓ˕սք˽ߝ // 使用缓冲区而不是直接处理 static uint8_t uart2_buffer[256]; static int index = 0; if(index < 255) { uart2_buffer[index++] = Res; } // 每收到16字节或超时处理一次 if(index >= 16 || Res == '\n') { gizPutData(uart2_buffer, index); index = 0; } } } #endif /** ************************************************************ * @file gizwits_product.c * @brief Gizwits control protocol processing, and platform-related hardware initialization * @author Gizwits * @date 2017-07-19 * @version V03030000 * @copyright Gizwits * * @note Gizwits is only for smart hardware * Gizwits Smart Cloud for Smart Products * Links | Value Added | Open | Neutral | Safety | Own | Free | Ecology * www.gizwits.com * ***********************************************************/ #include <stdio.h> #include <string.h> #include "gizwits_product.h" #include "usart.h" #include "LED.h" #include "Fan.h" static uint32_t timerMsCount; extern u8 temp; extern u8 humi; extern u8 light_intensity; /** Current datapoint */ dataPoint_t currentDataPoint; /**@} */ /**@name Gizwits User Interface * @{ */ /** * @brief Event handling interface * Description: * 1. Users can customize the changes in WiFi module status * 2. Users can add data points in the function of event processing logic, such as calling the relevant hardware peripherals operating interface * @param [in] info: event queue * @param [in] data: protocol data * @param [in] len: protocol data length * @return NULL * @ref gizwits_protocol.h */ int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *gizdata, uint32_t len) { uint8_t i = 0; dataPoint_t *dataPointPtr = (dataPoint_t *)gizdata; moduleStatusInfo_t *wifiData = (moduleStatusInfo_t *)gizdata; protocolTime_t *ptime = (protocolTime_t *)gizdata; #if MODULE_TYPE gprsInfo_t *gprsInfoData = (gprsInfo_t *)gizdata; #else moduleInfo_t *ptModuleInfo = (moduleInfo_t *)gizdata; #endif if((NULL == info) || (NULL == gizdata)) { return -1; } for(i=0; i<info->num; i++) { switch(info->event[i]) { case EVENT_Fan_OnOff: currentDataPoint.valueFan_OnOff = dataPointPtr->valueFan_OnOff; GIZWITS_LOG("Evt: EVENT_Fan_OnOff %d \n", currentDataPoint.valueFan_OnOff); if(0x01 == currentDataPoint.valueFan_OnOff) { Control_Fan(1);//user handle } else { Control_Fan(0);//user handle } break; case EVENT_LED_OnOff: currentDataPoint.valueLED_OnOff = dataPointPtr->valueLED_OnOff; GIZWITS_LOG("Evt: EVENT_LED_OnOff %d \n", currentDataPoint.valueLED_OnOff); if(0x01 == currentDataPoint.valueLED_OnOff) { Control_Light(1);//user handle } else { Control_Light(0);//user handle } break; case WIFI_SOFTAP: break; case WIFI_AIRLINK: break; case WIFI_STATION: break; case WIFI_CON_ROUTER: break; case WIFI_DISCON_ROUTER: break; case WIFI_CON_M2M: break; case WIFI_DISCON_M2M: break; case WIFI_RSSI: GIZWITS_LOG("RSSI %d\n", wifiData->rssi); break; case TRANSPARENT_DATA: GIZWITS_LOG("TRANSPARENT_DATA \n"); //user handle , Fetch data from [data] , size is [len] break; case WIFI_NTP: GIZWITS_LOG("WIFI_NTP : [%d-%d-%d %02d:%02d:%02d][%d] \n",ptime->year,ptime->month,ptime->day,ptime->hour,ptime->minute,ptime->second,ptime->ntp); break; case MODULE_INFO: GIZWITS_LOG("MODULE INFO ...\n"); #if MODULE_TYPE GIZWITS_LOG("GPRS MODULE ...\n"); //Format By gprsInfo_t GIZWITS_LOG("moduleType : [%d] \n",gprsInfoData->Type); #else GIZWITS_LOG("WIF MODULE ...\n"); //Format By moduleInfo_t GIZWITS_LOG("moduleType : [%d] \n",ptModuleInfo->moduleType); #endif break; default: break; } } return 0; } /** * User data acquisition * Here users need to achieve in addition to data points other than the collection of data collection, can be self-defined acquisition frequency and design data filtering algorithm * @param none * @return none */ void userHandle(void) { currentDataPoint.valuetemp = temp;//Add Sensor Data Collection currentDataPoint.valuehumi = humi;//Add Sensor Data Collection currentDataPoint.valuelight = light_intensity;//Add Sensor Data Collection } /** * Data point initialization function * In the function to complete the initial user-related data * @param none * @return none * @note The developer can add a data point state initialization value within this function */ void userInit(void) { memset((uint8_t*)&currentDataPoint, 0, sizeof(dataPoint_t)); /** Warning !!! DataPoint Variables Init , Must Within The Data Range **/ currentDataPoint.valueFan_OnOff = 0; currentDataPoint.valueLED_OnOff = 0; currentDataPoint.valuetemp = 0; currentDataPoint.valuehumi = 0; currentDataPoint.valuelight = 0; } /** * @brief gizTimerMs * millisecond timer maintenance function ,Millisecond increment , Overflow to zero * @param none * @return none */ void gizTimerMs(void) { timerMsCount++; } /** * @brief gizGetTimerCount * Read system time, millisecond timer * @param none * @return System time millisecond */ uint32_t gizGetTimerCount(void) { return timerMsCount; } /** * @brief mcuRestart * MCU Reset function * @param none * @return none */ void mcuRestart(void) { __set_FAULTMASK(1); NVIC_SystemReset(); } /**@} */ /** * @brief TIMER_IRQ_FUN * Timer Interrupt handler function * @param none * @return none */ void TIMER_IRQ_FUN(void) { gizTimerMs(); } /** * @brief UART_IRQ_FUN * UART Serial interrupt function ,For Module communication * Used to receive serial port protocol data between WiFi module * @param none * @return none */ void UART_IRQ_FUN(void) { uint8_t value = 0; //value = USART_ReceiveData(USART2);//STM32 test demo gizPutData(&value, 1); } /** * @brief uartWrite * Serial write operation, send data to the WiFi module * @param buf : Data address * @param len : Data length * * @return : Not 0,Serial send success; * -1,Input Param Illegal */ int32_t uartWrite(uint8_t *buf, uint32_t len) { uint32_t i = 0; if(NULL == buf) { return -1; } #ifdef PROTOCOL_DEBUG GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len); for(i=0; i<len; i++) { GIZWITS_LOG("%02x ", buf[i]); } GIZWITS_LOG("\n"); #endif for(i=0; i<len; i++) { USART_SendData(USART1, buf[i]);//STM32 test demo while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//Serial port to achieve the function, the buf[i] sent to the module if(i >=2 && buf[i] == 0xFF) { USART_SendData(USART1,0x55); while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //Serial port to achieve the function, the 0x55 sent to the module //USART_SendData(UART, 0x55);//STM32 test demo } } return len; } #include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "DHT11.h" #include "LED.h" #include "Light_Sensor.h" // 光敏电阻驱动(PA7) #include "Fan.h" #include "Buzzer.h" #include "TIM3.h" // TIM3定时器(1ms中断) #include "usart.h" // 串口通信(含机智云数据传输) #include "gizwits_product.h" // 机智云SDK #include "gizwits_protocol.h" // 阈值定义 #define TEMP_THRESHOLD 29 // 温度阈值(℃) #define LIGHT_THRESHOLD 128 // 光照阈值(0-255) extern uint8_t temp; extern uint8_t humi; extern dataPoint_t currentDataPoint; // 全局变量 uint8_t light_intensity; // 光照强度 void controlPeripherals(void) { // 温度控制风扇 if (temp > TEMP_THRESHOLD) { Control_Fan(1); // 风扇开启 currentDataPoint.valueFan_OnOff = 1; // 更新机智云风扇状态 OLED_ShowString(4, 1, "Fan: ON "); } else { Control_Fan(0); // 风扇关闭 currentDataPoint.valueFan_OnOff = 0; // 更新机智云风扇状态 OLED_ShowString(4, 1, "Fan: OFF"); } // 光照控制LED if (light_intensity < LIGHT_THRESHOLD) { Control_Light(1); // 光照不足,开灯 currentDataPoint.valueLED_OnOff = 1; } else { Control_Light(0); // 光照充足,关灯 currentDataPoint.valueLED_OnOff = 0; } // 超阈值报警(温度+湿度) if (temp > TEMP_THRESHOLD) { Buzzer_ON(); // 蜂鸣器报警 } else { Buzzer_OFF(); // 停止报警 } } // OLED显示更新 void updateOLED(void) { // 光照显示 OLED_ShowString(1, 1, "Light:"); OLED_ShowNum(1, 7, light_intensity, 3); OLED_ShowString(1, 10, "/255"); // 温度显示 OLED_ShowString(2, 1, "Temp:"); if(temp == 0xFF) { // 0xFF表示读取错误 OLED_ShowString(2, 6, "ERR"); } else { OLED_ShowNum(2, 6, temp, 2); OLED_ShowCC_F16x16(2, 8, 0); // 显示℃ } // 湿度显示 OLED_ShowString(3, 1, "Humi:"); OLED_ShowNum(3, 6, humi, 2); OLED_ShowCC_F16x16(3, 8, 1); // %显示 } int main(void) { // 初始化外设(按依赖顺序) NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Delay_Init(); uart1_init(115200); // 初始化USART1,用于printf输出 uart2_init(115200); printf("UART1 and UART2 initialized.\r\n"); // 现在应该可以输出 OLED_Init(); // OLED显示屏 OLED_ShowString(1, 1, "System Start"); Delay_ms(1000); OLED_Clear(); LED_Init(); // LED初始化 LightSensor_Init(); // 光敏电阻初始化(PA7) ADC1_Init(); // ADC初始化(读取光敏电阻) DHT11_UserConfig(); // DHT11温湿度传感器初始化 Fan_Init(); // 风扇初始化 Buzzer_Init(); // 蜂鸣器初始化 GENERAL_TIM_Init(); // TIM3初始化(1ms中断,机智云定时) userInit(); // 机智云用户初始化 gizwitsInit(); gizwitsSetMode(WIFI_AIRLINK_MODE); // 机智云设备初始化 Delay_ms(500); OLED_Clear(); // 清屏准备正式显示 while (1) { light_intensity = Get_Light_Intensity(); // 1. 采集传感器数据 collectSensorData(); // 2. 更新机智云数据点(供云端读取) currentDataPoint.valuetemp = temp; // 温度数据 currentDataPoint.valuehumi = humi; // 湿度数据 currentDataPoint.valuelight = light_intensity;// 光照数据 // 3. 控制外设(风扇、LED、蜂鸣器) controlPeripherals(); // 4. 更新OLED显示 updateOLED(); // 5. 机智云任务处理(数据上报/指令接收) userHandle(); // 用户自定义处理 gizwitsHandle(&currentDataPoint); // 机智云核心处理 // 6. 延时,降低CPU占用 Delay_ms(200); } } /** ************************************************************ * @file gizwits_protocol.c * @brief Corresponding gizwits_product.c header file (including product hardware and software version definition) * @author Gizwits * @date 2017-07-19 * @version V03030000 * @copyright Gizwits * * @note 机智云.只为智能硬件而生 * Gizwits Smart Cloud for Smart Products * 链接|增值ֵ|开放|中立|安全|自有|自由|生态 * www.gizwits.com * ***********************************************************/ #include "ringBuffer.h" #include "gizwits_product.h" #include "dataPointTools.h" /** Protocol global variables **/ gizwitsProtocol_t gizwitsProtocol; /**@name The serial port receives the ring buffer implementation * @{ */ rb_t pRb; ///< Ring buffer structure variable static uint8_t rbBuf[RB_MAX_LEN]; ///< Ring buffer data cache buffer /**@} */ /** * @brief Write data to the ring buffer * @param [in] buf : buf adress * @param [in] len : byte length * @return correct : Returns the length of the written data failure : -1 */ int32_t gizPutData(uint8_t *buf, uint32_t len) { int32_t count = 0; if(NULL == buf) { GIZWITS_LOG("ERR: gizPutData buf is empty \n"); return -1; } count = rbWrite(&pRb, buf, len); if(count != len) { GIZWITS_LOG("ERR: Failed to rbWrite \n"); return -1; } return count; } /** * @brief Protocol header initialization * * @param [out] head : Protocol header pointer * * @return 0, success; other, failure */ static int8_t gizProtocolHeadInit(protocolHead_t *head) { if(NULL == head) { GIZWITS_LOG("ERR: gizProtocolHeadInit head is empty \n"); return -1; } memset((uint8_t *)head, 0, sizeof(protocolHead_t)); head->head[0] = 0xFF; head->head[1] = 0xFF; return 0; } /** * @brief Protocol ACK check processing function * * @param [in] data : data adress * @param [in] len : data length * * @return 0, suceess; other, failure */ static int8_t gizProtocolWaitAck(uint8_t *gizdata, uint32_t len) { if(NULL == gizdata) { GIZWITS_LOG("ERR: data is empty \n"); return -1; } memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); memcpy((uint8_t *)gizwitsProtocol.waitAck.buf, gizdata, len); gizwitsProtocol.waitAck.dataLen = (uint16_t)len; gizwitsProtocol.waitAck.flag = 1; gizwitsProtocol.waitAck.sendTime = gizGetTimerCount(); return 0; } /** * @brief generates "controlled events" according to protocol * @param [in] issuedData: Controlled data * @param [out] info: event queue * @param [out] dataPoints: data point data * @return 0, the implementation of success, non-0, failed */ static int8_t ICACHE_FLASH_ATTR gizDataPoint2Event(gizwitsIssued_t *issuedData, eventInfo_t *info, dataPoint_t *dataPoints) { if((NULL == issuedData) || (NULL == info) ||(NULL == dataPoints)) { GIZWITS_LOG("gizDataPoint2Event Error , Illegal Param\n"); return -1; } /** Greater than 1 byte to do bit conversion **/ if(sizeof(issuedData->attrFlags) > 1) { if(-1 == gizByteOrderExchange((uint8_t *)&issuedData->attrFlags,sizeof(attrFlags_t))) { GIZWITS_LOG("gizByteOrderExchange Error\n"); return -1; } } if(0x01 == issuedData->attrFlags.flagFan_OnOff) { info->event[info->num] = EVENT_Fan_OnOff; info->num++; dataPoints->valueFan_OnOff = gizStandardDecompressionValue(Fan_OnOff_BYTEOFFSET,Fan_OnOff_BITOFFSET,Fan_OnOff_LEN,(uint8_t *)&issuedData->attrVals.wBitBuf,sizeof(issuedData->attrVals.wBitBuf)); } if(0x01 == issuedData->attrFlags.flagLED_OnOff) { info->event[info->num] = EVENT_LED_OnOff; info->num++; dataPoints->valueLED_OnOff = gizStandardDecompressionValue(LED_OnOff_BYTEOFFSET,LED_OnOff_BITOFFSET,LED_OnOff_LEN,(uint8_t *)&issuedData->attrVals.wBitBuf,sizeof(issuedData->attrVals.wBitBuf)); } return 0; } /** * @brief contrasts the current data with the last data * * @param [in] cur: current data point data * @param [in] last: last data point data * * @return: 0, no change in data; 1, data changes */ static int8_t ICACHE_FLASH_ATTR gizCheckReport(dataPoint_t *cur, dataPoint_t *last) { int8_t ret = 0; static uint32_t lastReportTime = 0; uint32_t currentTime = 0; if((NULL == cur) || (NULL == last)) { GIZWITS_LOG("gizCheckReport Error , Illegal Param\n"); return -1; } currentTime = gizGetTimerCount(); if(last->valueFan_OnOff != cur->valueFan_OnOff) { GIZWITS_LOG("valueFan_OnOff Changed\n"); ret = 1; } if(last->valueLED_OnOff != cur->valueLED_OnOff) { GIZWITS_LOG("valueLED_OnOff Changed\n"); ret = 1; } if(last->valuetemp != cur->valuetemp) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuetemp Changed\n"); ret = 1; } } if(last->valuehumi != cur->valuehumi) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuehumi Changed\n"); ret = 1; } } if(last->valuelight != cur->valuelight) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuelight Changed\n"); ret = 1; } } if(1 == ret) { lastReportTime = gizGetTimerCount(); } return ret; } /** * @brief User data point data is converted to wit the cloud to report data point data * * @param [in] dataPoints: user data point data address * @param [out] devStatusPtr: wit the cloud data point data address * * @return 0, the correct return; -1, the error returned */ static int8_t ICACHE_FLASH_ATTR gizDataPoints2ReportData(dataPoint_t *dataPoints , devStatus_t *devStatusPtr) { if((NULL == dataPoints) || (NULL == devStatusPtr)) { GIZWITS_LOG("gizDataPoints2ReportData Error , Illegal Param\n"); return -1; } gizMemset((uint8_t *)devStatusPtr->wBitBuf,0,sizeof(devStatusPtr->wBitBuf)); gizStandardCompressValue(Fan_OnOff_BYTEOFFSET,Fan_OnOff_BITOFFSET,Fan_OnOff_LEN,(uint8_t *)devStatusPtr,dataPoints->valueFan_OnOff); gizStandardCompressValue(LED_OnOff_BYTEOFFSET,LED_OnOff_BITOFFSET,LED_OnOff_LEN,(uint8_t *)devStatusPtr,dataPoints->valueLED_OnOff); gizByteOrderExchange((uint8_t *)devStatusPtr->wBitBuf,sizeof(devStatusPtr->wBitBuf)); devStatusPtr->valuetemp = gizY2X(temp_RATIO, temp_ADDITION, dataPoints->valuetemp); devStatusPtr->valuehumi = gizY2X(humi_RATIO, humi_ADDITION, dataPoints->valuehumi); devStatusPtr->valuelight = exchangeBytes(gizY2X(light_RATIO, light_ADDITION, dataPoints->valuelight)); return 0; } /** * @brief This function is called by the Gagent module to receive the relevant protocol data from the cloud or APP * @param [in] inData The protocol data entered * @param [in] inLen Enter the length of the data * @param [out] outData The output of the protocol data * @param [out] outLen The length of the output data * @return 0, the implementation of success, non-0, failed */ static int8_t gizProtocolIssuedProcess(char *did, uint8_t *inData, uint32_t inLen, uint8_t *outData, uint32_t *outLen) { uint8_t issuedAction = inData[0]; if((NULL == inData)||(NULL == outData)||(NULL == outLen)) { GIZWITS_LOG("gizProtocolIssuedProcess Error , Illegal Param\n"); return -1; } if(NULL == did) { memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent, 0, sizeof(eventInfo_t)); switch(issuedAction) { case ACTION_CONTROL_DEVICE: gizDataPoint2Event((gizwitsIssued_t *)&inData[1], &gizwitsProtocol.issuedProcessEvent,&gizwitsProtocol.gizCurrentDataPoint); gizwitsProtocol.issuedFlag = ACTION_CONTROL_TYPE; outData = NULL; *outLen = 0; break; case ACTION_READ_DEV_STATUS: if(0 == gizDataPoints2ReportData(&gizwitsProtocol.gizLastDataPoint,&gizwitsProtocol.reportData.devStatus)) { memcpy(outData+1, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(gizwitsReport_t)); outData[0] = ACTION_READ_DEV_STATUS_ACK; *outLen = sizeof(gizwitsReport_t)+1; } else { return -1; } break; case ACTION_W2D_TRANSPARENT_DATA: memcpy(gizwitsProtocol.transparentBuff, &inData[1], inLen-1); gizwitsProtocol.transparentLen = inLen - 1; gizwitsProtocol.issuedProcessEvent.event[gizwitsProtocol.issuedProcessEvent.num] = TRANSPARENT_DATA; gizwitsProtocol.issuedProcessEvent.num++; gizwitsProtocol.issuedFlag = ACTION_W2D_TRANSPARENT_TYPE; outData = NULL; *outLen = 0; break; default: break; } } return 0; } /** * @brief The protocol sends data back , P0 ACK * * @param [in] head : Protocol head pointer * @param [in] data : Payload data * @param [in] len : Payload data length * @param [in] proFlag : DID flag ,1 for Virtual sub device did ,0 for single product or gateway * * @return : 0,Ack success; * -1,Input Param Illegal * -2,Serial send faild */ static int32_t gizProtocolIssuedDataAck(protocolHead_t *head, uint8_t *gizdata, uint32_t len, uint8_t proFlag) { int32_t ret = 0; uint8_t tx_buf[RB_MAX_LEN]; uint32_t offset = 0; uint8_t sDidLen = 0; uint16_t data_len = 0; uint8_t *pTxBuf = tx_buf; if(NULL == gizdata) { GIZWITS_LOG("[ERR] data Is Null \n"); return -1; } if(0x1 == proFlag) { sDidLen = *((uint8_t *)head + sizeof(protocolHead_t)); data_len = 5 + 1 + sDidLen + len; } else { data_len = 5 + len; } GIZWITS_LOG("len = %d , sDidLen = %d ,data_len = %d\n", len,sDidLen,data_len); *pTxBuf ++= 0xFF; *pTxBuf ++= 0xFF; *pTxBuf ++= (uint8_t)(data_len>>8); *pTxBuf ++= (uint8_t)(data_len); *pTxBuf ++= head->cmd + 1; *pTxBuf ++= head->sn; *pTxBuf ++= 0x00; *pTxBuf ++= proFlag; offset = 8; if(0x1 == proFlag) { *pTxBuf ++= sDidLen; offset += 1; memcpy(&tx_buf[offset],(uint8_t *)head+sizeof(protocolHead_t)+1,sDidLen); offset += sDidLen; pTxBuf += sDidLen; } if(0 != len) { memcpy(&tx_buf[offset],gizdata,len); } tx_buf[data_len + 4 - 1 ] = gizProtocolSum( tx_buf , (data_len+4)); ret = uartWrite(tx_buf, data_len+4); if(ret < 0) { GIZWITS_LOG("uart write error %d \n", ret); return -2; } return 0; } /** * @brief Report data interface * * @param [in] action : PO action * @param [in] data : Payload data * @param [in] len : Payload data length * * @return : 0,Ack success; * -1,Input Param Illegal * -2,Serial send faild */ static int32_t gizReportData(uint8_t action, uint8_t *gizdata, uint32_t len) { int32_t ret = 0; protocolReport_t protocolReport; if(NULL == gizdata) { GIZWITS_LOG("gizReportData Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&protocolReport); protocolReport.head.cmd = CMD_REPORT_P0; protocolReport.head.sn = gizwitsProtocol.sn++; protocolReport.action = action; protocolReport.head.len = exchangeBytes(sizeof(protocolReport_t)-4); memcpy((gizwitsReport_t *)&protocolReport.reportData, (gizwitsReport_t *)gizdata,len); protocolReport.sum = gizProtocolSum((uint8_t *)&protocolReport, sizeof(protocolReport_t)); ret = uartWrite((uint8_t *)&protocolReport, sizeof(protocolReport_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); return -2; } gizProtocolWaitAck((uint8_t *)&protocolReport, sizeof(protocolReport_t)); return ret; }/** * @brief Datapoints reporting mechanism * * 1. Changes are reported immediately * 2. Data timing report , 600000 Millisecond * *@param [in] currentData : Current datapoints value * @return : NULL */ static void gizDevReportPolicy(dataPoint_t *currentData) { static uint32_t lastRepTime = 0; uint32_t timeNow = gizGetTimerCount(); if((1 == gizCheckReport(currentData, (dataPoint_t *)&gizwitsProtocol.gizLastDataPoint))) { GIZWITS_LOG("changed, report data\n"); if(0 == gizDataPoints2ReportData(currentData,&gizwitsProtocol.reportData.devStatus)) { gizReportData(ACTION_REPORT_DEV_STATUS, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(devStatus_t)); } memcpy((uint8_t *)&gizwitsProtocol.gizLastDataPoint, (uint8_t *)currentData, sizeof(dataPoint_t)); } if((0 == (timeNow % (600000))) && (lastRepTime != timeNow)) { GIZWITS_LOG("Info: 600S report data\n"); if(0 == gizDataPoints2ReportData(currentData,&gizwitsProtocol.reportData.devStatus)) { gizReportData(ACTION_REPORT_DEV_STATUS, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(devStatus_t)); } memcpy((uint8_t *)&gizwitsProtocol.gizLastDataPoint, (uint8_t *)currentData, sizeof(dataPoint_t)); lastRepTime = timeNow; } } /** * @brief Get a packet of data from the ring buffer * * @param [in] rb : Input data address * @param [out] data : Output data address * @param [out] len : Output data length * * @return : 0,Return correct ;-1,Return failure;-2,Data check failure */ static int8_t gizProtocolGetOnePacket(rb_t *rb, uint8_t *gizdata, uint16_t *len) { int32_t ret = 0; uint8_t sum = 0; int32_t i = 0; uint8_t tmpData; uint16_t tmpLen = 0; uint16_t tmpCount = 0; static uint8_t protocolFlag = 0; static uint16_t protocolCount = 0; static uint8_t lastData = 0; static uint8_t debugCount = 0; uint8_t *protocolBuff = gizdata; protocolHead_t *head = NULL; if((NULL == rb) || (NULL == gizdata) ||(NULL == len)) { GIZWITS_LOG("gizProtocolGetOnePacket Error , Illegal Param\n"); return -1; } tmpLen = rbCanRead(rb); if(0 == tmpLen) { return -1; } for(i=0; i<tmpLen; i++) { ret = rbRead(rb, &tmpData, 1); if(0 != ret) { if((0xFF == lastData) && (0xFF == tmpData)) { if(0 == protocolFlag) { protocolBuff[0] = 0xFF; protocolBuff[1] = 0xFF; protocolCount = 2; protocolFlag = 1; } else { if((protocolCount > 4) && (protocolCount != tmpCount)) { protocolBuff[0] = 0xFF; protocolBuff[1] = 0xFF; protocolCount = 2; } } } else if((0xFF == lastData) && (0x55 == tmpData)) { } else { if(1 == protocolFlag) { protocolBuff[protocolCount] = tmpData; protocolCount++; if(protocolCount > 4) { head = (protocolHead_t *)protocolBuff; tmpCount = exchangeBytes(head->len)+4; if (tmpCount >= MAX_PACKAGE_LEN || tmpCount <= 4) { protocolFlag = 0; protocolCount = 0; GIZWITS_LOG("ERR:the data length is too long or too small, will abandon \n"); } if(protocolCount == tmpCount) { break; } } } } lastData = tmpData; debugCount++; } } if((protocolCount > 4) && (protocolCount == tmpCount)) { sum = gizProtocolSum(protocolBuff, protocolCount); if(protocolBuff[protocolCount-1] == sum) { *len = tmpCount; protocolFlag = 0; protocolCount = 0; debugCount = 0; lastData = 0; return 0; } else { protocolFlag = 0; protocolCount = 0; return -2; } } return 1; } /** * @brief Protocol data resend * The protocol data resend when check timeout and meet the resend limiting * @param none * * @return none */ static void gizProtocolResendData(void) { int32_t ret = 0; if(0 == gizwitsProtocol.waitAck.flag) { return; } GIZWITS_LOG("Warning: timeout, resend data \n"); ret = uartWrite(gizwitsProtocol.waitAck.buf, gizwitsProtocol.waitAck.dataLen); if(ret != gizwitsProtocol.waitAck.dataLen) { GIZWITS_LOG("ERR: resend data error\n"); } gizwitsProtocol.waitAck.sendTime = gizGetTimerCount(); } /** * @brief Clear the ACK protocol message * * @param [in] head : Protocol header address * * @return 0, success; other, failure */ static int8_t gizProtocolWaitAckCheck(protocolHead_t *head) { protocolHead_t *waitAckHead = (protocolHead_t *)gizwitsProtocol.waitAck.buf; if(NULL == head) { GIZWITS_LOG("ERR: data is empty \n"); return -1; } if(waitAckHead->cmd+1 == head->cmd) { memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); } return 0; } /** * @brief Send general protocol message data * * @param [in] head : Protocol header address * * @return : Return effective data length;-1,return failure */ static int32_t gizProtocolCommonAck(protocolHead_t *head) { int32_t ret = 0; protocolCommon_t ack; if(NULL == head) { GIZWITS_LOG("ERR: gizProtocolCommonAck data is empty \n"); return -1; } memcpy((uint8_t *)&ack, (uint8_t *)head, sizeof(protocolHead_t)); ack.head.cmd = ack.head.cmd+1; ack.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); ack.sum = gizProtocolSum((uint8_t *)&ack, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&ack, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief ACK processing function * Time-out 200ms no ACK resend,resend two times at most * @param none * * @return none */ static void gizProtocolAckHandle(void) { if(1 == gizwitsProtocol.waitAck.flag) { if(SEND_MAX_NUM > gizwitsProtocol.waitAck.num) { // Time-out no ACK resend if(SEND_MAX_TIME < (gizGetTimerCount() - gizwitsProtocol.waitAck.sendTime)) { GIZWITS_LOG("Warning:gizProtocolResendData %d %d %d\n", gizGetTimerCount(), gizwitsProtocol.waitAck.sendTime, gizwitsProtocol.waitAck.num); gizProtocolResendData(); gizwitsProtocol.waitAck.num++; } } else { memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); } } } /** * @brief Protocol 4.1 WiFi module requests device information * * @param[in] head : Protocol header address * * @return Return effective data length;-1,return failure */ static int32_t gizProtocolGetDeviceInfo(protocolHead_t * head) { int32_t ret = 0; protocolDeviceInfo_t deviceInfo; if(NULL == head) { GIZWITS_LOG("gizProtocolGetDeviceInfo Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&deviceInfo); deviceInfo.head.cmd = ACK_GET_DEVICE_INFO; deviceInfo.head.sn = head->sn; memcpy((uint8_t *)deviceInfo.protocolVer, protocol_VERSION, 8); memcpy((uint8_t *)deviceInfo.p0Ver, P0_VERSION, 8); memcpy((uint8_t *)deviceInfo.softVer, SOFTWARE_VERSION, 8); memcpy((uint8_t *)deviceInfo.hardVer, HARDWARE_VERSION, 8); memcpy((uint8_t *)deviceInfo.productKey, PRODUCT_KEY, strlen(PRODUCT_KEY)); memcpy((uint8_t *)deviceInfo.productSecret, PRODUCT_SECRET, strlen(PRODUCT_SECRET)); memset((uint8_t *)deviceInfo.devAttr, 0, 8); deviceInfo.devAttr[7] |= DEV_IS_GATEWAY<<0; deviceInfo.devAttr[7] |= (0x01<<1); deviceInfo.ninableTime = exchangeBytes(NINABLETIME); #ifdef DATA_CONFIG_ENABLE deviceInfo.DataLen = exchangeBytes(GIZ_DATA_LEN); sprintf(deviceInfo.Data,"apName=%s&apPwd=%s&cfgMode=%s",AP_NAME,AP_PWD,CFG_MODE); #endif deviceInfo.head.len = exchangeBytes(sizeof(protocolDeviceInfo_t)-4); deviceInfo.sum = gizProtocolSum((uint8_t *)&deviceInfo, sizeof(protocolDeviceInfo_t)); ret = uartWrite((uint8_t *)&deviceInfo, sizeof(protocolDeviceInfo_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief Protocol 4.7 Handling of illegal message notification * @param[in] head : Protocol header address * @param[in] errno : Illegal message notification type * @return 0, success; other, failure */ static int32_t gizProtocolErrorCmd(protocolHead_t *head,errorPacketsType_t errno) { int32_t ret = 0; protocolErrorType_t errorType; if(NULL == head) { GIZWITS_LOG("gizProtocolErrorCmd Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&errorType); errorType.head.cmd = ACK_ERROR_PACKAGE; errorType.head.sn = head->sn; errorType.head.len = exchangeBytes(sizeof(protocolErrorType_t)-4); errorType.error = errno; errorType.sum = gizProtocolSum((uint8_t *)&errorType, sizeof(protocolErrorType_t)); ret = uartWrite((uint8_t *)&errorType, sizeof(protocolErrorType_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief Protocol 4.13 Get and process network time * * @param [in] head : Protocol header address * * @return 0, success; other, failure */ static int8_t gizProtocolNTP(protocolHead_t *head) { protocolUTT_t *UTTInfo = (protocolUTT_t *)head; if(NULL == head) { GIZWITS_LOG("ERR: NTP is empty \n"); return -1; } memcpy((uint8_t *)&gizwitsProtocol.TimeNTP.year,(uint8_t *)UTTInfo->time, 7); memcpy((uint8_t *)&gizwitsProtocol.TimeNTP.ntp,(uint8_t *)UTTInfo->ntp_time, 4); gizwitsProtocol.TimeNTP.year = exchangeBytes(gizwitsProtocol.TimeNTP.year); gizwitsProtocol.TimeNTP.ntp =exchangeWord(gizwitsProtocol.TimeNTP.ntp); gizwitsProtocol.NTPEvent.event[gizwitsProtocol.NTPEvent.num] = WIFI_NTP; gizwitsProtocol.NTPEvent.num++; gizwitsProtocol.issuedFlag = GET_NTP_TYPE; return 0; } /** * @brief Protocol 4.4 Device MCU restarts function * @param none * @return none */ static void gizProtocolReboot(void) { uint32_t timeDelay = gizGetTimerCount(); /*Wait 600ms*/ while((gizGetTimerCount() - timeDelay) <= 600); mcuRestart(); } /** * @brief Protocol 4.5 :The WiFi module informs the device MCU of working status about the WiFi module * @param[in] status WiFi module working status * @return none */ static int8_t gizProtocolModuleStatus(protocolWifiStatus_t *status) { static wifiStatus_t lastStatus; if(NULL == status) { GIZWITS_LOG("gizProtocolModuleStatus Error , Illegal Param\n"); return -1; } status->ststus.value = exchangeBytes(status->ststus.value); //OnBoarding mode status if(lastStatus.types.onboarding != status->ststus.types.onboarding) { if(1 == status->ststus.types.onboarding) { if(1 == status->ststus.types.softap) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_SOFTAP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: SoftAP or Web mode\n"); } if(1 == status->ststus.types.station) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_AIRLINK; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: AirLink mode\n"); } } else { if(1 == status->ststus.types.softap) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_SOFTAP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: SoftAP or Web mode\n"); } if(1 == status->ststus.types.station) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_STATION; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: Station mode\n"); } } } //binding mode status if(lastStatus.types.binding != status->ststus.types.binding) { lastStatus.types.binding = status->ststus.types.binding; if(1 == status->ststus.types.binding) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_OPEN_BINDING; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: in binding mode\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CLOSE_BINDING; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: out binding mode\n"); } } //router status if(lastStatus.types.con_route != status->ststus.types.con_route) { lastStatus.types.con_route = status->ststus.types.con_route; if(1 == status->ststus.types.con_route) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_ROUTER; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: connected router\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_ROUTER; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: disconnected router\n"); } } //M2M server status if(lastStatus.types.con_m2m != status->ststus.types.con_m2m) { lastStatus.types.con_m2m = status->ststus.types.con_m2m; if(1 == status->ststus.types.con_m2m) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_M2M; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: connected m2m\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_M2M; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: disconnected m2m\n"); } } //APP status if(lastStatus.types.app != status->ststus.types.app) { lastStatus.types.app = status->ststus.types.app; if(1 == status->ststus.types.app) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_APP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: app connect\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_APP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: no app connect\n"); } } //test mode status if(lastStatus.types.test != status->ststus.types.test) { lastStatus.types.test = status->ststus.types.test; if(1 == status->ststus.types.test) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_OPEN_TESTMODE; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: in test mode\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CLOSE_TESTMODE; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: out test mode\n"); } } gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_RSSI; gizwitsProtocol.wifiStatusEvent.num++; gizwitsProtocol.wifiStatusData.rssi = status->ststus.types.rssi; GIZWITS_LOG("RSSI is %d \n", gizwitsProtocol.wifiStatusData.rssi); gizwitsProtocol.issuedFlag = WIFI_STATUS_TYPE; return 0; } /**@name Gizwits User API interface * @{ */ /** * @brief gizwits Protocol initialization interface * Protocol-related timer, serial port initialization * Datapoint initialization * @param none * @return none */ void gizwitsInit(void) { pRb.rbCapacity = RB_MAX_LEN; pRb.rbBuff = rbBuf; if(0 == rbCreate(&pRb)) { GIZWITS_LOG("rbCreate Success \n"); } else { GIZWITS_LOG("rbCreate Faild \n"); } memset((uint8_t *)&gizwitsProtocol, 0, sizeof(gizwitsProtocol_t)); } /** * @brief WiFi configure interface * Set the WiFi module into the corresponding configuration mode or reset the module * @param[in] mode :0x0, reset the module ;0x01, SoftAp mode ;0x02, AirLink mode ;0x03, Production test mode; 0x04:allow users to bind devices * @return Error command code */ int32_t gizwitsSetMode(uint8_t mode) { int32_t ret = 0; protocolCfgMode_t cfgMode; protocolCommon_t setDefault; switch(mode) { case WIFI_RESET_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_SET_DEFAULT; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_SOFTAP_MODE: gizProtocolHeadInit((protocolHead_t *)&cfgMode); cfgMode.head.cmd = CMD_WIFI_CONFIG; cfgMode.head.sn = gizwitsProtocol.sn++; cfgMode.cfgMode = mode; cfgMode.head.len = exchangeBytes(sizeof(protocolCfgMode_t)-4); cfgMode.sum = gizProtocolSum((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); ret = uartWrite((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); break; case WIFI_AIRLINK_MODE: gizProtocolHeadInit((protocolHead_t *)&cfgMode); cfgMode.head.cmd = CMD_WIFI_CONFIG; cfgMode.head.sn = gizwitsProtocol.sn++; cfgMode.cfgMode = mode; cfgMode.head.len = exchangeBytes(sizeof(protocolCfgMode_t)-4); cfgMode.sum = gizProtocolSum((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); ret = uartWrite((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); break; case WIFI_PRODUCTION_TEST: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_PRODUCTION_TEST; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_NINABLE_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_NINABLE_MODE; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_REBOOT_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_REBOOT_MODULE; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; default: GIZWITS_LOG("ERR: CfgMode error!\n"); break; } return ret; } /** * @brief Get the the network time * Protocol 4.13:"Device MCU send" of "the MCU requests access to the network time" * @param[in] none * @return none */ void gizwitsGetNTP(void) { int32_t ret = 0; protocolCommon_t getNTP; gizProtocolHeadInit((protocolHead_t *)&getNTP); getNTP.head.cmd = CMD_GET_NTP; getNTP.head.sn = gizwitsProtocol.sn++; getNTP.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); getNTP.sum = gizProtocolSum((uint8_t *)&getNTP, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&getNTP, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR[NTP]: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&getNTP, sizeof(protocolCommon_t)); } /** * @brief Get Module Info * * @param[in] none * @return none */ void gizwitsGetModuleInfo(void) { int32_t ret = 0; protocolGetModuleInfo_t getModuleInfo; gizProtocolHeadInit((protocolHead_t *)&getModuleInfo); getModuleInfo.head.cmd = CMD_ASK_MODULE_INFO; getModuleInfo.head.sn = gizwitsProtocol.sn++; getModuleInfo.type = 0x0; getModuleInfo.head.len = exchangeBytes(sizeof(protocolGetModuleInfo_t)-4); getModuleInfo.sum = gizProtocolSum((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); ret = uartWrite((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); if(ret < 0) { GIZWITS_LOG("ERR[NTP]: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); } /** * @brief Module Info Analyse * * @param [in] head : * * @return 0, Success, , other,Faild */ static int8_t gizProtocolModuleInfoHandle(protocolHead_t *head) { protocolModuleInfo_t *moduleInfo = (protocolModuleInfo_t *)head; if(NULL == head) { GIZWITS_LOG("NTP is empty \n"); return -1; } #if MODULE_TYPE memcpy((uint8_t *)&gizwitsProtocol.gprsInfoNews,(uint8_t *)&moduleInfo->gprsModuleInfo, sizeof(gprsInfo_t)); #else memcpy((uint8_t *)&gizwitsProtocol.wifiModuleNews,(uint8_t *)&moduleInfo->wifiModuleInfo, sizeof(moduleInfo_t)); #endif gizwitsProtocol.moduleInfoEvent.event[gizwitsProtocol.moduleInfoEvent.num] = MODULE_INFO; gizwitsProtocol.moduleInfoEvent.num++; gizwitsProtocol.issuedFlag = GET_MODULEINFO_TYPE; return 0; } /** * @brief Protocol handling function * * @param [in] currentData :The protocol data pointer * @return none */ int32_t gizwitsHandle(dataPoint_t *currentData) { int8_t ret = 0; #ifdef PROTOCOL_DEBUG uint16_t i = 0; #endif uint8_t ackData[RB_MAX_LEN]; uint16_t protocolLen = 0; uint32_t ackLen = 0; protocolHead_t *recvHead = NULL; char *didPtr = NULL; uint16_t offset = 0; if(NULL == currentData) { GIZWITS_LOG("GizwitsHandle Error , Illegal Param\n"); return -1; } /*resend strategy*/ gizProtocolAckHandle(); ret = gizProtocolGetOnePacket(&pRb, gizwitsProtocol.protocolBuf, &protocolLen); if(0 == ret) { GIZWITS_LOG("Get One Packet!\n"); #ifdef PROTOCOL_DEBUG GIZWITS_LOG("WiFi2MCU[%4d:%4d]: ", gizGetTimerCount(), protocolLen); for(i=0; i<protocolLen;i++) { GIZWITS_LOG("%02x ", gizwitsProtocol.protocolBuf[i]); } GIZWITS_LOG("\n"); #endif recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf; switch (recvHead->cmd) { case CMD_GET_DEVICE_INTO: gizProtocolGetDeviceInfo(recvHead); break; case CMD_ISSUED_P0: GIZWITS_LOG("flag %x %x \n", recvHead->flags[0], recvHead->flags[1]); //offset = 1; if(0 == gizProtocolIssuedProcess(didPtr, gizwitsProtocol.protocolBuf+sizeof(protocolHead_t)+offset, protocolLen-(sizeof(protocolHead_t)+offset+1), ackData, &ackLen)) { gizProtocolIssuedDataAck(recvHead, ackData, ackLen,recvHead->flags[1]); GIZWITS_LOG("AckData : \n"); } break; case CMD_HEARTBEAT: gizProtocolCommonAck(recvHead); break; case CMD_WIFISTATUS: gizProtocolCommonAck(recvHead); gizProtocolModuleStatus((protocolWifiStatus_t *)recvHead); break; case ACK_REPORT_P0: case ACK_WIFI_CONFIG: case ACK_SET_DEFAULT: case ACK_NINABLE_MODE: case ACK_REBOOT_MODULE: gizProtocolWaitAckCheck(recvHead); break; case CMD_MCU_REBOOT: gizProtocolCommonAck(recvHead); GIZWITS_LOG("report:MCU reboot!\n"); gizProtocolReboot(); break; case CMD_ERROR_PACKAGE: break; case ACK_PRODUCTION_TEST: gizProtocolWaitAckCheck(recvHead); GIZWITS_LOG("Ack PRODUCTION_MODE success \n"); break; case ACK_GET_NTP: gizProtocolWaitAckCheck(recvHead); gizProtocolNTP(recvHead); GIZWITS_LOG("Ack GET_UTT success \n"); break; case ACK_ASK_MODULE_INFO: gizProtocolWaitAckCheck(recvHead); gizProtocolModuleInfoHandle(recvHead); GIZWITS_LOG("Ack GET_Module success \n"); break; default: gizProtocolErrorCmd(recvHead,ERROR_CMD); GIZWITS_LOG("ERR: cmd code error!\n"); break; } } else if(-2 == ret) { //Check failed, report exception recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf; gizProtocolErrorCmd(recvHead,ERROR_ACK_SUM); GIZWITS_LOG("ERR: check sum error!\n"); return -2; } switch(gizwitsProtocol.issuedFlag) { case ACTION_CONTROL_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)&gizwitsProtocol.gizCurrentDataPoint, sizeof(dataPoint_t)); memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent,0x0,sizeof(gizwitsProtocol.issuedProcessEvent)); break; case WIFI_STATUS_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.wifiStatusEvent, (uint8_t *)&gizwitsProtocol.wifiStatusData, sizeof(moduleStatusInfo_t)); memset((uint8_t *)&gizwitsProtocol.wifiStatusEvent,0x0,sizeof(gizwitsProtocol.wifiStatusEvent)); break; case ACTION_W2D_TRANSPARENT_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)gizwitsProtocol.transparentBuff, gizwitsProtocol.transparentLen); break; case GET_NTP_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.NTPEvent, (uint8_t *)&gizwitsProtocol.TimeNTP, sizeof(protocolTime_t)); memset((uint8_t *)&gizwitsProtocol.NTPEvent,0x0,sizeof(gizwitsProtocol.NTPEvent)); break; case GET_MODULEINFO_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.moduleInfoEvent, (uint8_t *)&gizwitsProtocol.wifiModuleNews, sizeof(moduleInfo_t)); memset((uint8_t *)&gizwitsProtocol.moduleInfoEvent,0x0,sizeof(moduleInfo_t)); break; default: break; } gizDevReportPolicy(currentData); return 0; } /** * @brief gizwits report transparent data interface * The user can call the interface to complete the reporting of private protocol data * @param [in] data :Private protocol data * @param [in] len :Private protocol data length * @return 0,success ;other,failure */ int32_t gizwitsPassthroughData(uint8_t * gizdata, uint32_t len) { int32_t ret = 0; uint8_t tx_buf[MAX_PACKAGE_LEN]; uint8_t *pTxBuf = tx_buf; uint16_t data_len = 6+len; if(NULL == gizdata) { GIZWITS_LOG("[ERR] gizwitsPassthroughData Error \n"); return (-1); } *pTxBuf ++= 0xFF; *pTxBuf ++= 0xFF; *pTxBuf ++= (uint8_t)(data_len>>8);//len *pTxBuf ++= (uint8_t)(data_len); *pTxBuf ++= CMD_REPORT_P0;//0x1b cmd *pTxBuf ++= gizwitsProtocol.sn++;//sn *pTxBuf ++= 0x00;//flag *pTxBuf ++= 0x00;//flag *pTxBuf ++= ACTION_D2W_TRANSPARENT_DATA;//P0_Cmd memcpy(&tx_buf[9],gizdata,len); tx_buf[data_len + 4 - 1 ] = gizProtocolSum( tx_buf , (data_len+4)); ret = uartWrite(tx_buf, data_len+4); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck(tx_buf, data_len+4); return 0; } /**@} */ 现在就是连不上网串 resend data ?? P<b#DHT11 OK: T=30, H=60Warning:gizProtocolResendData 461493 461241 1Warning: timeout, resend data ?? P<b#DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60DHT11 OK: T=30, H=60ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite
07-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值