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
 |