4280 lines
		
	
	
		
			144 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			4280 lines
		
	
	
		
			144 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /****************************************************************************
 | |
| 
 | |
| Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
 | |
| 
 | |
| This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
 | |
| be copied by any method or incorporated into another program without
 | |
| the express written consent of Aerospace C.Power. This Information or any portion
 | |
| thereof remains the property of Aerospace C.Power. The Information contained herein
 | |
| is believed to be accurate and Aerospace C.Power assumes no responsibility or
 | |
| liability for its use in any way and conveys no license or title under
 | |
| any patent or copyright and makes no representation or warranty that this
 | |
| Information is free from patent or copyright infringement.
 | |
| 
 | |
| ****************************************************************************/
 | |
| /* os_ship header files */
 | |
| #include "os_task_api.h"
 | |
| #include "os_event_api.h"
 | |
| #include "os_timer_api.h"
 | |
| #include "os_utils_api.h"
 | |
| 
 | |
| /* iot common header files */
 | |
| #include "iot_io_api.h"
 | |
| #include "iot_module_api.h"
 | |
| #include "iot_errno_api.h"
 | |
| #include "iot_task_api.h"
 | |
| #include "iot_pkt_api.h"
 | |
| #include "iot_board_api.h"
 | |
| #include "iot_oem_api.h"
 | |
| #include "iot_plc_api.h"
 | |
| #include "iot_version.h"
 | |
| #include "iot_version_api.h"
 | |
| 
 | |
| #include "iot_rtc_api.h"
 | |
| #include "iot_gpio_api.h"
 | |
| #include "iot_grapp.h"
 | |
| #include "iot_proto_common.h"
 | |
| #include "iot_gr_upgrade.h"
 | |
| #include "iot_proto_ge.h"
 | |
| #include "iot_cp_task.h"
 | |
| #include "iot_cp_socket.h"
 | |
| 
 | |
| #if (USE_N11_GPRS == 1)
 | |
| #include "n11_gprs.h"
 | |
| #endif
 | |
| 
 | |
| #if (CP_ZC_ENABLE == 1)
 | |
| #include "iot_bitmap_api.h"
 | |
| #include "cpl_types_api.h"
 | |
| #include "iot_gptmr_api.h"
 | |
| #endif
 | |
| 
 | |
| #if IOT_CP_TASK_ENABLE
 | |
| 
 | |
| #define IOT_CP_TASK_MSG_QUEUE        (0)
 | |
| #define IOT_CP_TASK_UART_BUF_SIZE    (512 + 64)
 | |
| #define IOT_CP_TASK_MSG_POOL_SIZE    (128)
 | |
| 
 | |
| #define IOT_CP_YEAR_START_FROM       (2000)
 | |
| 
 | |
| #ifndef IOT_CP_SEVER_WR_EN
 | |
| #define IOT_CP_SEVER_WR_EN            (1)
 | |
| #endif
 | |
| 
 | |
| #if (IOT_CP_SEVER_WR_EN == 1)
 | |
| /* store the respons infor for 60H, when 40H received */
 | |
| static cp_rpt_charg_abort_fn60_t resp_cmd_60h[IOT_CP_MAX_PLUG_CNT] = {0};
 | |
| /* bitmap for indcation whether 60h should be sent or not */
 | |
| static uint8_t is_wr_on = 0;
 | |
| /* report counter for every plug */
 | |
| static uint8_t rpt_60h_cnt[IOT_CP_MAX_PLUG_CNT] = {0};
 | |
| /* counter of interval for reporting retry */
 | |
| static uint8_t wr_invtl_cnt[IOT_CP_MAX_PLUG_CNT] = {0};
 | |
| /* indicate how many report pkt should be sent for each plug */
 | |
| #define IOT_CP_MAX_WR_60H_CNT         (3)
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #ifndef CP_TASK_DEBUG
 | |
| #define CP_TASK_DEBUG                 (0)
 | |
| #endif
 | |
| 
 | |
| static cp_flash_info_t *flash_info;
 | |
| 
 | |
| /* set default threshold value */
 | |
| const cp_plug_threshold_info_t def_cp_th = {
 | |
|     /* the current threshold when charge full, unit:1mA (1~1000) */
 | |
|     .full_chg_cur_th        = CP_DEFAULT_CFG_CHG_FULL_CURRENT,
 | |
|     /* threshold current timer for full charging */
 | |
|     .full_chg_cur_tm_th     = 0,
 | |
|     /* the current threshold when leak,unit:1 mA (1~255) */
 | |
|     .leak_cur_protc_th      = CP_DEFAULT_CFG_LEAK_CURRENT,
 | |
|     /* threshold of leakage current protection time */
 | |
|     .leak_cur_protc_tm_th   = 0,
 | |
|     /* the current threshold when load is over, unit:0.1A (1~160) */
 | |
|     .over_load_th           = CP_DEFAULT_CFG_OVERLOAD_CURRENT,
 | |
|     /* threshold of overload protection time */
 | |
|     .over_load_tm_th        = 0,
 | |
|     /* threshold of charging timeout */
 | |
|     .charg_timeout_th       = 0,
 | |
|     /* time of charge started */
 | |
|     .charg_start_tm         = 0,
 | |
|     /* open circurt current without load, uint:mA */
 | |
|     .discon_cur_th          = CP_DEFAULT_OPEN_CIRCUIT_CURRENT,
 | |
|     /* the rated voltage, such as 110V or 220v, unit: 1V */
 | |
|     .rated_volt             = CP_DEFAULT_CFG_RATED_VOLT,
 | |
|     /* fault status */
 | |
|     .alarm.alarm_en_data    = ALARM_EN_VALUE,
 | |
| };
 | |
| 
 | |
| #if USE_N11_GPRS
 | |
| 
 | |
| static uint32_t iot_grapp_sendto_mainboard_gprs_fn(iot_pkt_t *data)
 | |
