235 lines
6.7 KiB
C
235 lines
6.7 KiB
C
#include "ChargerTask.h"
|
||
|
||
static struct netconn *datalink_conn; // 数据链路句柄
|
||
#define LINK_SERVER_PORT 6001 // 网关UDP服务端口
|
||
#define LINK_STAKE_PORT 6001 // 桩通讯端口
|
||
|
||
/**
|
||
* @brief 桩IP地址
|
||
* @note 桩IP地址从10.12.19.101开始递增
|
||
*/
|
||
ip4_addr_t stake_ip_1 = IPADDR4_INIT_BYTES(10, 12, 19, 101); // 桩1IP地址
|
||
ip4_addr_t stake_ip_2 = IPADDR4_INIT_BYTES(10, 12, 19, 102); // 桩2IP地址
|
||
ip4_addr_t stake_ip_3 = IPADDR4_INIT_BYTES(10, 12, 19, 103); // 桩3IP地址
|
||
ip4_addr_t stake_ip_4 = IPADDR4_INIT_BYTES(10, 12, 19, 104); // 桩4IP地址
|
||
ip4_addr_t stake_ip_5 = IPADDR4_INIT_BYTES(10, 12, 19, 105); // 桩5IP地址
|
||
ip4_addr_t stake_ip_6 = IPADDR4_INIT_BYTES(10, 12, 19, 106); // 桩6IP地址
|
||
|
||
/**
|
||
* @brief UDP发送
|
||
* @note 发送数据到指定桩
|
||
* @param stake_index 目标桩ID
|
||
* @param data 数据指针
|
||
* @param len 数据长度
|
||
* @return err_t 错误码
|
||
*/
|
||
err_t udp_send_response(uint8_t stake_index, uint8_t *data, u16_t len)
|
||
{
|
||
struct netbuf *buf = netbuf_new();
|
||
if (!buf)
|
||
{
|
||
printf("[%s] %d\n", __func__, __LINE__);
|
||
return ERR_MEM;
|
||
}
|
||
ip4_addr_t *dst_ip = NULL;
|
||
switch (stake_index)
|
||
{
|
||
case 1:
|
||
dst_ip = &stake_ip_1;
|
||
break;
|
||
case 2:
|
||
dst_ip = &stake_ip_2;
|
||
break;
|
||
case 3:
|
||
dst_ip = &stake_ip_3;
|
||
break;
|
||
case 4:
|
||
dst_ip = &stake_ip_4;
|
||
break;
|
||
case 5:
|
||
dst_ip = &stake_ip_5;
|
||
break;
|
||
case 6:
|
||
dst_ip = &stake_ip_6;
|
||
break;
|
||
default:
|
||
printf("Invalid stake index\r\n");
|
||
return;
|
||
}
|
||
netbuf_ref(buf, data, len);
|
||
err_t err = netconn_sendto(datalink_conn, buf, dst_ip, LINK_STAKE_PORT);
|
||
netbuf_delete(buf);
|
||
return err;
|
||
}
|
||
|
||
void UDP_ParseTask_Function(void const *argument)
|
||
{
|
||
UdpMsg_t msg;
|
||
cJSON *root = NULL, *cmd = NULL, *id = NULL;
|
||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); /* 等待桩通讯协议层完成*/
|
||
while (1)
|
||
{
|
||
if (xQueueReceive(UDP_Message_Queue, &msg, portMAX_DELAY) == pdPASS)
|
||
{
|
||
root = cJSON_Parse((const char *)msg.data);
|
||
if (root == NULL)
|
||
{
|
||
printf("JSON Parse Failed: %s\r\n", msg.data);
|
||
vPortFree(msg.data);
|
||
continue;
|
||
}
|
||
id = cJSON_GetObjectItem(root, "id");
|
||
cmd = cJSON_GetObjectItem(root, "cmd");
|
||
|
||
if (cmd != NULL && id != NULL)
|
||
{
|
||
const char *cmd_str = cmd->valuestring;
|
||
handle_udp_downlink((uint8_t)id->valueint, cmd_str, root);
|
||
cJSON_Delete(root);
|
||
}
|
||
else
|
||
{
|
||
printf("Missing 'code' field\r\n");
|
||
cJSON_Delete(root);
|
||
}
|
||
vPortFree(msg.data);
|
||
msg.data = NULL;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief UPLinkTask_Function:桩通讯任务
|
||
*
|
||
* @note none
|
||
*
|
||
* @param taskID : 任务ID
|
||
*
|
||
* @retval runtime : 任务周期
|
||
*/
|
||
|
||
void UDPTask_Function(void const *argument)
|
||
{
|
||
err_t recv_err;
|
||
struct netbuf *datalink_buf = NULL;
|
||
datalink_conn = netconn_new(NETCONN_UDP);
|
||
netconn_bind(datalink_conn, IP_ADDR_ANY, LINK_SERVER_PORT);
|
||
UDP_Message_Queue_Init(); // 初始化UDP接收队列
|
||
/*桩UDP通讯初始化完成 发送云快充任务通知*/
|
||
xTaskNotifyGive(YkcTaskHandle);
|
||
xTaskNotifyGive(DownLinkTaskHandle);
|
||
xTaskNotifyGive(UDP_ParseTaskHandle);
|
||
|
||
while (1)
|
||
{
|
||
/*获取任务运行状态*/
|
||
TaskRunTimeStat.UPLinkTask.threads_runtime = GetTask_RunTime(UPLinkTaskID);
|
||
TaskRunTimeStat.UPLinkTask.threads_counter = GetTask_Beatcnt(UPLinkTaskID);
|
||
TaskRunTimeStat.UPLinkTask.threads_freestack = Get_Free_Stack(UPLinkTaskID);
|
||
|
||
recv_err = netconn_recv(datalink_conn, &datalink_buf);
|
||
|
||
if (recv_err == ERR_OK && datalink_buf != NULL)
|
||
{
|
||
uint8_t *playload;
|
||
uint16_t playload_len;
|
||
netbuf_data(datalink_buf, (void *)&playload, &playload_len);
|
||
if (playload_len > 0)
|
||
{
|
||
UdpMsg_t msg;
|
||
ip_addr_copy(msg.src_ip, *netbuf_fromaddr(datalink_buf)); // 获取UDP源IP
|
||
msg.src_port = netbuf_fromport(datalink_buf); // 获取UDP源端口
|
||
msg.len = playload_len;
|
||
msg.data = (char *)pvPortMalloc(playload_len + 1);
|
||
if (msg.data != NULL)
|
||
{
|
||
memcpy(msg.data, playload, playload_len);
|
||
msg.data[playload_len] = '\0';
|
||
if (xQueueSend(UDP_Message_Queue, &msg, 0) != pdPASS)
|
||
{
|
||
vPortFree(msg.data);
|
||
}
|
||
}
|
||
}
|
||
netbuf_delete(datalink_buf); // 释放UDP网络缓冲区
|
||
}
|
||
else
|
||
{
|
||
if (recv_err != ERR_TIMEOUT && recv_err != ERR_WOULDBLOCK)
|
||
{
|
||
printf("datalink netconn_recv err: %d\r\n", recv_err);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 解析充电桩上电指令
|
||
* @note 设置桩为本地在线状态,发送上电应答
|
||
* @param stake_index 桩索引
|
||
* @param json_pack json数据包
|
||
*/
|
||
void local_on_cmd_callback_power_on(uint8_t stake_index, cJSON *json_pack)
|
||
{
|
||
if (stake_index > 6)
|
||
{
|
||
return;
|
||
}
|
||
g_charger_manager.charger_piles[stake_index - 1].is_udp_online = true; // 设置桩为本地在线状态
|
||
|
||
cJSON *root = NULL;
|
||
char *str = NULL;
|
||
|
||
root = cJSON_CreateObject();
|
||
if (root == NULL)
|
||
{
|
||
printf("Failed to create JSON object for stake %d\r\n", stake_index);
|
||
return;
|
||
}
|
||
|
||
/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
|
||
cJSON_AddNumberToObject(root, "id", stake_index);
|
||
cJSON_AddStringToObject(root, "cmd", "power_on");
|
||
cJSON_AddNumberToObject(root, "code", 1);
|
||
|
||
str = cJSON_Print(root);
|
||
udp_send_response(stake_index, str, strlen(str));
|
||
free(str);
|
||
cJSON_Delete(root);
|
||
|
||
printf("电桩 %d 上电报文\r\n", stake_index);
|
||
}
|
||
|
||
/**
|
||
* @brief 解析充电桩计费模型请求指令
|
||
* @note 获取云快充下发的计费模型,回复给充电桩
|
||
* @param stake_index 桩索引
|
||
* @param json_pack json数据包
|
||
*/
|
||
void local_on_cmd_callback_get_billing_model(uint8_t stake_index, cJSON *json_pack)
|
||
{
|
||
if (stake_index > 6)
|
||
{
|
||
return;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
void handle_udp_downlink(uint8_t id, const char *cmd, cJSON *json_pack)
|
||
{
|
||
if (cmd == NULL)
|
||
return;
|
||
if (strcmp(cmd, "power_on") == 0)
|
||
{
|
||
local_on_cmd_callback_power_on(id, json_pack);
|
||
}
|
||
else if (strcmp(cmd, "get_billing_model") == 0)
|
||
{
|
||
local_on_cmd_callback_get_billing_model(id, json_pack);
|
||
}
|
||
else
|
||
{
|
||
printf("Unknown CMD: '%s' from ID %d\r\n", cmd, id);
|
||
}
|
||
} |