/*****************************************************************************
 * 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
/* 标准C库头文件. */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <netinet/tcp.h>
#include <sys/types.h>

/* 用户代码头文件. */
#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) //包头加包尾长度

/* Private macro -------------------------------------------------------------*/

/* Private typedef -----------------------------------------------------------*/
/* BEGIN: 以下结构体为私有协议数据 */
#pragma pack(1)
typedef struct{
    uint32_t StartFlag1;        //设备ID      0x40110304=ID=40110304
    uint8_t FarmeType;          //帧类型：     0x00  定时发送
    uint32_t RunSecCnt;         //系统运行时间  0x01020304=16909060秒
    uint16_t Local_Vbat;        //本机电池电压  0x1965=	6505/1000=6.501V
    int16_t RoomIn_Temp;        //本机温度     0x0C02=(3074/10)-273.1=34.3摄氏度
    float RMS_Ia;               //CH1:A相接地电流
    float RMS_Ib;               //CH2:B相接地电流
    float RMS_Ic;               //CH3:C相接地电流
    float RMS_In;               //CH4: [主缆电流]
    float RMS_Ground;           //CH5: [总接地电流]
    float RMS_rIa;              //CH6:A相运行电流
    float RMS_rIb;              //CH7:B相运行电流
    float RMS_rIc;              //CH8:C相运行电流
    int16_t RoomOut_Temp;       //环境温度  0x0C02=(3074/10)-273.1=34.3摄氏度
    uint16_t I16A_Gx;           //A相接头振动X轴  0x6655=（26197-16000=10197mg）
    uint16_t I16A_Gy;           //A相接头振动Y轴  0x6655=（26197-16000=10197mg）
    uint16_t I16A_Gz;           //A相接头振动Z轴  0x6655=（26197-16000=10197mg）
    uint16_t I16A_Temp1;        //A相电缆接头温度  0x0C02=(3074/10)-273.1=34.3摄氏度
    uint16_t I16A_Temp2;        //A相电缆表面温度  同上
    uint16_t I16B_Gx;           //B相接头振动X轴  0x6655=（26197-16000=10197mg）
    uint16_t I16B_Gy;           //B相接头振动Y轴  0x6655=（26197-16000=10197mg）
    uint16_t I16B_Gz;           //B相接头振动Z轴  0x6655=（26197-16000=10197mg）
    uint16_t I16B_Temp1;        //B相接头温度      0x0C02=(3074/10)-273.1=34.3摄氏度
    uint16_t I16B_Temp2;        //B相电缆表面温度  同上
    uint16_t I16C_Gx;           //C相接头振动X轴  0x6655=（26197-16000=10197mg）
    uint16_t I16C_Gy;           //C相接头振动Y轴  0x6655=（26197-16000=10197mg）
    uint16_t I16C_Gz;           //C相接头振动Z轴  0x6655=（26197-16000=10197mg）
    uint16_t I16C_Temp1;        //C相接头温度      0x0C02=(3074/10)-273.1=34.3摄氏度
    uint16_t I16C_Temp2;        //C相电缆表面温度  同上
    uint8_t Status_AG;          //A相姿态告警      0x01 告警  0x00正常  复归  故障
    uint8_t Status_BG;          //B相姿态告警      0x01 故障      0x00正常
    uint8_t Status_CG;          //C相姿态告警      0x01故障      0x00正常
    uint8_t Status_A_OT;        //A相温度超限告警  0x01故障      0x00正常
    uint8_t Status_B_OT;        //B相温度超限告警  0x01故障      0x00正常
    uint8_t Status_C_OT;        //C相温度超限告警  0x01故障      0x00正常
    uint8_t Status_Bat;         //电池电路硬件状态0x01故障      0x00正常
    uint8_t Error_AT;           //A相温度硬件状态  0x01故障      0x00正常
    uint8_t Error_BT;           //B相温度硬件状态  0x01故障      0x00正常
    uint8_t Error_CT;           //C相温度硬件状态  0x01故障      0x00正常
    uint8_t Error_AG;           //A相ADXL硬件状态 0x01故障      0x00正常
    uint8_t Error_BG;           //B相ADXL硬件状态 0x01故障      0x00正常
    uint8_t Error_CG;           //C相ADXL硬件状态 0x01故障      0x00正常
    uint8_t Error_ROT;          //环境温度硬件状态 0x01故障      0x00正常
    uint16_t WaterLevel;        //水位  0x20=32cm
    uint16_t RoomOut_Humidity;  //环境湿度    0x0321 = (801/10) = 80.1%
    uint8_t Error_Humidity;     //环境湿度硬件状态   1:告警，0:正常
    uint32_t Gas_O2;            //氧气浓度 0x000100013= （0x0013）=19 %VOL
    uint32_t Gas_CH4;           //甲烷浓度 同上
    uint32_t Gas_H2s;           //硫化氢浓度 同上
    uint32_t Gas_CO;            //一氧化碳浓度 同上
    float RMS_Va;               //A相电压
    float RMS_Vb;               //B相电压
    float RMS_Vc;               //C相电压
    uint16_t reserve;           //保留
    uint16_t endFlag;           //值：0X0D 0X0A   结束符  “/r/n”
}ca_land_rd_t;//实时数据报文  128 Byte