| {
 | |
|     if (NULL == data) {
 | |
|         return ERR_INVAL;
 | |
|     }
 | |
| 
 | |
|     int32_t ret = iot_n11_gprs_send(data, 0);
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /* The command handle. */
 | |
| typedef void(*cp_cmd_meter_handle_t)(cp_socket_cmd_arg_t *arg);
 | |
| 
 | |
| /* the table of plctxrx commands. */
 | |
| typedef struct _cp_cmd_list_t
 | |
| {
 | |
|     cp_cmd_meter_handle_t *handle;
 | |
| } cp_cmd_list_t;
 | |
| 
 | |
| typedef struct _cp_command_t
 | |
| {
 | |
|     /* current command's infor: include CID and op_code */
 | |
|     cp_socket_hdr_t cur_cid;
 | |
|     /* indication the command is running or not */
 | |
|     bool_t          cmd_running;
 | |
|     /* indication current cmd need response cfm or not */
 | |
|     bool_t          need_ack;
 | |
|     /* list of command handle */
 | |
|     cp_cmd_list_t     list;
 | |
| } cp_command_t;
 | |
| 
 | |
| void iot_cp_task_msg_post(uint16_t msg_type, uint16_t msg_id,
 | |
|         iot_pkt_t *data, uint32_t dir);
 | |
| 
 | |
| typedef struct _iot_plc_context {
 | |
|     /* task handle */
 | |
|     iot_task_h          task;
 | |
|     /* uart handler */
 | |
|     iot_uart_h          uart_h;
 | |
|     /* timer handle for waiting grapp initialized */
 | |
|     timer_id_t          appinit_timer;
 | |
|     /* timer handle for command handling timeout */
 | |
|     timer_id_t          cmdresp_expire_timer;
 | |
|     /* timer handle for local status updating */
 | |
|     timer_id_t          status_update_timer;
 | |
|     /* local device type see IOT_CP_DEV_CODE_XXX */
 | |
|     uint8_t             dev_type;
 | |
|     /* local mac address. */
 | |
|     uint8_t             local_mac[IOT_MAC_ADDR_LEN];
 | |
|     /* cco mac */
 | |
|     uint8_t             cco_mac[IOT_MAC_ADDR_LEN];
 | |
|     /* module started */
 | |
|     uint8_t             module_started;
 | |
|     /* plc state : inited,online,offine */
 | |
|     uint8_t             plc_state;
 | |
|     /* work role*/
 | |
|     uint8_t             work_role;
 | |
|     /**/
 | |
|     cp_task_cb          cp_task_cb;
 | |
| }iot_plc_context;
 | |
| 
 | |
| typedef struct _iot_cp_context_task {
 | |
|     /* present time */
 | |
|     cp_date_t           rtc_time;
 | |
|     /* working mode, 0--maintain, 1--normal */
 | |
|     uint8_t             work_mode;
 | |
|     /* plugs' infor */
 | |
|     cp_plug_info_t      plug_info[IOT_CP_MAX_PLUG_CNT];
 | |
|     /* flash info */
 | |
|     cp_flash_info_t     flash_info;
 | |
|     /* software information */
 | |
|     uint32_t            sw_info;
 | |
|     /* hardware information */
 | |
|     uint32_t            hw_info;
 | |
|     /* current command handling*/
 | |
|     cp_command_t        command;
 | |
|     /* communication is normal*/
 | |
|     uint8_t             is_communication_ok;
 | |
|     /* interval counter of querring RTC */
 | |
|     uint16_t            query_rtc_cnt;
 | |
|     /* count of rtc reporting to platform */
 | |
|     uint8_t             rtc_report_cnt;
 | |
|     /* interval counter of status reporting to platform */
 | |
|     uint16_t            rpt_intvl_cnt[IOT_CP_MAX_PLUG_CNT];
 | |
|     /* sequnce number for sending cmd*/
 | |
|     uint32_t            send_signal_sn;
 | |
|     /* sequnce number for received cmd*/
 | |
|     uint32_t            recv_signal_sn;
 | |
| #if (CP_ZC_ENABLE == 1)
 | |
|     /* relay info for zc control */
 | |
|     cp_relay_zc_ctrl_t  relay_ctrl;
 | |
| #endif
 | |
| } iot_cp_context;
 | |
| 
 | |
| static iot_cp_context   cp_context;
 | |
| static iot_plc_context  plc_context;
 | |
| 
 | |
| #define IOT_CUS_TASK_DATA_DUMP
 | |
| #ifdef  IOT_CUS_TASK_DATA_DUMP
 | |
| static char dump_buf[512 + 16];
 | |
| 
 | |
| void iot_cp_task_data_dump_inner(void * buf, uint32_t len, uint32_t line)
 | |
| {
 | |
|     char *p = buf, *q = dump_buf;
 | |
|     uint32_t i, buf_len;
 | |
| 
 | |
|     buf_len = iot_sprintf(q, "DUMP(%03d):", len);
 | |
| 
 | |
|     for (i = 0; i < len && buf_len < sizeof(dump_buf) - 13; i++, p++) {
 | |
|         buf_len += iot_sprintf(q + buf_len, " %02X", ((int)*p) & 0xFF);
 | |
|     }
 | |
| 
 | |
|     iot_cus_printf("\n[cp_task@%04d]:%s\n", line, dump_buf);
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| #define iot_cp_task_data_dump(buf, len) \
 | |
|     iot_cp_task_data_dump_inner(buf, len, __LINE__)
 | |
| #else
 | |
| 
 | |
| #define iot_cp_task_data_dump(buf, len)
 | |
| 
 | |
| #endif
 | |
| 
 | |
| static void iot_cp_send_relay_state_to_meter_task(uint8_t plug_id,
 | |
|     bool_t state);
 | |
| 
 | |
| static void iot_cp_set_charge_switch(uint8_t plug_id, bool_t is_on);
 | |
| 
 | |
| static void iot_cp_set_threshold_value(cp_plug_threshold_info_t *th_info,
 | |
|     uint8_t id);
 | |
| 
 | |
| static void iot_cp_send_param_cmd_to_meter_task(uint8_t op_code,
 | |
|     uint8_t plug_id);
 | |
| 
 | |
| static iot_pkt_t *iot_cp_alloc_ge_data_frm_pkt( uint16_t data_len);
 | |
| 
 | |
| static void iot_cp_frame_fill(uint8_t fn, uint8_t *cp_frm,
 | |
|     uint16_t data_len, uint8_t dir);
 | |
| 
 | |
| static void iot_cp_send_pkt(uint8_t *dst_mac, iot_pkt_t *ge_pkt, uint8_t dir);
 | |
| 
 | |
| #if IOT_CP_SEVER_WR_EN
 | |
| /* for cco: report data to uart once error aborting happened fn: 60H
 | |
|  * for sta: report data to uart and cco
 | |
|  */
 | |
| static void iot_cp_report_err_abort_for_wr(uint8_t plug_num )
 | |
| {
 | |
|     cp_rpt_charg_abort_fn60_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
|     uint8_t dir;
 | |
| 
 | |
|     if (plug_num >= IOT_CP_MAX_PLUG_CNT) {
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     if (!(is_wr_on & (1 << plug_num))) {
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     if (rpt_60h_cnt[plug_num] >= IOT_CP_MAX_WR_60H_CNT) {
 | |
|         is_wr_on &= ~(1 << plug_num);
 | |
|         wr_invtl_cnt[plug_num] = 0;
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     wr_invtl_cnt[plug_num]++;
 | |
|     if (wr_invtl_cnt[plug_num] < IOT_CP_TASK_REPORT_INTVL_CNT) {
 | |
|         goto out;
 | |
|     }
 | |
|     iot_cus_printf("%s rpt_bm %d, plug id %d\n",__FUNCTION__, is_wr_on, plug_num);
 | |
|     wr_invtl_cnt[plug_num] = 0;
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rpt_charg_abort_fn60_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         os_mem_cpy(rsp_cmd, &resp_cmd_60h[plug_num], sizeof(*rsp_cmd));
 | |
| 
 | |
|         data_len  = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
| 
 | |
|         /* send to uart */
 | |
|         if (plc_context.work_role == CP_PLC_ROLE_CCO) {
 | |
|             dir = IOT_CP_TRANS_DIR_UART;
 | |
|         } else {
 | |
|             dir =  IOT_CP_TRANS_DIR_PLC;
 | |
|         }
 | |
|         iot_cp_frame_fill(IOT_CP_CMD_RPT_ERR_ABORT, (uint8_t *)rsp_cmd,
 | |
|             data_len, dir);
 | |
|         iot_cp_send_pkt(plc_context.cco_mac, rsp_pkt, dir);
 | |
| 
 | |
|         rpt_60h_cnt[plug_num]++;
 | |
|     }
 | |
| out:
 | |
|     return;
 | |
| }
 | |
| #else
 | |
| static void iot_cp_report_err_abort_for_wr(uint8_t plug_num)
 | |
| {
 | |
|     (void)plug_num;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #if (CP_ZC_ENABLE == 1)
 | |
| 
 | |
| /* get relay state in bitmap */
 | |
| static bool_t iot_cp_bm_get_relay_state(uint8_t plug_id)
 | |
| {
 | |
|     bool_t relay_on = true;
 | |
|     uint8_t bm_relay = cp_context.relay_ctrl.bm_relay_state;
 | |
| 
 | |
|     if (iot_bitmap_is_set(&bm_relay, 1, plug_id)) {
 | |
|         relay_on = true;
 | |
|     } else {
 | |
|         relay_on = false;
 | |
|     }
 | |
|     return relay_on;
 | |
| }
 | |
| 
 | |
| /* set bitmap for relay state */
 | |
| static void iot_cp_bm_set_relay_state(uint8_t plug_id, bool_t is_on)
 | |
| {
 | |
|     uint8_t bm_relay = cp_context.relay_ctrl.bm_relay_state;
 | |
| 
 | |
|     if (true == is_on) {
 | |
|         iot_bitmap_set(&bm_relay, 1, plug_id);
 | |
|     } else {
 | |
|         iot_bitmap_clear(&bm_relay, 1, plug_id);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* get request of relay state changing in bitmap */
 | |
| static bool_t iot_cp_bm_get_relay_state_change_req(uint8_t plug_id)
 | |
| {
 | |
|     bool_t req_on = true;
 | |
|     uint8_t bm_req = cp_context.relay_ctrl.bm_req;
 | |
| 
 | |
|     if (iot_bitmap_is_set(&bm_req, 1, plug_id)) {
 | |
|         req_on = true;
 | |
|     } else {
 | |
|         req_on = false;
 | |
|     }
 | |
|     return req_on;
 | |
| 
 | |
| }
 | |
| 
 | |
| /* set bitmap for relay state change request */
 | |
| static void iot_cp_bm_set_relay_state_change_req(uint8_t plug_id, bool_t is_on)
 | |
| {
 | |
|     uint8_t bm_req = cp_context.relay_ctrl.bm_req;
 | |
| 
 | |
|     if (true == is_on) {
 | |
|         iot_bitmap_set(&bm_req, 1, plug_id);
 | |
|     } else {
 | |
|         iot_bitmap_clear(&bm_req, 1, plug_id);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* set relay's state change request and new state*/
 | |
| static void iot_cp_set_switch_change_req(uint8_t plug_id, bool_t is_on)
 | |
| {
 | |
|     iot_cp_bm_set_relay_state_change_req(plug_id, is_on);
 | |
|     iot_cp_bm_set_relay_state(plug_id, is_on);
 | |
| }
 | |
| 
 | |
| /* caculate the zc period */
 | |
| static uint32_t iot_cp_zc_period_cal(uint8_t *buf, uint8_t len)
 | |
| {
 | |
|     uint8_t i, j;
 | |
|     uint32_t temp;
 | |
| 
 | |
|     /* reorder the data buffer: ranking from small to large */
 | |
|     for (i = 0; i < (len - 1); i++) {
 | |
|         for (j = 0; j < (len - 1 - i); j++) {
 | |
|             if (buf[j] > buf[j + 1]) {
 | |
|                 temp = buf[j];
 | |
|                 buf[j] = buf[j + 1];
 | |
|                 buf[j + 1] = temp;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     /* delete some max and min, the total number of
 | |
|      * max and min is IOT_PLC_HW_DELETE_CNT
 | |
|      */
 | |
|     i = IOT_CP_ZC_DISCARD_DATA_CNT;
 | |
|     j = IOT_CP_ZC_SAMPLE_CNT;
 | |
|     temp = 0;
 | |
|     i >>= 1;
 | |
|     j -= i;
 | |
|     /* calculate the period of sinusoidal wave */
 | |
|     for (; i < j; i++) {
 | |
|         temp += buf[i];
 | |
|     }
 | |
|     j = IOT_CP_ZC_SAMPLE_CNT - IOT_CP_ZC_DISCARD_DATA_CNT;
 | |
| 
 | |
|     return (temp / j);
 | |
| }
 | |
| 
 | |
| /* get zc infor in gpio's ISR */
 | |
| static uint32_t iot_cp_zc_info_get(void)
 | |
| {
 | |
|     uint8_t reason = 0;
 | |
|     uint8_t ret = ERR_OK;
 | |
|     uint32_t trig_tick, delta_tick = 0;
 | |
|     cp_zc_info_t *zc_info = &cp_context.relay_ctrl.zc_info;
 | |
| 
 | |
|     /* make sure the interrupt is trigged at the falling edge */
 | |
|     if (!iot_gpio_value_get(zc_info->zc_gpio)) {
 | |
|         reason = 1;
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     trig_tick = iot_gpio_get_trigger_ticks(zc_info->zc_gpio);
 | |
| 
 | |
|     if (zc_info->zc_tick_vaild == 0) {
 | |
|         /* first time, record counter and set flag */
 | |
|         zc_info->pre_triger_ticks = trig_tick;
 | |
|         zc_info->zc_tick_vaild = 1;
 | |
|         reason = 2;
 | |
|         goto out;
 | |
|     } else {
 | |
|         delta_tick = trig_tick - zc_info->pre_triger_ticks;
 | |
|         if (trig_tick > zc_info->pre_triger_ticks) {
 | |
|             delta_tick = trig_tick - zc_info->pre_triger_ticks;
 | |
|         } else {
 | |
|             delta_tick = 0xffffffff - zc_info->pre_triger_ticks + trig_tick;
 | |
|         }
 | |
|         if ((delta_tick > IOT_CP_ZC_PERIOD_LIMIT_UPPER) ||
 | |
|             (delta_tick < IOT_CP_ZC_PERIOD_LIMIT_LOWER)) {
 | |
|             reason = 3;
 | |
|             goto out;
 | |
|         }
 | |
|     }
 | |
|     zc_info->zc_buf[zc_info->buf_indx] = delta_tick;
 | |
|     zc_info->buf_indx++;
 | |
|     if (zc_info->buf_indx >= IOT_CP_ZC_SAMPLE_CNT) {
 | |
|         zc_info->buf_indx = 0;
 | |
|         zc_info->zc_period = iot_cp_zc_period_cal(zc_info->zc_buf,
 | |
|             IOT_CP_ZC_SAMPLE_CNT);
 | |
|         /* check validity of the zc period */
 | |
|         if ((zc_info->zc_period > IOT_CP_ZC_PERIOD_LIMIT_UPPER) ||
 | |
|             (zc_info->zc_period < IOT_CP_ZC_PERIOD_LIMIT_LOWER)) {
 | |
|             zc_info->zc_period_vaild = false;
 | |
|         } else {
 | |
|             zc_info->zc_period_vaild = true;
 | |
|         }
 | |
|     }
 | |
|     zc_info->pre_triger_ticks = trig_tick;
 | |
| 
 | |
| out:
 | |
|     if (reason != 0) {
 | |
|         ret = ERR_FAIL;
 | |
|     }
 | |
|     iot_cus_printf("%s reason %d\n", __FUNCTION__, reason);
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static void iot_cp_gp_timer_start(uint32_t period)
 | |
| {
 | |
|     iot_gp_timer_set(cp_context.relay_ctrl.gp_timer_id, period, 0);
 | |
|     iot_gp_timer_start(cp_context.relay_ctrl.gp_timer_id);
 | |
|     cp_context.relay_ctrl.timer_running = true;
 | |
|     iot_cus_printf("[cp]gp timer will fire up in %lu us\n", period);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* caculate the GP timer's period then start it */
 | |
| static void iot_cp_zc_gp_timer_period_cal_and_set(void)
 | |
| {
 | |
|     uint8_t reason = 0;
 | |
|     uint32_t cur_ts, delta_ts;
 | |
|     uint32_t gp_period = 0;;
 | |
|     cp_zc_info_t *zc_info = &cp_context.relay_ctrl.zc_info;
 | |
| 
 | |
|     if (!zc_info->zc_period_vaild) {
 | |
|         reason = 1;
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     /* no relay control quest, go out */
 | |
|     if (cp_context.relay_ctrl.bm_req == 0) {
 | |
|         reason = 2;
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     cur_ts = iot_gp_timer_get_curr_ts();
 | |
|     if (cur_ts > zc_info->pre_triger_ticks) {
 | |
|         delta_ts = cur_ts - zc_info->pre_triger_ticks;
 | |
|     } else {
 | |
|         delta_ts = 0xffffffff - zc_info->pre_triger_ticks + cur_ts;
 | |
|     }
 | |
|     if (delta_ts > zc_info->zc_period) {
 | |
|         reason = 3;
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     gp_period = zc_info->zc_period - delta_ts;
 | |
| out:
 | |
|     if (reason != 0) {
 | |
|         iot_cus_printf("Get GP timer period failed, reason %d\n", reason);
 | |
|     } else {
 | |
|         if (reason > 2) {
 | |
|             iot_cp_gp_timer_start(gp_period);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* update the relay's status after gp timer's ISR */
 | |
| static void iot_cp_relay_ctrl_update_handle(iot_addrword_t data)
 | |
| {
 | |
|     (void)data;
 | |
|     cp_relay_zc_ctrl_t *relay = &cp_context.relay_ctrl;
 | |
|     uint8_t indx;
 | |
| 
 | |
|     if (relay->bm_req == 0) {
 | |
|         return ;
 | |
|     }
 | |
| 
 | |
|     for (indx = 0; indx < CP_SOCKET_ID_MAX; indx++) {
 | |
|         if (true == iot_cp_bm_get_relay_state_change_req(indx)) {
 | |
|             /* inform th lower layer task once relay state changed */
 | |
|             if (true == iot_cp_bm_get_relay_state(indx)) {
 | |
|                 iot_cp_send_relay_state_to_meter_task(indx, true);
 | |
|             } else {
 | |
|                 iot_cp_send_relay_state_to_meter_task(indx, false);
 | |
|             }
 | |
|             /* clear requst flag in bitmap */
 | |
|             iot_cp_bm_set_relay_state_change_req(indx, false);
 | |
|         }
 | |
|     }
 | |
|     return ;
 | |
| }
 | |
| 
 | |
| /* ISR of GP timer: set the gpio status to on or off */
 | |
| uint8_t  iot_cp_relay_ctrl_isr_handle(iot_addrword_t data)
 | |
| {
 | |
|     uint8_t indx;
 | |
|     cp_relay_zc_ctrl_t *relay = &cp_context.relay_ctrl;
 | |
| 
 | |
|     (void)data;
 | |
| 
 | |
|     for (indx = 0; indx < CP_SOCKET_ID_MAX; indx++) {
 | |
|         if (true == iot_cp_bm_get_relay_state_change_req(indx)) {
 | |
|             /* set relays to on or off state */
 | |
|             if (true == iot_cp_bm_get_relay_state(indx)) {
 | |
|                 iot_cp_set_charge_switch(indx, true);
 | |
|             } else {
 | |
|                 iot_cp_set_charge_switch(indx, false);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     relay->timer_running = false;
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| static void iot_cp_zc_gpio_isr_handle(int arg)
 | |
| {
 | |
|     (void)arg;
 | |
| 
 | |
|     iot_cp_zc_info_get();
 | |
| 
 | |
|     iot_cp_zc_gp_timer_period_cal_and_set();
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /* initialize GPIO for ZC_in */
 | |
| static uint8_t iot_cp_zc_gpio_init()
 | |
| {
 | |
|     uint8_t ret = ERR_OK;
 | |
|     uint8_t zc_gpio = 0xff;
 | |
|     uint8_t reason = 0;
 | |
| 
 | |
|     zc_gpio = cp_context.relay_ctrl.zc_info.zc_gpio;
 | |
| 
 | |
|     if (zc_gpio == 0xFF) {
 | |
|         reason = 1;
 | |
|         goto out;
 | |
|     }
 | |
|     if (iot_gpio_open_as_interrupt(zc_gpio)) {
 | |
|         reason = 2;
 | |
|         goto out;
 | |
|     }
 | |
|     if (iot_gpio_interrupt_config(zc_gpio, GPIO_INT_EDGE_RAISING,
 | |
|         iot_cp_zc_gpio_isr_handle, 0, GPIO_INT_FUNC_GET_TICKS)) {
 | |
|         reason = 3;
 | |
|         goto out;
 | |
|     }
 | |
|     if (iot_gpio_interrupt_enable(zc_gpio, 1)) {
 | |
|         reason = 4;
 | |
|         goto out;
 | |
|     }
 | |
| out:
 | |
|     if (reason != 1) {
 | |
|         ret = ERR_FAIL;
 | |
|     }
 | |
|     iot_cus_printf("Init ZC gpio%d %s reason %d\n", zc_gpio,
 | |
|         ret ? "failed" : "successfully", reason);
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| static uint8_t iot_cp_zc_hw_init(void)
 | |
| {
 | |
|     uint8_t reason = 0;
 | |
|     uint8_t ret = 0;
 | |
|     uint8_t timer_id = cp_context.relay_ctrl.gp_timer_id;
 | |
| 
 | |
|     timer_id = iot_gp_timer_create(0x0, iot_cp_relay_ctrl_update_handle,
 | |
|         iot_cp_relay_ctrl_isr_handle, 0);
 | |
|     if (timer_id >= GP_TIMER_COUNT) {
 | |
|         timer_id = IOT_CP_GP_TIMER_INVALID_ID;
 | |
|         reason = 1;
 | |
|     } else {
 | |
|         if(ERR_OK != iot_cp_zc_gpio_init()) {
 | |
|             reason = 2;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (reason != 0) {
 | |
|         ret = ERR_FAIL;
 | |
|     }
 | |
|     iot_cus_printf("Init ZC hardware %s reason %d\n",
 | |
|         ret ? "failed" : "successfully", reason);
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static void iot_cp_delay_time(uint32_t delay)
 | |
| {
 | |
|     (void)delay;
 | |
| }
 | |
| 
 | |
| static void iot_cp_set_moc(uint8_t plug_id, int32_t hi_low)
 | |
| {
 | |
|     (void)plug_id;
 | |
|     (void)hi_low;
 | |
| }
 | |
| 
 | |
| #else /* CP_ZC_ENABLE == 1 */
 | |
| 
 | |
| static void iot_cp_delay_time(uint32_t delay)
 | |
| {
 | |
|     os_delay(delay);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_set_moc:  set moc gpio hi_low
 | |
|  * @param plug_id:   socket port id, see CP_SOCKET_IDXX
 | |
|  * @param hi_low:    gpio hi low state, see IOT_CP_GPIO_OUPUT_XX
 | |
|  */
 | |
| static void iot_cp_set_moc(uint8_t plug_id, int32_t hi_low)
 | |
| {
 | |
|     if (plug_id == CP_SOCKET_ID_0 || plug_id == CP_SOCKET_ID_ALL)
 | |
|         iot_gpio_value_set(IOT_CP_GPIO_MOC1, hi_low);
 | |
|     if (plug_id == CP_SOCKET_ID_1 || plug_id == CP_SOCKET_ID_ALL)
 | |
|         iot_gpio_value_set(IOT_CP_GPIO_MOC2, hi_low);
 | |
|     if (plug_id == CP_SOCKET_ID_2 || plug_id == CP_SOCKET_ID_ALL)
 | |
|         iot_gpio_value_set(IOT_CP_GPIO_MOC3, hi_low);
 | |
|     if (plug_id == CP_SOCKET_ID_3 || plug_id == CP_SOCKET_ID_ALL)
 | |
|         iot_gpio_value_set(IOT_CP_GPIO_MOC4, hi_low);
 | |
| }
 | |
| 
 | |
| #endif /* CP_ZC_ENABLE == 0 */
 | |
| 
 | |
| static uint32_t iot_cp_get_send_signal_sn(void)
 | |
| {
 | |
|     cp_context.send_signal_sn++;
 | |
|     if (cp_context.send_signal_sn == 0) {
 | |
|         cp_context.send_signal_sn = 1;
 | |
|     }
 | |
| 
 | |
|     iot_cus_printf("new signal SN alloc: %lu\n", cp_context.send_signal_sn);
 | |
| 
 | |
|     return cp_context.send_signal_sn;
 | |
| }
 | |
| 
 | |
| static void iot_cp_send_relay_state_to_meter_task(uint8_t plug_id,
 | |
|     bool_t state);
 | |
| 
 | |
| /**
 | |
|  * @briefiot_cp_calc_cs:  calculate checksum
 | |
|  * @param data:     data need to calculate checksum
 | |
|  * @param len:      the data length to calculate checksum
 | |
|  * @retval: return the checksum calculated
 | |
|  */
 | |
| static uint8_t iot_cp_calc_cs(uint8_t *data, uint16_t len)
 | |
| {
 | |
|     uint16_t i;
 | |
|     uint8_t cs = data[0];
 | |
|     IOT_ASSERT(data && len);
 | |
| 
 | |
|     for (i = 1; i < len; i++) {
 | |
|         cs += data[i];
 | |
|     }
 | |
|     return cs;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_frame_fill:  fill cp frame header, checksum and tail field.
 | |
|  * @param fn:          cp's fucntion code
 | |
|  * @param cp_frm:      pointer of data field
 | |
|  * @param data_len:    length of data field
 | |
|  */
 | |
| static void iot_cp_frame_fill(uint8_t fn, uint8_t *cp_frm,
 | |
|     uint16_t data_len, uint8_t dir)
 | |
| {
 | |
|     cp_rsp_frame_t *frame_h= NULL;
 | |
|     uint8_t  *data_ptr = NULL;
 | |
|     uint8_t cal_crc;
 | |
| 
 | |
|     frame_h   = (cp_rsp_frame_t *)cp_frm;
 | |
|     frame_h->hdr.preamble = CP_FRM_PREAMBLE_CODE;
 | |
|     frame_h->hdr.fn       = fn;
 | |
|     frame_h->hdr.data_len = data_len;
 | |
|     cal_crc       = iot_cp_calc_cs(cp_frm, sizeof(*frame_h) + data_len);
 | |
|     data_ptr      = frame_h->data + data_len;
 | |
|     *(data_ptr++) = cal_crc;
 | |
|     *data_ptr     = CP_FRM_TAIL_CODE;
 | |
| 
 | |
|     if (dir == IOT_CP_TRANS_DIR_PLC) {
 | |
|         frame_h->hdr.preamble = CP_FRM_PREAMBLE_REPLY_CODE;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_get_cpcmd_hdr:    find a CP frame and return the frame header
 | |
|  * @param data:        data to be queried
 | |
|  * @param in_len:      data length of the query
 | |
|  * @param vaild_len:   if a frame is found to return virtual length
 | |
|  * @retval: return cp frame header if find cp frame.
 | |
|  */
 | |
| static cp_frm_hdr_t *iot_get_cpcmd_hdr(uint8_t *data, uint16_t in_len,
 | |
|     uint8_t *vaild_len)
 | |
| {
 | |
|     cp_frm_hdr_t *hdr = NULL;
 | |
|     uint8_t *ptr      = NULL;
 | |
|     uint8_t t_crc     = 0;
 | |
|     uint8_t cal_crc   = 0;
 | |
|     uint8_t frm_len   = 0;
 | |
|     uint8_t is_reply  = false;
 | |
|     uint16_t i        = 0;
 | |
|     if ((NULL == data) || (in_len < CP_FRM_MIN_LEN)) {
 | |
|         *vaild_len = 0;
 | |
|         iot_cus_printf("[cp]:cp frame check err\n");
 | |
|         return hdr;
 | |
|     }
 | |
|     for (i = 0; i < in_len; i++) {
 | |
|         data += i;
 | |
|         //a reply frame
 | |
|         if (CP_FRM_PREAMBLE_REPLY_CODE == (*data)) {
 | |
|            iot_cus_printf("[cp]reply frame found\n");
 | |
|            (*data) = CP_FRM_PREAMBLE_CODE;
 | |
|            is_reply = true;
 | |
|         }
 | |
|         if (CP_FRM_PREAMBLE_CODE == (*data)) {
 | |
|             ptr = data + CP_FRM_DATA_LEN_OFFSET;
 | |
|             frm_len = sizeof(cp_frm_hdr_t) + (*ptr) + CP_FRAME_TAIL_SIZE;
 | |
|             ptr = ptr + (*ptr);
 | |
|             ptr++;
 | |
|             t_crc = (*ptr);
 | |
|             cal_crc = iot_cp_calc_cs(data, frm_len - CP_FRAME_TAIL_SIZE);
 | |
|             if ((CP_FRM_TAIL_CODE == *(ptr+1)) && (t_crc == cal_crc)) {
 | |
|                 hdr = (cp_frm_hdr_t *)data;
 | |
|                 *vaild_len = frm_len;
 | |
|                 if (is_reply) {
 | |
|                     hdr->preamble = CP_FRM_PREAMBLE_REPLY_CODE;
 | |
|                 }
 | |
|                 return hdr;
 | |
|             } else {
 | |
|                 iot_cus_printf("[cp][err]cp frame CS err\n");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return hdr;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_ge_frm_check:  find a GE frame and return the frame header
 | |
|  * @param data    :  data to be queried
 | |
|  * @param in_len  :  data length of the query
 | |
|  * @param vaild_len: if a frame is found to return virtual length
 | |
|  * @retval: return ge frame header if find ge frame in data
 | |
|  */
 | |
| static ge_extend_fn_hdr_t *iot_cp_ge_frm_check(uint8_t *data,
 | |
|     uint16_t in_len, uint16_t *vaild_len)
 | |
| {
 | |
|     ge_extend_fn_hdr_t *head = NULL;
 | |
|     uint16_t pre_code   = 0;
 | |
|     uint16_t payload_len = 0;
 | |
|     uint8_t *ptr      = NULL;
 | |
|     uint16_t cal_crc  = 0;
 | |
|     uint16_t frm_crc  = 0;
 | |
|     uint16_t len_t, i = 0;
 | |
|     uint8_t *data_s   = NULL;
 | |
|     uint16_t t_len     = 0;
 | |
| 
 | |
|     *vaild_len = 0;
 | |
| 
 | |
|     if ((NULL == data) || (in_len < GE_FRM_MIN_LEN)) {
 | |
|         return head;
 | |
|     }
 | |
| 
 | |
|     iot_cus_printf("[cp]iot_cp_ge_frm_check inlen=%d\n", in_len);
 | |
|     for (i = 0, len_t = in_len; i < in_len; i++) {
 | |
|         if (i + 1 >= in_len) {
 | |
|             break;
 | |
|         }
 | |
|         /* check frame preamble coed */
 | |
|         pre_code = (data[i] << 8) + data[i+1];
 | |
|         if (pre_code == GE_FRM_PREAMBLE_CODE) {
 | |
|             data_s = data + i;
 | |
|         }
 | |
|         len_t--;
 | |
|         if ((data_s == NULL) || (len_t < GE_FRM_MIN_LEN)) {
 | |
|             /* left cmd length is not enought */
 | |
|             break;
 | |
|         }
 | |
|         head = (ge_extend_fn_hdr_t *)data_s;
 | |
|         /* check fn and sunfn for command */
 | |
|         if (head->hdr.fn == PROTO_UPGRADE_DL || head->hdr.fn == PROTO_UPGRADE_UL) {
 | |
|             if (head->hdr.fn == PROTO_UPGRADE_DL &&
 | |
|                 head->subfn == PROTO_UPGRADE_DATA) {
 | |
|                 /* calc upgrade data len */
 | |
|                 if (head->hdr.data_len == GREE_UPGRADE_DATA_CONTROL &&
 | |
|                     len_t > GREE_UPGRADE_DATA_FRM_LEN_HIG_BYTE) {
 | |
|                     payload_len = GREE_UPGRADE_DATA_FRM_CTL_LEN +
 | |
|                         data_s[GREE_UPGRADE_DATA_FRM_LEN_HIG_BYTE] * 256 +
 | |
|                         data_s[GREE_UPGRADE_DATA_FRM_LEN_LOW_BYTE];
 | |
|                 } else {
 | |
|                     return NULL;
 | |
|                 }
 | |
|             } else {
 | |
|                 /* calc other upgrade command length */
 | |
|                 payload_len = head->hdr.data_len;
 | |
|                 if (payload_len > GREE_UPGRADE_CMD_CONTROL_MIN) {
 | |
|                     payload_len -= GREE_UPGRADE_CMD_CONTROL_MIN;
 | |
|                 }
 | |
|             }
 | |
|         } else {
 | |
|             payload_len = head->hdr.data_len;
 | |
|         }
 | |
| 
 | |
|         ptr = data_s + GE_FRM_NORMAL_SEQ_POS + payload_len;
 | |
|         frm_crc = *ptr + (*(ptr + 1) << 8);
 | |
|         ptr += GE_FRM_CHECKSUM_FIELD_LEN;
 | |
| 
 | |
|         if (*ptr != GE_FRM_TAIL_CODE) {
 | |
|             iot_cus_printf("[cp]ge_frm_check tail check error\n");
 | |
|             continue;
 | |
|         }
 | |
|         /* calc frame length, exclude checksum and tail */
 | |
|         t_len = GE_FRM_MIN_LEN + payload_len - GE_FRM_CHECKSUM_FIELD_LEN -
 | |
|             GE_FRM_TAIL_FILED_LEN;
 | |
| 
 | |
|         /* checksum check */
 | |
|         cal_crc = ge_frm_checksum_calc(data_s, t_len );
 | |
|         if (cal_crc != frm_crc) {
 | |
|            iot_cus_printf("[cp]ge_frm_check crc check c_crc:%x != f_crc:%x\n",
 | |
|             cal_crc, frm_crc);
 | |
|            continue;
 | |
|         } else {
 | |
|             /* total frame length */
 | |
|             t_len += GE_FRM_CHECKSUM_FIELD_LEN + GE_FRM_TAIL_FILED_LEN;
 | |
|             *vaild_len = t_len;
 | |
| 
 | |
|             return head;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| uint8_t iot_cp_task_post_uart_cmd(uint8_t * data, uint16_t len, uint32_t param)
 | |
| {
 | |
|     iot_pkt_t* send_pkt = NULL;
 | |
|     (void)param;
 | |
|     send_pkt = iot_pkt_alloc(len, IOT_CP_TASK_ID);
 | |
|     if (send_pkt) {
 | |
|         /* copy data from buf to data packet */
 | |
|         os_mem_cpy(iot_pkt_put(send_pkt, len), data, len);
 | |
| 
 | |
|         /* alloc message to insert proto task msg queue */
 | |
|         iot_cp_task_msg_post(IOT_CP_TASK_MT_APPDATA,
 | |
|               IOT_CP_TASK_MSG_ID_CMD_HANDLE, send_pkt, IOT_CP_TRANS_DIR_UART);
 | |
|         return ERR_OK;
 | |
|     } else {
 | |
|         iot_cus_printf("[cp][err]no mem, frame len:%d\n", len);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_check_order_closed - check order whether closed
 | |
|  */
 | |
| static void iot_cp_check_order_closed(void)
 | |
| {
 | |
|     uint8_t plug_id;
 | |
| 
 | |
|     for (plug_id = 0; plug_id < CP_SOCKET_ID_ALL; plug_id++) {
 | |
|         iot_cus_printf("%s %d checked=%d end_type=%d\n", __FUNCTION__, plug_id,
 | |
|             flash_info->his_info[plug_id].checked,
 | |
|             flash_info->his_info[plug_id].end_type);
 | |
|         if (flash_info->his_info[plug_id].checked == IOT_CP_ORDER_UNCHECK &&
 | |
|             (flash_info->his_info[plug_id].end_type == 0 ||
 | |
|             flash_info->his_info[plug_id].end_type != IOT_CP_END_TPYE_END_PO)) {
 | |
|             /* report close order */
 | |
|             cp_context.plug_info[plug_id].rpt_bitmap |= CP_REPORT_ERR_ON;
 | |
|             cp_context.plug_info[plug_id].rpt_data =
 | |
|                 flash_info->his_info[plug_id].end_type | (plug_id << 6);
 | |
|             iot_cp_task_msg_post(IOT_CP_TASK_MT_REPORT,
 | |
|                 IOT_CP_CMD_RPT_ERR_ABORT, NULL,
 | |
|                 cp_context.plug_info[plug_id].rpt_data);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static uint8_t iot_cp_default_param_init(void)
 | |
| {
 | |
|     uint8_t plug_num;
 | |
|     flash_info = &cp_context.flash_info;
 | |
|     /* load flash information */
 | |
|     iot_proto_custom_pib_info_load((void*)flash_info, sizeof(cp_flash_info_t));
 | |
|     /* set to cp socket */
 | |
|     if (flash_info->th_eigenvalue != CP_THESHOLD_EIGENVALUE) {
 | |
|         /* set default threshold value to cp socket */
 | |
|         iot_cp_set_threshold_value((cp_plug_threshold_info_t*)&def_cp_th,
 | |
|             CP_SOCKET_ID_ALL);
 | |
|     }
 | |
| 
 | |
|     for (plug_num = 0; plug_num < CP_SOCKET_ID_ALL; plug_num++) {
 | |
|         iot_cp_send_param_cmd_to_meter_task(CP_SOCKET_OP_CONFIG, plug_num);
 | |
|     }
 | |
| 
 | |
|     iot_cp_check_order_closed();
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| /* initialize GPIO hardware */
 | |
| static uint8_t iot_cp_gpio_init(void)
 | |
| {
 | |
| #if USE_N11_GPRS == 0
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_RELAY1)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_RELAY1);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_MOC1)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_MOC1);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_RELAY2)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_RELAY1);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_MOC2)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_MOC1);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_RELAY3)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_RELAY1);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_MOC3)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_MOC1);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_RELAY4)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_RELAY1);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_MOC4)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_MOC1);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_NRESET)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_NRESET);
 | |
|     }
 | |
| 
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_PKEY)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_PKEY);
 | |
|     }
 | |
|     if (ERR_OK != iot_gpio_open_as_output(IOT_CP_GPIO_LED)) {
 | |
|         iot_cus_printf("[cp]open gpio%lu as output fail\n", IOT_CP_GPIO_LED);
 | |
|     }
 | |
| 
 | |
|     iot_cp_delay_time(IOT_CP_SWITCH_DELAY*2);
 | |
| 
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_NRESET, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_PKEY, IOT_CP_GPIO_OUPUT_LOW);
 | |
| 
 | |
|     iot_cp_delay_time(IOT_CP_SWITCH_DELAY*2);
 | |
| 
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_MOC1, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_RELAY1, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_MOC2, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_RELAY2, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_MOC3, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_RELAY3, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_MOC4, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_RELAY4, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_PKEY, IOT_CP_GPIO_OUPUT_HI);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_LED, IOT_CP_GPIO_OUPUT_HI);
 | |
|     iot_cp_delay_time(IOT_CP_SWITCH_DELAY*2);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_LED, IOT_CP_GPIO_OUPUT_LOW);
 | |
|     iot_gpio_value_set(IOT_CP_GPIO_PKEY, IOT_CP_GPIO_OUPUT_LOW);
 | |
| 
 | |
|  #endif
 | |
|     return ERR_OK;
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_set_charge_switch:  set charge state, start or stop
 | |
|  * @param plug_id:   socket port id, see CP_SOCKET_IDXX,
 | |
|  * @param flag:      start or stop flag,
 | |
|  *                   if set true, start charging,
 | |
|  *                   if set false, stop charging.
 | |
|  */
 | |
| static void iot_cp_set_charge_switch(uint8_t plug_id, bool_t is_on)
 | |
| {
 | |
|     int32_t hi_low = IOT_CP_GPIO_OUPUT_LOW;
 | |
| 
 | |
|     if (is_on) {
 | |
|         hi_low = IOT_CP_GPIO_OUPUT_HI;
 | |
|     } else {
 | |
|         hi_low = IOT_CP_GPIO_OUPUT_LOW;
 | |
|     }
 | |
| 
 | |
|     iot_cp_set_moc(plug_id, IOT_CP_GPIO_OUPUT_HI);
 | |
| 
 | |
|     iot_cp_delay_time(IOT_CP_SWITCH_DELAY);
 | |
| 
 | |
|     if (plug_id == CP_SOCKET_ID_0 || plug_id == CP_SOCKET_ID_ALL)
 | |
|         iot_gpio_value_set(IOT_CP_GPIO_RELAY1, hi_low);
 | |
|     if (plug_id == CP_SOCKET_ID_1 || plug_id == CP_SOCKET_ID_ALL)
 | |
|         iot_gpio_value_set(IOT_CP_GPIO_RELAY2, hi_low);
 | |
|     if (plug_id == CP_SOCKET_ID_2 || plug_id == CP_SOCKET_ID_ALL)
 | |
|         iot_gpio_value_set(IOT_CP_GPIO_RELAY3, hi_low);
 | |
|     if (plug_id == CP_SOCKET_ID_3 || plug_id == CP_SOCKET_ID_ALL)
 | |
|         iot_gpio_value_set(IOT_CP_GPIO_RELAY4, hi_low);
 | |
| 
 | |
|     iot_cp_delay_time(IOT_CP_SWITCH_DELAY);
 | |
| 
 | |
|     iot_cp_set_moc(plug_id, IOT_CP_GPIO_OUPUT_LOW);
 | |
| 
 | |
| #if (CP_ZC_ENABLE == 0)
 | |
|     /* if zc disabled, inform the lower task immediately, otherwise,
 | |
|      * infor the lower task  after the gp timer's ISR handled */
 | |
|     iot_cp_send_relay_state_to_meter_task(plug_id, is_on);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static void iot_cp_start_charging(uint8_t plug_id)
 | |
| {
 | |
|     iot_cus_printf("plug %d start charging...\n", plug_id);
 | |
| #if (CP_ZC_ENABLE == 1)
 | |
|     iot_cp_set_switch_change_req(plug_id, true);
 | |
| #else
 | |
|     iot_cp_set_charge_switch(plug_id, true);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static void iot_cp_stop_charging(uint8_t plug_id)
 | |
| {
 | |
| #if (CP_ZC_ENABLE == 1)
 | |
|     iot_cp_set_switch_change_req(plug_id, false);
 | |
| #else
 | |
|     iot_cp_set_charge_switch(plug_id, false);
 | |
| #endif
 | |
| 
 | |
|     iot_cus_printf("plug %d stop charging...\n", plug_id);
 | |
| }
 | |
| 
 | |
| /* set RTC */
 | |
| static void cp_rtc_set(cp_sub_date_t *tm)
 | |
| {
 | |
|     iot_time_tm_t rtc_tm;
 | |
|     rtc_tm.tm_year = IOT_CP_YEAR_START_FROM + tm->year;
 | |
|     os_mem_cpy(&rtc_tm.tm_mon, &tm->month, sizeof(cp_sub_date_t) -1);
 | |
|     iot_rtc_set(&rtc_tm);
 | |
| }
 | |
| 
 | |
| /* get RTC */
 | |
| static void cp_rtc_get(cp_sub_date_t *tm)
 | |
| {
 | |
|     iot_time_tm_t rtc_tm;
 | |
|     iot_rtc_get(&rtc_tm);
 | |
|     tm->year = (rtc_tm.tm_year - IOT_CP_YEAR_START_FROM) & 0xFF;
 | |
|     os_mem_cpy(&tm->month, &rtc_tm.tm_mon, sizeof(cp_sub_date_t) -1);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief cp_calc_weekday() - use Zeller's Rule to calc weekDay on any date
 | |
|  * @param y : year of the date, two digits, year start from 20 century
 | |
|  * @param m : month of the date
 | |
|  * @param d : day of the date
 | |
|  * @return : weekday from 0 to 6
 | |
|  */
 | |
| static uint8_t cp_calc_weekday(uint32_t y, uint8_t m, uint8_t d)
 | |
| {
 | |
|     uint8_t weekday = 0;
 | |
|     /* use Zeller's Rule: Day on any date in the calendar
 | |
|          W=(Y+[Y/4]+[C/4]-2C+[26(M+1)/10]+d-1)%7
 | |
|          W:weekday, C:century, Y:year(two digits), M:month, d:day
 | |
|     */
 | |
|     weekday = (uint8_t)(y+y/4+20/4-2*20+26*(m+1)/10+d-1)%7;
 | |
|    return weekday;
 | |
| }
 | |
| 
 | |
| static void cp_rtc_init(void)
 | |
| {
 | |
|     /* set the RTC to default value: 2019-05-01 00:00:00 wed. */
 | |
|     cp_context.rtc_time.sub_date_t.year = 19;
 | |
|     cp_context.rtc_time.sub_date_t.month = 5;
 | |
|     cp_context.rtc_time.sub_date_t.date = 1;
 | |
|     cp_context.rtc_time.sub_date_t.hour = 0;
 | |
|     cp_context.rtc_time.sub_date_t.min = 0;
 | |
|     cp_context.rtc_time.sub_date_t.sec = 0;
 | |
|     cp_context.rtc_time.week = 3;
 | |
| 
 | |
|     cp_rtc_set(&cp_context.rtc_time.sub_date_t);
 | |
| }
 | |
| /* initialize the plug's working state*/
 | |
| static void iot_cp_reinit_work_state(uint8_t plug_id)
 | |
| {
 | |
|     cp_plug_info_t *plug_info;
 | |
|     plug_info = (cp_plug_info_t*)(&cp_context.plug_info[plug_id]);
 | |
|     if (plug_info->plug_state.plug_in == 0) {
 | |
|         plug_info->plug_state.work_state = IOT_CP_WORK_STATE_IDLE;
 | |
|     } else {
 | |
|         plug_info->plug_state.work_state = IOT_CP_WORK_STATE_OCCUPIED;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void iot_cp_stop_charging_due_to_reason(uint8_t plug_id, uint8_t reason)
 | |
| {
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_plug_history_info_t *his_info;
 | |
|     uint32_t cur_ts;
 | |
|     cp_sub_date_t date = { 0 };
 | |
|     uint8_t his_last  = 0;
 | |
| 
 | |
|     if (plug_id >= CP_SOCKET_ID_MAX) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     plug_info = (cp_plug_info_t*)(&cp_context.plug_info[plug_id]);
 | |
|     iot_cus_printf("[cp]plug %d stop_charging, reason:%d\n", plug_id, reason);
 | |
| 
 | |
|     if (plug_info->plug_state.work_state != IOT_CP_WORK_STATE_CHARGING) {
 | |
|         if (reason == IOT_CP_END_TPYE_EMERG) {
 | |
|             /* emergence happend, under maintaince */
 | |
|             plug_info->plug_state.work_state = IOT_CP_WORK_STATE_MAINTAIN;
 | |
|         }
 | |
|         iot_cus_printf("[cp][err]plug %d not in charging mode\n", plug_id);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (reason == IOT_CP_END_TPYE_EMERG) {
 | |
|         /* emergence happend, under maintaince */
 | |
|         plug_info->plug_state.work_state = IOT_CP_WORK_STATE_MAINTAIN;
 | |
|     }
 | |
| 
 | |
|     if (reason == IOT_CP_END_TPYE_FAULT) {
 | |
|         plug_info->plug_state.work_state = IOT_CP_WORK_STATE_FAULT;
 | |
|     } else if (reason == IOT_CP_END_TPYE_DISCONN) {
 | |
|         /* socket plug out, change state to idle */
 | |
|         plug_info->plug_state.work_state = IOT_CP_WORK_STATE_IDLE;
 | |
|     } else if ((reason == IOT_CP_END_TPYE_CHARGED) ||
 | |
|         (reason == IOT_CP_END_TPYE_END_PO)) {
 | |
|         /* charged over */
 | |
|         plug_info->plug_state.work_state = IOT_CP_WORK_STATE_CHARGED;
 | |
|     }
 | |
| 
 | |
|     cur_ts = (uint32_t)(os_boot_time64() / IOT_SECOND_TO_MICROSECOND);
 | |
|     if (cur_ts >= plug_info->new_po_ts) {
 | |
|         plug_info->charg_time = (uint16_t)((cur_ts - plug_info->new_po_ts));
 | |
|     } else {
 | |
|         plug_info->charg_time = (uint16_t)((0xFFFFFFFF -
 | |
|             plug_info->new_po_ts + cur_ts));
 | |
|     }
 | |
|     /* change to minutes */
 | |
|     plug_info->charg_time = plug_info->charg_time / IOT_MINUTE_TO_SECOND;
 | |
| 
 | |
|     if (plug_info->plug_state.work_state == IOT_CP_WORK_STATE_CHARGED) {
 | |
|         cp_rtc_get(&plug_info->date_charged) ;
 | |
|     }
 | |
| 
 | |
|     if ((plug_info->his_last + 1) >= IOT_CP_MAX_HIS_INFO_CNT) {
 | |
|         plug_info->his_last = 0;
 | |
|         his_last = plug_info->his_last;
 | |
|     } else {
 | |
|         plug_info->his_last++;
 | |
|         his_last = plug_info->his_last;
 | |
|     }
 | |
|     his_info = &cp_context.flash_info.his_info[plug_id];
 | |
| 
 | |
|     if (reason == IOT_CP_END_TPYE_END_PO) {
 | |
|         his_info->checked = IOT_CP_ORDER_CHECKED;
 | |
|     }
 | |
| 
 | |
|     his_info->record_sn = his_last;
 | |
|     his_info->end_type   = reason;
 | |
|     his_info->work_state = plug_info->plug_state.work_state;
 | |
|     his_info->elect_cur  = plug_info->elect_cur;
 | |
|     his_info->charg_time = plug_info->charg_time;
 | |
|     his_info->fault_t    = plug_info->plug_state.fault_t;
 | |
|     his_info->fault_data = plug_info->plug_state.fault_data;
 | |
| 
 | |
|     cp_rtc_get(&date);
 | |
|     cp_context.rtc_time.week = cp_calc_weekday(date.year +
 | |
|         IOT_CP_YEAR_START_FROM, date.month, date.date);
 | |
|     his_info->end_date_t.week = cp_context.rtc_time.week;
 | |
|     os_mem_cpy(&his_info->end_date_t.sub_date_t, &date, sizeof(date));
 | |
| 
 | |
|     iot_proto_custom_pib_info_save((void*)flash_info, sizeof(cp_flash_info_t));
 | |
| 
 | |
|     plug_info->rpt_cnt = 0 ;
 | |
|     plug_info->rpt_cnt_down = IOT_CP_TASK_REPORT_INTVL_CNT;
 | |
| 
 | |
|     if (reason == IOT_CP_END_TPYE_END_PO) {
 | |
|         plug_info->plug_state.work_state = IOT_CP_WORK_STATE_OCCUPIED;
 | |
|     }
 | |
|     plug_info->rpt_data = reason + (plug_id << 6);
 | |
| 
 | |
|     /* if ending po cmd received,  report msg 60H should not be sent */
 | |
|     if (reason != IOT_CP_END_TPYE_END_PO) {
 | |
|         if (cp_context.is_communication_ok) {
 | |
|             plug_info->rpt_bitmap |= CP_REPORT_ERR_ON;
 | |
|         } else {
 | |
|             //plug_info->rpt_bitmap |= CP_REPORT_HISTORY_ON;
 | |
|             plug_info->rpt_bitmap |= CP_REPORT_ERR_ON;
 | |
|         }
 | |
|         iot_cp_task_msg_post(IOT_CP_TASK_MT_REPORT, IOT_CP_CMD_RPT_ERR_ABORT,
 | |
|             NULL, plug_info->rpt_data);
 | |
|     } else {
 | |
|         plug_info->rpt_bitmap &= CP_REPORT_ERR_OFF;
 | |
|     }
 | |
| 
 | |
|     /* switch off the reply */
 | |
|     iot_cp_task_msg_post(IOT_CP_TASK_MT_CHARG_SWITCH,
 | |
|         IOT_CP_TASK_MSG_ID_CHARGE_STOP, NULL, plug_id);
 | |
| }
 | |
| 
 | |
| static void iot_cp_send_param_cmd_to_meter_task(uint8_t op_code,
 | |
|     uint8_t plug_id)
 | |
| {
 | |
|     cp_socket_cmd_arg_t *set_cmd = NULL;
 | |
|     cp_socket_cmd_query_param_t *q_param = NULL;
 | |
|     cp_socket_cmd_cfg_param_t *cfg_param = NULL;
 | |
|     uint8_t pkt_len;
 | |
|     iot_pkt_t *t_pkt;
 | |
|     cp_plug_threshold_info_t *th_info;
 | |
| 
 | |
|     if ((plug_id >= CP_SOCKET_ID_MAX) || (op_code > CP_SOCKET_OP_MAX)) {
 | |
|         iot_cus_printf("[cp][err]invalid op_code %d or plug_id %d",
 | |
|             op_code, plug_id);
 | |
|         return;
 | |
|     }
 | |
|     pkt_len = sizeof(*set_cmd) + sizeof(*cfg_param);
 | |
|     t_pkt = iot_pkt_alloc(pkt_len, IOT_CP_TASK_ID);
 | |
|     if (NULL == t_pkt) {
 | |
|         iot_cus_printf("[cp][err]alloc pkt failed\n");
 | |
|         IOT_ASSERT(0);
 | |
|     }
 | |
|     iot_pkt_put(t_pkt, sizeof(*set_cmd));
 | |
|     set_cmd = (cp_socket_cmd_arg_t *)iot_pkt_data(t_pkt);
 | |
| 
 | |
|     set_cmd->hdr.cid = CP_SOCKET_CID_CONFIG;
 | |
|     set_cmd->hdr.opcode = op_code;
 | |
|     set_cmd->need_ack = 1;
 | |
|     switch (op_code) {
 | |
|     case CP_SOCKET_OP_CONFIG:
 | |
|     {
 | |
|         th_info = &cp_context.flash_info.plug_th[plug_id];
 | |
| 
 | |
|         set_cmd->dlen = sizeof(*cfg_param);
 | |
|         cfg_param = (cp_socket_cmd_cfg_param_t *)set_cmd->arg;
 | |
|         cfg_param->plug_id = plug_id;
 | |
|         cfg_param->rated_volt = th_info->rated_volt;
 | |
|         cfg_param->charge_full_i_th = th_info->full_chg_cur_th;
 | |
|         cfg_param->overload_i_th = th_info->over_load_th;
 | |
|         cfg_param->leak_i_th = th_info->leak_cur_protc_th;
 | |
|         cfg_param->discon_cur_th = th_info->discon_cur_th;
 | |
|         cfg_param->alarm.alarm_en_data = th_info->alarm.alarm_en_data;
 | |
| 
 | |
|         break;
 | |
|     }
 | |
|     case CP_SOCKET_OP_QUERY:
 | |
|     {
 | |
|         set_cmd->dlen = sizeof(*q_param);
 | |
|         q_param = (cp_socket_cmd_query_param_t *)set_cmd->arg;
 | |
|         q_param->plug_id = plug_id;
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|         IOT_ASSERT(0);
 | |
|     }
 | |
|     iot_pkt_put(t_pkt, set_cmd->dlen);
 | |
|     cp_socket_cmd_send_mssage(t_pkt);
 | |
| }
 | |
| 
 | |
| static void iot_cp_send_cfm_cmd_to_meter_task(uint8_t cid,
 | |
|     uint8_t result, uint8_t reason)
 | |
| {
 | |
|     cp_socket_cmd_arg_t *set_cmd = NULL;
 | |
|     cp_socket_cmd_confirm_t *cfm = NULL;
 | |
|     uint8_t pkt_len;
 | |
|     iot_pkt_t *t_pkt;
 | |
| 
 | |
|     pkt_len = sizeof(*set_cmd) + sizeof(*cfm);
 | |
|     t_pkt = iot_pkt_alloc(pkt_len, IOT_CP_TASK_ID);
 | |
|     if (NULL == t_pkt) {
 | |
|         iot_cus_printf("[cp][err]alloc pkt failed\n");
 | |
|         IOT_ASSERT(0);
 | |
|     }
 | |
|     iot_pkt_put(t_pkt, pkt_len);
 | |
|     set_cmd = (cp_socket_cmd_arg_t *)iot_pkt_data(t_pkt);
 | |
|     set_cmd->dlen = sizeof(*cfm);
 | |
|     set_cmd->hdr.cid = cid;
 | |
|     set_cmd->hdr.opcode = CP_SOCKET_OP_CFM;
 | |
|     set_cmd->need_ack = 0;
 | |
|     cfm = (cp_socket_cmd_confirm_t *)set_cmd->arg;
 | |
|     cfm->result =  result;
 | |
|     cfm->reason = reason;
 | |
|     cp_socket_cmd_send_mssage(t_pkt);
 | |
| }
 | |
| 
 | |
| static void iot_cp_send_relay_state_to_meter_task(uint8_t plug_id,
 | |
|     bool_t state)
 | |
| {
 | |
|     cp_socket_cmd_arg_t *set_cmd = NULL;
 | |
|     cp_relay_state_t *p_socket;
 | |
|     uint8_t pkt_len;
 | |
|     iot_pkt_t *t_pkt;
 | |
| 
 | |
|     if ((plug_id > CP_SOCKET_ID_MAX)) {
 | |
|         iot_cus_printf("[cp][err]invalid plug_id %d", plug_id);
 | |
|         return;
 | |
|     }
 | |
|     pkt_len = sizeof(*set_cmd) + sizeof(*p_socket);
 | |
|     t_pkt = iot_pkt_alloc(pkt_len, IOT_CP_TASK_ID);
 | |
|     if (NULL == t_pkt) {
 | |
|         iot_cus_printf("[cp][err]alloc pkt failed\n");
 | |
|         IOT_ASSERT(0);
 | |
|     }
 | |
|     iot_pkt_put(t_pkt, pkt_len);
 | |
|     set_cmd = (cp_socket_cmd_arg_t *)iot_pkt_data(t_pkt);
 | |
| 
 | |
|     set_cmd->hdr.cid = CP_SOCKET_CID_RELAY_STATE;
 | |
|     set_cmd->hdr.opcode = CP_SOCKET_OP_CONFIG;
 | |
|     set_cmd->need_ack = 0;
 | |
| 
 | |
|     set_cmd->dlen = sizeof(*p_socket);
 | |
|     p_socket = (cp_relay_state_t *)set_cmd->arg;
 | |
|     p_socket->plug_id = plug_id;
 | |
|     p_socket->relay_state = state;
 | |
| 
 | |
|     cp_socket_cmd_send_mssage(t_pkt);
 | |
| }
 | |
| 
 | |
| /**
 | |
| * @brief iot_cp_alloc_ge_data_frm_pkt: alloc ge data frame, put the data length
 | |
| * @param data_len:        ge frame total length, fraom head to tail
 | |
| * @retral:                pkt alloced
 | |
| */
 | |
| static iot_pkt_t *iot_cp_alloc_ge_data_frm_pkt( uint16_t data_len)
 | |
| {
 | |
|     iot_pkt_t *p_pkt  = NULL;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
| 
 | |
|     p_pkt = iot_pkt_alloc(data_len, IOT_CP_TASK_ID);
 | |
|     if (p_pkt != NULL) {
 | |
|         iot_pkt_put(p_pkt, data_len);
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(p_pkt);
 | |
|         iot_mac_addr_cpy(ge_data_frame->data, plc_context.local_mac);
 | |
|     } else {
 | |
|         iot_cus_printf("[cp]alloc ge160 pkt failed.\n");
 | |
|         IOT_ASSERT(0);
 | |
|     }
 | |
| 
 | |
|     return p_pkt;
 | |
| }
 | |
| 
 | |
| /**
 | |
| * @brief iot_cp_send_pkt: sending pkt to plc or uart depends on the direction
 | |
| * @param dst_mac:   destination address
 | |
| * @param ge_pkt:    pointer of a GE package
 | |
| * @param data_len:  length of data field
 | |
| * @param dir:       the direction of transmission, PLC or UART or booth
 | |
| */
 | |
| static void iot_cp_send_pkt(uint8_t *dst_mac, iot_pkt_t *ge_pkt, uint8_t dir)
 | |
| {
 | |
|     ge_frame_data_send_set_subfn160_t *cmd = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint16_t cal_crc;
 | |
|     uint16_t data_len;
 | |
| 
 | |
|     if (!iot_mac_addr_valid (dst_mac)) {
 | |
|         iot_cus_printf("%s invalid dst mac, pkt dropped\n", __FUNCTION__);
 | |
|         iot_pkt_free(ge_pkt);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     cmd   = (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(ge_pkt);
 | |
|     cmd->hdr.hdr.preamble  = GE_FRM_PREAMBLE_CODE;
 | |
|     cmd->hdr.hdr.fn        = PROTO_GE_PLC_SET_CMD;
 | |
|     cmd->hdr.subfn         = PROTO_GE_DATA_CMD;
 | |
|     cmd->hdr.hdr.data_len  = iot_pkt_data_len(ge_pkt) + IOT_MAC_ADDR_LEN
 | |
|         - sizeof(ge_frame_data_send_set_subfn160_t) - GE_FRAME_CRC_TAIL_SIZE;
 | |
|     iot_mac_addr_cpy(cmd->dest_mac, dst_mac);
 | |
| 
 | |
|     data_len = iot_pkt_data_len(ge_pkt) - GE_FRAME_CRC_TAIL_SIZE;
 | |
|     data_ptr = (uint8_t *)cmd + data_len;
 | |
|     cal_crc = ge_frm_checksum_calc((uint8_t *)cmd, data_len);
 | |
|     *data_ptr++ = (uint8_t)cal_crc;
 | |
|     *data_ptr++ = (uint8_t)(cal_crc >> 8);
 | |
|     *data_ptr = GE_FRM_TAIL_CODE;
 | |
| 
 | |
|     iot_cp_task_data_dump(iot_pkt_data(ge_pkt), iot_pkt_data_len(ge_pkt));
 | |
| 
 | |
|     /* send data to plc*/
 | |
|     if (dir == IOT_CP_TRANS_DIR_PLC) {
 | |
|         iot_cus_printf("[cp_context]post to GE.\n");
 | |
|         iot_cus_task_message_to_ge(iot_pkt_data(ge_pkt),
 | |
|             iot_pkt_data_len(ge_pkt));
 | |
|         iot_pkt_free(ge_pkt);
 | |
|     /* send data to Uart*/
 | |
|      } else {
 | |
|         iot_cus_printf("[cp_context]post to UART.\n");
 | |
| 
 | |
| #if USE_N11_GPRS
 | |
|         iot_grapp_sendto_mainboard_gprs_fn(ge_pkt);
 | |
| #else
 | |
|         iot_uart_send(plc_context.uart_h, ge_pkt, NULL);
 | |
| #endif
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_set_paramtr_hdl: set charging pile param value.fn:0x01.
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_set_paramtr_hdl(uint8_t *data,uint8_t dir)
 | |
| {
 | |
|     cp_param_cfg_fn01_t *cmd;
 | |
|     cp_rsp_param_cfg_fn01_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     cp_plug_threshold_info_t *th_info;
 | |
|     iot_pkt_t *rsp_pkt = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
|     uint16_t tmp_alarm = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN ;
 | |
|     cmd = (cp_param_cfg_fn01_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num  = cmd->plug_num;
 | |
| 
 | |
|     if (plug_num >= IOT_CP_MAX_PLUG_CNT) {
 | |
|         iot_cus_printf("%s, plug_num err%d\n", __FUNCTION__, plug_num);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     th_info = &flash_info->plug_th[plug_num];
 | |
| 
 | |
|     th_info->full_chg_cur_th    = cmd->full_chg_cur_th;
 | |
|     data_ptr = (uint8_t *)(&th_info->full_chg_cur_th);
 | |
|     iot_data_reverse(data_ptr, sizeof(th_info->full_chg_cur_th));
 | |
| 
 | |
|     th_info->full_chg_cur_tm_th = cmd->full_chg_cur_tm_th;
 | |
| 
 | |
|     th_info->over_load_th       = cmd->over_load_th;
 | |
|     data_ptr = (uint8_t *)(&th_info->over_load_th);
 | |
|     iot_data_reverse(data_ptr, sizeof(th_info->over_load_th));
 | |
| 
 | |
|     th_info->over_load_tm_th    = cmd->over_load_tm_th;
 | |
|     data_ptr = (uint8_t *)(&th_info->over_load_tm_th);
 | |
|     iot_data_reverse(data_ptr, sizeof(th_info->over_load_tm_th));
 | |
| 
 | |
|     os_mem_cpy(&th_info->leak_cur_protc_th,
 | |
|         &cmd->sub_info.leak_cur_protc_th, sizeof(cp_sub_info_t));
 | |
| 
 | |
|     th_info->rated_volt = cmd->rated_volt;
 | |
|     data_ptr = (uint8_t *)(&th_info->rated_volt);
 | |
|     iot_data_reverse(data_ptr, sizeof(th_info->rated_volt));
 | |
| 
 | |
|     tmp_alarm = cmd->alarm;
 | |
|     data_ptr = (uint8_t *)(&tmp_alarm);
 | |
|     iot_data_reverse(data_ptr, sizeof(tmp_alarm));
 | |
| 
 | |
|     os_mem_cpy(&th_info->alarm, &tmp_alarm, sizeof(uint16_t));
 | |
| 
 | |
|     iot_cus_printf("[%s][%d], plug_num:%d  rated_volt:%d  full_chg_cur_th:%d"
 | |
|         " over_load_th:%d\n", __FUNCTION__, __LINE__,
 | |
|         plug_num, th_info->rated_volt, th_info->full_chg_cur_th,
 | |
|         th_info->over_load_th);
 | |
| 
 | |
|     iot_proto_custom_pib_info_save((void*)flash_info, sizeof(cp_flash_info_t));
 | |
|     iot_cp_send_param_cmd_to_meter_task(CP_SOCKET_OP_CONFIG, plug_num);
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_param_cfg_fn01_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->result    = IOT_RESULT_CONFIG_SUCCESS;
 | |
|         rsp_cmd->plug_num  = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
| 
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| /**
 | |
|  * @brief iot_cp_cmd_set_rtc_time_hdl: set rtc time fn:0x02
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_set_rtc_time_hdl(uint8_t *data,uint8_t dir)
 | |
| {
 | |
|     cp_time_cfg_fn02_t *cmd;
 | |
|     cp_rsp_time_cfg_fn02_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_time_cfg_fn02_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     os_mem_cpy(&cp_context.rtc_time, &cmd->date_t, sizeof(cp_date_t));
 | |
|     cp_rtc_set(&cp_context.rtc_time.sub_date_t);
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_time_cfg_fn02_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->result    = IOT_RESULT_RTC_SUCCESS;
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
| 
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_set_work_mode_hdl: set work mode fn:0x03
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_set_work_mode_hdl(uint8_t *data,uint8_t dir)
 | |
| {
 | |
|     cp_mode_cfg_fn03_t *cmd;
 | |
|     cp_rsp_mode_cfg_fn03_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
|     uint8_t plug_id;
 | |
|     uint8_t result = IOT_RESULT_CONFIG_SUCCESS;
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_mode_cfg_fn03_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     if (cmd->work_mode >= IOT_CP_WORK_MODE_MAX) {
 | |
|         result = IOT_RESULT_RET_ERR_DATA;
 | |
|     } else {
 | |
|         result = IOT_RESULT_CONFIG_SUCCESS;
 | |
|         if (cp_context.work_mode != cmd->work_mode) {
 | |
|             for (plug_id = 0; plug_id < CP_SOCKET_ID_MAX; plug_id++) {
 | |
|                 if (cmd->work_mode == IOT_CP_MAINTENANCE_MODE) {
 | |
|                     /* stop charging once the cmd received, then send cfm frame */
 | |
|                     iot_cp_stop_charging_due_to_reason(plug_id,
 | |
|                         IOT_CP_END_TPYE_EMERG);
 | |
|                 } else {
 | |
|                     iot_cp_reinit_work_state(plug_id);
 | |
|                 }
 | |
|             }
 | |
|             cp_context.work_mode = cmd->work_mode;
 | |
|         }
 | |
|     }
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_mode_cfg_fn03_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->result = result;
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_set_new_po_hdl: set charging pile order fn:0x40
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_set_new_po_hdl(uint8_t *data,uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_plug_info_t *plug_info = NULL;
 | |
|     cp_new_po_cfg_fn40_t *cmd;
 | |
|     cp_plug_history_info_t *his_info = NULL;
 | |
|     cp_rsp_new_po_cfg_fn40_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *cp_data = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t plug_num = 0;
 | |
|     uint8_t data_len = 0;
 | |
|     uint8_t frame_len = 0;
 | |
|     uint8_t reason = IOT_CP_CFG_PO_RET_SUCCESS;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_new_po_cfg_fn40_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num = cmd->plug_num;
 | |
|     /* only plugin and no fault happened, setting new po can be successful */
 | |
|     if (cp_context.work_mode == IOT_CP_MAINTENANCE_MODE) {
 | |
|         return;
 | |
|     } else if (plug_num >= IOT_CP_MAX_PLUG_CNT) {
 | |
|         reason = IOT_CP_CFG_PO_RET_ERR_DATA;
 | |
|     } else {
 | |
|         plug_info = (cp_plug_info_t *)(&cp_context.plug_info[plug_num]);
 | |
|         his_info = &cp_context.flash_info.his_info[plug_num];
 | |
| 
 | |
|         iot_cus_printf("[cp]his[%d] checked=%d end_type=%d\n", plug_num,
 | |
|             his_info->checked, his_info->end_type);
 | |
| 
 | |
|         switch (plug_info->plug_state.work_state) {
 | |
|         case IOT_CP_WORK_STATE_CHARGING:
 | |
|         case IOT_CP_WORK_STATE_MAINTAIN:
 | |
|         {
 | |
|             reason = IOT_CP_CFG_PO_RET_BUSY;
 | |
|             break;
 | |
|         }
 | |
|         case IOT_CP_WORK_STATE_FAULT:
 | |
|         {
 | |
|             reason = IOT_CP_CFG_PO_RET_DEV_FAULT;
 | |
|             break;
 | |
|         }
 | |
|         case IOT_CP_WORK_STATE_IDLE:
 | |
|         {
 | |
|             reason = IOT_CP_CFG_PO_RET_PLUG_OUT;
 | |
|             break;
 | |
|         }
 | |
|         case IOT_CP_WORK_STATE_OCCUPIED:
 | |
|         {
 | |
|             if (his_info->checked == IOT_CP_ORDER_UNCHECK) {
 | |
|                 plug_info->rpt_bitmap &= CP_REPORT_ERR_OFF;
 | |
|                 his_info->checked = IOT_CP_ORDER_CHECKED;
 | |
|             }
 | |
| 
 | |
|             if ((cmd->charge_mode == IOT_CP_CHARGE_MODE_FIX_TIME) ||
 | |
|                 (cmd->charge_mode == IOT_CP_CHARGE_MODE_POWER)) {
 | |
|                 if (cmd->charge_data == 0) {
 | |
|                     reason = IOT_CP_CFG_PO_RET_ERR_DATA;
 | |
|                     /* end the po once new po cmd received,
 | |
|                      * then save flag to flash */
 | |
|                     iot_proto_custom_pib_info_save((void*)flash_info,
 | |
|                         sizeof(cp_flash_info_t));
 | |
|                 }
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         default:
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         iot_cus_printf("%s, now state: %d, return reason:%d\n",
 | |
|             __FUNCTION__, plug_info->plug_state.work_state, reason);
 | |
|     }
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_new_po_cfg_fn40_t*)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         os_mem_cpy(rsp_cmd->po_num, cmd->po_num, CP_PO_NUMBER_SIZE);
 | |
|         rsp_cmd->result = reason;
 | |
|         if (plug_info == NULL) {
 | |
|             rsp_cmd->fault = 0;
 | |
| 
 | |
|         } else {
 | |
|             os_mem_cpy(&rsp_cmd->fault, &plug_info->plug_state.fault_t,
 | |
|                 sizeof(uint16_t));
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->fault);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->fault));
 | |
|         }
 | |
|         rsp_cmd->plug_num  = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|          if (plug_num >= IOT_CP_MAX_PLUG_CNT) {
 | |
|             /* plug num is too big */
 | |
|             return;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (reason == IOT_CP_CFG_PO_RET_SUCCESS) {
 | |
|         os_mem_set(his_info, 0 , sizeof(*his_info));
 | |
|         os_mem_cpy(plug_info->po_num, cmd->po_num, CP_PO_NUMBER_SIZE);
 | |
|         plug_info->charge_mode = cmd->charge_mode;
 | |
|         plug_info->charge_data = cmd->charge_data;
 | |
|         data_ptr = (uint8_t *)(&plug_info->charge_data);
 | |
|         iot_data_reverse(data_ptr, sizeof(plug_info->charge_data));
 | |
|         /* record the date when the new po rececived */
 | |
|         cp_rtc_get(&plug_info->date_t);
 | |
|         cp_context.rtc_time.week = cp_calc_weekday(
 | |
|             cp_context.rtc_time.sub_date_t.year + IOT_CP_YEAR_START_FROM,
 | |
|             cp_context.rtc_time.sub_date_t.month,
 | |
|             cp_context.rtc_time.sub_date_t.date);
 | |
| 
 | |
|         os_mem_cpy(&his_info->po_num, cmd->po_num, CP_PO_NUMBER_SIZE);
 | |
| 
 | |
|         his_info->checked = IOT_CP_ORDER_UNCHECK;
 | |
| 
 | |
|         his_info->start_date_t.week = cp_context.rtc_time.week;
 | |
|         os_mem_cpy(&his_info->start_date_t.sub_date_t,
 | |
|             &cp_context.rtc_time.sub_date_t, sizeof(cp_sub_date_t));
 | |
| 
 | |
|         his_info->elect_last = plug_info->elect_cur;
 | |
| 
 | |
|         iot_proto_custom_pib_info_save(flash_info, sizeof(cp_flash_info_t));
 | |
|         /*timestamp unit is seconds */
 | |
|         plug_info->new_po_ts = (uint32_t)(os_boot_time64() /
 | |
|             IOT_SECOND_TO_MICROSECOND);
 | |
|         plug_info->elect_last = plug_info->elect_cur;
 | |
|         plug_info->elect_cur = 0;
 | |
|         plug_info->early_charg_time = plug_info->charg_time;
 | |
|         plug_info->charg_time = 0;
 | |
|         plug_info->early_elect_last = plug_info->early_elect_cur;
 | |
|         plug_info->early_elect_cur = 0;
 | |
| 
 | |
|         iot_cp_task_msg_post(IOT_CP_TASK_MT_CHARG_SWITCH,
 | |
|             IOT_CP_TASK_MSG_ID_CHARGE_START, NULL, plug_num);
 | |
| 
 | |
|         plug_info->plug_state.work_state = IOT_CP_WORK_STATE_CHARGING;
 | |
|     }
 | |
| 
 | |
| #if (IOT_CP_SEVER_WR_EN == 1)
 | |
|     else {
 | |
|         os_mem_set(&resp_cmd_60h[plug_num], 0,
 | |
|             sizeof(cp_rpt_charg_abort_fn60_t));
 | |
|         os_mem_cpy(&resp_cmd_60h[plug_num].po_num, cmd->po_num,
 | |
|             CP_PO_NUMBER_SIZE);
 | |
|         resp_cmd_60h[plug_num].signal_sn = cmd->signal_sn;
 | |
|         switch (reason) {
 | |
|         case IOT_CP_CFG_PO_RET_DEV_FAULT:
 | |
|         {
 | |
|             resp_cmd_60h[plug_num].end_type = IOT_CP_END_TPYE_FAULT;
 | |
|             os_mem_cpy(&resp_cmd_60h[plug_num].fault_t,
 | |
|                 &plug_info->plug_state.fault_t, sizeof(cp_fault_t));
 | |
|             resp_cmd_60h[plug_num].fault_data =
 | |
|                 plug_info->plug_state.fault_data;
 | |
|             break;
 | |
|         }
 | |
|         case IOT_CP_CFG_PO_RET_PLUG_OUT:
 | |
|         {
 | |
|             resp_cmd_60h[plug_num].end_type = IOT_CP_END_TPYE_DISCONN;
 | |
|             break;
 | |
|         }
 | |
|         default:
 | |
|             resp_cmd_60h[plug_num].end_type = IOT_CP_END_TPYE_CHARGED;
 | |
|             break;
 | |
|         }
 | |
|         resp_cmd_60h[plug_num].work_state = plug_info->plug_state.work_state;
 | |
|         resp_cmd_60h[plug_num].plug_num = cmd->plug_num;
 | |
| 
 | |
|         rpt_60h_cnt[plug_num] = 0;
 | |
|         is_wr_on |= (1 << plug_num);
 | |
|         iot_cus_printf("[cp]wr enabled %d plug id %d\n", is_wr_on, plug_num);
 | |
|         iot_cp_report_err_abort_for_wr(plug_num);
 | |
|     }
 | |
| 
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_set_end_po_hdl: close charging pile order fn:0x41.
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_set_end_po_hdl(uint8_t *data,uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt   = NULL;
 | |
|     cp_end_po_cfg_fn41_t *cmd;
 | |
|     cp_plug_history_info_t *his_info = NULL;
 | |
|     cp_rsp_end_po_cfg_fn41_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
|     uint8_t result = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     if (cp_context.work_mode == IOT_CP_MAINTENANCE_MODE) {
 | |
|         iot_cus_printf("[cp]In maintaince mode, cmd discard!\n");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_end_po_cfg_fn41_t*)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num  = cmd->plug_num ;
 | |
| 
 | |
|     if (plug_num >= IOT_CP_MAX_PLUG_CNT){
 | |
|         iot_cus_printf("%s, plug num %d is large than %d\n", __FUNCTION__,
 | |
|             cmd->plug_num, IOT_CP_MAX_PLUG_CNT);
 | |
|         result = IOT_CP_CFG_PO_RET_ERR_DATA;
 | |
|     } else {
 | |
|         his_info = &cp_context.flash_info.his_info[plug_num];
 | |
| 
 | |
|         if (0 != os_mem_cmp(his_info->po_num, cmd->po_num, CP_PO_NUMBER_SIZE)) {
 | |
|             result = IOT_CP_CFG_PO_RET_NO_PO;
 | |
|         } else {
 | |
|             result = IOT_CP_CFG_PO_RET_SUCCESS;
 | |
|             iot_cp_stop_charging_due_to_reason(plug_num, IOT_CP_END_TPYE_END_PO);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_end_po_cfg_fn41_t*)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         os_mem_cpy(rsp_cmd->po_num, cmd->po_num, CP_PO_NUMBER_SIZE);
 | |
|         rsp_cmd->result = result;
 | |
|         if (his_info == NULL) {
 | |
|             rsp_cmd->early_elect_cur  = 0;
 | |
|             rsp_cmd->early_elect_last = 0;
 | |
|             rsp_cmd->early_charg_time = 0;
 | |
|         } else {
 | |
|             rsp_cmd->early_elect_cur  = his_info->elect_cur;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->early_elect_cur);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->early_elect_cur));
 | |
|             rsp_cmd->early_elect_last = his_info->elect_last;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->early_elect_last);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->early_elect_last));
 | |
|             rsp_cmd->early_charg_time = his_info->charg_time;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->early_charg_time);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->early_charg_time));
 | |
|         }
 | |
|         rsp_cmd->plug_num  = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_set_find_free_hdl: check plug port is free or not, fn:0x42.
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_set_find_free_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt = NULL;
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_search_idle_fn42_t *cmd;
 | |
|     cp_rsp_search_idle_fn42_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_search_idle_fn42_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num  = cmd->plug_num;
 | |
|     plug_info = (cp_plug_info_t *)(&cp_context.plug_info[plug_num]);
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_search_idle_fn42_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         if (plug_info->plug_state.work_state == IOT_CP_WORK_STATE_IDLE) {
 | |
|             rsp_cmd->result = IOT_RESULT_FIND_FREE_SUCCESS;
 | |
|         } else {
 | |
|             rsp_cmd->result = IOT_RESULT_FIND_FREE_ERR;
 | |
|         }
 | |
|         rsp_cmd->plug_num  = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_set_emergent_stop_hdl: stop charging due emergency fn:0x66
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_set_emergent_stop_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     /* stop charging once the cmd received, no response is needed */
 | |
|     cp_rsp_emergency_stop_fn66_t * rsp_cmd;
 | |
|     cp_set_emergency_stop_fn66_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame;
 | |
|     uint16_t frm_len;
 | |
|     uint8_t data_len;
 | |
|     uint8_t plug_id;
 | |
|     iot_pkt_t *rsp_pkt;
 | |
| 
 | |
|     cmd = (cp_set_emergency_stop_fn66_t *)(data + IOT_MAC_ADDR_LEN);
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     for (plug_id = 0; plug_id < CP_SOCKET_ID_MAX; plug_id++) {
 | |
|         iot_cp_stop_charging_due_to_reason(plug_id, IOT_CP_END_TPYE_EMERG);
 | |
|     }
 | |
|     cp_context.work_mode = IOT_CP_MAINTENANCE_MODE;
 | |
| 
 | |
|     frm_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frm_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_emergency_stop_fn66_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->result    = IOT_RESULT_CONFIG_SUCCESS;
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
| 
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_query_status_hdl: query charging pile status,fn:0x20
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_query_status_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt = NULL;
 | |
|     cp_plug_info_t *plug_info = NULL;
 | |
|     cp_rsp_sta_status_fn20_t *rsp_cmd;
 | |
|     cp_query_sta_status_fn20_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_query_sta_status_fn20_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     plug_num  = cmd->plug_num;
 | |
| 
 | |
|     if (plug_num < CP_SOCKET_ID_MAX) {
 | |
|         plug_info = (cp_plug_info_t *)(&cp_context.plug_info[plug_num]);
 | |
|     }
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_sta_status_fn20_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         if (plug_info == NULL) {
 | |
|             rsp_cmd->work_state = IOT_CP_WORK_STATE_NOT_SUPPORT;
 | |
|             rsp_cmd->plug_in    = 0;
 | |
|             os_mem_set(&rsp_cmd->fault_t, 0, sizeof(cp_fault_t));
 | |
|         } else {
 | |
|             rsp_cmd->work_state = plug_info->plug_state.work_state;
 | |
|             rsp_cmd->plug_in    = plug_info->plug_state.plug_in;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->plug_in);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->plug_in));
 | |
|             rsp_cmd->fault_t    = plug_info->plug_state.fault_t;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->fault_t);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->fault_t));
 | |
|         }
 | |
|         rsp_cmd->plug_num   = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn  = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_query_devic_data_hdl: query charging pile device charging
 | |
|  *               data,fn:0x21
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_query_devic_data_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt = NULL;
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_plug_history_info_t *his_info;
 | |
|     cp_rsp_charg_data_fn21_t *rsp_cmd;
 | |
|     cp_query_charg_data_fn21_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_query_charg_data_fn21_t*)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num  = cmd->plug_num;
 | |
|     plug_info = (cp_plug_info_t*)(&cp_context.plug_info[plug_num]);
 | |
|     his_info  = &cp_context.flash_info.his_info[plug_num];
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_charg_data_fn21_t*)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         os_mem_cpy(rsp_cmd->po_num, his_info->po_num, CP_PO_NUMBER_SIZE);
 | |
|         rsp_cmd->dev_type    = plc_context.dev_type;
 | |
|         rsp_cmd->tmperature  = plug_info->tmperature;
 | |
|         rsp_cmd->volt        = plug_info->volt;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->volt);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->volt));
 | |
|         rsp_cmd->current     = plug_info->current;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->current);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->current));
 | |
|         rsp_cmd->power       = plug_info->power;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->power);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->power));
 | |
|         rsp_cmd->leak_current= plug_info->leak_current;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->leak_current);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->leak_current));
 | |
|         rsp_cmd->freq        = plug_info->freq;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->freq);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->freq));
 | |
|         rsp_cmd->factor      = plug_info->factor;
 | |
| 
 | |
|         if(plug_info->plug_state.work_state != IOT_CP_WORK_STATE_CHARGING) {
 | |
| 
 | |
|             rsp_cmd->elect_cur  = his_info->elect_cur;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->elect_cur);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_cur));
 | |
|             rsp_cmd->elect_last = his_info->elect_last;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->elect_last);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_last));
 | |
