4280 lines
144 KiB
C
4280 lines
144 KiB
C
|
/****************************************************************************
|
||
|
|
||
|
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 */
|