typedef struct{
    uint32_t StartFlag1;        //设备ID           0x40110304=ID=40110304
    uint8_t FarmeType;          //帧类型：          0x01  告警发送
    uint32_t RunSecCnt;         //系统运行时间      0x01020304=16909060秒
    uint8_t WaveNum;            //当前的录波物理编号：最新的文件    值：[0-127]
    uint8_t RMS_Ig_Err;         //总接地电流告      0x01 告警    0x00正常
    uint16_t RMS_Ig_Before;     //总接地电流变化前  0x0533=1331/10=133.1A
    uint16_t RMS_Ig_After;      //总接地电流变化后  0x0533=1331/10=133.1A
    uint8_t RMS_Ia_Err;         //A相电流告警      0x01 告警    0x00正常
    uint16_t RMS_Ia_Before;     //A相电流变化前    0x0533=1331/10=133.1A
    uint16_t RMS_Ia_After;      //A相电流变化后    0x0533=1331/10=133.1A
    uint8_t Sanke_a_Err;        //A相振动告警      0x01 告警    0x00正常
    uint16_t Sanke_a_x;         //A相X振动值
    uint16_t Sanke_a_y;         //A相Y振动值
    uint16_t Sanke_a_z;         //A相Z振动值
    uint8_t Temper_a_Err;       //A相温度告警     0x01 告警    0x00正常
    uint8_t Temper_a_Change;    //A相温度变化值   0x02         升高了2度
    uint16_t Temper_a_Before;   //A相温度前       0x0C02=(3074/10)-273.1=34.3摄氏度
    uint16_t Temper_a_After;    //A相温度后       0x0C02=(3074/10)-273.1=34.3摄氏度
    uint8_t RMS_Ib_Err;         //B相电流告警      0x01 告警    0x00正常
    uint16_t RMS_Ib_Before;     //B相电流变化前    0x0533=1331/10=133.1A
    uint16_t RMS_Ib_After;      //B相电流变化后    0x0533=1331/10=133.1A
    uint8_t Sanke_b_Err;        //B相振动告警      0x01 告警    0x00正常
    uint16_t Sanke_b_x;         //B相X振动值
    uint16_t Sanke_b_y;         //B相Y振动值
    uint16_t Sanke_b_z;         //B相Z振动值
    uint8_t Temper_b_Err;       //B相温度告警     0x01 告警    0x00正常
    uint8_t Temper_b_Change;    //B相温度变化值   0x02         升高了2度
    uint16_t Temper_b_Before;   //B相温度前       0x0C02=(3074/10)-273.1=34.3摄氏度
    uint16_t Temper_b_After;    //B相温度后       0x0C02=(3074/10)-273.1=34.3摄氏度
    uint8_t RMS_Ic_Err;         //C相电流告警      0x01 告警    0x00正常
    uint16_t RMS_Ic_Before;     //C相电流变化前    0x0533=1331/10=133.1A
    uint16_t RMS_Ic_After;      //C相电流变化后   0x0533=1331/10=133.1A
    uint8_t Sanke_c_Err;        //C相振动告警    0x01 告警    0x00正常
    uint16_t Sanke_c_x;         //C相X振动值
    uint16_t Sanke_c_y;         //C相Y振动值
    uint16_t Sanke_c_z;         //C相Z振动值
    uint8_t Temper_c_Err;       //C相温度告警    0x01 告警    0x00正常
    uint8_t Temper_c_Change;    //C相温度变化值 0x02         升高了2度
    uint16_t Temper_c_Before;   //C相温度前 0x0C02=(3074/10)-273.1=34.3摄氏度
    uint16_t Temper_c_After;    //C相温度后 0x0C02=(3074/10)-273.1=34.3摄氏度
    uint16_t endFlag;           //值：0X0D 0X0A   结束符  “/r/n”
}ca_land_war_t;//告警数据 71Byte