|             rsp_cmd->charg_time = his_info->charg_time;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->charg_time);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->charg_time));
 | |
|             os_mem_cpy(&rsp_cmd->sub_date_t.year,
 | |
|                 &his_info->end_date_t.sub_date_t.year,sizeof(cp_sub_date_t));
 | |
|         } else {
 | |
|             rsp_cmd->elect_cur   = plug_info->elect_cur;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->elect_cur);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_cur));
 | |
|             rsp_cmd->elect_last  = plug_info->elect_last;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->elect_last);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_last));
 | |
|             rsp_cmd->charg_time  = plug_info->charg_time;
 | |
|             data_ptr = (uint8_t *)(&rsp_cmd->charg_time);
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->charg_time));
 | |
|             cp_rtc_get(&cp_context.rtc_time.sub_date_t);
 | |
|             cp_context.rtc_time.week = cp_calc_weekday(
 | |
|                 cp_context.rtc_time.sub_date_t.year + IOT_CP_YEAR_START_FROM,
 | |
|                 cp_context.rtc_time.sub_date_t.month,
 | |
|                 cp_context.rtc_time.sub_date_t.date);
 | |
| 
 | |
|             os_mem_cpy(&rsp_cmd->sub_date_t.year,
 | |
|                 &cp_context.rtc_time.sub_date_t.year, sizeof(cp_sub_date_t));
 | |
