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

/*****************************************************************************
* 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 <EFBFBD><EFBFBD><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 - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
len - <EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD><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 - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD><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 - <EFBFBD><EFBFBD><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 - <EFBFBD><EFBFBD><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 - ˽<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD> */
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 ****************/