Files
kunlun/app/chargepile/iot_cp_task.c

4280 lines
144 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
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 */