|         }
 | |
| 
 | |
|         rsp_cmd->plug_num  = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_query_ver_info_hdl: query charging pile device
 | |
|  *               version info,fn:0x22
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_query_ver_info_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_rsp_ver_info_fn22_t *rsp_cmd;
 | |
|     cp_query_ver_info_fn22_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_query_ver_info_fn22_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
| 
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_ver_info_fn22_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->sw_info = cp_context.sw_info;
 | |
|         rsp_cmd->hw_info = cp_context.hw_info;
 | |
| 
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_query_paramtr_hdl: query charging pile param, fn:0x23
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_query_paramtr_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_rsp_cfg_param_fn23_t *rsp_cmd;
 | |
|     cp_query_cfg_param_fn23_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     cp_plug_threshold_info_t *th_info;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_query_cfg_param_fn23_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num  = cmd->plug_num;
 | |
| 
 | |
|     if (plug_num >= IOT_CP_MAX_PLUG_CNT) {
 | |
|         iot_cus_printf("%s, plug_num err%d\n", __FUNCTION__, plug_num);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     th_info = &flash_info->plug_th[plug_num];
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_cfg_param_fn23_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->full_chg_cur_th = th_info->full_chg_cur_th;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->full_chg_cur_th);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->full_chg_cur_th));
 | |
