Files
kunlun/app/smart_grid/common/swc_lib/iot_swc_api.c
2024-09-28 14:24:04 +08:00

232 lines
6.5 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types_api.h"
/* common includes */
#include "iot_errno_api.h"
#include "iot_module_api.h"
#include "iot_utils_api.h"
#include "iot_ipc_api.h"
#include "iot_pkt_api.h"
#include "iot_swc_lib.h"
#include "iot_swc_api.h"
#include "iot_plc_msg_api.h"
/* swc lib internal includes */
#include "swc_lib_internal.h"
#if (IOT_SWC_ENABLE)
/* reserved length for swc mac header and other data in the front */
#define SWC_HEAD_RESERVE_LEN 64
/* reserved length for swc data in the end */
#define SWC_TAIL_RESERVE_LEN 4
iot_ipc_addr_t swc_stack_addr = {IOT_IPC_FID_SWC, IOT_IPC_CID_SWC_MAC};
iot_pkt_t *iot_plc_msdu_2_swc_msdu(iot_pkt_t *msdu)
{
uint32_t msdu_hdr_len;
uint32_t app_data_len;
uint8_t *app_data;
uint8_t *data_ptr = iot_pkt_block_ptr(msdu, IOT_PKT_BLOCK_DATA);
iot_plc_msg_header_t *plc_hdr = (iot_plc_msg_header_t *)data_ptr;
iot_plc_msdu_send_t *plc_msdu = (iot_plc_msdu_send_t*)(plc_hdr + 1);
msdu_hdr_len = sizeof(iot_plc_msg_header_t) + sizeof(iot_plc_msdu_send_t);
app_data_len = iot_pkt_data_len(msdu) - msdu_hdr_len;
app_data = data_ptr + msdu_hdr_len;
uint8_t msg_type = IOT_SWC_MSG_TYPE_BCAST;
if (plc_msdu->msg_type == IOT_PLC_MSG_TYPE_UNICAST) {
msg_type = IOT_SWC_MSG_TYPE_UNICAST;
}
iot_pkt_t *swc_pkt = iot_swc_alloc_msdu(msg_type, plc_msdu->dst,
plc_msdu->src, plc_msdu->lid, plc_msdu->len);
uint8_t *data_ptr2 = iot_pkt_block_ptr(swc_pkt, IOT_PKT_BLOCK_TAIL);
os_mem_cpy(data_ptr2, app_data, app_data_len);
iot_pkt_put(swc_pkt, app_data_len);
return swc_pkt;
}
uint8_t *swc_lib_prep_msg(iot_pkt_t *buf,
uint8_t msg_id, uint8_t req_id)
{
uint8_t *data;
iot_swc_msg_header_t *header;
data = iot_pkt_block_ptr(buf, IOT_PKT_BLOCK_DATA);
header = (iot_swc_msg_header_t *)data;
header->msg_id = msg_id;
header->req_id = req_id;
iot_pkt_put(buf, sizeof(*header));
data += sizeof(*header);
return data;
}
static iot_pkt_t *iot_swc_alloc_msdu_internal(uint8_t msg_type,
uint8_t *dst, uint8_t *src, uint8_t lid, uint16_t len,
uint8_t head_reserved_len, uint8_t tail_reserved_len)
{
(void)lid;
uint32_t size;
iot_pkt_t *buf = NULL;
iot_swc_msdu_send_t *send;
os_acquire_mutex(p_swc_lib->lock);
size = head_reserved_len + len + tail_reserved_len;
if (size > SWC_LIB_MSG_LONG_BUF_SIZE)
goto out;
buf = iot_pkt_alloc(size, IOT_SWC_LIB_MID);
if (buf) {
size = head_reserved_len - sizeof(iot_swc_msdu_send_t);
size -= sizeof(iot_swc_msg_header_t);
iot_pkt_reserve(buf, size);
send = (iot_swc_msdu_send_t *)swc_lib_prep_msg(buf,
IOT_SWC_MSG_MSDU_SEND, IOT_SWC_API_REQ_ID_DEFAULT);
send->msg_type = msg_type;
send->len = len;
send->lid = lid;
IOT_ASSERT(dst);
if (dst) {
iot_mac_addr_cpy(send->dst, dst);
}
IOT_ASSERT(src);
if (src) {
iot_mac_addr_cpy(send->src, src);
}
iot_pkt_put(buf, sizeof(*send));
} else {
IOT_ASSERT(0);
}
out:
os_release_mutex(p_swc_lib->lock);
return buf;
}
iot_pkt_t *iot_swc_alloc_msdu(uint8_t msg_type, uint8_t *dst,
uint8_t *src, uint8_t lid, uint16_t len)
{
iot_pkt_t *pkt = NULL;
pkt = iot_swc_alloc_msdu_internal(msg_type, dst, src, lid, len,
SWC_HEAD_RESERVE_LEN, SWC_TAIL_RESERVE_LEN);
return pkt;
}
void iot_swc_send_msdu(iot_pkt_t *pkt)
{
iot_pkt_t *tmp_pkt;
uint32_t size;
if (iot_pkt_tail_len(pkt) < SWC_TAIL_RESERVE_LEN) {
/* although we already reserved required tail len in
* iot_swc_alloc_msdu. it's possible that app won't follow
* the requested len strictly. try to allocate a larger packet
* to overcome the issue.
*/
size = iot_pkt_block_len(pkt, IOT_PKT_BLOCK_ALL);
size += SWC_TAIL_RESERVE_LEN - iot_pkt_tail_len(pkt);
tmp_pkt = iot_ipc_pkt_alloc(size, IOT_SWC_LIB_MID);
if (tmp_pkt == NULL) {
IOT_ASSERT(0);
iot_pkt_free(pkt);
return;
} else {
iot_pkt_cpy(tmp_pkt, pkt);
iot_pkt_free(pkt);
pkt = tmp_pkt;
}
}
iot_ipc_send(p_swc_lib->ipc_h, &swc_stack_addr, pkt);
return;
}
void iot_swc_send_plc_msdu(iot_pkt_t *pkt)
{
iot_pkt_t *swc_pkt;
if (pkt == NULL) {
return;
}
swc_pkt = iot_plc_msdu_2_swc_msdu(pkt);
iot_swc_send_msdu(swc_pkt);
iot_pkt_free(pkt);
}
void iot_swc_set_cfg(uint8_t req_id, uint8_t *addr,
uint8_t dev_type, uint8_t reset)
{
iot_pkt_t *buf;
iot_swc_cfg_set_req_t *set;
os_acquire_mutex(p_swc_lib->lock);
switch (dev_type) {
case IOT_SWC_DEV_TYPE_METER_CONTROLLER:
case IOT_SWC_DEV_TYPE_CONCENTRATOR:
case IOT_SWC_DEV_TYPE_POWER_METER:
case IOT_SWC_DEV_TYPE_REPEATER:
case IOT_SWC_DEV_TYPE_COLLECTOR_1:
case IOT_SWC_DEV_TYPE_COLLECTOR_2:
case IOT_SWC_DEV_TYPE_INVAL:
break;
default:
IOT_ASSERT(0);
goto drop;
}
buf = iot_ipc_pkt_alloc(SWC_LIB_MSG_SHORT_BUF_SIZE, IOT_SWC_LIB_MID);
if (buf == NULL) {
IOT_ASSERT(0);
goto drop;
}
/* prepare a iot_swc_MSG_CFG_SET_REQ message */
set = (iot_swc_cfg_set_req_t *)swc_lib_prep_msg(buf,
IOT_SWC_MSG_CFG_SET_REQ, req_id);
if (addr) {
iot_mac_addr_cpy(set->addr, addr);
} else {
os_mem_set(set->addr, 0, sizeof(set->addr));
}
set->dev_type = dev_type;
set->reset = reset;
iot_pkt_put(buf, sizeof(*set));
os_release_mutex(p_swc_lib->lock);
iot_ipc_send(p_swc_lib->ipc_h, &swc_stack_addr, buf);
return;
drop:
os_release_mutex(p_swc_lib->lock);
return;
}
#endif