Files
kunlun/app/brm/src/iot_brm_adp.c
2024-09-28 14:24:04 +08:00

930 lines
29 KiB
C
Executable File

/****************************************************************************
*
* Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
*
* This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
* be copied by any method or incorporated into another program without
* the express written consent of Aerospace C.Power. This Information or any portion
* thereof remains the property of Aerospace C.Power. The Information contained herein
* is believed to be accurate and Aerospace C.Power assumes no responsibility or
* liability for its use in any way and conveys no license or title under
* any patent or copyright and makes no representation or warranty that this
* Information is free from patent or copyright infringement.
*
* ****************************************************************************/
/* os_ship header files */
#include "os_task_api.h"
#include "os_timer_api.h"
/* iot common header files */
#include "iot_io_api.h"
#include "iot_errno_api.h"
#include "iot_pkt_api.h"
#include "iot_crc_api.h"
#include "iot_utils_api.h"
#include "iot_energe_meter_api.h"
#include "iot_brm_common.h"
#include "iot_brm_rtc.h"
#include "iot_brm_adp.h"
#include "iot_brm_flash.h"
#include "iot_brm_rec.h"
#include "iot_brm_evt.h"
#include "iot_brm_proto_devadp_645_ext.h"
#if (IOT_BRM_ENABLE && PLC_SUPPORT_STA_ROLE)
#define BRM_ADP_MODULE_VERSION "1.0.005"
/* Max number of the energy meter adapter device state. */
#define BRM_ADP_DEV_STATE_MAX (DM_STATE_DEV_MAX)
/* define adp record event max count */
#define IOT_BRM_REC_ADP_EVT_MAX (40 * 30)
/* define adp record read buffer size */
#define IOT_BRM_ADP_REC_READ_BUF_SIZE 2048
#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
#define IOT_BRM_ADP_THRESHOLD_START \
(IOT_BRM_EVT_REGION_END + IOT_BRM_RESERVE_SIZE3)
#define IOT_BRM_ADP_THRESHOLD_SIZE (1024)
#define IOT_BRM_ADP_THRESHOLD_END \
(IOT_BRM_ADP_THRESHOLD_START + IOT_BRM_ADP_THRESHOLD_SIZE)
/* define the start, size, and end of evt recording region */
#define IOT_BRM_ADP_EVT_REGION_START IOT_BRM_ADP_THRESHOLD_END
#define IOT_BRM_ADP_EVT_REGION_SIZE (256 * 1024)
#define IOT_BRM_ADP_EVT_REGION_END \
IOT_BRM_ADP_EVT_REGION_START + IOT_BRM_ADP_EVT_REGION_SIZE
/* The energy meter adapter context. */
static brm_adp_context_t brm_adp_context;
static iot_brm_rec_region_desc_t g_adp_evt_rcd_region;
static uint8_t *g_buf;
static void iot_brm_adp_dev_fsm_state_process(
iot_brm_event_record_t *p_event_record);
static void iot_brm_adp_evt_send_at_join_in(void);
static void iot_brm_adp_plc_status_update(void);
/* check if oter request is exsiting */
static bool_t iot_brm_adp_fsm_evt_check_other_req_exsit(uint16_t new_evt)
{
bool_t is_exsit = false;
uint16_t check_val = (1 << new_evt);
if (new_evt < DM_STATE_DEV_MAX) {
if ((brm_adp_context.dev_fsm.chg_req_bitmp | check_val) != check_val) {
is_exsit = true;
}
}
return is_exsit;
}
/* set the new event request bit in bitmap */
static void iot_brm_adp_fsm_evt_set_req_bitmap(uint16_t new_evt)
{
/* only one bit could be set in bitmap */
if (new_evt < DM_STATE_DEV_MAX) {
brm_adp_context.dev_fsm.chg_req_bitmp = (1 << new_evt);
}
}
/* clear the new event request bit in bitmap */
static void iot_brm_adp_fsm_evt_clr_req_bitmap()
{
brm_adp_context.dev_fsm.chg_req_bitmp = 0;
}
static void iot_brm_adp_fsm_reset_req_cnt(void)
{
brm_adp_context.dev_fsm.chg_req_cnt = 0;
}
static bool_t iot_brm_adp_fsm_evt_req_change(
iot_brm_event_record_t *p_event, uint16_t new_evt)
{
bool_t req_cfm = false;
if (iot_brm_adp_fsm_evt_check_other_req_exsit(new_evt)) {
iot_brm_adp_fsm_reset_req_cnt();
}
brm_adp_context.dev_fsm.chg_req_cnt++;
iot_brm_adp_fsm_evt_set_req_bitmap(new_evt);
if (brm_adp_context.dev_fsm.chg_req_cnt >= IOT_BRM_FSM_REQ_CFM_CNT) {
p_event->rcd_data.event = new_evt;
req_cfm = true;
iot_brm_adp_fsm_reset_req_cnt();
iot_brm_adp_fsm_evt_clr_req_bitmap();
iot_brm_adp_dev_fsm_state_process(p_event);
iot_brm_printf("%s req event--%d confirmed\n",__FUNCTION__, new_evt);
}
return req_cfm;
}
/* Report event */
static void iot_brm_adp_event_report(iot_brm_event_record_t *p_last_adc_rec)
{
(void)p_last_adc_rec;
iot_cus_printf("%s start send request\n", __FUNCTION__);
iot_brm_evt_set(iot_brm_evt_adp_id);
return;
}
/* Process corresponding state for device finite state machine. */
static void iot_brm_adp_dev_fsm_state_process(
iot_brm_event_record_t *p_event_record)
{
uint32_t event;
brm_adp_dev_state_e new_state;
brm_adp_dev_state_e cur_state = brm_adp_context.dev_fsm.cur_state;
char *em_adp_fsm_symbol[4] = {"OFFLINE", "STANDBY", "WORKING", "TRAPING"};
if (NULL == p_event_record) {
IOT_ASSERT(0);
return;
}
event = p_event_record->rcd_data.event;
iot_cus_printf("[brmadp] %s current event=%d, device fsm cur_state=%s.\n",
__FUNCTION__, event, em_adp_fsm_symbol[cur_state]);
p_event_record->state = cur_state;
/* Process current state in device fsm. */
new_state =
brm_adp_context.dev_fsm.table.handle[cur_state](event, p_event_record);
if (new_state != cur_state) {
iot_cus_printf("[brmadp] change fsm from %s to %s.\n",
em_adp_fsm_symbol[cur_state], em_adp_fsm_symbol[new_state]);
brm_adp_context.dev_fsm.prev_state = cur_state;
brm_adp_context.dev_fsm.cur_state = new_state;
iot_brm_adp_event_report(p_event_record);
}
return;
}
void iot_brm_adp_fsm_event_process(void)
{
uint8_t week;
iot_time_tm_t tm;
iot_brm_event_record_t env_rcd = {0};
uint32_t current_phase_a, current_phase_b, current_phase_c, tt_current;
uint32_t power_phase_a, power_phase_b, power_phase_c, tt_power;
iot_brm_meter_info_t *meter_info = iot_brm_load_meter_info();
iot_brm_threshold_t *thr = &brm_adp_context.threshold;
iot_brm_adp_plc_status_update();
iot_brm_adp_evt_send_at_join_in();
env_rcd.rcd_data.w = meter_info->e_t.ept_pos[0];
os_mem_cpy(env_rcd.rcd_data.p, meter_info->var.p,
sizeof(int32_t)*IOT_BRM_PHASE_MAX);
os_mem_cpy(env_rcd.rcd_data.i, meter_info->var.i,
sizeof(int32_t)*IOT_BRM_PHASE_C);
os_mem_cpy(env_rcd.rcd_data.v, meter_info->var.v,
sizeof(uint16_t)*IOT_BRM_PHASE_C);
os_mem_cpy(env_rcd.rcd_data.f, meter_info->var.pf,
sizeof(uint16_t)*IOT_BRM_PHASE_MAX);
power_phase_a = ABS(meter_info->var.p[IOT_BRM_PHASE_A]);
power_phase_b = ABS(meter_info->var.p[IOT_BRM_PHASE_B]);
power_phase_c = ABS(meter_info->var.p[IOT_BRM_PHASE_C]);
tt_power = power_phase_a + power_phase_b + power_phase_c;
current_phase_a = ABS(meter_info->var.i[IOT_BRM_PHASE_A - 1]);
current_phase_b = ABS(meter_info->var.i[IOT_BRM_PHASE_B - 1]);
current_phase_c = ABS(meter_info->var.i[IOT_BRM_PHASE_C - 1]);
tt_current = current_phase_a + current_phase_b + current_phase_c;
iot_brm_rtc_get_time(&tm, &week);
env_rcd.time = iot_brm_rtctime_to_time(&tm);
iot_cus_printf("time=%d-%d-%d %d:%d:%d %lu\n",
tm.tm_year,tm.tm_mon,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec,
env_rcd.time);
iot_cus_printf("[brmadp] %s current=[%d %d %d], power=[%d %d %d]\n",
__FUNCTION__, meter_info->var.i[IOT_BRM_PHASE_A - 1],
meter_info->var.i[IOT_BRM_PHASE_B - 1],
meter_info->var.i[IOT_BRM_PHASE_C - 1],
meter_info->var.p[IOT_BRM_PHASE_A],
meter_info->var.p[IOT_BRM_PHASE_B],
meter_info->var.p[IOT_BRM_PHASE_C]);
iot_cus_printf("cur state--%d, p_trap--%d, i_standby--%d, i_work--%d\n",
brm_adp_context.dev_fsm.cur_state, thr->p_trap,
thr->i_standby, thr->i_work);
/* check P > P(trap). */
if (tt_power > ABS(thr->p_trap)) {
if (DM_STATE_DEV_TRAPING != brm_adp_context.dev_fsm.cur_state) {
iot_brm_adp_fsm_evt_req_change(&env_rcd, DM_EVENT_DEV_TRAP_START);
} else {
iot_brm_adp_fsm_reset_req_cnt();
}
} else {
if (DM_STATE_DEV_TRAPING == brm_adp_context.dev_fsm.cur_state) {
if (!iot_brm_adp_fsm_evt_req_change(&env_rcd,
DM_EVENT_DEV_TRAP_STOP)) {
return;
}
brm_adp_context.dev_fsm.chg_req_cnt = 2;
}
/* check I > I(work). */
if (tt_current > ABS(thr->i_work)) {
if (DM_STATE_DEV_WORKING != brm_adp_context.dev_fsm.cur_state) {
iot_brm_adp_fsm_evt_set_req_bitmap(DM_EVENT_DEV_WORK_START);
iot_brm_adp_fsm_evt_req_change(&env_rcd,
DM_EVENT_DEV_WORK_START);
} else {
iot_brm_adp_fsm_reset_req_cnt();
}
} else {
if (DM_STATE_DEV_WORKING == brm_adp_context.dev_fsm.cur_state) {
if (!iot_brm_adp_fsm_evt_req_change(&env_rcd,
DM_EVENT_DEV_WORK_STOP)) {
/* if not confirmed need wait */
return;
}
brm_adp_context.dev_fsm.chg_req_cnt = 2;
}
/* check I > I(standby). */
if (tt_current > ABS(thr->i_standby)) {
if (DM_STATE_DEV_STANDBY != brm_adp_context.dev_fsm.cur_state) {
iot_brm_adp_fsm_evt_set_req_bitmap(DM_EVENT_DEV_POWER_ON);
iot_brm_adp_fsm_evt_req_change(&env_rcd,
DM_EVENT_DEV_POWER_ON);
} else {
iot_brm_adp_fsm_reset_req_cnt();
}
} else {
if (DM_STATE_DEV_OFFLINE != brm_adp_context.dev_fsm.cur_state) {
iot_brm_adp_fsm_evt_set_req_bitmap(DM_EVENT_DEV_POWER_OFF);
iot_brm_adp_fsm_evt_req_change(&env_rcd,
DM_EVENT_DEV_POWER_OFF);
} else {
iot_brm_adp_fsm_reset_req_cnt();
}
}
}
}
return;
}
/* Device fsm handle used when no device plug into our brm state. */
static brm_adp_dev_state_e brm_adp_dev_fsm_handle_dev_offline(uint32_t event,
iot_brm_event_record_t *p_event_record)
{
uint8_t save_event = 0;
brm_adp_dev_state_e state = brm_adp_context.dev_fsm.cur_state;
switch (event) {
case DM_EVENT_DEV_POWER_ON:
{
/* Switch offline state to standby state. */
state = DM_STATE_DEV_STANDBY;
save_event = 1;
break;
}
case DM_EVENT_DEV_WORK_START:
{
/* Switch offline state to working state. */
state = DM_STATE_DEV_WORKING;
save_event = 1;
break;
}
case DM_EVENT_DEV_TRAP_START:
{
/* Switch offline state to traping state. */
state = DM_STATE_DEV_TRAPING;
save_event = 1;
break;
}
default:
iot_cus_printf("[brmadp] %s event=%d, device fsm state wrong!\n",
__FUNCTION__, event);
IOT_ASSERT(0);
break;
}
if (save_event){
/* Save event record to flash. */
iot_cus_printf("[brmadp] %s write event=%d record\n",
__FUNCTION__, event);
iot_brm_adp_evt_save(p_event_record);
}
return state;
}
/* Device fsm handle used when device plug into our brm,
* staying in standby state.
*/
static brm_adp_dev_state_e brm_adp_dev_fsm_handle_dev_standby(uint32_t event,
iot_brm_event_record_t *p_event_record)
{
uint8_t save_event = 0;
brm_adp_dev_state_e state = brm_adp_context.dev_fsm.cur_state;
switch (event) {
case DM_EVENT_DEV_POWER_OFF:
{
/* Switch standby state to offline state. */
state = DM_STATE_DEV_OFFLINE;
save_event = 1;
break;
}
case DM_EVENT_DEV_WORK_START:
{
/* Switch standby state to working state. */
state = DM_STATE_DEV_WORKING;
save_event = 1;
break;
}
case DM_EVENT_DEV_TRAP_START:
{
/* Switch standby state to traping state. */
state = DM_STATE_DEV_TRAPING;
save_event = 1;
break;
}
default:
iot_cus_printf("[brmadp] %s event=%d, device fsm state wrong!\n",
__FUNCTION__, event);
IOT_ASSERT(0);
break;
}
if (save_event){
/* Save event record to flash. */
iot_cus_printf("[brmadp] %s write event=%d record\n",
__FUNCTION__, event);
iot_brm_adp_evt_save(p_event_record);
}
return state;
}
/* Device fsm handle used when device plug into our brm,
* working right state.
*/
static brm_adp_dev_state_e brm_adp_dev_fsm_handle_dev_work(uint32_t event,
iot_brm_event_record_t *p_event_record)
{
uint8_t save_event = 0;
brm_adp_dev_state_e state = brm_adp_context.dev_fsm.cur_state;
switch (event) {
case DM_EVENT_DEV_POWER_ON:
{
/* Switch working state to standby state. */
state = DM_STATE_DEV_STANDBY;
save_event = 1;
break;
}
case DM_EVENT_DEV_POWER_OFF:
{
/* Switch working state to offline state. */
state = DM_STATE_DEV_OFFLINE;
save_event = 1;
break;
}
case DM_EVENT_DEV_WORK_STOP:
{
save_event = 1;
break;
}
case DM_EVENT_DEV_TRAP_START:
{
/* Switch working state to traping state. */
state = DM_STATE_DEV_TRAPING;
save_event = 1;
break;
}
default:
iot_cus_printf("[brmadp] %s event=%d, device fsm state wrong!\n",
__FUNCTION__, event);
IOT_ASSERT(0);
break;
}
if (save_event){
/* Save event record to flash. */
iot_cus_printf("[brmadp] %s write event=%d record\n",
__FUNCTION__, event);
iot_brm_adp_evt_save(p_event_record);
}
return state;
}
/* Device fsm handle used when device plug into our brm,
* running in trouble state.
*/
static brm_adp_dev_state_e brm_adp_dev_fsm_handle_dev_traping(uint32_t event,
iot_brm_event_record_t *p_event_record)
{
uint8_t save_event = 0;
brm_adp_dev_state_e state = brm_adp_context.dev_fsm.cur_state;
switch (event) {
case DM_EVENT_DEV_POWER_ON:
{
/* Switch traping state to standby state. */
state = DM_STATE_DEV_STANDBY;
save_event = 1;
break;
}
case DM_EVENT_DEV_POWER_OFF:
{
/* Switch traping state to offline state. */
state = DM_STATE_DEV_OFFLINE;
save_event = 1;
break;
}
case DM_EVENT_DEV_WORK_START:
{
/* Switch traping state to working state. */
state = DM_STATE_DEV_WORKING;
save_event = 1;
break;
}
case DM_EVENT_DEV_WORK_STOP:
{
/* Switch traping state to standby state. */
state = DM_STATE_DEV_STANDBY;
save_event = 1;
break;
}
case DM_EVENT_DEV_TRAP_STOP:
{
save_event = 1;
break;
}
default:
iot_cus_printf("[brmadp] %s event=%d, device fsm state wrong!\n",
__FUNCTION__, event);
IOT_ASSERT(0);
break;
}
if (save_event){
/* Save event record to flash. */
iot_cus_printf("[brmadp] %s write event=%d record\n",
__FUNCTION__, event);
iot_brm_adp_evt_save(p_event_record);
}
return state;
}
/* The table of device finite state machine handle */
static brm_adp_dev_fsm_handle_t dev_fsm_handle_table[BRM_ADP_DEV_STATE_MAX] =
{
brm_adp_dev_fsm_handle_dev_offline, /* DM_STATE_DEV_OFFLINE */
brm_adp_dev_fsm_handle_dev_standby, /* DM_STATE_DEV_STANDBY */
brm_adp_dev_fsm_handle_dev_work, /* DM_STATE_DEV_WORKING */
brm_adp_dev_fsm_handle_dev_traping, /* DM_STATE_DEV_TRAPING */
};
uint8_t iot_brm_adp_threshold_load(void)
{
uint8_t ret = ERR_OK;
iot_cus_printf("[brmadp] read to_add=%p\n", &(brm_adp_context.threshold));
ret = iot_brm_flash_read(IOT_BRM_ADP_THRESHOLD_START,
(uint8_t*)(&(brm_adp_context.threshold)), sizeof(iot_brm_threshold_t));
if (ret) {
iot_cus_printf("[brmadp] %s err:%d\n", __FUNCTION__, ret);
} else {
iot_cus_printf("[brmadp] %s threshold:%d %d %d\n", __FUNCTION__,
brm_adp_context.threshold.i_standby,
brm_adp_context.threshold.i_work,
brm_adp_context.threshold.p_trap);
if (brm_adp_context.threshold.i_standby == 0xFFFFFFFF ||
brm_adp_context.threshold.i_work == 0xFFFFFFFF ||
brm_adp_context.threshold.p_trap == 0xFFFFFFFF) {
ret = ERR_FAIL;
}
}
return ret;
}
iot_brm_threshold_t *iot_brm_adp_get_threshold(void)
{
return &brm_adp_context.threshold;
}
void iot_brm_adp_threshold_save(iot_brm_threshold_t *threshold)
{
uint8_t ret = ERR_OK;
if (threshold->i_standby != brm_adp_context.threshold.i_standby ||
threshold->i_work != brm_adp_context.threshold.i_work ||
threshold->p_trap != brm_adp_context.threshold.p_trap) {
brm_adp_context.threshold.i_standby = threshold->i_standby;
brm_adp_context.threshold.i_work = threshold->i_work;
brm_adp_context.threshold.p_trap = threshold->p_trap;
iot_cus_printf("[brmadp] %s threshold:%d %d %d\n", __FUNCTION__,
brm_adp_context.threshold.i_standby,
brm_adp_context.threshold.i_work,
brm_adp_context.threshold.p_trap);
ret = iot_brm_flash_write(IOT_BRM_ADP_THRESHOLD_START,
(uint8_t*)(&(brm_adp_context.threshold)), sizeof(iot_brm_threshold_t));
if (ret) {
iot_cus_printf("[brmadp] %s err:%d\n", __FUNCTION__, ret);
}
} else {
iot_cus_printf("[brmadp] %s no need to save\n", __FUNCTION__);
}
}
uint8_t iot_brm_adp_bottom_val_load(void)
{
uint8_t ret = ERR_OK;
ret = iot_brm_flash_read(IOT_BRM_ADP_THRESHOLD_END,
(uint8_t*)&brm_adp_context.meter_bottom_val, sizeof(uint32_t));
if (ret) {
iot_cus_printf("[brmadp] %s err:%d\n", __FUNCTION__, ret);
}
return ret;
}
void iot_brm_adp_bottom_val_save(uint32_t bottom_val)
{
uint8_t ret = ERR_OK;
if (bottom_val != brm_adp_context.meter_bottom_val) {
iot_cus_printf("[brmadp] %s %d\n", __FUNCTION__,
brm_adp_context.meter_bottom_val);
ret = iot_brm_flash_write(IOT_BRM_ADP_THRESHOLD_END,
(uint8_t*)&brm_adp_context.meter_bottom_val, sizeof(uint32_t));
if (ret) {
iot_cus_printf("[brmadp] %s err:%d\n", __FUNCTION__, ret);
}
}
}
uint8_t iot_brm_get_adp_evt_entry_size(void)
{
return sizeof(iot_brm_rec_head_t) + sizeof(iot_brm_load_record_t);
}
/* Save event record to flash. */
void iot_brm_adp_evt_save(iot_brm_event_record_t *p_evt_rec)
{
iot_brm_rec_head_t *hdr;
hdr = (iot_brm_rec_head_t *)g_buf;
hdr->rec_seq = g_adp_evt_rcd_region.seq;
hdr->ts = p_evt_rec->time;
os_mem_cpy(hdr->data, &p_evt_rec->rcd_data, sizeof(iot_brm_load_record_t));
iot_brm_data_print("iot_brm_adp_evt_save:", g_buf,
g_adp_evt_rcd_region.entry_size);
iot_brm_rec_write(&g_adp_evt_rcd_region,
p_evt_rec->time, g_buf, 1, 0);
return;
}
/* read event record count of daily storage. */
uint8_t iot_brm_read_adp_evt_daily_cnt(uint32_t ts)
{
uint8_t count = 0;
uint8_t ret;
uint32_t i, n_per, remain_n, read_n, pos, idx;
uint8_t *data;
uint8_t crc;
iot_brm_rec_head_t *hdr;
iot_brm_rec_region_desc_t *region = &g_adp_evt_rcd_region;
//read 1k Bytes data every time
n_per = IOT_BRM_ADP_REC_READ_BUF_SIZE / region->entry_size;
remain_n = region->rec_depth;
for (idx = 0, pos = region->start; remain_n; ) {
read_n = (remain_n >= n_per ? n_per : remain_n);
pos = region->start + idx * region->entry_size;
ret = iot_brm_flash_read(pos, g_buf, read_n * region->entry_size);
if (ret) {
break;
}
data = g_buf;
for (i = 0; i < read_n; i++) {
hdr = (iot_brm_rec_head_t *)data;
crc = iot_getcrc8(hdr->data, region->entry_size - sizeof(*hdr));
/* traverse all valid records */
if (crc == hdr->crc) {
//check
if (hdr->ts - ts > 0 && (hdr->ts - ts) < (60*60*24)){
iot_cus_printf("read rcd_ts=%lu que_ts=%lu\n",hdr->ts, ts);
count++;
}
} else {
break;
}
data += region->entry_size;
idx++;
}
pos += read_n * region->entry_size;
remain_n -= read_n;
}
return count;
}
/* load event record from flash. */
uint8_t iot_brm_adp_evt_load(uint32_t ts, uint8_t start_inx, uint8_t cnt,
iot_pkt_t **pkt)
{
uint8_t count = 0;
uint8_t resp_cnt = 0;
uint32_t i, n_per, remain_n, read_n, pos, idx;
uint8_t *data;
uint8_t crc;
iot_brm_rec_head_t *hdr;
iot_pkt_t *buf = NULL;
uint8_t *data_pos = NULL;
iot_brm_rec_region_desc_t *region = &g_adp_evt_rcd_region;
buf = iot_pkt_alloc(sizeof(proto_645_ext_event_record_item_t) * cnt,
IOT_BRM_MID);
if (buf == NULL) {
goto err;
}
//read 1k Bytes data every time
n_per = IOT_BRM_ADP_REC_READ_BUF_SIZE / region->entry_size;
remain_n = region->rec_depth;
for (idx = 0, pos = region->start; remain_n; ) {
read_n = (remain_n >= n_per ? n_per : remain_n);
pos = region->start + idx * region->entry_size;
if (iot_brm_flash_read(pos, g_buf, read_n * region->entry_size)) {
goto err;
}
data = g_buf;
for (i = 0; i < read_n; i++) {
hdr = (iot_brm_rec_head_t *)data;
crc = iot_getcrc8(hdr->data, region->entry_size - sizeof(*hdr));
/* traverse all valid records */
if (crc == hdr->crc) {
//check
if (hdr->ts - ts > 0 && (hdr->ts - ts) < (60*60*24)){
count++;
if (count > start_inx && resp_cnt < cnt) {
iot_cus_printf("read rcd_ts=%lu que_ts=%lu\n",hdr->ts, ts);
data_pos = iot_pkt_data(buf) +
sizeof(proto_645_ext_event_record_item_t) * resp_cnt;
iot_brm_adp_trans_evt_to_resp((uint8_t*)hdr, data_pos);
iot_pkt_put(buf, sizeof(proto_645_ext_event_record_item_t));
resp_cnt++;
} else if (resp_cnt >= cnt) {
break;
}
}
} else {
break;
}
data += region->entry_size;
idx++;
}
pos += read_n * region->entry_size;
remain_n -= read_n;
}
iot_cus_printf("read cnt=%d\n", resp_cnt);
iot_brm_data_print("evt_load", iot_pkt_data(buf), iot_pkt_data_len(buf));
err:
if (resp_cnt == 0 && buf != NULL) {
iot_pkt_free(buf);
} else {
*pkt = buf;
}
return resp_cnt;
}
/* load the latest event record from flash. */
uint8_t iot_brm_adp_latest_evt_load(iot_pkt_t **pkt)
{
uint32_t ret = ERR_OK;
uint8_t *data;
uint8_t crc;
iot_brm_rec_head_t *hdr;
iot_pkt_t *buf = NULL;
uint32_t pos = 0;
iot_brm_rec_region_desc_t *region = &g_adp_evt_rcd_region;
buf = iot_pkt_alloc(sizeof(proto_645_ext_event_record_item_t), IOT_BRM_MID);
if (buf == NULL) {
iot_cus_printf("[brmadp]alloc pkt failed!\n");
ret = ERR_FAIL;
goto out;
}
pos = region->start + (region->new_idx - 1) * region->entry_size;
if (iot_brm_flash_read(pos, g_buf, region->entry_size)) {
ret = ERR_FAIL;
iot_cus_printf("[brmadp]read flash ERROR!\n");
goto out;
}
data = g_buf;
hdr = (iot_brm_rec_head_t *)data;
crc = iot_getcrc8(hdr->data, region->entry_size - sizeof(*hdr));
/* traverse all valid records */
if (crc == hdr->crc) {
iot_brm_adp_trans_evt_to_resp((uint8_t *)hdr, iot_pkt_data(buf));
iot_pkt_put(buf, sizeof(proto_645_ext_event_record_item_t));
} else {
iot_cus_printf("[brmadp]Event CRC err, dropped!\n");
}
iot_brm_data_print("latest evt_load", iot_pkt_data(buf),
iot_pkt_data_len(buf));
out:
*pkt = buf;
return ret;
}
/* get load record from flash. */
uint8_t iot_brm_adp_load_data(uint32_t ts, uint8_t cnt, iot_pkt_t **pkt)
{
uint8_t resp_cnt = 0, crc;
uint8_t *data;
uint16_t resp_idx = 0;
uint32_t i, n_per, remain_n, read_n, pos, idx;
iot_brm_rec_head_t *hdr;
iot_pkt_t *buf = NULL;
uint8_t *data_pos = NULL;
iot_brm_rec_region_desc_t *region = iot_brm_get_cur_reg();
buf = iot_pkt_alloc(sizeof(proto_645_ext_load_diagram_item_t) * cnt,
IOT_BRM_MID);
if (buf == NULL) {
goto err;
}
/* fill pkt */
iot_pkt_put(buf, sizeof(proto_645_ext_load_diagram_item_t) * cnt);
iot_brm_adp_load_resp_init(iot_pkt_data(buf), ts, cnt);
//read 1k Bytes data every time
n_per = IOT_BRM_ADP_REC_READ_BUF_SIZE / region->entry_size;
remain_n = region->rec_depth;
for (idx = 0, pos = region->start; remain_n; ) {
read_n = (remain_n >= n_per ? n_per : remain_n);
pos = region->start + idx * region->entry_size;
if (iot_brm_flash_read(pos, g_buf, read_n * region->entry_size)) {
goto err;
}
data = g_buf;
for (i = 0; i < read_n; i++) {
hdr = (iot_brm_rec_head_t *)data;
crc = iot_getcrc8(hdr->data, region->entry_size - sizeof(*hdr));
/* traverse all valid records */
if (crc == hdr->crc) {
/* check ts */
if (hdr->ts >= ts && ((hdr->ts - ts) % 15*60) == 0) {
resp_idx = (hdr->ts - ts) / 900;
if (resp_cnt >= cnt ) {
goto end;
} else if (resp_idx < cnt) {
iot_cus_printf("read ts=%lu que_ts=%lu resp_idx=%d\n",
hdr->ts, ts, resp_idx);
data_pos = iot_pkt_data(buf) +
sizeof(proto_645_ext_load_diagram_item_t) * resp_idx;
iot_brm_adp_trans_load_to_resp((uint8_t*)hdr, data_pos);
resp_cnt++;
}
}
} else {
break;
}
data += region->entry_size;
idx++;
}
pos += read_n * region->entry_size;
remain_n -= read_n;
}
end:
resp_cnt = cnt;
iot_cus_printf("read cnt=%d\n", resp_cnt);
iot_brm_data_print("resp_load", iot_pkt_data(buf), iot_pkt_data_len(buf));
err:
if (resp_cnt == 0 && buf != NULL) {
iot_pkt_free(buf);
} else {
*pkt = buf;
}
return resp_cnt;
}
/* sent the latest event record once joined the network */
static void iot_brm_adp_evt_send_at_join_in(void)
{
if (brm_adp_context.evt_on_join == 0) {
/* send the latest event record once sta joins in */
if (brm_adp_context.link_ready == 1) {
iot_brm_adp_event_report(NULL);
brm_adp_context.evt_on_join = 1;
}
}
}
/* update plc status: joined or not */
static void iot_brm_adp_plc_status_update(void)
{
uint16_t link_ready = 0;
link_ready = iot_brm_get_plc_state();
/* clear the event flag once sta leaves */
if (link_ready == 0) {
if (brm_adp_context.link_ready == 1) {
brm_adp_context.evt_on_join = 0;
}
}
if (brm_adp_context.link_ready != link_ready) {
brm_adp_context.link_ready = link_ready;
}
}
void iot_brm_adp_evt_region_init(void)
{
uint32_t start = IOT_BRM_ADP_EVT_REGION_START;
g_adp_evt_rcd_region.start = start;
g_adp_evt_rcd_region.entry_size = iot_brm_get_adp_evt_entry_size();
g_adp_evt_rcd_region.size =
g_adp_evt_rcd_region.entry_size * IOT_BRM_REC_ADP_EVT_MAX;
g_adp_evt_rcd_region.rec_depth = IOT_BRM_REC_ADP_EVT_MAX;
start += g_adp_evt_rcd_region.size;
iot_brm_printf("%s - rec_adp_evt_region: [%08x - %08x], block %lu, "
"entry_size %lu\n", __FUNCTION__,
g_adp_evt_rcd_region.start, start - 1,
g_adp_evt_rcd_region.rec_depth,
g_adp_evt_rcd_region.entry_size);
iot_brm_rec_load(&g_adp_evt_rcd_region, 0);
IOT_ASSERT(start <= IOT_BRM_ADP_EVT_REGION_END);
}
uint32_t iot_brm_adp_init(void)
{
uint32_t ret = ERR_OK;
os_mem_set(&brm_adp_context, 0x0, sizeof(brm_adp_context));
g_buf = os_mem_malloc(IOT_BRM_MID, IOT_BRM_ADP_REC_READ_BUF_SIZE);
if (g_buf == NULL) {
ret = ERR_NOMEM;
goto out;
}
/* Init device finite state machine. */
brm_adp_context.dev_fsm.prev_state = DM_STATE_DEV_OFFLINE;
brm_adp_context.dev_fsm.cur_state = DM_STATE_DEV_OFFLINE;
brm_adp_context.dev_fsm.table.handle = dev_fsm_handle_table;
/* Init adp record event */
iot_brm_adp_evt_region_init();
if (ERR_OK != iot_brm_adp_threshold_load()) {
brm_adp_context.threshold.p_trap = 20000; /* mW*/
brm_adp_context.threshold.i_standby = 10; /* ma*/
brm_adp_context.threshold.i_work = 500; /* ma*/
iot_cus_printf("[brmadp][war] load threshold failed, "
"use default threshold i_standby=%d i_work=%d p_trap=%d\n",
brm_adp_context.threshold.i_standby,
brm_adp_context.threshold.i_work,
brm_adp_context.threshold.p_trap);
iot_brm_adp_threshold_save(&brm_adp_context.threshold);
}
iot_brm_evt_init(iot_brm_evt_adp_id, NULL, 1);
iot_cus_printf("[brmadp] %s module ver:%s, init successfully!\n",
__FUNCTION__, BRM_ADP_MODULE_VERSION);
out:
return ret;
}
#endif /* end (IOT_BRM_ENABLE && PLC_SUPPORT_STA_ROLE) */