| 
 | |
|         rsp_cmd->full_chg_cur_tm_th = th_info->full_chg_cur_tm_th;
 | |
|         rsp_cmd->over_load_th       = th_info->over_load_th;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->over_load_th);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->over_load_th));
 | |
| 
 | |
|         rsp_cmd->over_load_tm_th    = th_info->over_load_tm_th;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->over_load_tm_th);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->over_load_tm_th));
 | |
| 
 | |
|         os_mem_cpy(&rsp_cmd->sub_info.leak_cur_protc_th,
 | |
|             &th_info->leak_cur_protc_th, sizeof(cp_sub_info_t));
 | |
|         rsp_cmd->rated_volt = th_info->rated_volt;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->rated_volt);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->rated_volt));
 | |
| 
 | |
|         //rsp_cmd->alarm    = th_info->alarm;
 | |
|         os_mem_cpy(&rsp_cmd->alarm, &th_info->alarm, sizeof(uint16_t));
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->alarm);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->alarm));
 | |
| 
 | |
|         rsp_cmd->plug_num   = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn  = cmd->signal_sn;
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
| 
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_query_time_hdl: query charging pile time, fn:0x24
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_query_time_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_rsp_sta_time_fn24_t *rsp_cmd;
 | |
|     cp_query_sta_time_fn24_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t data_len  = 0 ;
 | |
|     uint8_t frame_len = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_query_sta_time_fn24_t*)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_sta_time_fn24_t*)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         cp_rtc_get(&cp_context.rtc_time.sub_date_t);
 | |
|         cp_context.rtc_time.week = cp_calc_weekday(
 | |
|             cp_context.rtc_time.sub_date_t.year + IOT_CP_YEAR_START_FROM,
 | |
|             cp_context.rtc_time.sub_date_t.month,
 | |
|             cp_context.rtc_time.sub_date_t.date);
 | |
| 
 | |
|         os_mem_cpy(&rsp_cmd->date_t.week, &cp_context.rtc_time.week,
 | |
|             sizeof(cp_date_t));
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_query_chag_record_hdl: query charging record history
 | |
|  *               charging order data, fn:0x25
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_query_chag_record_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_plug_history_info_t *his_info;
 | |
|     cp_rsp_charg_record_fn25_t *rsp_cmd;
 | |
|     cp_query_charg_record_fn25_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
|     uint8_t record_index;
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_query_charg_record_fn25_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num  = cmd->plug_num;
 | |
|     plug_info = (cp_plug_info_t *)(&cp_context.plug_info[plug_num]);
 | |
| 
 | |
|     if (plug_info->his_last > cmd->record_sn) {
 | |
|         record_index = plug_info->his_last - cmd->record_sn;
 | |
|     } else {
 | |
|         record_index = IOT_CP_MAX_HIS_INFO_CNT  - cmd->record_sn
 | |
|             + plug_info->his_last;
 | |
|     }
 | |
|     if (record_index >= IOT_CP_MAX_HIS_INFO_CNT) {
 | |
|         record_index = plug_info->his_last;
 | |
|     }
 | |
| 
 | |
|     his_info = &cp_context.flash_info.his_info[plug_num];
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_charg_record_fn25_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->record_sn  = cmd->record_sn;
 | |
|         os_mem_cpy(rsp_cmd->po_num , his_info->po_num, CP_PO_NUMBER_SIZE);
 | |
|         rsp_cmd->end_type   = his_info->end_type;
 | |
|         rsp_cmd->work_state = his_info->work_state;
 | |
|         rsp_cmd->elect_cur  = his_info->elect_cur;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->elect_cur);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_cur));
 | |
|         rsp_cmd->elect_last = his_info->elect_last;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->elect_last);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_last));
 | |
|         rsp_cmd->charg_time = his_info->charg_time;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->charg_time);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->charg_time));
 | |
|         rsp_cmd->fault_t    = his_info->fault_t ;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->fault_t);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->fault_t));
 | |
|         rsp_cmd->fault_data = his_info->fault_data;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->fault_data);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->fault_data));
 | |
|         rsp_cmd->plug_num   = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn  = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_concent_query_data_hdl: concentrator query charging data fn:0x65
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_concent_query_data_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_concentrator_query_data_fn65_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     cp_rsp_concentrator_query_data_fn65_t *rsp_cmd;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_concentrator_query_data_fn65_t*)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num  = cmd->plug_num;
 | |
|     plug_info = (cp_plug_info_t*)(&cp_context.plug_info[plug_num]);
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_concentrator_query_data_fn65_t *)(ge_data_frame->data
 | |
|             + IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         os_mem_cpy(rsp_cmd->po_num , plug_info->po_num, CP_PO_NUMBER_SIZE);
 | |
|         rsp_cmd->dev_type   = plc_context.dev_type;;
 | |
|         rsp_cmd->tmperature = plug_info->tmperature;
 | |
|         rsp_cmd->volt       = plug_info->volt;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->volt);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->volt));
 | |
|         rsp_cmd->current    = plug_info->current;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->current);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->current));
 | |
|         rsp_cmd->power      = plug_info->power;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->power);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->power));
 | |
|         rsp_cmd->elect_cur  = plug_info->elect_cur;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->elect_cur);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_cur));
 | |
|         rsp_cmd->elect_last = plug_info->elect_last;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->elect_last);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_last));
 | |
|         rsp_cmd->charg_time = plug_info->charg_time;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->charg_time);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->charg_time));
 | |
|         rsp_cmd->leak_current = plug_info->leak_current ;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->leak_current);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->leak_current));
 | |
|         rsp_cmd->freq       = plug_info->freq;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->freq);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->freq));
 | |
|         rsp_cmd->factor     = plug_info->factor;
 | |
|         rsp_cmd->plug_num   = cmd->plug_num;
 | |
|         rsp_cmd->signal_sn  = cmd->signal_sn;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_cmd_query_meter_data_hdl:  query merter data fn:0x80
 | |
|  * @param data:  point to the charging pile command frame.
 | |
|  * @param dir:   data from UART and GE needto be handled separately
 | |
|  */
 | |
| static void iot_cp_cmd_query_meter_data_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_query_meter_data_fn80_t *cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     cp_rsp_meter_data_fn80 *rsp_cmd;
 | |
|     uint8_t *cp_data  = NULL;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
|     uint8_t *data_ptr = NULL;
 | |
| 
 | |
|     iot_cus_printf("%s, dir:%d\n", __FUNCTION__, dir);
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_query_meter_data_fn80_t*)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_num  = CP_SOCKET_ID_0;
 | |
|     plug_info = (cp_plug_info_t*)(&cp_context.plug_info[plug_num]);
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rsp_meter_data_fn80 *)(ge_data_frame->data
 | |
|             + IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->signal_sn = cmd->signal_sn;
 | |
|         rsp_cmd->volt = plug_info->volt;
 | |
|         data_ptr = (uint8_t *)&rsp_cmd->volt;
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->volt));
 | |
|         rsp_cmd->leak_i = plug_info->leak_current;
 | |
|         data_ptr = (uint8_t *)&rsp_cmd->leak_i;
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->leak_i));
 | |
|         rsp_cmd->freq = plug_info->freq;
 | |
|         data_ptr = (uint8_t *)&rsp_cmd->freq;
 | |
|             iot_data_reverse(data_ptr, sizeof(rsp_cmd->freq));
 | |
| 
 | |
|         for (plug_num = 0; plug_num < CP_SOCKET_ID_MAX; plug_num++) {
 | |
|             plug_info = (cp_plug_info_t*)(&cp_context.plug_info[plug_num]);
 | |
| 
 | |
|             rsp_cmd->em_info[plug_num].current = plug_info->current;
 | |
|             data_ptr = (uint8_t *)&rsp_cmd->em_info[plug_num].current;
 | |
|             iot_data_reverse(data_ptr,
 | |
|                 sizeof(rsp_cmd->em_info[plug_num].current));
 | |
| 
 | |
|             rsp_cmd->em_info[plug_num].power = plug_info->power;
 | |
|             data_ptr = (uint8_t *)&rsp_cmd->em_info[plug_num].power;
 | |
|             iot_data_reverse(data_ptr,
 | |
|                 sizeof(rsp_cmd->em_info[plug_num].power));
 | |
| 
 | |
|             rsp_cmd->em_info[plug_num].factor = plug_info->factor;
 | |
| 
 | |
|             rsp_cmd->em_info[plug_num].incumbent_v =
 | |
|                 plug_info->plug_state.incumbent_v;
 | |
|             data_ptr = (uint8_t *)&rsp_cmd->em_info[plug_num].incumbent_v;
 | |
|             iot_data_reverse(data_ptr,
 | |
|                 sizeof(rsp_cmd->em_info[plug_num].incumbent_v));
 | |
| 
 | |
|             rsp_cmd->em_info[plug_num].work_state =
 | |
|                 plug_info->plug_state.work_state;
 | |
|             rsp_cmd->em_info[plug_num].plug_state =
 | |
|                 plug_info->plug_state.plug_in;
 | |
| 
 | |
|             rsp_cmd->em_info[plug_num].fault = plug_info->plug_state.fault_t;
 | |
|             data_ptr = (uint8_t *)&rsp_cmd->em_info[plug_num].fault;
 | |
|             iot_data_reverse(data_ptr,
 | |
|                 sizeof(rsp_cmd->em_info[plug_num].fault));
 | |
|         }
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         iot_cp_frame_fill(cmd->hdr.fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(data, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
| * @param data:  point to the charging pile command frame.
 | |
| * @param dir:   data from UART and GE needto be handled separately
 | |
| */
 | |
| /* report data to monitor once error aborting  happened fn=0x60*/
 | |
| static void iot_cp_cmd_rpt_err_abort_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_ack_charg_abort_fn60_t *cmd;
 | |
|     uint8_t * cp_data;
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_ack_charg_abort_fn60_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_info = (cp_plug_info_t *)(&cp_context.plug_info[cmd->plug_num]);
 | |
|     if (cmd->result == IOT_RESULT_RET_ERR_DATA) {
 | |
|         iot_cus_printf("report err \n");
 | |
|     } else {
 | |
|         iot_cus_printf("report success plug_info : %d\n", cmd->plug_num);
 | |
|         if (plug_info->plug_state.work_state == IOT_CP_WORK_STATE_CHARGED) {
 | |
|             plug_info->plug_state.work_state = IOT_CP_WORK_STATE_OCCUPIED;
 | |
|         }
 | |
|         /* save checked to falsh */
 | |
|         cp_context.flash_info.his_info[cmd->plug_num].checked =
 | |
|             IOT_CP_ORDER_CHECKED;
 | |
|         iot_proto_custom_pib_info_save((void*)flash_info,
 | |
|             sizeof(cp_flash_info_t));
 | |
|         plug_info->rpt_bitmap &= CP_REPORT_ERR_OFF;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
| * @param data:  point to the charging pile command frame.
 | |
| * @param dir:   data from UART and GE needto be handled separately
 | |
| */
 | |
| /* report correcting time fn:0x61*/
 | |
| static void iot_cp_cmd_rpt_query_rtc_hdl(uint8_t *data, uint8_t dir)
 | |
| {
 | |
|     cp_ack_query_sta_time_fn61_t *cmd;
 | |
|     uint8_t * cp_data;
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_ack_query_sta_time_fn61_t*)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     os_mem_cpy(&cp_context.rtc_time.week, &cmd->date_t.week,
 | |
|         sizeof(cp_date_t));
 | |
|     cp_rtc_set(&cp_context.rtc_time.sub_date_t);
 | |
|     cp_context.rtc_report_cnt = 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
| * @param data:  point to the charging pile command frame.
 | |
| * @param dir:   data from UART and GE needto be handled separately
 | |
| */
 | |
| /* report node's history info ack fn:0x63 */
 | |
| static void iot_cp_cmd_rpt_history_data_hdl(uint8_t *data,
 | |
|     uint8_t dir)
 | |
| {
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_ack_history_data_fn63_t *cmd;
 | |
|     uint8_t * cp_data;
 | |
| 
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cmd = (cp_ack_history_data_fn63_t *)cp_data;
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     plug_info = (cp_plug_info_t *)(&cp_context.plug_info[cmd->plug_num]);
 | |
| 
 | |
|     if (cmd->result == IOT_RESULT_RET_ERR_DATA) {
 | |
|         iot_cus_printf("report err \n");
 | |
|     } else {
 | |
|         iot_cus_printf("report success plug_info %d: \n", cmd->plug_num);
 | |
|         plug_info->rpt_bitmap &= CP_REPORT_HISTORY_OFF;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
| * @param data:  point to the charging pile command frame.
 | |
| * @param dir:   data from UART and GE needto be handled separately
 | |
| */
 | |
| /* query node's parameter fn:0x64*/
 | |
| static void iot_cp_cmd_rpt_status_change_hdl(uint8_t *data,
 | |
|     uint8_t dir)
 | |
| {
 | |
|     cp_ack_status_change_fn64_t  *cmd;
 | |
|     cmd = (cp_ack_status_change_fn64_t *)(data + IOT_MAC_ADDR_LEN);
 | |
|     if ((cmd->hdr.data_len + CP_FRM_MIN_LEN) != (sizeof(*cmd))) {
 | |
|         iot_cus_printf("%s, cmd len err%d\n", __FUNCTION__, cmd->hdr.data_len);
 | |
|         return;
 | |
|     }
 | |
|     if (cmd->result == IOT_RESULT_RET_ERR_DATA) {
 | |
|         iot_cus_printf("report err\n");
 | |
|     } else {
 | |
|         iot_cus_printf("report success\n");
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*command handle*/
 | |
| static iot_cp_handle_t iot_cp_cmd_handle_list[] = {
 | |
| 
 | |
|     /* config node's parameter */
 | |
|     {IOT_CP_CMD_SET_PARAMTR,        iot_cp_cmd_set_paramtr_hdl},
 | |
|     /* config node's time */
 | |
|     {IOT_CP_CMD_SET_RTC_TIME,       iot_cp_cmd_set_rtc_time_hdl},
 | |
|     /* config node's working mode */
 | |
|     {IOT_CP_CMD_SET_WORK_MODE,      iot_cp_cmd_set_work_mode_hdl},
 | |
|     /* set up a new order */
 | |
|     {IOT_CP_CMD_SET_NEW_PO,         iot_cp_cmd_set_new_po_hdl},
 | |
|     /* close an order */
 | |
|     {IOT_CP_CMD_SET_END_PO,         iot_cp_cmd_set_end_po_hdl},
 | |
|     /* find free nodes */
 | |
|     {IOT_CP_CMD_SET_FIND_FREE,      iot_cp_cmd_set_find_free_hdl},
 | |
|     /* stop charging due to emergency */
 | |
|     {IOT_CP_CMD_SET_EMERGENT_STOP,  iot_cp_cmd_set_emergent_stop_hdl},
 | |
| 
 | |
|     /* query node's status  */
 | |
|     {IOT_CP_CMD_QUERY_STATUS,       iot_cp_cmd_query_status_hdl},
 | |
|     /* query data of charging device  */
 | |
|     {IOT_CP_CMD_QUERY_DEVIC_DATA,   iot_cp_cmd_query_devic_data_hdl},
 | |
|     /* query node's version info */
 | |
|     {IOT_CP_CMD_QUERY_VER_INFO,     iot_cp_cmd_query_ver_info_hdl},
 | |
|     /* query node's parameter */
 | |
|     {IOT_CP_CMD_QUERY_PARAMTR,      iot_cp_cmd_query_paramtr_hdl},
 | |
|     /* query node's time */
 | |
|     {IOT_CP_CMD_QUERY_TIME,         iot_cp_cmd_query_time_hdl},
 | |
|     /*query the historical charging order*/
 | |
|     {IOT_CP_CMD_QUERY_CHAG_RECORD,  iot_cp_cmd_query_chag_record_hdl},
 | |
|     /* concentrator query node's charging data  */
 | |
|     {IOT_CP_CMD_CONCENT_QUERY_DATA, iot_cp_cmd_concent_query_data_hdl},
 | |
| 
 | |
|     /* query node's meter data  */
 | |
|     {IOT_CP_CMD_QUERY_METER_DATA,    iot_cp_cmd_query_meter_data_hdl},
 | |
| 
 | |
| 
 | |
|     /* report data to monitor once error aborting  happened */
 | |
|     {IOT_CP_CMD_RPT_ERR_ABORT,      iot_cp_cmd_rpt_err_abort_hdl},
 | |
|     /* query correcting time */
 | |
|     {IOT_CP_CMD_RPT_QUERY_RTC,      iot_cp_cmd_rpt_query_rtc_hdl},
 | |
|     /* query node's history info */
 | |
|     {IOT_CP_CMD_RPT_HISTORY_DATA,   iot_cp_cmd_rpt_history_data_hdl},
 | |
|     /* query node's parameter */
 | |
|     {IOT_CP_CMD_RPT_STATUS_CHANGE,  iot_cp_cmd_rpt_status_change_hdl},
 | |
| };
 | |
| 
 | |
| #define iot_cp_list_size()   (sizeof(iot_cp_cmd_handle_list) /\
 | |
|     sizeof(iot_cp_cmd_handle_list[0]))
 | |
| 
 | |
| /*gets the command handle*/
 | |
| static iot_cp_fn_t iot_cp_cmd_handler_get(uint16_t cmd) {
 | |
|     uint8_t index;
 | |
|     iot_cp_fn_t handle = NULL;
 | |
| 
 | |
|     for (index = 0; index < iot_cp_list_size(); index++) {
 | |
|         if (iot_cp_cmd_handle_list[index].cmd == cmd) {
 | |
|             iot_cus_printf("[cp]:Get the handle\n");
 | |
|             handle = iot_cp_cmd_handle_list[index].fn_cmd;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
|     if (handle == NULL) {
 | |
|         iot_cus_printf("[cp]:No command found\n");
 | |
|     }
 | |
|     /* return NULL if no command found. */
 | |
|     return handle;
 | |
| }
 | |
| 
 | |
| /* for cco: report data to uart once error aborting happened fn: 60H
 | |
|  * for sta: report data to uart and cco
 | |
|  */
 | |
| static void iot_cp_report_err_abort_hdl(uint8_t *data , uint8_t fn)
 | |
| {
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_plug_history_info_t *history_info;
 | |
|     cp_rpt_charg_abort_fn60_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t data_len  = 0;
 | |
|     uint8_t frame_len = 0;
 | |
|     uint8_t plug_num  = 0;
 | |
|     uint8_t dir;
 | |
| 
 | |
|     plug_num = (*data >> 6) & 0xFF;
 | |
| 
 | |
|     iot_cus_printf("%s, plug_id %d, abord reason %d, fn:%d\n", __FUNCTION__,
 | |
|         plug_num, *data, fn);
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rpt_charg_abort_fn60_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         plug_info = (cp_plug_info_t*)(&cp_context.plug_info[plug_num]);
 | |
|         history_info = &cp_context.flash_info.his_info[plug_num];
 | |
| 
 | |
|         if(plug_info->rpt_cnt == 0){
 | |
|             rsp_cmd->signal_sn = iot_cp_get_send_signal_sn();
 | |
|             plug_info->send_signal_sn[CP_SIGNAL_REPORT_ERR] =
 | |
|                 rsp_cmd->signal_sn;
 | |
|             plug_info->send_signal_sn[CP_SIGNAL_REPORT_HISTORY] =
 | |
|                 iot_cp_get_send_signal_sn();
 | |
|         } else {
 | |
|             rsp_cmd->signal_sn =
 | |
|                 plug_info->send_signal_sn[CP_SIGNAL_REPORT_ERR];
 | |
|         }
 | |
| 
 | |
|         os_mem_cpy(rsp_cmd->po_num, history_info->po_num, CP_PO_NUMBER_SIZE);
 | |
|         rsp_cmd->end_type   = *data & 0x3F;
 | |
|         rsp_cmd->work_state = history_info->work_state;
 | |
|         rsp_cmd->elect_cur  = history_info->elect_cur;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->elect_cur);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_cur));
 | |
|         rsp_cmd->elect_last = history_info->elect_last;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->elect_last);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_last));
 | |
|         rsp_cmd->charg_time = history_info->charg_time;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->charg_time);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->charg_time));
 | |
|         rsp_cmd->fault_t    = history_info->fault_t;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->fault_t);
 | |
|         iot_data_reverse(data_ptr,sizeof(rsp_cmd->fault_t));
 | |
|         rsp_cmd->fault_data = history_info->fault_data;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->fault_data);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->fault_data));
 | |
|         rsp_cmd->plug_num = plug_num;
 | |
|         data_len  = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
| 
 | |
|         /* send to uart */
 | |
|         if (plc_context.work_role == CP_PLC_ROLE_CCO) {
 | |
|             dir = IOT_CP_TRANS_DIR_UART;
 | |
|         } else {
 | |
|             dir =  IOT_CP_TRANS_DIR_PLC;
 | |
|         }
 | |
