232 lines
6.5 KiB
C
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
|