typedef struct{
    uint32_t StatusA;           //24个通道的温度数据的正确性判断 Bit24： 0 开关量正常 1开关量报警
    int16_t TempA[24];          //测温带的温度 （I16）/16【原始值】
    uint32_t StatusB;
    int16_t TempB[24];
    uint32_t StatusC;
    int16_t TempC[24];
} ca_land_tmp_t;//测温带数据 156 Byte

typedef struct{
    uint32_t proVer;            //协议版本号 0x00000363
    uint32_t utc;
    ca_land_rd_t rtd;
    uint32_t reslved1;          //调试工具   用来存历史数据条数
    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];      //电源故障 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;               //报文长度：所有字节总长度
    uint16_t Type;              //报文类型
    uint32_t ID;                //从机ID: 【ex. 0x40111234 】
    uint32_t LifeCnt;           //主机每次加1，从机应答收到的值
    uint16_t gNum;              //报文分组数目:（1-65535）；
    uint16_t gNumIndex;         //报文分组编号；0 ～ （gNum－1）
} ca_land_head_t;//朗德协议包头

typedef struct{
    uint32_t CheckSum;
    uint32_t EndFlag1;
} ca_land_tail_t;//朗德协议包尾
/* END: 以上结构体为私有协议数据 */

/* 私有协议全局控制结构 */
typedef struct{
    int fd;                                 // TCP server 监听使用的 socket
    char buf[CA_LAND_BUF_SIZE];             // 通讯使用收发包 buf
    ca_land_state_t state;                  // 协议状态
} ca_land_ctrl_t;

ca_land_ctrl_t ca_land_ctrl;                // 全局控制结构

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/

/* Internal functions --------------------------------------------------------*/
/* description: 显示当前状态
   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: 私有协议 socket 属性配置
   param: fd - socket 描述符
   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
    /* 开启保活, 保活参数表示 60 秒内无交互后, 每隔 6 秒检测一次. 10 次都没得到响应时会断开连接 */
    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

    /* 发送超时配置 */
    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;
    }

    /* 发送超时 */
    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: 初始化报文头
   param: cmd - 命令字
          len - 数据长度
   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: 报文校验和计算
   param: data_len - 报文总长度
   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; // 起始位和报文尾不参与计算
    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;

    /* 初始化报文头 */
    _ca_land_head_init(CA_LAND_CMD_REQ_ID, 36);
    _ca_land_cheak_sum(head->Len);

    /* 发送数据 */
    if (send(fd, pkt, head->Len, 0) < 0)
    {
        DBG(DBG_M_CA_LAND_ERR, "LAND send ERR!\r\n");
        return E_SYS_CALL;
    }

    /* 调试打印 */
    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: 数据报文组装
   param: data - 环流数据段
   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: 数据报文发送
   param: data - 环流数据段
   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;

    /* 初始化报文头 */
    _ca_land_head_init(CA_LAND_CMD_REPLY_RD, sizeof(ca_land_date_t));

    /* 填充数据 */
    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);

    /* 发送数据 */
    if (send(fd, pkt, head->Len, 0) < 0)
    {
        DBG(DBG_M_CA_LAND_ERR, "LAND send ERR!\r\n");
        return E_SYS_CALL;
    }

    /* 调试打印 */
    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: 私有协议数据发送线程
   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);
    }
    
    /* 绑定端口 */
    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);
        
        /* 创建 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);

            /* 如果 4G 连接, 服务器未连接, 假 4G 连接需要重启设备 */
            if (cfg->is_4G && state->is_4g_connect)
            {
                err_cnt++;
                if (err_cnt >= 10)
                {
                    // 如果是私网卡会连不上
                    //reboot_system(LOG_CA_LAND, BOOT_CONNECT_ERR);
                }
            }
            else
            {
                err_cnt = 0;
            }
            
            continue;
        }

        _ca_land_socket_set(fd);
        ca_land_ctrl.fd = fd;

        /* 定时发送数据 */
        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: 私有协预初始化
   param:
   return: E_XXX */
int32_t ca_land_init(void)
{
    cmd_install_element(COMMON_NODE, &ca_land_show_state_cmd);

    return E_NONE;
}

/* description: 朗德协议初始化函数.
   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: 私有协议状态结构体获取
   param:
   return: ca_land_state_t - 私有协议状态结构体指针 */
ca_land_state_t* ca_land_state_get(void)
{
    return &ca_land_ctrl.state;
}

/* description: 私有协议状态显示
   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 ****************/