| 
 | |
|         iot_cp_frame_fill(fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(plc_context.cco_mac, rsp_pkt, dir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* query correcting time  fn: 61H */
 | |
| static void iot_cp_report_query_rtc_hdl(uint8_t *data , uint8_t fn)
 | |
| {
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_rpt_query_sta_time_fn61_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t data_len   = 0;
 | |
|     uint8_t frame_len  = 0;
 | |
|     uint8_t dir;
 | |
|     (void)data;
 | |
| 
 | |
|     iot_cus_printf("%s, fn:%d\n", __FUNCTION__, fn);
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         iot_cus_printf("query_rtc ge_data_frame2=%X\n", ge_data_frame);
 | |
|         rsp_cmd = (cp_rpt_query_sta_time_fn61_t *)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->signal_sn = iot_cp_get_send_signal_sn();
 | |
|         data_len  = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
| 
 | |
|         if (plc_context.work_role == CP_PLC_ROLE_CCO) {
 | |
|            dir = IOT_CP_TRANS_DIR_UART;
 | |
|         } else {
 | |
|            dir = IOT_CP_TRANS_DIR_PLC;
 | |
|         }
 | |
|         iot_cp_frame_fill(fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(plc_context.cco_mac, rsp_pkt, dir);
 | |
|         cp_context.rtc_report_cnt++;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* report history data fn: 63H */
 | |
| static void iot_cp_report_history_data_hdl(uint8_t *data ,uint8_t fn)
 | |
| {
 | |
| #if 0
 | |
|     iot_pkt_t      *rsp_pkt  = NULL;
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_plug_history_info_t *his_info;
 | |
|     cp_rpt_history_data_fn63_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t   *data_ptr = NULL;
 | |
|     uint8_t   plug_num  = 0;
 | |
|     uint8_t   data_len  = 0;
 | |
|     uint8_t   frame_len = 0;
 | |
|     uint8_t   dir;
 | |
| 
 | |
|     plug_num = (*data >> 6) & 0xFF;
 | |
| 
 | |
|     iot_cus_printf("%s, fn:%d\n", __FUNCTION__, fn);
 | |
| 
 | |
|     plug_info = (cp_plug_info_t *)(&cp_context.plug_info[plug_num]);
 | |
|     his_info = &cp_context.flash_info.his_info[plug_num];
 | |
| 
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rpt_history_data_fn63_t*)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
| 
 | |
|         rsp_cmd->signal_sn =
 | |
|             plug_info->send_signal_sn[CP_SIGNAL_REPORT_HISTORY];
 | |
|         os_mem_cpy(rsp_cmd->po_num, his_info->po_num, CP_PO_NUMBER_SIZE);
 | |
|         rsp_cmd->end_type     = his_info->end_type;
 | |
|         rsp_cmd->charg_time   = his_info->charg_time;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->charg_time);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->charg_time));
 | |
|         rsp_cmd->elect_cur    = his_info->elect_cur;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->elect_cur);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_cur));
 | |
|         rsp_cmd->elect_last   = his_info->elect_last;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->elect_last);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->elect_last));
 | |
| 
 | |
|         os_mem_cpy(&his_info->start_date_t.sub_date_t.year,
 | |
|             &plug_info->date_t.year,sizeof(cp_sub_date_t));
 | |
|         os_mem_cpy(&rsp_cmd->date_t.year,
 | |
|             &his_info->start_date_t.sub_date_t.year, sizeof(cp_sub_date_t));
 | |
|         rsp_cmd->plug_num = plug_num;
 | |
| 
 | |
|         data_len = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
|         if (plc_context.work_role == CP_PLC_ROLE_CCO) {
 | |
|            dir = IOT_CP_TRANS_DIR_UART;
 | |
|         } else {
 | |
|            dir = IOT_CP_TRANS_DIR_PLC;
 | |
|         }
 | |
