You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

604 lines
22 KiB
C

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*****************************************************************************
* file lib/process/ca_land.c
* author YuLiang
* version 1.0.0
* date 20-Dec-2023
* brief This file provides all the LandPower protocol related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2023 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef CFG_DEV_TYPE_LAND_CA
/* <20><>׼C<D7BC><43>ͷ<EFBFBD>ļ<EFBFBD>. */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <netinet/tcp.h>
#include <sys/types.h>
/* <20>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD>. */
#include "cmd.h"
#include "process.h"
#include "ca_land.h"
#include "ca_collect.h"
/* Private define ------------------------------------------------------------*/
#define CA_LAND_BUF_SIZE 1512
#define CA_LAND_CMD_BUF_LEN 3024
#define CA_LAND_SHIQUCHA 28800
#define CA_LAND_CMD_REPLY_RD 0xC081
#define CA_LAND_CMD_REQ_ID 0xC401
#define CA_LAND_START_FLAG 0x5555AAAA
#define CA_LAND_END_FLAG 0x5AA55AA5
#define CA_LAND_HEAD_LEN (sizeof(ca_land_head_t) + 8) //<2F><>ͷ<EFBFBD>Ӱ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD>
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* BEGIN: <20><><EFBFBD>½ṹ<C2BD><E1B9B9>Ϊ˽<CEAA><CBBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#pragma pack(1)
typedef struct{
uint32_t StartFlag1; //<2F>豸ID 0x40110304=ID=40110304
uint8_t FarmeType; //֡<><D6A1><EFBFBD>ͣ<EFBFBD> 0x00 <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
uint32_t RunSecCnt; //ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> 0x01020304=16909060<36><30>
uint16_t Local_Vbat; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ѹ 0x1965= 6505/1000=6.501V
int16_t RoomIn_Temp; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
float RMS_Ia; //CH1:A<><41><EFBFBD>ӵص<D3B5><D8B5><EFBFBD>
float RMS_Ib; //CH2:B<><42><EFBFBD>ӵص<D3B5><D8B5><EFBFBD>
float RMS_Ic; //CH3:C<><43><EFBFBD>ӵص<D3B5><D8B5><EFBFBD>
float RMS_In; //CH4: [<5B><><EFBFBD>µ<EFBFBD><C2B5><EFBFBD>]
float RMS_Ground; //CH5: [<5B>ܽӵص<D3B5><D8B5><EFBFBD>]
float RMS_rIa; //CH6:A<><41><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>
float RMS_rIb; //CH7:B<><42><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>
float RMS_rIc; //CH8:C<><43><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>
int16_t RoomOut_Temp; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint16_t I16A_Gx; //A<><41><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>X<EFBFBD><58> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16A_Gy; //A<><41><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>Y<EFBFBD><59> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16A_Gz; //A<><41><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>Z<EFBFBD><5A> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16A_Temp1; //A<><41><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD>ͷ<EFBFBD><EFBFBD> 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint16_t I16A_Temp2; //A<><41><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD> ͬ<><CDAC>
uint16_t I16B_Gx; //B<><42><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>X<EFBFBD><58> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16B_Gy; //B<><42><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>Y<EFBFBD><59> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16B_Gz; //B<><42><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>Z<EFBFBD><5A> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16B_Temp1; //B<><42><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD> 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint16_t I16B_Temp2; //B<><42><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD> ͬ<><CDAC>
uint16_t I16C_Gx; //C<><43><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>X<EFBFBD><58> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16C_Gy; //C<><43><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>Y<EFBFBD><59> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16C_Gz; //C<><43><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>Z<EFBFBD><5A> 0x6655=<3D><>26197-16000=10197mg<6D><67>
uint16_t I16C_Temp1; //C<><43><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD> 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint16_t I16C_Temp2; //C<><43><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD> ͬ<><CDAC>
uint8_t Status_AG; //A<><41><EFBFBD><EFBFBD>̬<EFBFBD>澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
uint8_t Status_BG; //B<><42><EFBFBD><EFBFBD>̬<EFBFBD>澯 0x01 <20><><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Status_CG; //C<><43><EFBFBD><EFBFBD>̬<EFBFBD>澯 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Status_A_OT; //A<><41><EFBFBD>¶ȳ<C2B6><C8B3>޸澯 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Status_B_OT; //B<><42><EFBFBD>¶ȳ<C2B6><C8B3>޸澯 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Status_C_OT; //C<><43><EFBFBD>¶ȳ<C2B6><C8B3>޸澯 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Status_Bat; //<2F><><EFBFBD>ص<EFBFBD>·Ӳ<C2B7><D3B2>״̬0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Error_AT; //A<><41><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2>״̬ 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Error_BT; //B<><42><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2>״̬ 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Error_CT; //C<><43><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2>״̬ 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Error_AG; //A<><41>ADXLӲ<4C><D3B2>״̬ 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Error_BG; //B<><42>ADXLӲ<4C><D3B2>״̬ 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Error_CG; //C<><43>ADXLӲ<4C><D3B2>״̬ 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Error_ROT; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2>״̬ 0x01<30><31><EFBFBD><EFBFBD> 0x00<30><30><EFBFBD><EFBFBD>
uint16_t WaterLevel; //ˮλ 0x20=32cm
uint16_t RoomOut_Humidity; //<2F><><EFBFBD><EFBFBD>ʪ<EFBFBD><CAAA> 0x0321 = (801/10) = 80.1%
uint8_t Error_Humidity; //<2F><><EFBFBD><EFBFBD>ʪ<EFBFBD><CAAA>Ӳ<EFBFBD><D3B2>״̬ 1:<3A><EFBFBD><E6BEAF>0:<3A><><EFBFBD><EFBFBD>
uint32_t Gas_O2; //<2F><><EFBFBD><EFBFBD>Ũ<EFBFBD><C5A8> 0x000100013= <20><>0x0013<31><33>=19 %VOL
uint32_t Gas_CH4; //<2F><><EFBFBD><EFBFBD>Ũ<EFBFBD><C5A8> ͬ<><CDAC>
uint32_t Gas_H2s; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ũ<EFBFBD><C5A8> ͬ<><CDAC>
uint32_t Gas_CO; //һ<><D2BB><EFBFBD><EFBFBD>̼Ũ<CCBC><C5A8> ͬ<><CDAC>
float RMS_Va; //A<><41><EFBFBD><EFBFBD>ѹ
float RMS_Vb; //B<><42><EFBFBD><EFBFBD>ѹ
float RMS_Vc; //C<><43><EFBFBD><EFBFBD>ѹ
uint16_t reserve; //<2F><><EFBFBD><EFBFBD>
uint16_t endFlag; //ֵ<><D6B5>0X0D 0X0A <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>/r/n<><6E>
}ca_land_rd_t;//ʵʱ<CAB5><CAB1><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD> 128 Byte
typedef struct{
uint32_t StartFlag1; //<2F>豸ID 0x40110304=ID=40110304
uint8_t FarmeType; //֡<><D6A1><EFBFBD>ͣ<EFBFBD> 0x01 <20><EFBFBD><E6BEAF><EFBFBD><EFBFBD>
uint32_t RunSecCnt; //ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> 0x01020304=16909060<36><30>
uint8_t WaveNum; //<2F><>ǰ<EFBFBD><C7B0>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD>µ<EFBFBD><C2B5>ļ<EFBFBD> ֵ<><D6B5>[0-127]
uint8_t RMS_Ig_Err; //<2F>ܽӵص<D3B5><D8B5><EFBFBD><EFBFBD><EFBFBD> 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint16_t RMS_Ig_Before; //<2F>ܽӵص<D3B5><D8B5><EFBFBD><EFBFBD>仯ǰ 0x0533=1331/10=133.1A
uint16_t RMS_Ig_After; //<2F>ܽӵص<D3B5><D8B5><EFBFBD><EFBFBD><EFBFBD><E4BBAF> 0x0533=1331/10=133.1A
uint8_t RMS_Ia_Err; //A<><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint16_t RMS_Ia_Before; //A<><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>仯ǰ 0x0533=1331/10=133.1A
uint16_t RMS_Ia_After; //A<><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4BBAF> 0x0533=1331/10=133.1A
uint8_t Sanke_a_Err; //A<><41><EFBFBD>񶯸澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint16_t Sanke_a_x; //A<><41>X<EFBFBD><58><EFBFBD><EFBFBD>ֵ
uint16_t Sanke_a_y; //A<><41>Y<EFBFBD><59><EFBFBD><EFBFBD>ֵ
uint16_t Sanke_a_z; //A<><41>Z<EFBFBD><5A><EFBFBD><EFBFBD>ֵ
uint8_t Temper_a_Err; //A<><41><EFBFBD>¶ȸ澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Temper_a_Change; //A<><41><EFBFBD>¶ȱ仯ֵ 0x02 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>
uint16_t Temper_a_Before; //A<><41><EFBFBD><EFBFBD>ǰ 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint16_t Temper_a_After; //A<><41><EFBFBD>¶Ⱥ<C2B6> 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint8_t RMS_Ib_Err; //B<><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint16_t RMS_Ib_Before; //B<><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>仯ǰ 0x0533=1331/10=133.1A
uint16_t RMS_Ib_After; //B<><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4BBAF> 0x0533=1331/10=133.1A
uint8_t Sanke_b_Err; //B<><42><EFBFBD>񶯸澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint16_t Sanke_b_x; //B<><42>X<EFBFBD><58><EFBFBD><EFBFBD>ֵ
uint16_t Sanke_b_y; //B<><42>Y<EFBFBD><59><EFBFBD><EFBFBD>ֵ
uint16_t Sanke_b_z; //B<><42>Z<EFBFBD><5A><EFBFBD><EFBFBD>ֵ
uint8_t Temper_b_Err; //B<><42><EFBFBD>¶ȸ澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Temper_b_Change; //B<><42><EFBFBD>¶ȱ仯ֵ 0x02 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>
uint16_t Temper_b_Before; //B<><42><EFBFBD><EFBFBD>ǰ 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint16_t Temper_b_After; //B<><42><EFBFBD>¶Ⱥ<C2B6> 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint8_t RMS_Ic_Err; //C<><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint16_t RMS_Ic_Before; //C<><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>仯ǰ 0x0533=1331/10=133.1A
uint16_t RMS_Ic_After; //C<><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4BBAF> 0x0533=1331/10=133.1A
uint8_t Sanke_c_Err; //C<><43><EFBFBD>񶯸澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint16_t Sanke_c_x; //C<><43>X<EFBFBD><58><EFBFBD><EFBFBD>ֵ
uint16_t Sanke_c_y; //C<><43>Y<EFBFBD><59><EFBFBD><EFBFBD>ֵ
uint16_t Sanke_c_z; //C<><43>Z<EFBFBD><5A><EFBFBD><EFBFBD>ֵ
uint8_t Temper_c_Err; //C<><43><EFBFBD>¶ȸ澯 0x01 <20>澯 0x00<30><30><EFBFBD><EFBFBD>
uint8_t Temper_c_Change; //C<><43><EFBFBD>¶ȱ仯ֵ 0x02 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>
uint16_t Temper_c_Before; //C<><43><EFBFBD><EFBFBD>ǰ 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint16_t Temper_c_After; //C<><43><EFBFBD>¶Ⱥ<C2B6> 0x0C02=(3074/10)-273.1=34.3<EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD>
uint16_t endFlag; //ֵ<><D6B5>0X0D 0X0A <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>/r/n<><6E>
}ca_land_war_t;//<2F><EFBFBD><E6BEAF><EFBFBD><EFBFBD> 71Byte
typedef struct{
uint32_t StatusA; //24<32><34>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><C2B6><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>ж<EFBFBD> Bit24<32><34> 0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int16_t TempA[24]; //<2F><><EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD> <20><>I16<31><36>/16<31><36>ԭʼֵ<CABC><D6B5>
uint32_t StatusB;
int16_t TempB[24];
uint32_t StatusC;
int16_t TempC[24];
} ca_land_tmp_t;//<2F><><EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD> 156 Byte
typedef struct{
uint32_t proVer; //Э<><D0AD><EFBFBD><EFBFBD><E6B1BE> 0x00000363
uint32_t utc;
ca_land_rd_t rtd;
uint32_t reslved1; //<2F><><EFBFBD>Թ<EFBFBD><D4B9><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʷ<EFBFBD><CAB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ca_land_war_t war;
uint8_t reslved2;
ca_land_tmp_t mul;
uint32_t reslved3;
uint32_t powertatus;
uint32_t vbat;
uint32_t vout;
uint32_t batteryStatus;
float Gpslatitude;
float Gpslongitude;
uint8_t PowerFail[8]; //<2F><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD> 485
uint32_t vsc;
uint8_t reslved4[104];
} ca_land_date_t;//512Byte
#pragma pack()
typedef struct{
uint32_t Head; //StartFlag1 0X5555AAAA
uint16_t Len; //<2F><><EFBFBD>ij<EFBFBD><C4B3>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD>ܳ<EFBFBD><DCB3><EFBFBD>
uint16_t Type; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint32_t ID; //<2F>ӻ<EFBFBD>ID: <20><>ex. 0x40111234 <20><>
uint32_t LifeCnt; //<2F><><EFBFBD><EFBFBD>ÿ<EFBFBD>μ<EFBFBD>1<EFBFBD><31><EFBFBD>ӻ<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>յ<EFBFBD><D5B5><EFBFBD>ֵ
uint16_t gNum; //<2F><><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD>Ŀ:<3A><>1-65535<33><35><EFBFBD><EFBFBD>
uint16_t gNumIndex; //<2F><><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>0 <20><> <20><>gNum<75><6D>1<EFBFBD><31>
} ca_land_head_t;//<2F>ʵ<EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD>ͷ
typedef struct{
uint32_t CheckSum;
uint32_t EndFlag1;
} ca_land_tail_t;//<2F>ʵ<EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD>β
/* END: <20><><EFBFBD>Ͻṹ<CFBD><E1B9B9>Ϊ˽<CEAA><CBBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
/* ˽<><CBBD>Э<EFBFBD><D0AD>ȫ<EFBFBD>ֿ<EFBFBD><D6BF>ƽṹ */
typedef struct{
int fd; // TCP server <20><><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD> socket
char buf[CA_LAND_BUF_SIZE]; // ͨѶʹ<D1B6><CAB9><EFBFBD>շ<EFBFBD><D5B7><EFBFBD> buf
ca_land_state_t state; // Э<><D0AD>״̬
} ca_land_ctrl_t;
ca_land_ctrl_t ca_land_ctrl; // ȫ<>ֿ<EFBFBD><D6BF>ƽ
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* description: <20><>ʾ<EFBFBD><CABE>ǰ״̬
param:
return: CMD_XXX */
CMD(ca_land_show_state,
ca_land_show_state_cmd,
"show land",
"Show\n"
"LandPower protocol\n")
{
ca_land_state_show();
return CMD_SUCCESS;
}
/* description: ˽<><CBBD>Э<EFBFBD><D0AD> socket <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
param: fd - socket <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return: E_XXX */
int32_t _ca_land_socket_set(int fd)
{
//int keep_alive = 1;
//int keep_idle = 60;
//int keep_interval = 6;
//int keep_count = 10;
int keep_time = 30000;
struct timeval timeout;
#if 0
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ 60 <20><><EFBFBD><EFBFBD><EFBFBD>޽<EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD>, ÿ<><C3BF> 6 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>. 10 <20>ζ<EFBFBD>û<EFBFBD>õ<EFBFBD><C3B5><EFBFBD>Ӧʱ<D3A6><CAB1><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD><EFBFBD> */
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive, sizeof(keep_alive)))
{
DBG(DBG_M_CA_LAND_ERR, "Error setsockopt(SO_KEEPALIVE) failed, return %s!\r\n", safe_strerror(errno));
return E_SYS_CALL;
}
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_idle, sizeof(keep_idle)))
{
DBG(DBG_M_CA_LAND_ERR, "Error setsockopt(TCP_KEEPIDLE) failed, return %s!\r\n", safe_strerror(errno));
return E_SYS_CALL;
}
if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keep_interval, sizeof(keep_interval)))
{
DBG(DBG_M_CA_LAND_ERR, "Error setsockopt(TCP_KEEPINTVL) failed, return %s!\r\n", safe_strerror(errno));
return E_SYS_CALL;
}
if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT, (void *)&keep_count, sizeof(keep_count)))
{
DBG(DBG_M_CA_LAND_ERR, "Error setsockopt(TCP_KEEPCNT) failed, return %s!\r\n", safe_strerror(errno));
return E_SYS_CALL;
}
#endif
/* <20><><EFBFBD>ͳ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> */
if (setsockopt(fd, SOL_TCP, TCP_USER_TIMEOUT, (void *)&keep_time, sizeof(keep_time)))
{
DBG(DBG_M_CA_LAND_ERR, "Error setsockopt(TCP_USER_TIMEOUT) failed, return %s!\r\n", safe_strerror(errno));
return E_SYS_CALL;
}
/* <20><><EFBFBD>ͳ<EFBFBD>ʱ */
timeout.tv_sec = 30;
timeout.tv_usec = 0;
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)))
{
DBG(DBG_M_CA_LAND_ERR, "Error setsockopt(SO_SNDTIMEO) failed, return %s!\r\n", safe_strerror(errno));
return E_SYS_CALL;
}
return E_NONE;
}
/* description: <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
param: cmd - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
len - <20><><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
return: */
void _ca_land_head_init(uint16_t cmd, int32_t len)
{
char *pkt = ca_land_ctrl.buf;
ca_land_head_t *head = (ca_land_head_t*)pkt;
memset(pkt, 0, CA_LAND_BUF_SIZE);
head->Head = CA_LAND_START_FLAG;
head->Len = CA_LAND_HEAD_LEN + len;
head->Type = cmd;
head->ID = device_info.dev_id;
head->LifeCnt = 1;
head->gNum = 1;
head->gNumIndex = 0;
}
/* description: <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>
param: data_len - <20><><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
return: */
void _ca_land_cheak_sum(int32_t data_len)
{
char *pkt = ca_land_ctrl.buf;
uint32_t *temp = (uint32_t*)(pkt + 4);
ca_land_tail_t *tail = (ca_land_tail_t*)(pkt + data_len - 8);
int32_t i = 0;
int32_t len = (data_len - 12) >> 2; // <20><>ʼλ<CABC>ͱ<EFBFBD><CDB1><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint32_t cheakSum = 0;
for(i = 0; i < len; i++ )
{
cheakSum += *temp;
temp++;
}
tail->CheckSum = cheakSum;
tail->EndFlag1 = CA_LAND_END_FLAG;
}
int32_t _ca_land_heart_send(void)
{
char *pkt = ca_land_ctrl.buf;
ca_land_head_t *head = (ca_land_head_t*)pkt;
int fd = ca_land_ctrl.fd;
/* <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ */
_ca_land_head_init(CA_LAND_CMD_REQ_ID, 36);
_ca_land_cheak_sum(head->Len);
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if (send(fd, pkt, head->Len, 0) < 0)
{
DBG(DBG_M_CA_LAND_ERR, "LAND send ERR!\r\n");
return E_SYS_CALL;
}
/* <20><><EFBFBD>Դ<EFBFBD>ӡ */
DBG(DBG_M_CA_LAND, "LAND send(%d): %d %d\r\n", head->Len, time(NULL));
if (dbg_stat_get(DBG_M_CA_LAND))
{
buf_print(pkt, 32);
}
return E_NONE;
}
/* description: <20><><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD><EFBFBD><EFBFBD>װ
param: data - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>
return: */
void _ca_land_date(ca_land_rd_t *data)
{
ca_coll_dev_data_t *dev_data = ca_coll_cable_data_get();
data->StartFlag1 = device_info.dev_id;
data->endFlag = 0x0A0D;
data->Local_Vbat = dev_data->vbat;
data->RoomIn_Temp = dev_data->temperature +2731;
data->RunSecCnt = start_time;
data->RMS_Ia = dev_data->elec[0] / 1000.0;
data->RMS_Ib = dev_data->elec[1] / 1000.0;
data->RMS_Ic = dev_data->elec[2] / 1000.0;
data->RMS_rIa = dev_data->elec[3] / 1000.0;
data->RMS_Ground = dev_data->elec[4] / 1000.0;
}
/* description: <20><><EFBFBD>ݱ<EFBFBD><DDB1>ķ<EFBFBD><C4B7><EFBFBD>
param: data - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>
return: E_XXX */
int32_t _ca_land_real_data_send(void)
{
char *pkt = ca_land_ctrl.buf;
ca_land_head_t *head = (ca_land_head_t*)pkt;
ca_land_date_t *rd = (ca_land_date_t*)(pkt + sizeof(ca_land_head_t));
ca_coll_dev_data_t *dev_data = ca_coll_cable_data_get();
time_t now = time(NULL);
int fd = ca_land_ctrl.fd;
/* <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ */
_ca_land_head_init(CA_LAND_CMD_REPLY_RD, sizeof(ca_land_date_t));
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
rd->proVer = 0x00000601;
rd->utc = now - CA_LAND_SHIQUCHA;
rd->powertatus = 0;
rd->batteryStatus = 0;
rd->vbat = dev_data->vbat;
rd->vsc = dev_data->vsc;
rd->vout = dev_data->vin;
rd->Gpslatitude = 0;
rd->Gpslongitude = 0;
rd->reslved1 = 0;
_ca_land_date(&rd->rtd);
_ca_land_cheak_sum(head->Len);
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if (send(fd, pkt, head->Len, 0) < 0)
{
DBG(DBG_M_CA_LAND_ERR, "LAND send ERR!\r\n");
return E_SYS_CALL;
}
/* <20><><EFBFBD>Դ<EFBFBD>ӡ */
DBG(DBG_M_CA_LAND, "LAND send(%d): %d %d\r\n", head->Len, now);
if (dbg_stat_get(DBG_M_CA_LAND))
{
buf_print(pkt, 32);
}
return E_NONE;
}
/* description: ˽<><CBBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD><EFBFBD>߳<EFBFBD>
param:
return: */
void *_ca_land_handle_send(void *arg)
{
static uint8_t cnt = 0;
ca_coll_cfg_t *cfg = ca_coll_cfg_get();
ca_coll_state_t *state = ca_coll_cable_state_get();
struct sockaddr_in server;
int fd = ca_land_ctrl.fd;
int8_t err_cnt = 0;
while (!is_system_init)
{
sleep(1);
}
/* <20>󶨶˿<F3B6A8B6> */
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(cfg->land_ip);
server.sin_port = htons(cfg->land_port);
printf("land_ip:%s land_port:%d\n", cfg->land_ip, cfg->land_port);
while (1)
{
sleep(30);
/* <20><><EFBFBD><EFBFBD> socket */
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
log_err(LOG_CA_LAND, "ERROR at socket create return %s!", safe_strerror(errno));
continue;
}
if (connect(fd, (struct sockaddr*)&server, sizeof(server)) < 0)
{
DBG(DBG_M_CA_LAND_ERR, "ERROR at socket connect return %s!\r\n", safe_strerror(errno));
close(fd);
/* <20><><EFBFBD><EFBFBD> 4G <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>, <20><> 4G <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>豸 */
if (cfg->is_4G && state->is_4g_connect)
{
err_cnt++;
if (err_cnt >= 10)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˽<EFBFBD><CBBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//reboot_system(LOG_CA_LAND, BOOT_CONNECT_ERR);
}
}
else
{
err_cnt = 0;
}
continue;
}
_ca_land_socket_set(fd);
ca_land_ctrl.fd = fd;
/* <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
cnt = 0;
while(1)
{
if (ca_land_ctrl.state.is_send_data)
{
ca_land_ctrl.state.is_send_data = FALSE;
if (_ca_land_real_data_send() != E_NONE)
{
ca_land_ctrl.state.is_connect = FALSE;
DBG(DBG_M_CA_LAND_ERR, "ERROR at server disconnect!\r\n");
close(fd);
break;
}
ca_land_ctrl.state.is_connect = TRUE;
}
else if(cnt >= 30)
{
cnt = 0;
if (_ca_land_heart_send() != E_NONE)
{
ca_land_ctrl.state.is_connect = FALSE;
DBG(DBG_M_CA_LAND_ERR, "ERROR at server disconnect!\r\n");
close(fd);
break;
}
ca_land_ctrl.state.is_connect = TRUE;
}
sleep(1);
cnt++;
}
}
return NULL;
}
/* Interface functions -------------------------------------------------------*/
/* description: ˽<><CBBD>ЭԤ<D0AD><D4A4>ʼ<EFBFBD><CABC>
param:
return: E_XXX */
int32_t ca_land_init(void)
{
cmd_install_element(COMMON_NODE, &ca_land_show_state_cmd);
return E_NONE;
}
/* description: <20>ʵ<EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
param: 111.47.21.141
return: */
int32_t ca_land_init_after(void)
{
ca_coll_cfg_t *cfg = ca_coll_cfg_get();
struct sched_param param;
pthread_attr_t attr;
pthread_t pid;
int32_t rv = 0;
if (!cfg->is_land)
{
return E_NONE;
}
pthread_attr_init(&attr);
param.sched_priority = 25;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
rv = pthread_create(&pid, &attr, _ca_land_handle_send, NULL);
if (rv != 0)
{
log_err(LOG_CA_LAND, "Can't create debug pthread %d!", rv);
return E_SYS_CALL;
}
else
{
thread_m_add("CA_LAND", pid);
}
pthread_attr_destroy(&attr);
return E_NONE;
}
/* description: ˽<><CBBD>Э<EFBFBD><D0AD>״̬<D7B4><EFBFBD><E1B9B9><EFBFBD><EFBFBD>ȡ
param:
return: ca_land_state_t - ˽<><CBBD>Э<EFBFBD><D0AD>״̬<D7B4><EFBFBD><E1B9B9>ָ<EFBFBD><D6B8> */
ca_land_state_t* ca_land_state_get(void)
{
return &ca_land_ctrl.state;
}
/* description: ˽<><CBBD>Э<EFBFBD><D0AD>״̬<D7B4><CCAC>ʾ
param:
return: */
void ca_land_state_show(void)
{
ca_land_state_t *state = &ca_land_ctrl.state;
printh("Connect: %s\r\n\n", state->is_connect ? "yes" : "no");
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/