Browse Source

feat: add EC800K buffered TCP mode

test/at-buffer-mode
蔡享 1 month ago
parent
commit
e44d9e8322
  1. 168
      applications/VK_Client.c
  2. 48
      applications/VK_Com.c
  3. 3
      applications/VK_Com.h
  4. 282
      applications/drv_ec800k.c
  5. 34
      applications/drv_ec800k.h

168
applications/VK_Client.c

@ -31,6 +31,10 @@
static char cmd_cmd[128] = {0};
static uint8_t socket_tx_buffer[LTE_SOCKET_TX_CHUNK_SIZE];
static uint8_t socket_rx_buffer[LTE_SOCKET_RX_CHUNK_SIZE];
static rt_size_t socket_tx_pending = 0;
static rt_tick_t last_ack_query_tick = 0;
no_carrier_match_t _no_carrier_t = {0};
@ -39,6 +43,10 @@ void client_tcp_close(Cclient_t *client) {
char close_cmd[24];
client->connect_sta = false;
BSP_LTE_SetDataTxPaused(true);
BSP_LTE_ClearSocketEvents();
fmu_net_queue_reset();
socket_tx_pending = 0;
rt_snprintf(close_cmd, sizeof(close_cmd), AT_QICLOSE, client->connect_ID);
BSP_LTE_SendCmd(close_cmd, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_QICLOSE);
@ -149,6 +157,8 @@ static const char *disconnect_reason_name(lte_disconnect_reason_t reason) {
case LTE_DISC_AT_TIMEOUT: return "AT_TIMEOUT";
case LTE_DISC_QIOPEN_FAILED: return "QIOPEN_FAILED";
case LTE_DISC_MODULE_RESET: return "MODULE_RESET";
case LTE_DISC_SERVER_SILENCE: return "SERVER_SILENCE";
case LTE_DISC_SOCKET_SEND: return "SOCKET_SEND";
default: return "UNKNOWN";
}
}
@ -180,6 +190,15 @@ void lte_diag_disconnect(lte_disconnect_reason_t reason) {
lte_diag.fmu_rx_bytes, lte_diag.fmu_tx_bytes,
lte_diag.server_rx_bytes, lte_diag.server_rx_read_events,
lte_diag.server_silence_timeout_count);
LOG_I("[DISC] socket_tx=%u send_ok=%u send_fail=%u prompt_timeout=%u read_errors=%u",
lte_diag.socket_tx_bytes, lte_diag.socket_send_ok,
lte_diag.socket_send_fail, lte_diag.socket_prompt_timeouts,
lte_diag.socket_read_errors);
LOG_I("[DISC] acked=%u unacked=%u ack_queries=%u ack_errors=%u",
lte_diag.socket_acked_bytes, lte_diag.socket_unacked_bytes,
lte_diag.socket_ack_queries, lte_diag.socket_ack_errors);
LOG_I("[DISC] tx_queue_high=%u drops=%u",
lte_diag.tx_queue_high_water, lte_diag.tx_queue_drops);
LOG_I("[DISC] age_uart2_rx=%u age_uart2_tx=%u age_fmu_rx=%u age_server_rx=%u",
diag_age(now, lte_diag.last_uart2_rx_tick),
diag_age(now, lte_diag.last_uart2_tx_tick),
@ -211,11 +230,7 @@ int16_t EC800K_Reset(void) {
lte_dev.client1->connect_sta = false;
//lte_dev.client2->connect_sta = false;
rt_thread_mdelay(3000);
BSP_LTE_SendData((uint8_t *)"+++", 3);
rt_thread_mdelay(2000);
BSP_LTE_SendData((uint8_t *)"+++", 3);
rt_thread_mdelay(2000);
rt_thread_mdelay(1000);
uint8_t try_count = 5;
@ -261,9 +276,9 @@ int16_t client_tcp_connect(Cclient_t *client) {
BSP_LTE_InitLogClock();
//
BSP_LTE_SendCmd(AT_CFG_TRANS_SIZE, DEFAULT_EXPECT, DEFAULT_ERROR,
BSP_LTE_SendCmd(AT_CFG_RECV_IND, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL);
BSP_LTE_SendCmd(AT_CFG_TRANS_WAITTM, DEFAULT_EXPECT, DEFAULT_ERROR,
BSP_LTE_SendCmd(AT_QISDE0, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL);
BSP_LTE_SendCmd(AT_CFG_PASSIVE_CLOSED, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL);
@ -276,7 +291,7 @@ int16_t client_tcp_connect(Cclient_t *client) {
// 2, 打开链接
memset(cmd_cmd, 0, sizeof(cmd_cmd));
cmd_len = rt_snprintf(cmd_cmd, sizeof(cmd_cmd), AT_QIOPEN_TRANS,
cmd_len = rt_snprintf(cmd_cmd, sizeof(cmd_cmd), AT_QIOPEN_BUFFER,
client->connect_ID, client->mode, client->ip,
client->port);
if (cmd_len < 0 || cmd_len >= (int)sizeof(cmd_cmd)) {
@ -285,8 +300,7 @@ int16_t client_tcp_connect(Cclient_t *client) {
return -1;
}
/* 透传模式成功返回 CONNECT;一次尝试只发送一次 QIOPEN。 */
while (0 != BSP_LTE_SendCmd(cmd_cmd, CONNECTE_OK, DEFAULT_ERROR,
LTE_CMD_WAIT_QIOPEN)) {
while (0 != BSP_LTE_OpenSocket(cmd_cmd, client->connect_ID)) {
lte_diag.qioopen_failures++;
client_tcp_close(client);
#ifdef debug_mode
@ -305,8 +319,12 @@ int16_t client_tcp_connect(Cclient_t *client) {
#endif
}
client->connect_sta = true;
BSP_LTE_ClearSocketEvents();
fmu_net_queue_reset();
socket_tx_pending = 0;
BSP_LTE_SetDataTxPaused(false);
lte_diag_connect_success();
last_ack_query_tick = lte_diag.connect_tick;
client->error_cnt = 0;
lte_dev.reset_flag = DTU_CF_NO_NEED_RESET;
@ -323,7 +341,7 @@ int16_t client_tcp_connect(Cclient_t *client) {
mav_len = mavlink_msg_to_send_buffer(mav_buf, &msg);
for (int i = 0; i < 3; i++) {
BSP_LTE_SendData(mav_buf, mav_len);
BSP_LTE_SendSocketData(client->connect_ID, mav_buf, mav_len);
}
rt_device_t fmu_com = fmu_com_get();
if (fmu_com != RT_NULL) {
@ -334,11 +352,11 @@ int16_t client_tcp_connect(Cclient_t *client) {
rt_sprintf(buf, "{\"sn\":\"%s\",\"client_id\":\"%s\",\"csq\":\"%d\"}\r\n",
lte_dev.iccid, lte_dev.imei, lte_dev.csq);
BSP_LTE_SendData((uint8_t *)buf, sizeof(buf));
BSP_LTE_SendSocketData(client->connect_ID, (uint8_t *)buf, sizeof(buf));
BSP_LTE_SendData((uint8_t *)buf, sizeof(buf));
BSP_LTE_SendSocketData(client->connect_ID, (uint8_t *)buf, sizeof(buf));
BSP_LTE_SendData((uint8_t *)buf, sizeof(buf));
BSP_LTE_SendSocketData(client->connect_ID, (uint8_t *)buf, sizeof(buf));
//hw_printf(buf);
#endif
@ -350,37 +368,7 @@ int16_t client_tcp_connect(Cclient_t *client) {
static rt_tick_t last_rx_tick = 0;
#endif
/* Leave transparent mode only after the UART has been quiet for the
* required guard time. The caller keeps data_tx_paused asserted until the
* next successful QIOPEN. */
static bool client_exit_transparent_mode(CLte_dev_t *pLte_dev) {
rt_tick_t deadline;
rt_ssize_t len;
BSP_LTE_SetDataTxPaused(true);
rt_thread_mdelay(1000);
BSP_LTE_SendData((uint8_t *)"+++", 3);
rt_thread_mdelay(1000);
deadline = rt_tick_get() + 2000;
while ((rt_int32_t)(rt_tick_get() - deadline) < 0) {
if (pLte_dev->com_dev_rx_sem != RT_NULL) {
rt_sem_take(pLte_dev->com_dev_rx_sem, 100);
}
rt_memset(pLte_dev->at_buf, 0, sizeof(pLte_dev->at_buf));
len = rt_device_read(pLte_dev->com_dev, 0, pLte_dev->at_buf,
sizeof(pLte_dev->at_buf) - 1);
if (len > 0) {
lte_diag_uart2_rx((rt_size_t)len);
pLte_dev->at_buf[len] = '\0';
if (rt_strstr((const char *)pLte_dev->at_buf, DEFAULT_EXPECT) != RT_NULL) {
return true;
}
}
}
return false;
}
#if 0
void client_yield(CLte_dev_t *pLte_dev) {
while (1) {
if (pLte_dev->client1->connect_sta == true) {
@ -468,6 +456,96 @@ void client_yield(CLte_dev_t *pLte_dev) {
}
}
#endif
void client_yield(CLte_dev_t *pLte_dev) {
while (1) {
if (pLte_dev->client1->connect_sta == true) {
int16_t socket_result;
BSP_LTE_PollSocketUrc(20);
if (pLte_dev->socket_closed_pending) {
LOG_W("[URC] socket closed received");
lte_diag_disconnect(LTE_DISC_CLOSED);
client_tcp_close(pLte_dev->client1);
continue;
}
while (pLte_dev->socket_recv_pending &&
pLte_dev->client1->connect_sta) {
rt_device_t fmu_com;
int16_t read_length = BSP_LTE_ReadSocketData(
pLte_dev->client1->connect_ID, socket_rx_buffer,
sizeof(socket_rx_buffer));
if (read_length < 0) {
lte_diag_disconnect(pLte_dev->socket_closed_pending
? LTE_DISC_CLOSED
: LTE_DISC_AT_TIMEOUT);
client_tcp_close(pLte_dev->client1);
break;
}
if (read_length == 0) break;
lte_diag.server_rx_bytes += read_length;
lte_diag.server_rx_read_events++;
lte_diag.last_server_rx_tick = rt_tick_get();
#if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0
last_rx_tick = lte_diag.last_server_rx_tick;
#endif
fmu_com = fmu_com_get();
if (fmu_com != RT_NULL) {
rt_ssize_t written = rt_device_write(fmu_com, 0, socket_rx_buffer,
read_length);
if (written > 0) lte_diag_fmu_tx((rt_size_t)written);
}
if (read_length == sizeof(socket_rx_buffer))
pLte_dev->socket_recv_pending = true;
}
if (!pLte_dev->client1->connect_sta) continue;
if (socket_tx_pending == 0) {
socket_tx_pending = fmu_net_queue_get(socket_tx_buffer,
sizeof(socket_tx_buffer));
}
if (socket_tx_pending > 0) {
socket_result = BSP_LTE_SendSocketData(
pLte_dev->client1->connect_ID, socket_tx_buffer,
(uint16_t)socket_tx_pending);
if (socket_result == 0) {
socket_tx_pending = 0;
} else if (socket_result < 0) {
lte_diag_disconnect(LTE_DISC_SOCKET_SEND);
client_tcp_close(pLte_dev->client1);
continue;
} else {
rt_thread_mdelay(50);
}
}
if (rt_tick_get() - last_ack_query_tick >= RT_TICK_PER_SECOND * 5) {
last_ack_query_tick = rt_tick_get();
BSP_LTE_QuerySocketSendStatus(pLte_dev->client1->connect_ID);
}
#if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0
if (rt_tick_get() - last_rx_tick >
RT_TICK_PER_SECOND * LTE_SERVER_SILENCE_TIMEOUT_SEC) {
lte_diag.server_silence_timeout_count++;
LOG_W("server silence timeout, reconnect\n");
lte_diag_disconnect(LTE_DISC_SERVER_SILENCE);
client_tcp_close(pLte_dev->client1);
continue;
}
#endif
} else {
if (pLte_dev->reset_flag == DTU_CF_NEED_RESET) BSP_LTE_Config();
client_tcp_connect(pLte_dev->client1);
#if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0
last_rx_tick = rt_tick_get();
#endif
}
}
}
void client_task(void) {
client_yield(&lte_dev);

48
applications/VK_Com.c

@ -3,6 +3,7 @@
#include "drv_ec800k.h"
#include "rtdef.h"
#include "rtthread.h"
#include <ipc/ringbuffer.h>
#define ENABLE_MEMORY_USAGE_LOG 0
@ -15,6 +16,12 @@
rt_device_t fmu_com = RT_NULL;
rt_sem_t fmu_com_rx_sem = RT_NULL;
#define FMU_NET_QUEUE_SIZE 512
static struct rt_ringbuffer fmu_net_queue;
static struct rt_mutex fmu_net_queue_lock;
static uint8_t fmu_net_queue_pool[FMU_NET_QUEUE_SIZE];
static bool fmu_net_queue_ready = false;
#if ENABLE_MEMORY_USAGE_LOG
static rt_size_t thread_stack_used(rt_thread_t thread) {
rt_uint8_t *stack;
@ -69,9 +76,48 @@ int fmu_com_register(rt_device_t com_dev) {
rt_device_set_rx_indicate(fmu_com, fmu_com_rx_cb);
if (!fmu_net_queue_ready) {
rt_ringbuffer_init(&fmu_net_queue, fmu_net_queue_pool,
sizeof(fmu_net_queue_pool));
rt_mutex_init(&fmu_net_queue_lock, "fmuNet", RT_IPC_FLAG_PRIO);
fmu_net_queue_ready = true;
}
return 0;
}
rt_size_t fmu_net_queue_put(const uint8_t *data, rt_size_t length) {
rt_size_t queued;
rt_size_t used;
if (!fmu_net_queue_ready || data == RT_NULL || length == 0) return 0;
rt_mutex_take(&fmu_net_queue_lock, RT_WAITING_FOREVER);
queued = rt_ringbuffer_put(&fmu_net_queue, data, length);
used = rt_ringbuffer_data_len(&fmu_net_queue);
rt_mutex_release(&fmu_net_queue_lock);
if (queued < length) lte_diag.tx_queue_drops += length - queued;
if (used > lte_diag.tx_queue_high_water) lte_diag.tx_queue_high_water = used;
return queued;
}
rt_size_t fmu_net_queue_get(uint8_t *data, rt_size_t length) {
rt_size_t read;
if (!fmu_net_queue_ready || data == RT_NULL || length == 0) return 0;
rt_mutex_take(&fmu_net_queue_lock, RT_WAITING_FOREVER);
read = rt_ringbuffer_get(&fmu_net_queue, data, length);
rt_mutex_release(&fmu_net_queue_lock);
return read;
}
void fmu_net_queue_reset(void) {
if (!fmu_net_queue_ready) return;
rt_mutex_take(&fmu_net_queue_lock, RT_WAITING_FOREVER);
rt_ringbuffer_reset(&fmu_net_queue);
rt_mutex_release(&fmu_net_queue_lock);
}
/*接收到串口的数据,并将数据转发到网络端*/
void com_task(void) {
static uint8_t buff[128];
@ -90,7 +136,7 @@ void com_task(void) {
if (lte_dev.client1->connect_sta == true &&
lte_dev.data_tx_paused == false) {
/* 仅在客户端2连接时转发 */
BSP_LTE_SendData(buff, len);
fmu_net_queue_put(buff, len);
}
} else {
break;

3
applications/VK_Com.h

@ -15,6 +15,9 @@ void com_task(void);
rt_device_t fmu_com_get(void);
int fmu_com_register(rt_device_t com_dev);
rt_size_t fmu_net_queue_put(const uint8_t *data, rt_size_t length);
rt_size_t fmu_net_queue_get(uint8_t *data, rt_size_t length);
void fmu_net_queue_reset(void);
#ifdef __cplusplus
}

282
applications/drv_ec800k.c

@ -38,6 +38,116 @@ CLte_dev_t lte_dev = {
lte_diag_t lte_diag = {0};
static bool lte_log_clock_query_done = false;
static char socket_urc_line[80];
static rt_size_t socket_urc_line_len = 0;
static volatile bool socket_open_seen = false;
static volatile int16_t socket_open_result = -1;
static int parse_decimal(const char **text) {
int value = 0;
bool found = false;
const char *p = *text;
while (*p == ' ') p++;
while (*p >= '0' && *p <= '9') {
found = true;
value = value * 10 + (*p++ - '0');
}
*text = p;
return found ? value : -1;
}
static void lte_process_urc_line(const char *line) {
const char *p;
if (rt_strstr(line, "+QIURC:") != RT_NULL) {
if (rt_strstr(line, "\"recv\"") != RT_NULL) {
lte_dev.socket_recv_pending = true;
} else if (rt_strstr(line, "\"closed\"") != RT_NULL) {
lte_dev.socket_closed_pending = true;
}
}
p = rt_strstr(line, "+QIOPEN:");
if (p != RT_NULL) {
int connect_id;
int error;
p += rt_strlen("+QIOPEN:");
connect_id = parse_decimal(&p);
if (*p == ',') p++;
error = parse_decimal(&p);
if (connect_id == lte_dev.client1->connect_ID && error >= 0) {
socket_open_result = (int16_t)error;
socket_open_seen = true;
}
}
}
static void lte_process_text(const uint8_t *data, rt_size_t length) {
rt_size_t i;
for (i = 0; i < length; i++) {
uint8_t ch = data[i];
if (ch == '\r') continue;
if (ch == '\n') {
if (socket_urc_line_len > 0) {
socket_urc_line[socket_urc_line_len] = '\0';
lte_process_urc_line(socket_urc_line);
socket_urc_line_len = 0;
}
} else if (ch >= 0x20 && ch <= 0x7e) {
if (socket_urc_line_len < sizeof(socket_urc_line) - 1) {
socket_urc_line[socket_urc_line_len++] = (char)ch;
} else {
socket_urc_line_len = 0;
}
}
}
}
static rt_ssize_t lte_read_available(uint8_t *buffer, rt_size_t capacity) {
rt_ssize_t length = rt_device_read(lte_dev.com_dev, 0, buffer, capacity);
if (length > 0) lte_diag_uart2_rx((rt_size_t)length);
return length;
}
static void lte_drain_socket_input(void) {
rt_ssize_t length;
do {
length = lte_read_available(lte_dev.at_buf, sizeof(lte_dev.at_buf));
if (length > 0) lte_process_text(lte_dev.at_buf, (rt_size_t)length);
} while (length > 0);
while (rt_sem_take(lte_dev.com_dev_rx_sem, 0) == RT_EOK) { }
}
static int lte_wait_text(const char *success, const char *failure,
rt_tick_t timeout) {
rt_tick_t deadline = rt_tick_get() + timeout;
rt_size_t used = 0;
rt_memset(lte_dev.at_buf, 0, sizeof(lte_dev.at_buf));
while ((rt_int32_t)(rt_tick_get() - deadline) < 0) {
rt_ssize_t length;
rt_sem_take(lte_dev.com_dev_rx_sem, 50);
length = lte_read_available(lte_dev.at_buf + used,
sizeof(lte_dev.at_buf) - 1 - used);
if (length <= 0) continue;
lte_process_text(lte_dev.at_buf + used, (rt_size_t)length);
used += (rt_size_t)length;
lte_dev.at_buf[used] = '\0';
if (lte_dev.socket_closed_pending) return 1;
if (success != RT_NULL && rt_strstr((char *)lte_dev.at_buf, success)) return 0;
if ((failure != RT_NULL && rt_strstr((char *)lte_dev.at_buf, failure)) ||
rt_strstr((char *)lte_dev.at_buf, DEFAULT_ERROR)) return 1;
if (used >= sizeof(lte_dev.at_buf) - 1) {
rt_memcpy(lte_dev.at_buf, lte_dev.at_buf + used - 32, 32);
used = 32;
lte_dev.at_buf[used] = '\0';
}
}
return -1;
}
void lte_diag_at_begin(const char *cmd) {
rt_size_t i;
@ -135,6 +245,178 @@ void BSP_LTE_SetDataTxPaused(bool paused) {
}
}
void BSP_LTE_ClearSocketEvents(void) {
lte_dev.socket_recv_pending = false;
lte_dev.socket_closed_pending = false;
socket_open_seen = false;
socket_open_result = -1;
socket_urc_line_len = 0;
}
int16_t BSP_LTE_OpenSocket(const char *cmd, uint8_t connect_id) {
rt_tick_t deadline;
(void)connect_id;
lte_drain_socket_input();
socket_open_seen = false;
socket_open_result = -1;
lte_diag_at_begin(cmd);
LOG_I("%s", cmd);
BSP_LTE_SendData((uint8_t *)cmd, rt_strlen(cmd));
deadline = rt_tick_get() + LTE_CMD_WAIT_QIOPEN;
while ((rt_int32_t)(rt_tick_get() - deadline) < 0) {
rt_ssize_t length;
rt_sem_take(lte_dev.com_dev_rx_sem, 100);
length = lte_read_available(lte_dev.at_buf, sizeof(lte_dev.at_buf) - 1);
if (length > 0) {
lte_dev.at_buf[length] = '\0';
lte_process_text(lte_dev.at_buf, (rt_size_t)length);
if (rt_strstr((char *)lte_dev.at_buf, DEFAULT_ERROR)) {
lte_diag_at_end(1);
return 1;
}
}
if (socket_open_seen) {
LOG_I("[SOCKET] open result=%d", socket_open_result);
lte_diag_at_end(socket_open_result == 0 ? 0 : 1);
return socket_open_result == 0 ? 0 : 1;
}
}
lte_diag_at_end(-1);
return -1;
}
int16_t BSP_LTE_SendSocketData(uint8_t connect_id, const uint8_t *data,
uint16_t length) {
char command[32];
int result;
if (data == RT_NULL || length == 0 || length > 1460) return -1;
lte_drain_socket_input();
rt_snprintf(command, sizeof(command), AT_QISEND, connect_id, length);
BSP_LTE_SendData((uint8_t *)command, rt_strlen(command));
result = lte_wait_text(TPOK, DEFAULT_ERROR, LTE_CMD_WAIT_PROMPT);
if (result != 0) {
if (result < 0) lte_diag.socket_prompt_timeouts++;
lte_diag.socket_send_fail++;
return result < 0 ? -1 : 1;
}
BSP_LTE_SendData((uint8_t *)data, length);
result = lte_wait_text(QI_SEND_OK, QI_SEND_FAIL, LTE_CMD_WAIT_SEND);
if (result == 0) {
lte_diag.socket_tx_bytes += length;
lte_diag.socket_send_ok++;
return 0;
}
lte_diag.socket_send_fail++;
return result < 0 ? -1 : 1;
}
int16_t BSP_LTE_QuerySocketSendStatus(uint8_t connect_id) {
char command[24];
const char *p;
int total;
int acked;
int unacked;
lte_drain_socket_input();
rt_snprintf(command, sizeof(command), AT_QISEND, connect_id, 0);
BSP_LTE_SendData((uint8_t *)command, rt_strlen(command));
if (lte_wait_text("\r\nOK\r\n", DEFAULT_ERROR, LTE_CMD_WAIT_SEND) != 0) {
lte_diag.socket_ack_errors++;
return -1;
}
p = rt_strstr((char *)lte_dev.at_buf, "+QISEND:");
if (p == RT_NULL) {
lte_diag.socket_ack_errors++;
return -1;
}
p += rt_strlen("+QISEND:");
total = parse_decimal(&p);
if (*p == ',') p++;
acked = parse_decimal(&p);
if (*p == ',') p++;
unacked = parse_decimal(&p);
if (total < 0 || acked < 0 || unacked < 0) {
lte_diag.socket_ack_errors++;
return -1;
}
(void)total;
lte_diag.socket_acked_bytes = (rt_uint32_t)acked;
lte_diag.socket_unacked_bytes = (rt_uint32_t)unacked;
lte_diag.socket_ack_queries++;
return 0;
}
int16_t BSP_LTE_ReadSocketData(uint8_t connect_id, uint8_t *data,
uint16_t capacity) {
char command[32];
rt_tick_t deadline;
rt_size_t used = 0;
if (data == RT_NULL || capacity == 0 || capacity > LTE_SOCKET_RX_CHUNK_SIZE)
return -1;
lte_drain_socket_input();
lte_dev.socket_recv_pending = false;
rt_snprintf(command, sizeof(command), "AT+QIRD=%u,%u\r\n",
connect_id, capacity);
BSP_LTE_SendData((uint8_t *)command, rt_strlen(command));
rt_memset(lte_dev.at_buf, 0, sizeof(lte_dev.at_buf));
deadline = rt_tick_get() + LTE_CMD_WAIT_SEND;
while ((rt_int32_t)(rt_tick_get() - deadline) < 0) {
rt_ssize_t length;
char *header;
char *payload;
const char *number;
int payload_length;
rt_sem_take(lte_dev.com_dev_rx_sem, 50);
length = lte_read_available(lte_dev.at_buf + used,
sizeof(lte_dev.at_buf) - 1 - used);
if (length <= 0) continue;
used += (rt_size_t)length;
lte_dev.at_buf[used] = '\0';
header = rt_strstr((char *)lte_dev.at_buf, "+QIRD:");
if (header == RT_NULL) {
if (rt_strstr((char *)lte_dev.at_buf, "\"closed\"") != RT_NULL) {
lte_dev.socket_closed_pending = true;
return -1;
}
continue;
}
number = header + rt_strlen("+QIRD:");
payload_length = parse_decimal(&number);
payload = rt_strstr((char *)number, "\r\n");
if (payload_length < 0 || payload == RT_NULL) continue;
payload += 2;
if ((rt_size_t)(payload - (char *)lte_dev.at_buf) + payload_length + 6 > used)
continue;
if (payload_length > capacity) {
lte_diag.socket_read_errors++;
return -1;
}
if (header > (char *)lte_dev.at_buf)
lte_process_text(lte_dev.at_buf, (rt_size_t)(header - (char *)lte_dev.at_buf));
if (payload_length > 0) rt_memcpy(data, payload, payload_length);
lte_process_text((uint8_t *)payload + payload_length, 6);
return (int16_t)payload_length;
}
lte_diag.socket_read_errors++;
return -1;
}
void BSP_LTE_PollSocketUrc(uint32_t waittime) {
rt_ssize_t length;
if (rt_sem_take(lte_dev.com_dev_rx_sem, waittime) != RT_EOK) return;
do {
length = lte_read_available(lte_dev.at_buf, sizeof(lte_dev.at_buf));
if (length > 0) lte_process_text(lte_dev.at_buf, (rt_size_t)length);
} while (length > 0);
}
void BSP_LTE_InitLogClock(void) {
if (lte_log_clock_query_done) {
return;

34
applications/drv_ec800k.h

@ -88,6 +88,7 @@ extern "C" {
#define AT_TPCLOSE "+++\r\n"
#define AT_CIPSEND "AT+CIPSEND=%d,%d\r\n"
#define AT_QISEND "AT+QISEND=%d,%d\r\n"
#define AT_QISDE0 "AT+QISDE=0\r\n"
#define QI_SEND_OK "\r\nSEND OK\r\n"
#define QI_SEND_FAIL "\r\nSEND FAIL\r\n"
#define AT_CGMR "AT+CGMR\r\n"
@ -98,6 +99,8 @@ extern "C" {
#define AT_QIOPEN_TRANS \
"AT+QIOPEN=1,%d,\"%s\",\"%s\",%s,0,2\r\n" // transparent Mode
#define AT_QIOPEN_BUFFER \
"AT+QIOPEN=1,%d,\"%s\",\"%s\",%s,0,0\r\n" // buffer Mode
#define AT_QIOPEN_FORW \
"AT+QIOPEN=1,%d,\"%s\",\"%s\",%s,0,1\r\n" // Immediate Forwarding Mode
@ -199,6 +202,7 @@ extern "C" {
//AT CFG
#define AT_CFG_TRANS_SIZE "AT+QICFG=\"transpktsize\",512\r\n"
#define AT_CFG_TRANS_WAITTM "AT+QICFG=\"transwaittm\",0\r\n"
#define AT_CFG_RECV_IND "AT+QICFG=\"recvind\",1\r\n"
#define AT_CFG_PASSIVE_CLOSED "AT+QICFG=\"passiveclosed\",1\r\n"
#define AT_CFG_TCP_KEEPALIVE "AT+QICFG=\"tcp/keepalive\",1,30,25,3\r\n"
@ -206,9 +210,12 @@ extern "C" {
#define LTE_CMD_WAIT_QICLOSE (10000)
#define LTE_CMD_WAIT_QIACT (150000)
#define LTE_CMD_WAIT_QIDEACT (40000)
#define LTE_CMD_WAIT_PROMPT (3000)
#define LTE_CMD_WAIT_SEND (10000)
#define LTE_SOCKET_RX_CHUNK_SIZE (128)
#define LTE_SOCKET_TX_CHUNK_SIZE (256)
/* Set after confirming the server MAVLink heartbeat period. 0 disables the
* application-level silence recovery and leaves NO CARRIER/keepalive active. */
/* Set after confirming the server MAVLink heartbeat period. */
#define LTE_SERVER_SILENCE_TIMEOUT_SEC (15)
typedef struct {
@ -227,6 +234,8 @@ typedef enum {
LTE_DISC_AT_TIMEOUT,
LTE_DISC_QIOPEN_FAILED,
LTE_DISC_MODULE_RESET,
LTE_DISC_SERVER_SILENCE,
LTE_DISC_SOCKET_SEND,
} lte_disconnect_reason_t;
typedef struct {
@ -250,6 +259,17 @@ typedef struct {
rt_uint32_t server_rx_bytes;
rt_uint32_t server_rx_read_events;
rt_uint32_t server_silence_timeout_count;
rt_uint32_t socket_tx_bytes;
rt_uint32_t socket_send_ok;
rt_uint32_t socket_send_fail;
rt_uint32_t socket_prompt_timeouts;
rt_uint32_t socket_read_errors;
rt_uint32_t socket_acked_bytes;
rt_uint32_t socket_unacked_bytes;
rt_uint32_t socket_ack_queries;
rt_uint32_t socket_ack_errors;
rt_uint32_t tx_queue_drops;
rt_uint32_t tx_queue_high_water;
rt_tick_t last_uart2_rx_tick;
rt_tick_t last_uart2_tx_tick;
rt_tick_t last_fmu_rx_tick;
@ -299,6 +319,8 @@ typedef struct {
bool reset_flag;
bool dev_init_flag;
volatile bool data_tx_paused;
volatile bool socket_recv_pending;
volatile bool socket_closed_pending;
} CLte_dev_t;
extern CLte_dev_t lte_dev;
@ -320,6 +342,14 @@ void BSP_LTE_SetDataTxPaused(bool paused);
void BSP_LTE_Config(void);
void BSP_LTE_InitLogClock(void);
int16_t BSP_LTE_OpenSocket(const char *cmd, uint8_t connect_id);
int16_t BSP_LTE_SendSocketData(uint8_t connect_id, const uint8_t *data,
uint16_t length);
int16_t BSP_LTE_ReadSocketData(uint8_t connect_id, uint8_t *data,
uint16_t capacity);
int16_t BSP_LTE_QuerySocketSendStatus(uint8_t connect_id);
void BSP_LTE_PollSocketUrc(uint32_t waittime);
void BSP_LTE_ClearSocketEvents(void);
int BSP_LTE_GetICCID(char *pICCID);

Loading…
Cancel
Save