Files
kunlun/app/sg_ctrl/iot_sg_ctrl_gw_app.c
2024-09-28 14:24:04 +08:00

375 lines
11 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* iot common header files */
#include "iot_io_api.h"
#include "iot_pkt_api.h"
/* smart grid internal header files */
#include "proto_gw_app.h"
#include "iot_sg_ctrl.h"
#if (IOT_SG_CONTROLLER_ENABLE && IOT_GW_CTRL_APP_ENABLE)
void iot_sg_ctrl_gw_read_meter(uint8_t *data, uint16_t datalen,
uint16_t sn)
{
iot_pkt_t *plc_pkt;
uint16_t total_size;
uint8_t *pkt_data;
gw_app_meter_r_ul_t *meter_read_hdr;
gw_app_header_t *app_hdr;
total_size = sizeof(*app_hdr) + sizeof(*meter_read_hdr) + datalen;
plc_pkt = iot_plc_alloc_ctrl_proto_msdu(sg_ctrl_global->app_handle,
NULL, sg_ctrl_global->local_mac_addr,
GW_APP_PRIO_METER_READ, total_size, IOT_PLC_MAX_RETRY_CNT);
IOT_ASSERT(plc_pkt);
pkt_data = iot_pkt_block_ptr(plc_pkt, IOT_PKT_BLOCK_TAIL);
/* fill in header */
app_hdr = (gw_app_header_t *)pkt_data;
app_hdr->id = GW_APP_ID_CONCENTRATOR_METER_R;
app_hdr->port = GW_APP_PORT_OTHER;
app_hdr->control = 0;
meter_read_hdr = (gw_app_meter_r_ul_t *)(app_hdr + 1);
meter_read_hdr->ver = GW_APP_VERSION;
meter_read_hdr->header_len = sizeof(*meter_read_hdr);
meter_read_hdr->seq = sn;
meter_read_hdr->data_type = GW_APP_DATA_TYPE_TRANSPARENT;
meter_read_hdr->data_len = datalen;
meter_read_hdr->ack_status = 0;
meter_read_hdr->option = 0;
os_mem_cpy(meter_read_hdr->data, data, datalen);
iot_pkt_put(plc_pkt, total_size);
iot_plc_send_msdu(sg_ctrl_global->app_handle, plc_pkt);
return ;
}
void iot_sg_ctrl_gw_get_id_info(uint8_t id_type, uint16_t sn, uint8_t qr_cnt)
{
uint8_t *data_ptr;
iot_pkt_t *plc_pkt;
gw_app_header_t *app_hdr;
gw_app_query_module_id_dl_t *query_data;
uint16_t total_size = sizeof(*app_hdr) + sizeof(*query_data);
total_size = sizeof(*app_hdr) + sizeof(*query_data);
plc_pkt = iot_plc_alloc_ctrl_proto_msdu(sg_ctrl_global->app_handle,
NULL, sg_ctrl_global->local_mac_addr,
GW_APP_PRIO_METER_READ, total_size, IOT_PLC_MAX_RETRY_CNT);
IOT_ASSERT(plc_pkt);
data_ptr = iot_pkt_block_ptr(plc_pkt, IOT_PKT_BLOCK_TAIL);
app_hdr = (gw_app_header_t *)data_ptr;
app_hdr->id = GW_APP_ID_QUERY_MODULE_ID_INFO;
app_hdr->port = GW_APP_PORT_OTHER;
app_hdr->control = GW_APP_CONTROL;
query_data = (gw_app_query_module_id_dl_t *)(app_hdr + 1);
query_data->ver = GW_APP_VERSION;
query_data->header_len = sizeof(*query_data);
query_data->dir = 0;
query_data->seq = sn;
if (id_type == 1) {
query_data->id_type = GW_APP_ID_INFO_TYPE_CHIP;
} else {
if (qr_cnt & 0x01) {
query_data->id_type = GW_APP_ID_INFO_TYPE_MOD;
} else {
query_data->id_type = GW_APP_ID_INFO_TYPE_MOD_EXT;
}
}
iot_pkt_put(plc_pkt, total_size);
iot_plc_send_msdu(sg_ctrl_global->app_handle, plc_pkt);
}
static void iot_sg_ctrl_gw_handle_sta_read_meter_data(gw_app_header_t *app_hdr,
uint32_t app_len)
{
gw_app_meter_r_ul_t *meter_read_hdr;
uint16_t app_sn;
uint8_t reason = 0;
info_pool_t *info_pool = &sg_ctrl_global->info_pool;
meter_read_hdr = (gw_app_meter_r_ul_t *)(app_hdr + 1);
if (app_len < sizeof(*meter_read_hdr)) {
reason = 1;
goto out;
}
app_len = app_len - sizeof(*meter_read_hdr);
if (app_len < meter_read_hdr->data_len ) {
reason = 2;
goto out;
}
if (meter_read_hdr->ver != GW_APP_VERSION) {
reason = 3;
goto out;
}
if (meter_read_hdr->data_type != GW_APP_DATA_TYPE_TRANSPARENT) {
reason = 4;
goto out;
}
app_sn = meter_read_hdr->seq;
if (false == iot_sg_ctrl_pool_sn_exist(info_pool, app_sn, true)) {
reason = 5;
goto out;
}
if (iot_sg_ctrl_ul_sn_exist(app_sn)) {
reason = 6;
goto out;
}
out:
if (reason) {
iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__,
reason);
} else {
iot_sg_ctrl_rpt_sta_data(meter_read_hdr->data,
(uint16_t)meter_read_hdr->data_len, IOT_CTRL_EVENT_METER_DATA);
}
}
static void iot_sg_ctrl_gw_handle_sta_id_info(gw_app_header_t *app_hdr,
uint32_t len)
{
info_pool_t *info_pool = &sg_ctrl_global->info_pool;
gw_app_query_chip_id_ul_t *rpt_chip_id;
gw_app_query_module_id_ul_t *rpt =
(gw_app_query_module_id_ul_t *)(app_hdr + 1);
uint8_t reason = 0;
if (len < sizeof(*rpt)) {
reason = 1;
goto err;
}
if (rpt->dir != 1) {
reason = 2;
goto err;
}
if (false == iot_sg_ctrl_pool_sn_exist(info_pool, rpt->seq, true)) {
reason = 3;
goto err;
}
if (iot_sg_ctrl_ul_sn_exist(rpt->seq)) {
reason = 4;
goto err;
}
if (rpt->id_type == GW_APP_ID_INFO_TYPE_CHIP) {
rpt_chip_id = (gw_app_query_chip_id_ul_t *)(app_hdr + 1);
if (len < sizeof(*rpt_chip_id)) {
reason = 5;
goto err;
}
if (rpt_chip_id->chip_id_len > GW_APP_CHIP_ID_INFO_LEN) {
reason = 6;
goto err;
}
iot_sg_ctrl_id_info_rpt(rpt_chip_id->chip_info,
rpt_chip_id->chip_id_len, PROTO_CTRL_ID_INFO_TYPE_CHIP,
rpt_chip_id->dev_type);
} else {
if (rpt->module_id_len > GW_APP_MODULE_ID_INFO_LEN) {
reason = 7;
goto err;
}
iot_sg_ctrl_id_info_rpt(rpt->module_info, rpt->module_id_len,
PROTO_CTRL_ID_INFO_TYPE_MODULE, rpt->dev_type);
}
err:
iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__, reason);
}
void iot_sg_ctrl_gw_handle_sta_app_data(iot_pkt_t *pkt)
{
uint32_t pkt_len;
gw_app_header_t *app_hdr;
uint8_t reason = 0;
app_hdr = (gw_app_header_t *)iot_pkt_data(pkt);
pkt_len = (uint16_t)iot_pkt_block_len(pkt, IOT_PKT_BLOCK_DATA);
if (pkt_len <= sizeof(*app_hdr)) {
reason = 1;
goto out;
}
if (app_hdr->port != GW_APP_PORT_OTHER) {
iot_cus_printf("WARNING: %s drop invalid gw app data\n", __FUNCTION__);
reason = 2;
goto out;
}
switch (app_hdr->id) {
case GW_APP_ID_CONCENTRATOR_METER_R:
{
iot_sg_ctrl_gw_handle_sta_read_meter_data(app_hdr,
pkt_len - sizeof(*app_hdr));
}
break;
case GW_APP_ID_QUERY_MODULE_ID_INFO:
{
iot_sg_ctrl_gw_handle_sta_id_info(app_hdr, pkt_len - sizeof(*app_hdr));
}
break;
default:
reason = 3;
break;
}
out:
if (reason) {
iot_cus_printf("%s : drop req , reason %lu \n", __FUNCTION__, reason);
}
iot_pkt_free(pkt);
}
void iot_sg_ctrl_gw_handle_cco_app_data(iot_pkt_t *pkt)
{
gw_app_header_t *app_hdr;
gw_app_ctrl_proto_t *rsp = NULL;
info_pool_t *info_pool = &sg_ctrl_global->info_pool;
uint8_t app_sn = 0;
uint8_t *pkt_data;
uint32_t pkt_len;
uint8_t reason = 0;
pkt_data = iot_pkt_data(pkt);
app_hdr = (gw_app_header_t *)pkt_data;
pkt_len = iot_pkt_block_len(pkt, IOT_PKT_BLOCK_DATA);
if (pkt_len <= sizeof(*app_hdr)) {
reason = 1;
goto out;
}
pkt_len = pkt_len - sizeof(*app_hdr);
switch (app_hdr->id) {
case GW_APP_ID_CTRL_PROTO:
{
rsp = (gw_app_ctrl_proto_t *)(app_hdr + 1);
if (pkt_len < sizeof(*rsp)) {
reason = 2;
goto out;
}
pkt_len = pkt_len - sizeof(*rsp);
if (pkt_len < rsp->data_len) {
reason = 3;
goto out;
}
if (rsp->proto_type != GW_APP_CTRL_PROTO_3762) {
reason = 4;
goto out;
}
break;
}
default:
reason = 5;
goto out;
}
if (iot_sg_ctrl_get_ckq_data_sn((uint8_t *)(rsp + 1), &app_sn)) {
if (iot_sg_ctrl_ul_sn_exist(app_sn)) {
reason = 6;
goto out;
}
} else if (false == iot_sg_ctrl_pool_sn_exist(info_pool, app_sn, true)) {
reason = 7;
}
out:
if ((!reason) && rsp) {
iot_pkt_set_data(pkt, rsp->data);
iot_pkt_set_tail(pkt, rsp->data + rsp->data_len);
iot_sg_ctrl_rpt_cco_data(pkt);
} else {
iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__,
reason);
iot_pkt_free(pkt);
}
return;
}
void iot_sg_ctrl_gw_send_data_to_cco(uint8_t *data, uint16_t len)
{
gw_app_header_t *app_hdr;
gw_app_ctrl_proto_t *ctrl_hdr;
iot_pkt_t *plc_pkt;
uint8_t *pkt_data;
uint16_t total_size;
total_size = sizeof(*app_hdr) + sizeof(*ctrl_hdr) + len;
plc_pkt = iot_plc_alloc_ctrl_proto_msdu(sg_ctrl_global->app_handle,
NULL, sg_ctrl_global->local_mac_addr,
GW_APP_PRIO_METER_READ, total_size, IOT_PLC_MAX_RETRY_CNT);
IOT_ASSERT(plc_pkt);
pkt_data = iot_pkt_block_ptr(plc_pkt, IOT_PKT_BLOCK_TAIL);
/* fill in header */
app_hdr = (gw_app_header_t *)pkt_data;
app_hdr->id = GW_APP_ID_CTRL_PROTO;
app_hdr->port = GW_APP_PORT_OTHER;
app_hdr->control = 0;
ctrl_hdr = (gw_app_ctrl_proto_t *)(app_hdr + 1);
ctrl_hdr->proto_type = GW_APP_CTRL_PROTO_3762;
ctrl_hdr->data_len = len;
os_mem_cpy(ctrl_hdr->data, data, len);
iot_pkt_put(plc_pkt, total_size);
iot_plc_send_msdu(sg_ctrl_global->app_handle, plc_pkt);
return;
}
#else /* IOT_SG_CONTROLLER_ENABLE && IOT_GW_APP_ENABLE */
void iot_sg_ctrl_gw_read_meter(uint8_t *data, uint16_t datalen,
uint16_t sn)
{
(void)data;
(void)datalen;
(void)sn;
}
void iot_sg_ctrl_gw_get_id_info(uint8_t id_type, uint16_t sn, uint8_t qr_cnt)
{
(void)id_type;
(void)sn;
(void)qr_cnt;
}
void iot_sg_ctrl_gw_handle_sta_app_data(iot_pkt_t *pkt)
{
(void)pkt;
}
void iot_sg_ctrl_gw_handle_cco_app_data(iot_pkt_t *pkt)
{
(void)pkt;
}
void iot_sg_ctrl_gw_send_data_to_cco(uint8_t *data, uint16_t len)
{
(void)data;
(void)len;
}
#endif /* IOT_SG_CONTROLLER_ENABLE && IOT_GW_APP_ENABLE */