|         iot_cp_frame_fill(fn, (uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(plc_context.cco_mac, rsp_pkt, dir);
 | |
|     }
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /* report status change fn : 64H */
 | |
| static void iot_cp_report_status_change_hdl(uint8_t *data ,uint8_t fn)
 | |
| {
 | |
| 
 | |
|     iot_pkt_t *rsp_pkt  = NULL;
 | |
|     cp_plug_info_t *plug_info;
 | |
|     cp_rpt_status_change_fn64_t *rsp_cmd;
 | |
|     ge_frame_data_send_set_subfn160_t *ge_data_frame = NULL;
 | |
|     uint8_t *data_ptr = NULL;
 | |
|     uint8_t plug_num   = 0;
 | |
|     uint8_t data_len   = 0;
 | |
|     uint8_t frame_len  = 0;
 | |
|     uint8_t dir;
 | |
| 
 | |
|     (void)data;
 | |
| 
 | |
|     iot_cus_printf("%s, plug_id %d, fn:%d\n", __FUNCTION__, *data, fn);
 | |
|     plug_num = *data;
 | |
| 
 | |
|     /*TODO: get plug_num*/
 | |
|     plug_info = (cp_plug_info_t*)(&cp_context.plug_info[plug_num]);
 | |
|     frame_len = sizeof(*rsp_cmd) + CP_GE_DATA_FRM_MIN_SIZE;
 | |
|     rsp_pkt = iot_cp_alloc_ge_data_frm_pkt(frame_len);
 | |
|     if (rsp_pkt != NULL) {
 | |
|         ge_data_frame =
 | |
|             (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(rsp_pkt);
 | |
|         rsp_cmd = (cp_rpt_status_change_fn64_t*)(ge_data_frame->data +
 | |
|             IOT_MAC_ADDR_LEN);
 | |
|         rsp_cmd->signal_sn = iot_cp_get_send_signal_sn();
 | |
|         rsp_cmd->work_state  = plug_info->plug_state.work_state;
 | |
| 
 | |
|         rsp_cmd->fault_t     = plug_info->plug_state.fault_t;
 | |
|         rsp_cmd->plug_num    = plug_num;
 | |
|         data_ptr = (uint8_t *)(&rsp_cmd->fault_t);
 | |
|         iot_data_reverse(data_ptr, sizeof(rsp_cmd->fault_t));
 | |
|         if (plug_info->plug_state.work_state == IOT_CP_WORK_STATE_CHARGING) {
 | |
|             os_mem_cpy(rsp_cmd->po_num, plug_info->po_num, CP_PO_NUMBER_SIZE);
 | |
|         } else {
 | |
|             os_mem_set(rsp_cmd->po_num, 0, CP_PO_NUMBER_SIZE);
 | |
|         }
 | |
|         data_len  = sizeof(*rsp_cmd) - CP_FRM_MIN_LEN;
 | |
| 
 | |
|         if (plc_context.work_role == CP_PLC_ROLE_CCO) {
 | |
|            dir = IOT_CP_TRANS_DIR_UART;
 | |
|         } else {
 | |
|            dir = IOT_CP_TRANS_DIR_PLC;
 | |
|         }
 | |
|         iot_cp_frame_fill(fn,(uint8_t *)rsp_cmd, data_len, dir);
 | |
|         iot_cp_send_pkt(plc_context.cco_mac, rsp_pkt, dir);
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| static iot_cp_handle_t iot_cp_report_handle_list[] = {
 | |
|     /* report data to monitor once error aborting  happened */
 | |
|    {IOT_CP_CMD_RPT_ERR_ABORT,      iot_cp_report_err_abort_hdl},
 | |
|    /* query correcting time */
 | |
|    {IOT_CP_CMD_RPT_QUERY_RTC,      iot_cp_report_query_rtc_hdl},
 | |
|    /* query node's history info */
 | |
|    {IOT_CP_CMD_RPT_HISTORY_DATA,   iot_cp_report_history_data_hdl},
 | |
|    /* query node's parameter */
 | |
|    {IOT_CP_CMD_RPT_STATUS_CHANGE,  iot_cp_report_status_change_hdl},
 | |
| };
 | |
| #define iot_cp_report_list_size()   (sizeof(iot_cp_report_handle_list) /\
 | |
|     sizeof(iot_cp_report_handle_list[0]))
 | |
| 
 | |
| /*gets the report handle*/
 | |
| static iot_cp_fn_t iot_cp_report_handler_get(uint16_t cmd) {
 | |
|     uint8_t index;
 | |
|     iot_cp_fn_t handle = NULL;
 | |
| 
 | |
|     for (index = 0; index < iot_cp_report_list_size(); index++) {
 | |
|         if (iot_cp_report_handle_list[index].cmd == cmd) {
 | |
|             iot_cus_printf("[cp]:Get the report handle\n");
 | |
|             handle = iot_cp_report_handle_list[index].fn_cmd;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
|     if (handle == NULL) {
 | |
|         iot_cus_printf("[cp]:No report found\n");
 | |
|     }
 | |
|     /* return NULL if no  found. */
 | |
|     return handle;
 | |
| }
 | |
| 
 | |
| static void iot_cp_task_handle_report_msg(iot_cp_task_msg_t *msg)
 | |
| {
 | |
|     iot_cp_fn_t handler = NULL;
 | |
| 
 | |
|     iot_cus_printf("get report message fn:%d\n",msg->task_msg.id);
 | |
| 
 | |
|     handler = iot_cp_report_handler_get(msg->task_msg.id);
 | |
|     if (NULL != handler) {
 | |
|         handler((uint8_t *)&msg->data2, msg->task_msg.id);
 | |
|     }
 | |
|     return ;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * CP frame Check:
 | |
|  * if the CP frame is local , a handle is executed
 | |
|  * if not, it will be sent to UART or PLC.
 | |
|  * @param pkt:
 | |
|  * @param dir: where the frame come from
 | |
|  */
 | |
| static void iot_cp_cmd_handle(iot_pkt_t *pkt, uint32_t dir)
 | |
| {
 | |
|     uint16_t data_len;
 | |
|     uint16_t cp_data_len;
 | |
|     uint8_t  vaild_len = 0;
 | |
|     uint8_t  *data;
 | |
|     uint8_t  *cp_data;
 | |
|     uint8_t  dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
 | |
|     iot_cp_fn_t handler = NULL;
 | |
|     cp_frm_hdr_t *hdr   = NULL;
 | |
|     iot_pkt_t *p_pkt  = NULL;
 | |
|     ge_frame_data_send_set_subfn160_t *frame = NULL;
 | |
| 
 | |
|     data = iot_pkt_data(pkt);
 | |
|     data_len = (uint16_t)iot_pkt_data_len(pkt) ;
 | |
|     if ((data_len - IOT_MAC_ADDR_LEN * 2) < CP_FRM_MIN_LEN) {
 | |
|         iot_pkt_free(pkt);
 | |
|         iot_cus_printf("[cp][err]:get CP handle err\n");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     iot_mac_addr_cpy(dst_mac, data);
 | |
|     data += IOT_MAC_ADDR_LEN;
 | |
|     data_len -= IOT_MAC_ADDR_LEN;
 | |
|     /* CP frame data offest*/
 | |
|     cp_data = data + IOT_MAC_ADDR_LEN;
 | |
|     cp_data_len = data_len - IOT_MAC_ADDR_LEN;
 | |
| 
 | |
|     hdr = iot_get_cpcmd_hdr(cp_data, cp_data_len, &vaild_len);
 | |
|     if (NULL != hdr) {
 | |
|         iot_cp_task_data_dump(iot_pkt_data(pkt), iot_pkt_data_len(pkt));
 | |
| 
 | |
|         /* check reply frame */
 | |
|         if (hdr->preamble == CP_FRM_PREAMBLE_REPLY_CODE) {
 | |
|             iot_cus_printf("[cp]reply frame found\n");
 | |
|             hdr->preamble = CP_FRM_PREAMBLE_CODE;
 | |
|             vaild_len = data_len + CP_GE_DATA_FRM_MIN_SIZE - IOT_MAC_ADDR_LEN;
 | |
| 
 | |
|             /* a reply frame trans to UART */
 | |
|             p_pkt = iot_cp_alloc_ge_data_frm_pkt(vaild_len);
 | |
|             if (p_pkt != NULL) {
 | |
|                 frame =
 | |
|                     (ge_frame_data_send_set_subfn160_t *)iot_pkt_data(p_pkt);
 | |
|                 os_mem_cpy(frame->data, data, data_len);
 | |
|                 iot_cp_send_pkt(dst_mac, p_pkt, IOT_CP_TRANS_DIR_UART);
 | |
|             }
 | |
|         } else {
 | |
|             /* the CP frame is local, a handle will execute */
 | |
|             iot_cus_printf("[cp]data frame's target is local module\n");
 | |
|             handler = iot_cp_cmd_handler_get(hdr->fn);
 | |
|             if (NULL != handler) {
 | |
|                 cp_context.is_communication_ok = true;
 | |
|                 handler((uint8_t *)data, dir);
 | |
|             }
 | |
|         }
 | |
|     } else {
 | |
|         iot_cus_printf("[cp]cp frame not found \n");
 | |
|     }
 | |
|     iot_pkt_free(pkt);
 | |
| }
 | |
| 
 | |
| void iot_cp_send_ge_cmd_to_uart(uint8_t *data, uint16_t len)
 | |
| {
 | |
|     iot_pkt_t *pkt = iot_pkt_alloc(len, IOT_CP_TASK_ID);
 | |
| 
 | |
|     if (pkt) {
 | |
|         iot_pkt_put(pkt, len);
 | |
|         os_mem_cpy(iot_pkt_data(pkt), data, len);
 | |
| 
 | |
|         iot_cus_printf("[cp]iot_cp_send_ge_cmd_to_uart\n");
 | |
| #if USE_N11_GPRS
 | |
|         iot_grapp_sendto_mainboard_gprs_fn(pkt);
 | |
| #else
 | |
|         iot_uart_send(plc_context.uart_h, pkt, NULL);
 | |
| #endif
 | |
|     } else {
 | |
|         iot_cus_printf("[cp]alloc mem error\n");
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * process GE command frame :
 | |
|  * if it is a GE command frame, STA will record the CC0 MAC
 | |
|  * @param data    :  queried frames
 | |
|  * @param in_len  :  length of the queried frame
 | |
|  */
 | |
| static void iot_cp_handle_control_cmd_from_ge(uint8_t *data, uint16_t len)
 | |
| {
 | |
|     ge_frame_conn_ind_rpt_set_subfn9_t *join_ind = NULL;
 | |
|     ge_extend_fn_hdr_t *frm_hdr;
 | |
|     ge_frame_boot_ready_id_set_subfn24_t *get_local_addr =NULL;
 | |
|     bool_t  report_to_uart = true;
 | |
|     frm_hdr = (ge_extend_fn_hdr_t *)data;
 | |
| 
 | |
|     if (frm_hdr->hdr.fn == PROTO_GE_PLC_SET_CMD) {
 | |
|         switch (frm_hdr->subfn) {
 | |
|         case PROTO_CONN_IND_RPT_CMD:
 | |
|         {
 | |
|             //  handle sta join in
 | |
|             if (plc_context.work_role == CP_PLC_ROLE_STA) {
 | |
|                 join_ind = (ge_frame_conn_ind_rpt_set_subfn9_t *)data;
 | |
|                 iot_mac_addr_cpy(plc_context.cco_mac, join_ind->mac);
 | |
|                 plc_context.plc_state = CP_NET_STATUS_ONLINE;
 | |
|                 if (cp_context.is_communication_ok == false) {
 | |
|                     cp_context.is_communication_ok = true;
 | |
|                 }
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         case PROTO_DISCONN_IND_RPT_CMD:
 | |
|         {
 | |
|             if (plc_context.work_role == CP_PLC_ROLE_STA) {
 | |
|                 plc_context.plc_state = CP_NET_STATUS_OFFLINE;
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         case PROTO_BOOT_READY_ID_CMD:
 | |
|         {
 | |
|             get_local_addr = (ge_frame_boot_ready_id_set_subfn24_t *)data;
 | |
|             if (iot_mac_addr_valid(get_local_addr->local_mac)) {
 | |
|                 iot_mac_addr_cpy(plc_context.local_mac,
 | |
|                     get_local_addr->local_mac);
 | |
|             }
 | |
|             if (plc_context.work_role == CP_PLC_ROLE_CCO) {
 | |
|                 iot_mac_addr_cpy(plc_context.cco_mac,
 | |
|                     get_local_addr->local_mac);
 | |
|             } else {
 | |
|                 if (iot_mac_addr_valid(get_local_addr->cco_mac)) {
 | |
|                     iot_mac_addr_cpy(plc_context.cco_mac,
 | |
|                         get_local_addr->cco_mac);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             iot_cp_task_msg_post(IOT_CP_TASK_MT_REPORT,
 | |
|                 IOT_CP_CMD_RPT_QUERY_RTC, NULL, 0);
 | |
| 
 | |
|             break;
 | |
|         }
 | |
|         default:
 | |
|             break;
 | |
|         }
 | |
|     } else if (frm_hdr->hdr.fn == PROTO_GE_PLC_RESP_CMD) {
 | |
| 
 | |
|         switch (frm_hdr->subfn) {
 | |
|         case PROTO_LOCAL_MAC_RESP_CMD:
 | |
|         {
 | |
|            ge_frame_local_mac_resp_subfn1_t *local_mac_resp =
 | |
|                (ge_frame_local_mac_resp_subfn1_t *)data;
 | |
|            iot_mac_addr_cpy(plc_context.local_mac, local_mac_resp->mac);
 | |
|            break;
 | |
|         }
 | |
|         case PROTO_MODULE_INFO_RESP_CMD:
 | |
|         {
 | |
|            ge_frame_module_info_resp_subfn18_t *module_info_resp =
 | |
|                (ge_frame_module_info_resp_subfn18_t *)data;
 | |
|            iot_mac_addr_cpy(plc_context.local_mac, module_info_resp->mac);
 | |
|            break;
 | |
|         }
 | |
|         default:
 | |
|            break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (report_to_uart) {
 | |
|         iot_cp_send_ge_cmd_to_uart(data, len);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_task_plc_msg_process() - post msg to handle GE frame from PLC.
 | |
|  * @p_pkt_frame : pointer of frame data.
 | |
|  */
 | |
| uint32_t iot_cp_task_plc_msg_process(iot_pkt_t *p_pkt_frame)
 | |
| {
 | |
|     iot_cp_task_msg_post(IOT_CP_TASK_MT_APPDATA,
 | |
|         IOT_CP_TASK_MSG_ID_CMD_HANDLE, p_pkt_frame, IOT_CP_TRANS_DIR_PLC);
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| static void iot_cp_task_handle_status_update(void)
 | |
| {
 | |
|     uint8_t i;
 | |
|     uint32_t cur_ts;
 | |
|     cp_plug_info_t *plug_info;
 | |
| 
 | |
|     static uint8_t led_cnt = 0;
 | |
|     static bool_t  led_on = 0;
 | |
| 
 | |
|     led_cnt++;
 | |
|     if (led_cnt >= 3) {
 | |
|         led_cnt = 0;
 | |
|         if (led_on == true) {
 | |
|             iot_gpio_value_set(IOT_CP_GPIO_LED, IOT_CP_GPIO_OUPUT_HI);
 | |
|             led_on = false;
 | |
|         } else {
 | |
|             iot_gpio_value_set(IOT_CP_GPIO_LED, IOT_CP_GPIO_OUPUT_LOW);
 | |
|             led_on = true;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     cp_context.query_rtc_cnt++;
 | |
|     /* query RTC every 100*IOT_CP_TASK_QUERY_RTC_INTVL_CNT ms*/
 | |
|     if (cp_context.query_rtc_cnt >= IOT_CP_TASK_QUERY_RTC_INTVL_CNT) {
 | |
|         if(cp_context.rtc_report_cnt == IOT_CP_TASK_RPT_RTC_MAX_CNT){
 | |
|             //cp_context.communication_states = false;
 | |
|             cp_context.rtc_report_cnt = 0;
 | |
|         }
 | |
|         iot_cp_task_msg_post(IOT_CP_TASK_MT_REPORT,IOT_CP_CMD_RPT_QUERY_RTC,
 | |
|             NULL, 0 );
 | |
|         cp_context.query_rtc_cnt = 0;
 | |
|     }
 | |
| 
 | |
|     for (i = 0; i < CP_SOCKET_ID_ALL; i++) {
 | |
|         iot_cp_report_err_abort_for_wr(i);
 | |
|         plug_info = (cp_plug_info_t *)(&cp_context.plug_info[i]);
 | |
| 
 | |
|         if (plug_info->plug_state.work_state == IOT_CP_WORK_STATE_CHARGING) {
 | |
|             cur_ts = (uint32_t)(os_boot_time64() / IOT_SECOND_TO_MICROSECOND);
 | |
|             if (cur_ts >= plug_info->new_po_ts) {
 | |
|                 plug_info->charg_time = (uint16_t)(cur_ts -
 | |
|                     plug_info->new_po_ts);
 | |
|             } else {
 | |
|                 plug_info->charg_time = (uint16_t)(0xFFFFFFFF -
 | |
|                     plug_info->new_po_ts + cur_ts);
 | |
|             }
 | |
| 
 | |
|             /* change to minutes */
 | |
|             plug_info->charg_time =
 | |
|                 plug_info->charg_time / IOT_MINUTE_TO_SECOND;
 | |
|         }
 | |
| 
 | |
|         cp_context.flash_info.his_info[i].charg_time = plug_info->charg_time;
 | |
|         cp_context.flash_info.his_info[i].elect_cur = plug_info->elect_cur;
 | |
|         /* check the charging mode */
 | |
|         switch (plug_info->charge_mode) {
 | |
|         case IOT_CP_CHARGE_MODE_TIME:
 | |
|         case IOT_CP_CHARGE_MODE_FIX_TIME:
 | |
|         {
 | |
|             if ((plug_info->charg_time >= plug_info->charge_data) &&
 | |
|                 (plug_info->plug_state.work_state ==
 | |
|                     IOT_CP_WORK_STATE_CHARGING)) {
 | |
|                 iot_cus_printf("mode %d chag data:%d, state: %d, time %d\n",
 | |
|                     plug_info->charge_mode, plug_info->charge_data,
 | |
|                     plug_info->plug_state.work_state, plug_info->charg_time);
 | |
|                 iot_cp_stop_charging_due_to_reason(i, IOT_CP_END_TPYE_CHARGED);
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         case IOT_CP_CHARGE_MODE_POWER:
 | |
|         {
 | |
|             if (plug_info->elect_cur >= plug_info->charge_data) {
 | |
|                 iot_cp_stop_charging_due_to_reason(i, IOT_CP_END_TPYE_CHARGED);
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         case IOT_CP_CHARGE_MODE_FULL_CHARG:
 | |
|         {
 | |
|             //TODO:
 | |
|             break;
 | |
|         }
 | |
|         default:
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         /* check the plug status, report it to platform at regular time or after
 | |
|         *  an event happened
 | |
|         */
 | |
|         cp_context.rpt_intvl_cnt[i]++;
 | |
| 
 | |
|         if (plug_info->plug_state.pre_work_state !=
 | |
|             plug_info->plug_state.work_state) {
 | |
|             iot_cus_printf("state changed: pre state %d, new state %d\n",
 | |
|                 plug_info->plug_state.pre_work_state,
 | |
|                 plug_info->plug_state.work_state);
 | |
|             iot_cp_task_msg_post(IOT_CP_TASK_MT_REPORT,
 | |
|                 IOT_CP_CMD_RPT_STATUS_CHANGE, NULL, i);
 | |
|             plug_info->plug_state.pre_work_state =
 | |
|                 plug_info->plug_state.work_state;
 | |
|             cp_context.rpt_intvl_cnt[i] = 0;
 | |
|         } else if (cp_context.rpt_intvl_cnt[i] >
 | |
|             IOT_CP_TASK_RPT_STATUS_INTVL_CNT) {
 | |
|             if (plug_info->plug_state.work_state == IOT_CP_WORK_STATE_CHARGING) {
 | |
|                 iot_cp_task_msg_post(IOT_CP_TASK_MT_REPORT,
 | |
|                     IOT_CP_CMD_RPT_STATUS_CHANGE, NULL, i);
 | |
|             }
 | |
|             cp_context.rpt_intvl_cnt[i] = 0;
 | |
|             /* make some delay for next plug's report */
 | |
|             if (i < CP_SOCKET_ID_3) {
 | |
|                 cp_context.rpt_intvl_cnt[i+1] -= os_rand() % 5;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if ((plug_info->rpt_bitmap != 0) && cp_context.is_communication_ok) {
 | |
|             if (!(plug_info->rpt_cnt_down--)) {
 | |
|                 plug_info->rpt_cnt++;
 | |
| 
 | |
|                 if (plug_info->rpt_bitmap & CP_REPORT_ERR_ON) {
 | |
|                     iot_cp_task_msg_post(IOT_CP_TASK_MT_REPORT,
 | |
|                         IOT_CP_CMD_RPT_ERR_ABORT, NULL, plug_info->rpt_data);
 | |
|                 }
 | |
|                 if (plug_info->rpt_bitmap & CP_REPORT_HISTORY_ON) {
 | |
|                     iot_cp_task_msg_post(IOT_CP_TASK_MT_REPORT,
 | |
|                         IOT_CP_CMD_RPT_HISTORY_DATA, NULL, plug_info->rpt_data);
 | |
|                 }
 | |
|                 if (plug_info->rpt_cnt == IOT_CP_TASK_RPT_RETRY_MAX_CNT) {
 | |
|                     if (plug_info->rpt_bitmap & CP_REPORT_ERR_ON) {
 | |
|                         //plug_info->rpt_bitmap |= CP_REPORT_HISTORY_ON;
 | |
|                         //plug_info->rpt_bitmap &= CP_REPORT_ERR_OFF;
 | |
|                         plug_info->rpt_bitmap |= CP_REPORT_ERR_ON;
 | |
|                     }
 | |
|                     plug_info->rpt_cnt = 1;
 | |
|                     cp_context.is_communication_ok = false;
 | |
| 
 | |
|                 }
 | |
|                 plug_info->rpt_cnt_down = IOT_CP_TASK_REPORT_INTVL_CNT;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_task_handle_timer_msg() - process data from local timer.
 | |
|  * @msg : message.
 | |
|  */
 | |
| static void iot_cp_task_handle_timer_msg(iot_cp_task_msg_t *msg)
 | |
| {
 | |
|     switch (msg->task_msg.id) {
 | |
|     case IOT_CP_TASK_MSG_ID_TMR_TIMEOUT:
 | |
|     {
 | |
|         if (plc_context.module_started == false &&
 | |
|             iot_grapp_init_success()) {
 | |
|             plc_context.module_started = true;
 | |
|             os_stop_timer(plc_context.appinit_timer);
 | |
|             iot_grapp_reg_fn_receive_from_ge(HOST_PORT_CUSTOM_TASK,
 | |
|                 iot_cp_task_plc_msg_process);
 | |
|             /* start timer for updating local status */
 | |
|             os_start_timer(plc_context.status_update_timer,
 | |
|                 IOT_CP_TASK_TIMER_UPDATE_PERIOD);
 | |
|             /* init threshold param */
 | |
|             iot_cp_default_param_init();
 | |
|             /* initialize GPIO hardware*/
 | |
|             iot_cp_gpio_init();
 | |
|         }
 | |
|         break;
 | |
|     }
 | |
|     case IOT_CP_TASK_MSG_ID_TMR_PERIOD:
 | |
|     {
 | |
|         iot_cp_task_handle_status_update();
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|     {
 | |
|         iot_cus_printf("[cp_task]unknown timer message id #%d.\n",
 | |
|             msg->task_msg.id);
 | |
|         break;
 | |
|     }
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_process_appdata() - handle app data from uart or plc.
 | |
|  * @p_cp_msg : message.
 | |
|  */
 | |
| static uint8_t iot_cp_process_appdata(iot_cp_task_msg_t *p_cp_msg)
 | |
| {
 | |
|     uint8_t ret = ERR_OK;
 | |
|     iot_pkt_t *p_pkt_frame;
 | |
|     iot_pkt_t *t_pkt;
 | |
|     iot_pkt_t *p_pkt;
 | |
|     ge_extend_fn_hdr_t *ge_hdr;
 | |
|     ge_frame_data_send_set_subfn160_t *frame;
 | |
|     ge_frame_data_send_set_subfn160_t *rep_frame = NULL;
 | |
|     uint8_t   *data;
 | |
|     uint8_t   *p_buffer;
 | |
|     uint8_t   dir;
 | |
|     uint16_t  fe_cnt;
 | |
|     uint16_t  len = 0;
 | |
|     uint16_t  vaild_len = 0;
 | |
|     uint16_t  data_len = 0;
 | |
|     uint8_t   is_local = true;
 | |
|     p_pkt_frame = (iot_pkt_t *)p_cp_msg->data;
 | |
|     dir =  p_cp_msg->data2;
 | |
| 
 | |
|     len  = (uint16_t)iot_pkt_block_len(p_pkt_frame, IOT_PKT_BLOCK_DATA);
 | |
|     data = iot_pkt_block_ptr(p_pkt_frame, IOT_PKT_BLOCK_DATA);
 | |
| 
 | |
| again:
 | |
|     ge_hdr = iot_cp_ge_frm_check(data, len, &vaild_len);
 | |
|     if (NULL != ge_hdr) {
 | |
|         /* GE data frame (FE-A0) */
 | |
|         if ((ge_hdr->hdr.fn == PROTO_GE_PLC_SET_CMD) &&
 | |
|             (ge_hdr->subfn == PROTO_GE_DATA_CMD)) {
 | |
|             frame = (ge_frame_data_send_set_subfn160_t *)ge_hdr;
 | |
|             if ((frame->hdr.hdr.data_len <= IOT_MAC_ADDR_LEN * 2)) {
 | |
|                 iot_cus_printf("[cp]GE data find failed\n");
 | |
|                 return ERR_FAIL;
 | |
|             }
 | |
|             iot_cus_printf("[cp]GE data frame found\n");
 | |
| 
 | |
|             /* note a local frame trans to GE */
 | |
|             if (dir == IOT_CP_TRANS_DIR_UART) {
 | |
|                 if ((!iot_mac_addr_cmp(frame->dest_mac, plc_context.local_mac))
 | |
|                     && (!iot_mac_is_bcast(frame->dest_mac))) {
 | |
|                     iot_cus_printf("[cp]:isn't a local frame\n");
 | |
|                     is_local = false;
 | |
|                     p_pkt = iot_cp_alloc_ge_data_frm_pkt(vaild_len);
 | |
|                     if (p_pkt != NULL) {
 | |
|                         rep_frame = (ge_frame_data_send_set_subfn160_t *)
 | |
|                             iot_pkt_data(p_pkt);
 | |
|                         os_mem_cpy(rep_frame->data, frame->data,
 | |
|                             frame->hdr.hdr.data_len);
 | |
|                         iot_cp_send_pkt(frame->dest_mac, p_pkt,
 | |
|                             IOT_CP_TRANS_DIR_PLC);
 | |
|                     } else {
 | |
|                         iot_cus_printf("[cp]alloc pkt failed @%d.\n" ,__LINE__);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             if (is_local) {
 | |
|                 data_len = frame->hdr.hdr.data_len;
 | |
|                 t_pkt = iot_pkt_alloc(data_len, IOT_CP_TASK_ID);
 | |
|                 if (NULL == t_pkt) {
 | |
|                     iot_cus_printf("[cp]alloc pkt failed @%d.\n" ,__LINE__);
 | |
|                     return ERR_FAIL;
 | |
|                 }
 | |
|                 p_buffer = iot_pkt_put(t_pkt, data_len);
 | |
|                 os_mem_cpy(p_buffer, frame->dest_mac, data_len);
 | |
|                 /* get command handler */
 | |
|                 iot_cp_cmd_handle(t_pkt, dir);
 | |
|             }
 | |
|         } else {
 | |
|         /* GE command frame */
 | |
|             if (dir == IOT_CP_TRANS_DIR_PLC) {
 | |
|                 iot_cp_handle_control_cmd_from_ge((uint8_t *)ge_hdr, vaild_len);
 | |
|             } else if (dir == IOT_CP_TRANS_DIR_UART) {
 | |
|                 iot_cus_task_message_to_ge((uint8_t *)ge_hdr, vaild_len);
 | |
|             }
 | |
|         }
 | |
|         fe_cnt = (uint16_t)((uint8_t *)ge_hdr - data);
 | |
|         data   = vaild_len + (uint8_t *)ge_hdr;
 | |
|     } else {
 | |
|         iot_cus_printf("[cp]no GE cmd found\n");
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     len = len - vaild_len - fe_cnt;
 | |
| 
 | |
|     if (len) {
 | |
|         goto again;
 | |
|     }
 | |
| 
 | |
| out:
 | |
| 
 | |
|     iot_pkt_free(p_pkt_frame);
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_task_update_state_for_err_event: refesh mster data event post
 | |
|  *                      by cp socket
 | |
|  * @param plug_id:      plug port id
 | |
|  * @param is_err:       plug port error happen or resume
 | |
|  */
 | |
| static void iot_cp_task_update_state_for_err_event(uint8_t plug_id, bool_t is_err)
 | |
| {
 | |
|     cp_plug_info_t *pt_info = &cp_context.plug_info[plug_id];
 | |
| 
 | |
|     if (is_err) {
 | |
|         if (pt_info->plug_state.work_state == IOT_CP_WORK_STATE_CHARGING) {
 | |
|             iot_cp_stop_charging_due_to_reason(plug_id, IOT_CP_END_TPYE_FAULT);
 | |
|             pt_info->plug_state.restore_state = IOT_CP_END_TPYE_CHARGED;
 | |
|         } else if (pt_info->plug_state.work_state != IOT_CP_WORK_STATE_FAULT) {
 | |
|             pt_info->plug_state.restore_state =
 | |
|                 pt_info->plug_state.work_state;
 | |
|             pt_info->plug_state.work_state = IOT_CP_WORK_STATE_FAULT;
 | |
|         }
 | |
|     } else if (pt_info->plug_state.work_state == IOT_CP_WORK_STATE_FAULT) {
 | |
|         pt_info->plug_state.work_state = pt_info->plug_state.restore_state;
 | |
|     }
 | |
| 
 | |
|     iot_cus_printf("%s plug id %d, is err %d, new state %d\n", __FUNCTION__,
 | |
|         plug_id, is_err, pt_info->plug_state.work_state);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @briefiot_cp_task_refesh_meter_data_on_event: refesh mster data event post by
 | |
|  *                      cp socket
 | |
|  * @param plug_id:      plug port id
 | |
|  * @param meter_data:   socket plug meter data
 | |
|  */
 | |
| static void iot_cp_task_refesh_meter_data_on_event(uint8_t plug_id,
 | |
|     cp_socket_plug_meter_data_t *meter_data)
 | |
| {
 | |
|     cp_plug_info_t *pt_info;
 | |
|     uint8_t reason = ERR_OK;
 | |
| 
 | |
|     pt_info = &cp_context.plug_info[plug_id];
 | |
| 
 | |
|     if (plug_id > CP_SOCKET_ID_ALL) {
 | |
|         iot_cus_printf("[cp][err]invalid plug id\n");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (reason != ERR_OK) {
 | |
|         iot_cus_printf("%s plug id %d, on state %d, operation canceled for "
 | |
|             "reason %d!\n", __FUNCTION__, plug_id,
 | |
|             pt_info->plug_state.work_state, reason);
 | |
|         return;
 | |
|     }
 | |
|     pt_info->current = meter_data->charging_i;
 | |
|     pt_info->factor = meter_data->pwr_factor;
 | |
|     pt_info->power = meter_data->power_rate;
 | |
|     pt_info->elect_total = meter_data->pwr_consum;
 | |
| 
 | |
|     if (pt_info->plug_state.work_state == IOT_CP_WORK_STATE_CHARGING) {
 | |
|         if (meter_data->pwr_consum >= pt_info->elect_init) {
 | |
|             pt_info->elect_cur = meter_data->pwr_consum -
 | |
|                 pt_info->elect_init;
 | |
|         } else {
 | |
|             pt_info->elect_cur = 0xFFFFFFFF - pt_info->elect_init +
 | |
|                 meter_data->pwr_consum;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* handle parameter query/set/setting confirm */
 | |
| void cp_meter_cmd_handle_param(cp_socket_cmd_arg_t *cmd_arg)
 | |
| {
 | |
|     cp_socket_cmd_confirm_t *cfm;
 | |
| 
 | |
|     switch(cmd_arg->hdr.opcode) {
 | |
|     case CP_SOCKET_OP_CFM:
 | |
|     {
 | |
|         cfm = (cp_socket_cmd_confirm_t *)cmd_arg->arg;
 | |
|         if (cfm->result != 0) {
 | |
|             iot_cus_printf("[cp][err]config parameter failed, reason %d\n",
 | |
|                 cfm->reason);
 | |
|         }
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|         iot_cus_printf("[cp][err]opcode[%d] is not supported\n",
 | |
|             cmd_arg->hdr.opcode);
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief cp_meter_cmd_handle_plug_info: plug info command handle
 | |
|  * @param cmd_arg:   argument for charging pile socket command handle
 | |
|  */
 | |
| void cp_meter_cmd_handle_plug_info(cp_socket_cmd_arg_t *cmd_arg)
 | |
| {
 | |
|     cp_socket_cmd_plug_info_resp_t *rsp;
 | |
|     uint8_t plug_cnt, i;
 | |
|     cp_plug_info_t *pt_info = NULL;
 | |
|     cp_socket_plug_info_t *pt_plug = NULL;
 | |
|     uint8_t charg_timeout;
 | |
| 
 | |
|     switch(cmd_arg->hdr.opcode) {
 | |
|     case CP_SOCKET_OP_RESPONSE:
 | |
|     {
 | |
|         rsp = (cp_socket_cmd_plug_info_resp_t *)cmd_arg;
 | |
|         plug_cnt = rsp->plug_cnt;
 | |
|         for (i = 0; i < plug_cnt; i++) {
 | |
|             pt_plug = &rsp->plug_info[i];
 | |
|             pt_info = &cp_context.plug_info[pt_plug->plug_id];
 | |
|             pt_info->freq = rsp->freq;
 | |
|             pt_info->volt = rsp->volt;
 | |
|             pt_info->leak_current = rsp->leak_i;
 | |
|             pt_info->factor = pt_plug->meter_data.pwr_factor;
 | |
|             pt_info->current = pt_plug->meter_data.charging_i;
 | |
|             pt_info->power = pt_plug->meter_data.power_rate;
 | |
|             pt_info->plug_state.plug_in = pt_plug->is_plug_in;
 | |
|             if (pt_info->plug_state.fault_t.charg_timeout) {
 | |
|                 charg_timeout = 1;
 | |
|             } else {
 | |
|                 charg_timeout = 0;
 | |
|             }
 | |
|             os_mem_cpy((uint8_t *)&pt_info->plug_state.fault_t,
 | |
|                 (uint8_t *)&pt_plug->fault_status, sizeof(uint16_t));
 | |
|             if (charg_timeout) {
 | |
|                 pt_info->plug_state.fault_t.charg_timeout = 1;
 | |
|             } else {
 | |
|                 pt_info->plug_state.fault_t.charg_timeout = 0;
 | |
|             }
 | |
|         }
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|         iot_cus_printf("[cp][err]opcode[%d] is not supported\n",
 | |
|             cmd_arg->hdr.opcode);
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief cp_meter_cmd_handle_plug_io_indication: plug info command handle
 | |
|  * @param cmd_arg:   argument for charging pile socket command handle
 | |
|  */
 | |
| void cp_meter_cmd_handle_plug_io_indication(uint8_t plug_id, bool_t is_plug_in,
 | |
|      cp_socket_fault_t *fault_src)
 | |
| {
 | |
|     bool_t charg_timeout = 0;
 | |
|     cp_plug_info_t *pt_info = &cp_context.plug_info[plug_id];
 | |
| 
 | |
|     if (pt_info->plug_state.plug_in != is_plug_in) {
 | |
|         iot_cus_printf("old pulg status %d, new status %d, "
 | |
|             " work state %d\n",pt_info->plug_state.plug_in,
 | |
|             is_plug_in, pt_info->plug_state.work_state);
 | |
| 
 | |
|         if (is_plug_in == false) {
 | |
|             switch (pt_info->plug_state.work_state) {
 | |
|             case IOT_CP_WORK_STATE_CHARGING:
 | |
|             {
 | |
|                 iot_cp_stop_charging_due_to_reason(plug_id,
 | |
|                     IOT_CP_END_TPYE_DISCONN);
 | |
|                 break;
 | |
|             }
 | |
|             case IOT_CP_WORK_STATE_CHARGED:
 | |
|             case IOT_CP_WORK_STATE_OCCUPIED:
 | |
|             {
 | |
|                 pt_info->plug_state.work_state = IOT_CP_WORK_STATE_IDLE;
 | |
|                 break;
 | |
|             }
 | |
|             default:
 | |
|                 break;
 | |
|             }
 | |
|         } else {
 | |
|             if (pt_info->plug_state.work_state == IOT_CP_WORK_STATE_IDLE) {
 | |
|                 pt_info->plug_state.work_state = IOT_CP_WORK_STATE_OCCUPIED;
 | |
|             } else {
 | |
|                 iot_cus_printf("[cp][err]status err\n");
 | |
|             }
 | |
|         }
 | |
|         pt_info->plug_state.plug_in = is_plug_in;
 | |
|     }
 | |
| 
 | |
|     charg_timeout = (bool_t)pt_info->plug_state.fault_t.charg_timeout;
 | |
|     os_mem_cpy((uint8_t *)&pt_info->plug_state.fault_t,
 | |
|         (uint8_t *)fault_src, sizeof(uint16_t));
 | |
|     pt_info->plug_state.fault_t.charg_timeout = charg_timeout;
 | |
| }
 | |
| 
 | |
| void cp_meter_cmd_handle_status_event(cp_socket_cmd_arg_t *cmd_arg)
 | |
| {
 | |
|     cp_socket_cmd_event_status_t *event =
 | |
|         (cp_socket_cmd_event_status_t *)cmd_arg->arg;
 | |
|     cp_plug_info_t *pt_info;
 | |
|     uint8_t plug_indx;
 | |
|     uint8_t result = ERR_OK;
 | |
|     uint8_t reason = CP_SOCKET_NO_FAIL;
 | |
|     cp_fault_t *p_fault;
 | |
|     bool_t is_err;
 | |
|     uint8_t i;
 | |
| 
 | |
|     if (NULL == cmd_arg) {
 | |
|         iot_cus_printf("[cp][err]Invalid arg: NULL!\n");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     iot_cus_printf("%s opcode %d, evet_id %d, plug id %d\n", __FUNCTION__,
 | |
|         cmd_arg->hdr.opcode, event->event_id, event->plug_id);
 | |
| 
 | |
|     switch(cmd_arg->hdr.opcode) {
 | |
|     case CP_SOCKET_OP_INDICATION:
 | |
|     {
 | |
|         for (plug_indx = 0; plug_indx < CP_SOCKET_ID_ALL; plug_indx++) {
 | |
|             if (event->plug_id != CP_SOCKET_ID_ALL &&
 | |
|                 event->plug_id != plug_indx) {
 | |
|                 continue;
 | |
|             }
 | |
|             pt_info = &cp_context.plug_info[plug_indx];
 | |
|             pt_info->volt = event->volt;
 | |
|             pt_info->leak_current = event->leak_i;
 | |
|             pt_info->plug_state.incumbent_v = (uint16_t)event->incumbent_v;
 | |
|             iot_cp_task_refesh_meter_data_on_event(plug_indx,
 | |
|                 &event->meter_data);
 | |
|             switch(event->event_id) {
 | |
|             case CP_SOCKET_EVENT_ID_CHARG_START_CFM:
 | |
|             {
 | |
|                 iot_cus_printf("[cp]start charging cmd excuted!\n");
 | |
|                 break;
 | |
|             }
 | |
|             case CP_SOCKET_EVENT_ID_CHARG_STOP_CFM:
 | |
|             {
 | |
|                 if (pt_info->plug_state.work_state ==
 | |
|                     IOT_CP_WORK_STATE_CHARGING &&
 | |
|                     pt_info->charge_mode != IOT_CP_CHARGE_MODE_FIX_TIME) {
 | |
|                     iot_cp_stop_charging_due_to_reason(plug_indx,
 | |
|                         IOT_CP_END_TPYE_CHARGED);
 | |
|                 }
 | |
|                 break;
 | |
|             }
 | |
|             case CP_SOCKET_EVENT_ID_PLUG_IO:
 | |
|             {
 | |
|                 iot_cus_printf("[cp]PLUG_IO plug_indx=%d is_plug_in=%d\n",
 | |
|                     plug_indx, event->is_plug_in);
 | |
|                 cp_meter_cmd_handle_plug_io_indication(plug_indx,
 | |
|                     event->is_plug_in, &event->fault_src);
 | |
|                 break;
 | |
|             }
 | |
|             case CP_SOCKET_EVENT_ID_ABNORM_VOLT:
 | |
|             {
 | |
|                 p_fault = &pt_info->plug_state.fault_t;
 | |
|                 pt_info->volt = event->volt;
 | |
|                 p_fault->overvolt = event->fault_src.overvolt;
 | |
|                 p_fault->undervolt = event->fault_src.undervolt;
 | |
|                 pt_info->current = event->meter_data.charging_i;
 | |
|                 pt_info->plug_state.fault_data = pt_info->volt;
 | |
|                 iot_cus_printf("[cp]ABNORM_VOLT volt=%d overvolt=%d "
 | |
|                     "undervolt=%d current= %d\n", pt_info->volt,
 | |
|                     p_fault->overvolt, p_fault->undervolt, pt_info->current);
 | |
|                 // send indication to CCO, then stop charging
 | |
|                 is_err = (p_fault->undervolt || p_fault->overvolt) ? 1 : 0 ;
 | |
|                 for (i = 0; i < CP_SOCKET_ID_ALL; i++) {
 | |
|                     iot_cp_task_update_state_for_err_event(i, is_err);
 | |
|                 }
 | |
|                 break;
 | |
|             }
 | |
|             case CP_SOCKET_EVENT_ID_ABNORM_CURR:
 | |
|             {
 | |
|                 p_fault = &pt_info->plug_state.fault_t;
 | |
|                 p_fault->overcur = event->fault_src.overcur;
 | |
|                 p_fault->overload = event->fault_src.overload;
 | |
|                 pt_info->current = event->meter_data.charging_i;
 | |
|                 pt_info->power = event->meter_data.power_rate;
 | |
|                 if (p_fault->overcur)
 | |
|                     pt_info->plug_state.fault_data = pt_info->current;
 | |
|                 else if (p_fault->overload) {
 | |
|                     pt_info->plug_state.fault_data = pt_info->power;
 | |
|                 }
 | |
|                 iot_cus_printf("[cp]ABNORM_CURR current=%d power=%d overcur=%d "
 | |
|                     "overload=%d\n", pt_info->current, pt_info->power,
 | |
|                     p_fault->overcur, p_fault->overload);
 | |
|                 /* send indication to CCO, then stop charging. */
 | |
|                 is_err = (p_fault->overcur || p_fault->overload) ? 1 : 0 ;
 | |
|                 iot_cp_task_update_state_for_err_event(plug_indx, is_err);
 | |
|                 break;
 | |
|             }
 | |
|             case CP_SOCKET_EVENT_ID_LEAKAGE:
 | |
|             {
 | |
|                 p_fault = &pt_info->plug_state.fault_t;
 | |
|                 p_fault->leak_cur_protec = event->fault_src.leak_cur_protec;
 | |
|                 pt_info->plug_state.fault_data = pt_info->leak_current;
 | |
|                 iot_cus_printf("[cp]LEAKAGE leak_cur_protec=%d\n",
 | |
|                     p_fault->leak_cur_protec);
 | |
|                 is_err = (p_fault->leak_cur_protec) ? 1 : 0 ;
 | |
|                 for (i = 0; i < CP_SOCKET_ID_ALL; i++) {
 | |
|                     iot_cp_task_update_state_for_err_event(i, is_err);
 | |
|                 }
 | |
|                 break;
 | |
|             }
 | |
|             case CP_SOCKET_EVENT_ID_GROUND_ERR:
 | |
|             {
 | |
|                 break;
 | |
|             }
 | |
|             default:
 | |
|                 result = ERR_FAIL;
 | |
|                 reason = CP_SOCKET_FAIL_OPC_NOT_SUPPORT;
 | |
|                 break;
 | |
|             }
 | |
|             pt_info++;
 | |
|         }
 | |
|         iot_cp_send_cfm_cmd_to_meter_task(cmd_arg->hdr.cid, result, reason);
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|         iot_cus_printf("[cp][err]opcode[%d] is not supported\n",
 | |
|             cmd_arg->hdr.opcode);
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void cp_meter_cmd_handle_data_event(cp_socket_cmd_arg_t *cmd_arg)
 | |
| {
 | |
|     uint8_t i;
 | |
|     bool_t charg_timeout;
 | |
|     cp_socket_cmd_event_data_rpt_t *rpt;
 | |
|     cp_plug_info_t *pt_info = NULL;
 | |
|     cp_socket_plug_info_t *pt_plug = NULL;
 | |
| 
 | |
|     switch(cmd_arg->hdr.opcode) {
 | |
|     case CP_SOCKET_OP_INDICATION:
 | |
|     {
 | |
|         rpt = (cp_socket_cmd_event_data_rpt_t *)cmd_arg->arg;
 | |
|         for (i = 0; i < rpt->plug_cnt; i++) {
 | |
|             pt_plug = &rpt->plug_info[i];
 | |
|             pt_info = &cp_context.plug_info[pt_plug->plug_id];
 | |
|             pt_info->freq = rpt->freq;
 | |
|             pt_info->volt = rpt->volt;
 | |
|             pt_info->leak_current = rpt->leak_i;
 | |
|             pt_info->plug_state.incumbent_v = (uint16_t)pt_plug->incumbent_v;
 | |
|             iot_cp_task_refesh_meter_data_on_event(pt_plug->plug_id,
 | |
|                 &pt_plug->meter_data);
 | |
| #if CP_TASK_DEBUG
 | |
|             iot_cus_printf("[cp_task] %s receive data: freq=%d, volt=%d,"
 | |
|                 "leak_current=%d, factor=%d, current=%d, power=%d, plug_in=%d, "
 | |
|                 "elect_cur=%d.\n", __FUNCTION__, pt_info->freq,
 | |
|                 pt_info->rated_volt, pt_info->leak_current,
 | |
|                 pt_info->factor, pt_info->current, pt_info->power,
 | |
|                 pt_info->plug_state.plug_in, pt_info->elect_cur);
 | |
| #endif
 | |
|             charg_timeout = (bool_t)pt_info->plug_state.fault_t.charg_timeout;
 | |
|             os_mem_cpy((uint8_t *)&pt_info->plug_state.fault_t,
 | |
|                 (uint8_t *)&pt_plug->fault_status, sizeof(uint16_t));
 | |
|             pt_info->plug_state.fault_t.charg_timeout = charg_timeout;
 | |
|         }
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|         break;
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| /* The table of energy meter adapter layer command. */
 | |
| static cp_cmd_meter_handle_t meter_cmd_handle_list[CP_SOCKET_CID_MAX] =
 | |
| {
 | |
|     cp_meter_cmd_handle_param,          /* CP_CID_PARAM */
 | |
|     cp_meter_cmd_handle_plug_info,      /* CP_CID_PLUG_INFO */
 | |
|     cp_meter_cmd_handle_status_event,   /* CP_CID_STATUS_EVENT */
 | |
|     cp_meter_cmd_handle_data_event,     /* CP_CID_DATA_EVENT */
 | |
| };
 | |
| 
 | |
| static void iot_cp_process_merter_data(iot_cp_task_msg_t *p_cp_msg)
 | |
| {
 | |
|     uint8_t cid = 0;
 | |
| 
 | |
|     if ((NULL == p_cp_msg) || (NULL == p_cp_msg->data)) {
 | |
|         iot_cus_printf("iot_cp_process_merter_data assert\n");
 | |
|         IOT_ASSERT(0);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     iot_pkt_t *t_pkt = (iot_pkt_t *)p_cp_msg->data;
 | |
|     cp_socket_cmd_arg_t *arg = (cp_socket_cmd_arg_t *)iot_pkt_data(t_pkt);
 | |
| 
 | |
|     cid = arg->hdr.cid;
 | |
| 
 | |
|     iot_cus_printf("[cp]cmd received: cid=%d, op_code=%d\n", cid,
 | |
|         arg->hdr.opcode);
 | |
| 
 | |
|     if (cid >= CP_SOCKET_CID_MAX) {
 | |
|         IOT_ASSERT(0);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     /* check if cmd_running is false. */
 | |
|     if (cp_context.command.cmd_running == false) {
 | |
|         cp_context.command.cur_cid = arg->hdr;
 | |
|         cp_context.command.cmd_running = true;
 | |
|         cp_context.command.need_ack = (bool_t)arg->need_ack;
 | |
|         cp_context.command.list.handle[cid](arg);
 | |
|         cp_context.command.cmd_running = false;
 | |
|     } else {
 | |
|         iot_cus_printf("[cp][war]pre-cmd is running, new cmd is dropped\n");
 | |
|     }
 | |
| 
 | |
|     if (NULL != t_pkt) {
 | |
|         iot_pkt_free(t_pkt);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void iot_cp_process_charge_switch(iot_cp_task_msg_t *p_cp_msg)
 | |
| {
 | |
|     IOT_ASSERT(p_cp_msg);
 | |
| 
 | |
|     switch (p_cp_msg->task_msg.id) {
 | |
|     case IOT_CP_TASK_MSG_ID_CHARGE_START:
 | |
|     {
 | |
|         iot_cp_start_charging(p_cp_msg->data2);
 | |
|         break;
 | |
|     }
 | |
|     case IOT_CP_TASK_MSG_ID_CHARGE_STOP:
 | |
|     {
 | |
|         iot_cp_stop_charging(p_cp_msg->data2);;
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|     {
 | |
|         iot_pkt_free(p_cp_msg->data);
 | |
|         iot_cus_printf("[cp_task]unknown timer message type #%d.\n",
 | |
|             p_cp_msg->task_msg.type);
 | |
|         break;
 | |
|     }
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_task_msg_exe_func() - messages handle function.
 | |
|  * @param task_h: handle of task.
 | |
|  * @param p_msg: message that will be processed.
 | |
|  */
 | |
| void iot_cp_task_msg_exe_func(iot_task_h task_h, iot_task_msg_t *p_msg)
 | |
| {
 | |
|     iot_cp_task_msg_t *p_cp_msg = (iot_cp_task_msg_t *)p_msg;
 | |
| 
 | |
|     switch (p_cp_msg->task_msg.type) {
 | |
|     case IOT_CP_TASK_MT_TIMER:
 | |
|     {
 | |
|         iot_cp_task_handle_timer_msg(p_cp_msg);
 | |
|         break;
 | |
|     }
 | |
|     /* process the data frame */
 | |
|     case IOT_CP_TASK_MT_APPDATA:
 | |
|     {
 | |
|         iot_cp_process_appdata(p_cp_msg);
 | |
|         break;
 | |
|     }
 | |
|     case IOT_CP_TASK_MT_METER:
 | |
|     {
 | |
|         iot_cp_process_merter_data(p_cp_msg);
 | |
|         break;
 | |
|     }
 | |
|     case IOT_CP_TASK_MT_REPORT:
 | |
|     {
 | |
|         iot_cp_task_handle_report_msg(p_cp_msg);
 | |
|         break;
 | |
|     }
 | |
|     case IOT_CP_TASK_MT_CHARG_SWITCH:
 | |
|     {
 | |
|         iot_cp_process_charge_switch(p_cp_msg);
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|     {
 | |
|         iot_pkt_free(p_cp_msg->data);
 | |
|         iot_cus_printf("[cp_task]unknown timer message type #%d.\n",
 | |
|             p_cp_msg->task_msg.type);
 | |
|         break;
 | |
|     }
 | |
|     }
 | |
| 
 | |
|     iot_task_free_msg(task_h, p_msg);
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_task_msg_cancel_func() - pull back messages that sent to this
 | |
|  *   task.
 | |
|  * @param task_h: handle of task.
 | |
|  * @param p_msg: message that will be pull back.
 | |
|  */
 | |
| void iot_cp_task_msg_cancel_func(iot_task_h task_h, iot_task_msg_t *p_msg)
 | |
| {
 | |
|     iot_cp_task_msg_t *p_cp_msg = (iot_cp_task_msg_t *)p_msg;
 | |
| 
 | |
|     switch(p_cp_msg->task_msg.type) {
 | |
|     case IOT_CP_TASK_MT_TIMER:
 | |
|     case IOT_CP_TASK_MT_APPDATA:
 | |
|     {
 | |
|         iot_pkt_free(p_cp_msg->data);
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|     {
 | |
|      iot_cus_printf("[cp_task]unknown timer message type #%d.\n",
 | |
|             p_cp_msg->task_msg.type);
 | |
|         break;
 | |
|     }
 | |
|     }
 | |
| 
 | |
|     iot_task_free_msg(task_h, p_msg);
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /* throw out the data frame message */
 | |
| void iot_cp_task_msg_post(uint16_t msg_type, uint16_t msg_id,
 | |
|         iot_pkt_t *data, uint32_t dir)
 | |
| {
 | |
|     iot_task_msg_t      *msg;
 | |
|     iot_cp_task_msg_t   *task_msg;
 | |
|     msg = iot_task_alloc_msg_with_reserved(plc_context.task, 0);
 | |
|     if (NULL == msg) {
 | |
|         if (NULL != data) {
 | |
|             iot_pkt_free(data);
 | |
|         }
 | |
|         iot_cus_printf("[cp]alloc pkt failed @%d.\n" ,__LINE__);
 | |
|         return;
 | |
|     }
 | |
|     task_msg = (iot_cp_task_msg_t*)msg;
 | |
|     task_msg->task_msg.type = msg_type;
 | |
|     task_msg->task_msg.id   = msg_id;
 | |
|     task_msg->data          = (void*)data;
 | |
|     task_msg->data2         = dir;
 | |
| 
 | |
|     iot_task_queue_msg(plc_context.task, &task_msg->task_msg, 0);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_task_uart_receive_func() - Uart driver callback function
 | |
|  *   when data received.
 | |
|  * @param buffer: pointer of data buffer.
 | |
|  * @param buffer_len: length of data received.
 | |
|  * @param is_full_frame: tell if this is a whole frame in this buffer.
 | |
|  * @param invalid_data_len: length of invalid data received. we ignore this.
 | |
|  */
 | |
| void iot_cp_task_uart_receive_func(uint8_t* p_buffer, uint32_t buffer_len,
 | |
|     bool_t is_full_frame, uint32_t invalid_data_len)
 | |
| {
 | |
|     (void)is_full_frame;
 | |
|     (void)invalid_data_len;
 | |
| 
 | |
|     iot_cp_task_data_dump((void*)p_buffer, buffer_len);
 | |
| 
 | |
|     if (p_buffer && buffer_len > 0) {
 | |
|         /* parser ge command and post to task */
 | |
|         iot_proto_data_parse_and_post(p_buffer, buffer_len,
 | |
|             iot_cp_task_post_uart_cmd, 0);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| #if USE_N11_GPRS
 | |
| uint8_t iot_grapp_n11_message_to_ge(uint8_t *mq_str, uint16_t str_len)
 | |
| {
 | |
|     iot_cp_task_uart_receive_func(mq_str, str_len, true, 0);
 | |
|     return ERR_OK;
 | |
| }
 | |
| #endif
 | |
| /**
 | |
|  * @brief iot_led_ctrl_task_timer_exe() - timer timeout callback function.
 | |
|  * @timer_id : timer id with that timer who causes this api-call.
 | |
|  * @arg : param past to this callback api.
 | |
|  */
 | |
| void iot_cp_task_task_timer_exe(timer_id_t timer_id, void * arg)
 | |
| {
 | |
|     (void)timer_id;
 | |
|     (void)arg;
 | |
| 
 | |
|     iot_cp_task_msg_post(IOT_CP_TASK_MT_TIMER,
 | |
|         IOT_CP_TASK_MSG_ID_TMR_TIMEOUT, NULL,0);
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_task_task_period_timer_exe() - timer timeout callback function.
 | |
|  * @timer_id : timer id with that timer who causes this api-call.
 | |
|  * @arg : param past to this callback api.
 | |
|  */
 | |
| void iot_cp_task_task_period_timer_exe(timer_id_t timer_id, void * arg)
 | |
| {
 | |
|     (void)timer_id;
 | |
|     (void)arg;
 | |
| 
 | |
|     iot_cp_task_msg_post(IOT_CP_TASK_MT_TIMER, IOT_CP_TASK_MSG_ID_TMR_PERIOD,
 | |
|         NULL,0);
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /* send pkt to uart port */
 | |
| uint32_t iot_cp_task_uart_send(iot_pkt_t *p_pkt)
 | |
| {
 | |
|     uint32_t ret;
 | |
| 
 | |
| #if USE_N11_GPRS
 | |
|     ret = iot_grapp_sendto_mainboard_gprs_fn(p_pkt);
 | |
| #else
 | |
|     ret = iot_uart_send(plc_context.task, p_pkt, NULL);
 | |
| #endif
 | |
|     return (ERR_OK == ret) ? ERR_OK : ERR_FAIL;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * TODO: meter adapt-task should call this func to registor its callback
 | |
|  * function
 | |
|  */
 | |
| uint32_t iot_cp_task_callback_reg_meter_task(cp_task_cb cb)
 | |
| {
 | |
|     uint32_t ret = ERR_FAIL;
 | |
| 
 | |
|     if (cb) {
 | |
|         plc_context.cp_task_cb = cb;
 | |
|         ret = ERR_OK;
 | |
|     }
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /* TODO: cp-task should regist this funciton on to
 | |
|  * meter adap-task's callback funtion
 | |
|  */
 | |
| static uint32_t iot_cp_meter_adap_task_cb_handle(iot_pkt_t * data_pkt)
 | |
| {
 | |
|     // TODO: post a message to handle meter infor from meter adapt-task
 | |
|     iot_cp_task_msg_post(IOT_CP_TASK_MT_METER, IOT_CP_TASK_MSG_ID_MERTER_DATA,
 | |
|         data_pkt, 0);
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_set_threshold_value() - set threshold_info to cp socket
 | |
|  * @param th_info : point to threshold_info data
 | |
|  * @param id      : save plug id, see CP_SOCKET_ID_XXX
 | |
|  */
 | |
| static void iot_cp_set_threshold_value(cp_plug_threshold_info_t *th_info,
 | |
|     uint8_t id)
 | |
| {
 | |
|     uint8_t plug_id;
 | |
| 
 | |
|     if (id > IOT_CP_MAX_PLUG_CNT) {
 | |
|         iot_cus_printf("[cp]set_threshold id err %d\n", id);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     /* if id equal to IOT_CP_MAX_PLUG_CNT, th_info will be set to all port */
 | |
|     for (plug_id = 0; plug_id < IOT_CP_MAX_PLUG_CNT; plug_id++) {
 | |
|         if (id == plug_id || id == IOT_CP_MAX_PLUG_CNT) {
 | |
|             os_mem_cpy(&flash_info->plug_th[plug_id], th_info,
 | |
|                 sizeof(cp_plug_threshold_info_t));
 | |
|             iot_cp_send_param_cmd_to_meter_task(CP_SOCKET_OP_CONFIG, plug_id);
 | |
|         }
 | |
|     }
 | |
|     flash_info->th_eigenvalue = CP_THESHOLD_EIGENVALUE;
 | |
|     iot_proto_custom_pib_info_save((void*)flash_info, sizeof(cp_flash_info_t));
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cp_task_init() - The main entry to initialize our customer task.
 | |
|  */
 | |
| uint32_t iot_cp_task_init(void)
 | |
| {
 | |
|     iot_task_config_t task_cfg;
 | |
|     os_mem_set(&cp_context, 0, sizeof(iot_cp_context));
 | |
|     os_mem_set(&plc_context, 0, sizeof(iot_plc_context));
 | |
| 
 | |
|     /* create task */
 | |
|     os_mem_set(&task_cfg, 0x0, sizeof(task_cfg));
 | |
|     task_cfg.stack_size = IOT_CP_TASK_TASK_STACK_SIZE;
 | |
|     task_cfg.task_prio  = IOT_CP_TASK_PROTO_TASK_PRIO;
 | |
|     task_cfg.msg_size   = sizeof(iot_cp_task_msg_t);
 | |
|     task_cfg.msg_cnt    = IOT_CP_TASK_TASK_POOL_SIZE;
 | |
|     task_cfg.queue_cnt  = 1;
 | |
|     task_cfg.queue_cfg[0].quota = 0;
 | |
|     task_cfg.msg_exe_func       = iot_cp_task_msg_exe_func;
 | |
|     task_cfg.msg_cancel_func    = iot_cp_task_msg_cancel_func;
 | |
| #if USE_N11_GPRS != 1
 | |
|     plc_context.uart_h = iot_uart_open(iot_board_get_uart(UART_METER_PORT),
 | |
|         iot_cp_task_uart_receive_func, IOT_CP_TASK_UART_BUF_SIZE, NULL);
 | |
| #endif
 | |
| 
 | |
|     plc_context.task = iot_task_create(IOT_CP_TASK_ID, &task_cfg);
 | |
| 
 | |
|     if (NULL == plc_context.task) {
 | |
|         iot_cus_printf("[cp_task]create task failed.\n");
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
|     plc_context.dev_type = IOT_CP_DEV_CODE_2200W_PLC;
 | |
| 
 | |
|     plc_context.appinit_timer = os_create_timer(IOT_CP_TASK_ID, true,
 | |
|         iot_cp_task_task_timer_exe, NULL);
 | |
| 
 | |
|     os_start_timer(plc_context.appinit_timer, IOT_CP_TASK_TIMER_PERIOD);
 | |
| 
 | |
|     if (0 == plc_context.appinit_timer) {
 | |
|         iot_cus_printf("[cp_task]create timer failed.\n");
 | |
|         iot_task_delete(plc_context.task);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| 
 | |
|     plc_context.status_update_timer = os_create_timer(IOT_CP_TASK_ID, true,
 | |
|         iot_cp_task_task_period_timer_exe, NULL);
 | |
| 
 | |
|     if (0 == plc_context.status_update_timer) {
 | |
|         iot_cus_printf("[cp_task]create periodic timer failed.\n");
 | |
|         iot_task_delete(plc_context.task);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| 
 | |
|     cp_socket_task_init();
 | |
| 
 | |
|     cp_socket_register(iot_cp_meter_adap_task_cb_handle);
 | |
|     cp_context.command.list.handle = meter_cmd_handle_list;
 | |
|     /* get a random initial value for sending SN */
 | |
|     cp_context.send_signal_sn = os_rand();
 | |
| 
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     plc_context.work_role = CP_PLC_ROLE_CCO;
 | |
|     plc_context.plc_state = CP_NET_STATUS_INVALID;
 | |
| #else
 | |
|     plc_context.work_role = CP_PLC_ROLE_STA;
 | |
|     plc_context.plc_state = CP_NET_STATUS_INVALID;
 | |
| #endif
 | |
| 
 | |
|     cp_context.sw_info = iot_version_hex();
 | |
|     cp_context.hw_info = iot_board_hw_version_hex();
 | |
| 
 | |
|     cp_context.work_mode = IOT_CP_NORMAL_MODE;
 | |
|     /* init RTC */
 | |
|     cp_rtc_init();
 | |
| #if USE_N11_GPRS
 | |
|     iot_n11_gprs_init();
 | |
| 
 | |
|     iot_n11_gprs_register_call_back((void *)iot_grapp_n11_message_to_ge);
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #if (CP_ZC_ENABLE == 1)
 | |
| 
 | |
|     iot_cp_zc_hw_init();
 | |
| 
 | |
| #endif
 | |
|     iot_cus_printf("[cp_task]task create successfully.\n");
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| uint32_t app_cp_task_entry()
 | |
| {
 | |
|     uint32_t ret = ERR_PENDING;
 | |
| 
 | |
|     if (ERR_OK == iot_cp_task_init())
 | |
|     {
 | |
|         ret = ERR_OK;
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| #endif /* IOT_CP_TASK_ENABLE */
 |