2024-12-30 11:50:48 +08:00
|
|
|
|
/*
|
|
|
|
|
* @Author : stark1898y 1658608470@qq.com
|
|
|
|
|
* @Date : 2024-09-04 13:33:49
|
|
|
|
|
* @LastEditors: mbw && 1600520629@qq.com
|
2025-01-25 14:11:51 +08:00
|
|
|
|
* @LastEditTime: 2025-01-25 13:38:31
|
2025-01-10 09:52:43 +08:00
|
|
|
|
* @FilePath: \JT-DT-YD4N02A_RTT_MRS-NT26K\bsp\src\at_device_nt26k.c
|
2024-12-30 11:50:48 +08:00
|
|
|
|
* @Description :
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 2024 by yzy, All Rights Reserved.
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*
|
|
|
|
|
* Change Logs:
|
|
|
|
|
* Date Author Notes
|
|
|
|
|
* 2019-12-13 qiyongzhong first version
|
|
|
|
|
*/
|
2025-01-08 11:43:58 +08:00
|
|
|
|
// #include <stdio.h>
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#include <string.h>
|
|
|
|
|
#include "bsp_flash.h"
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#include <at_device_nt26k.h>
|
|
|
|
|
#include "bsp_nt26k.h"
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#include "user_sys.h"
|
|
|
|
|
#include "bsp_rtc.h"
|
|
|
|
|
#include "bsp_led.h"
|
|
|
|
|
#include "bsp_rng.h"
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#define LOG_TAG "at.dev.nt26k"
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#include <at_log.h>
|
|
|
|
|
|
|
|
|
|
#include "pin.h"
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#if IOT_MODULE_SWITCH == 1
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_POWER_OFF RT_FALSE
|
|
|
|
|
#define NT26K_POWER_ON RT_TRUE
|
|
|
|
|
#define NT26K_POWER_ON_TIME 3
|
|
|
|
|
#define NT26K_POWER_OFF_TIME 4
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#define AT_CLIENT_RECV_BUFF_LEN 512
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define AT_DEFAULT_TIMEOUT 5000
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#ifdef AT_DEVICE_USING_NT26K
|
|
|
|
|
#define NT26K_WAIT_CONNECT_TIME 5000
|
|
|
|
|
#define NT26K_THREAD_STACK_SIZE 4096
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 2)
|
2024-12-30 18:04:47 +08:00
|
|
|
|
|
2024-12-30 11:50:48 +08:00
|
|
|
|
char data_buf[AT_CLIENT_RECV_BUFF_LEN] = {0};
|
2024-12-31 17:48:22 +08:00
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k_sys_info nt26k = {0};
|
|
|
|
|
struct rt_completion nt26k_init_complate;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
volatile rt_uint8_t socket_id = 0;
|
|
|
|
|
|
2025-01-08 11:43:58 +08:00
|
|
|
|
// 将本地时间转换为对应时区时间
|
2025-01-17 13:23:16 +08:00
|
|
|
|
void Time_Zone_Conversion(TsRtcDateTime *timeInfo)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-08 11:43:58 +08:00
|
|
|
|
// 根据时区差异进行转换,这里时区差为8小时,没有分钟差异。
|
2025-01-17 13:23:16 +08:00
|
|
|
|
timeInfo->hour += RT_LIBC_DEFAULT_TIMEZONE; // 小时部分加8小时
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (timeInfo->hour >= 24)
|
2025-01-17 13:23:16 +08:00
|
|
|
|
{ // 如果超过24小时,则天数加1,小时数减24。
|
2025-01-08 11:43:58 +08:00
|
|
|
|
timeInfo->day++;
|
|
|
|
|
timeInfo->hour -= 24;
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (timeInfo->day > 365)
|
|
|
|
|
{
|
2025-01-08 11:43:58 +08:00
|
|
|
|
timeInfo->year += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_err_t Nt26k_Reset(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_I("NT26K Reset");
|
|
|
|
|
rt_pin_mode(NT26K_RST_PIN, PIN_MODE_OUTPUT);
|
|
|
|
|
rt_pin_write(NT26K_RST_PIN, PIN_LOW);
|
|
|
|
|
rt_thread_mdelay(10);
|
|
|
|
|
rt_pin_write(NT26K_RST_PIN, PIN_HIGH);
|
|
|
|
|
rt_thread_mdelay(50);
|
|
|
|
|
rt_pin_write(NT26K_RST_PIN, PIN_LOW);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_power_on(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
struct at_device_nt26k *nt26k = RT_NULL;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-15 09:56:50 +08:00
|
|
|
|
nt26k = (struct at_device_nt26k *)device->user_data;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_pin_write(nt26k->pwr_en_pin, PIN_LOW);
|
|
|
|
|
rt_thread_mdelay(10);
|
|
|
|
|
rt_pin_write(nt26k->pwr_en_pin, PIN_HIGH);
|
|
|
|
|
|
|
|
|
|
return device->class->device_ops->control(device, AT_DEVICE_CTRL_WAKEUP, RT_NULL);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static rt_err_t nt26k_power_off(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
struct at_device_nt26k *nt26k = RT_NULL;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
nt26k = (struct at_device_nt26k *)device->user_data;
|
2025-01-17 10:41:37 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device->class->device_ops->control(device, AT_DEVICE_RF_CLOSE, RT_NULL);
|
2025-01-17 10:41:37 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_pin_write(nt26k->pwr_en_pin, PIN_LOW);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static rt_err_t nt26k_Close_Rf(struct at_device *device)
|
2025-01-17 10:41:37 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_response_t resp = at_create_resp(64, 0, rt_tick_from_millisecond(60000));
|
2025-01-17 10:41:37 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("no memory for resp create.");
|
|
|
|
|
at_delete_resp(resp);
|
2025-01-17 10:41:37 +08:00
|
|
|
|
return (-RT_ERROR);
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+QPOWD=1") == RT_EOK)
|
2025-01-17 10:41:37 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_get_line_by_kw(resp, "POWERED DOWN") != RT_NULL)
|
|
|
|
|
{
|
|
|
|
|
at_delete_resp(resp);
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
2025-01-17 10:41:37 +08:00
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2025-01-17 10:41:37 +08:00
|
|
|
|
return (-RT_ERROR);
|
|
|
|
|
}
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#ifdef TEST_ENABLE
|
2025-01-09 15:29:36 +08:00
|
|
|
|
void TEST_Nt26k_Reset()
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
Nt26k_Reset(RT_NULL);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-08 11:43:58 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
MSH_CMD_EXPORT(TEST_Nt26k_Reset, "test_nt26k_reset");
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_sleep(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_response_t resp = RT_NULL;
|
2024-12-30 18:04:47 +08:00
|
|
|
|
struct at_device_nt26k *nt26k = RT_NULL;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k = (struct at_device_nt26k *)device->user_data;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (!nt26k->power_status) // power off
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
return (RT_EOK);
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (nt26k->sleep_status) // is sleep status
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
return (RT_EOK);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("no memory for resp create.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return (-RT_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
/* enable sleep mode */
|
2024-12-30 11:50:48 +08:00
|
|
|
|
// Sleep1
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+ECPMUCFG=1,2") != RT_EOK)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("enable sleep fail.\"AT+ECPMUCFG=1,2\" execute fail.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return (-RT_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* enable PSM mode */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CPSMS=1,,,,\"00100010\"") != RT_EOK)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("enable sleep fail.\"AT+CPSMS=1,,,,\"00100010\" execute fail.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return (-RT_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k->sleep_status = RT_TRUE;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return (RT_EOK);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_wakeup(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
struct at_device_nt26k *nt26k = RT_NULL;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k = (struct at_device_nt26k *)device->user_data;
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (nt26k->pwr_key_pin != -1)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_pin_write(nt26k->pwr_key_pin, PIN_LOW);
|
|
|
|
|
rt_thread_mdelay(100);
|
|
|
|
|
rt_pin_write(nt26k->pwr_key_pin, PIN_HIGH);
|
2024-12-31 17:48:22 +08:00
|
|
|
|
nt26k->sleep_status = RT_TRUE;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
return (RT_EOK);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static void urc_tcp_recv(struct at_client *client, const char *data, rt_size_t size)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int len = 0;
|
|
|
|
|
rt_uint16_t crc16 = 0;
|
|
|
|
|
rt_uint16_t rec_crc16 = 0;
|
|
|
|
|
char crc16_buf[6] = {0};
|
2024-12-31 17:48:22 +08:00
|
|
|
|
rt_uint8_t recv_byte_buf[AT_CLIENT_RECV_BUFF_LEN] = {0};
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_memset(data_buf, 0, sizeof(data_buf));
|
2025-01-08 11:43:58 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (sscanf(data, "+QIURC: \"recv\",%*d,%d,%s", &len, data_buf) == 2)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
HexStrToBytes(data_buf, recv_byte_buf, len * 2);
|
|
|
|
|
LOG_D("nt26k recv data: %s", data_buf);
|
|
|
|
|
crc16 = crc1021(data_buf, len * 2 - 10); // 去掉帧尾三个字节和2个字节的校验值,字符长度为10
|
2025-01-09 15:29:36 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_strncpy(crc16_buf, data_buf + len * 2 - 10, 4);
|
|
|
|
|
LOG_D("nt26k crc16: %04s", crc16_buf);
|
|
|
|
|
rec_crc16 = strtol(crc16_buf, NULL, 16);
|
|
|
|
|
if (crc16 != rec_crc16) // 看下数据接收的是否正确
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("nt26k recv data error {crc16 [%x]!= rec_crc16[%x]}", crc16, rec_crc16);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
/*比较数组的长度和结构体的长度是否一致,如果不一致则数据解析错误,如果一致复制数组值到结构体中*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (len == sizeof(struct Nt26kRecvData))
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_memset(nt26k_ops.recv, 0, sizeof(struct Nt26kRecvData)); // 清空结构体
|
|
|
|
|
rt_memcpy(nt26k_ops.recv, recv_byte_buf, sizeof(struct Nt26kRecvData));
|
|
|
|
|
if ((nt26k_ops.recv->recv_data.event_type == INSTRUCTION_HEART_BEAT) ||
|
|
|
|
|
(nt26k_ops.recv->recv_data.event_type == EVENT_TYPE_POWER_ON))
|
|
|
|
|
// 加这个的原因就是如果有指令下发,会出现两个信号量,指令会执行两次,所以排除心跳包才释放信号量
|
2024-12-31 17:48:22 +08:00
|
|
|
|
{
|
2025-01-22 13:33:38 +08:00
|
|
|
|
rt_sem_release(nt26k_recv_msg_sem);// 接收到的是心跳包
|
2025-01-08 11:43:58 +08:00
|
|
|
|
}
|
2025-01-10 09:52:43 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_sem_release(nt26k_recv_sem);
|
2025-01-23 09:24:23 +08:00
|
|
|
|
rt_sem_release(nt26k_recv_msg_sem);// 接收到的是响应包
|
2025-01-10 09:52:43 +08:00
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("nt26k recv data error {len [%d]!= sizeof(struct Nt26kRecvData)[%d]}", len, sizeof(struct Nt26kRecvData));
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_memset(recv_byte_buf, 0, sizeof(recv_byte_buf));
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static void urc_device_reset(struct at_client *client, const char *data, rt_size_t size)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("device reset");
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k_conncet_tcp_flag = 0;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static void urc_tcp_disconnect(struct at_client *client, const char *data, rt_size_t size)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-31 17:48:22 +08:00
|
|
|
|
size_t id;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (sscanf(data, "+QIURC: \"closed\",%d", &id) == 1)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
|
|
|
|
if (id == socket_id)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_W("socket %d disconnect", id);
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k_conncet_tcp_flag = 0;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_sem_release(nt26k_disconnect_sem);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct at_urc urc_table[] = {
|
2025-01-17 13:23:16 +08:00
|
|
|
|
{"+QIURC: \"recv\"", "\r\n", urc_tcp_recv},
|
|
|
|
|
{"boot.rom", "\r\n", urc_device_reset}, // 这个是软件复位时,
|
|
|
|
|
{"Lierda", "\r\n", urc_device_reset}, // 这个时硬件复位时回复
|
2024-12-31 17:48:22 +08:00
|
|
|
|
{"+QIURC: \"closed\"", "\r\n", urc_tcp_disconnect}, // tcp连接断开
|
2024-12-30 11:50:48 +08:00
|
|
|
|
};
|
2025-01-08 11:43:58 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
void show_resp_info(at_response_t resp)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
/* Print response line buffer */
|
|
|
|
|
const char *line_buffer = RT_NULL;
|
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
for (rt_size_t line_num = 1; line_num <= resp->line_counts; line_num++)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if ((line_buffer = at_resp_get_line(resp, line_num)) != RT_NULL)
|
|
|
|
|
LOG_I("line %d buffer : %s", line_num, line_buffer);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
else
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_I("Parse line buffer error!");
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int at_device_nt26k_disconnect_tcp(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#define NT26K_CLOSE_REP_TIME (5 * AT_DEFAULT_TIMEOUT)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_response_t resp = at_create_resp(AT_CLIENT_RECV_BUFF_LEN, 0, NT26K_CLOSE_REP_TIME);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("No memory for response structure!");
|
|
|
|
|
at_delete_resp(resp);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
return -RT_ENOMEM;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, TCP_CLOSE_SOCKET, socket_id) != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
return -RT_ERROR;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
nt26k_conncet_tcp_flag = 0;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int at_device_nt26k_connect_tcp(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
if (nt26k_conncet_tcp_flag)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_EOK;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
ASSERT(device);
|
|
|
|
|
int err_code = 0;
|
2025-01-20 16:34:30 +08:00
|
|
|
|
flash_sever_info upload_sever_info = {0};
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_response_t resp = at_create_resp(64, 4, AT_DEFAULT_TIMEOUT);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("No memory for response structure!");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ENOMEM;
|
|
|
|
|
}
|
2025-01-20 16:34:30 +08:00
|
|
|
|
if (Flash_Get_Sever_Data(&upload_sever_info) != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("Get Sever Data Failed");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
2025-01-20 16:34:30 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, TCP_CONNECT_CMD, upload_sever_info.server_url, upload_sever_info.server_port) == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+QIOPEN:", "+QIOPEN:%d,%d", &socket_id, &err_code) > 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
|
|
|
|
if (err_code == 0)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("nt26k connect to tcp server success");
|
2025-01-09 15:29:36 +08:00
|
|
|
|
nt26k_conncet_tcp_flag = 1;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("nt26k connect to tcp server failed. error code: %d", err_code);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (err_code == 570)
|
|
|
|
|
{
|
|
|
|
|
nt26k_disconnect_pdp_flag = 1;
|
2024-12-30 18:04:47 +08:00
|
|
|
|
}
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int at_send_data(struct at_device *device, const char *data, rt_size_t size)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#define NT26K_SEND_RESP_TIME (3000)
|
2025-01-17 13:23:16 +08:00
|
|
|
|
const char *line_buffer = RT_NULL;
|
|
|
|
|
rt_uint8_t retry = 0;
|
2025-01-25 14:11:51 +08:00
|
|
|
|
at_response_t resp = at_create_resp(AT_CLIENT_RECV_BUFF_LEN, 2, NT26K_SEND_RESP_TIME);
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_uint8_t max_retry_count = (rt_uint8_t)Flash_Get_SysCfg(kIotRetryId);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("no memory for nt26k device(%s) response structure.", device->name);
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
while (retry < max_retry_count)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, TCP_SEND_DATA, socket_id, data) == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if ((line_buffer = at_resp_get_line(resp, 2)) != RT_NULL)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (rt_strstr(line_buffer, "SEND OK") != RT_NULL)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("send data success, socket_id: %d", socket_id);
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 18:04:47 +08:00
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
2025-01-08 11:43:58 +08:00
|
|
|
|
}
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
retry++;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(1000);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int nt26k_check_link_status(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-15 09:56:50 +08:00
|
|
|
|
at_response_t resp = RT_NULL;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int result = -RT_ERROR;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("no memory for resp create.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return (-RT_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = -RT_ERROR;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CEREG?") == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
int link_stat = 0;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+CEREG:", "+CEREG: %*d,%d", &link_stat) > 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
|
|
|
|
if (link_stat == 1 || link_stat == 5)
|
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-17 10:41:37 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* ============================= nt26k network interface operations ============================= */
|
|
|
|
|
/* set nt26k network interface device status and address information */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int nt26k_netdev_set_info(struct netdev *netdev)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#define NT26K_INFO_RESP_SIZE 128
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_INFO_RESP_TIMO rt_tick_from_millisecond(1000)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int result = RT_EOK;
|
|
|
|
|
at_response_t resp = RT_NULL;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
struct at_device *device = RT_NULL;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(netdev);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("get device(%s) failed.", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set network interface device status */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev_low_level_set_status(netdev, RT_TRUE);
|
|
|
|
|
netdev_low_level_set_link_status(netdev, RT_TRUE);
|
|
|
|
|
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
resp = at_create_resp(NT26K_INFO_RESP_SIZE, 0, NT26K_INFO_RESP_TIMO);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("no memory for resp create.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ENOMEM;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device->class->device_ops->control(device, AT_DEVICE_CTRL_NET_CONN, RT_NULL); // 打开连接
|
2024-12-30 11:50:48 +08:00
|
|
|
|
__exit:
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2024-12-30 18:04:47 +08:00
|
|
|
|
* @brief check nt26k network interface device status
|
2024-12-30 11:50:48 +08:00
|
|
|
|
*
|
2024-12-30 18:04:47 +08:00
|
|
|
|
* @param netdev: nt26k network interface device
|
2024-12-30 11:50:48 +08:00
|
|
|
|
*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static void nt26k_check_link_status_entry(void *parameter)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-13 09:12:44 +08:00
|
|
|
|
#define NT26K_LINK_DELAY_TIME (10 * 60 * RT_TICK_PER_SECOND)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_LINK_STATUS_OK 1
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
int link_status;
|
|
|
|
|
struct at_device *device = RT_NULL;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
struct netdev *netdev = (struct netdev *)parameter;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("get device(%s) failed.", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
while (1)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
link_status = nt26k_check_link_status(device);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (link_status < 0)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(NT26K_LINK_DELAY_TIME);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* check the network interface device link status */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if ((NT26K_LINK_STATUS_OK == link_status) != netdev_is_link_up(netdev))
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev_low_level_set_link_status(netdev, (NT26K_LINK_STATUS_OK == link_status));
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-10 09:52:43 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_delay(NT26K_LINK_DELAY_TIME);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int nt26k_netdev_check_link_status(struct netdev *netdev)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_LINK_THREAD_TICK 20
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#define NT26K_LINK_THREAD_STACK_SIZE (1024 + 512)
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_LINK_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX - 2)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
rt_thread_t tid;
|
|
|
|
|
char tname[RT_NAME_MAX] = {0};
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(netdev);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-25 10:26:13 +08:00
|
|
|
|
rt_snprintf(tname, RT_NAME_MAX, "%s_link", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* create nt26k link status polling thread */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
tid = rt_thread_create(tname, nt26k_check_link_status_entry, (void *)netdev,
|
|
|
|
|
NT26K_LINK_THREAD_STACK_SIZE, NT26K_LINK_THREAD_PRIORITY, NT26K_LINK_THREAD_TICK);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (tid != RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_startup(tid);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_net_init(struct at_device *device);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_netdev_set_up(struct netdev *netdev)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
struct at_device *device = RT_NULL;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
|
|
|
|
|
LOG_D("netdev->name:%s", netdev->name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("get device(%s) failed.", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device->is_init == RT_FALSE)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
nt26k_net_init(device);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
device->is_init = RT_TRUE;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev_low_level_set_status(netdev, RT_TRUE);
|
|
|
|
|
LOG_D("network interface device(%s) set up status.", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_netdev_set_down(struct netdev *netdev)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
struct at_device *device = RT_NULL;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("get device(%s) failed.", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device->is_init == RT_TRUE)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
nt26k_power_off(device);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
device->is_init = RT_FALSE;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev_low_level_set_status(netdev, RT_FALSE);
|
|
|
|
|
LOG_D("network interface device(%s) set down status.", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_DNS_RESP_LEN 64
|
|
|
|
|
#define NT26K_DNS_RESP_TIMEO rt_tick_from_millisecond(300)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int result = RT_EOK;
|
|
|
|
|
at_response_t resp = RT_NULL;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
struct at_device *device = RT_NULL;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(netdev);
|
|
|
|
|
RT_ASSERT(dns_server);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("get device(%s) failed.", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
resp = at_create_resp(NT26K_DNS_RESP_LEN, 0, NT26K_DNS_RESP_TIMEO);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("no memory for resp create.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ENOMEM;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* send "AT+QIDNSCFG=<pri_dns>[,<sec_dns>]" commond to set dns servers */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+QIDNSCFG=%d,%s",
|
|
|
|
|
dns_num, inet_ntoa(*dns_server)) != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev_low_level_set_dns_server(netdev, dns_num, dns_server);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
__exit:
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NETDEV_USING_PING
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_netdev_ping(struct netdev *netdev, const char *host, size_t data_len,
|
|
|
|
|
uint32_t timeout, struct netdev_ping_resp *ping_resp
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#if RT_VER_NUM >= 0x50100
|
2025-01-17 13:23:16 +08:00
|
|
|
|
,
|
|
|
|
|
rt_bool_t is_bind
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#endif
|
2025-01-09 15:29:36 +08:00
|
|
|
|
)
|
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#define NT26K_PING_RESP_SIZE 128
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_PING_IP_SIZE 16
|
|
|
|
|
#define NT26K_PING_TIMEO (NT26K_CON_REP_TIME)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_err_t result = RT_EOK;
|
|
|
|
|
int response = -1, recv_data_len, ping_time, ttl;
|
2024-12-30 18:04:47 +08:00
|
|
|
|
char ip_addr[NT26K_PING_IP_SIZE] = {0};
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_response_t resp = RT_NULL;
|
|
|
|
|
struct at_device *device = RT_NULL;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
#if RT_VER_NUM >= 0x50100
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_UNUSED(is_bind);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(netdev);
|
|
|
|
|
RT_ASSERT(host);
|
|
|
|
|
RT_ASSERT(ping_resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("get device(%s) failed.", netdev->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
resp = at_create_resp(NT26K_PING_RESP_SIZE, 4, NT26K_PING_TIMEO);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("no memory for resp create");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* send "AT+QPING=<contextID>"<host>"[,[<timeout>][,<pingnum>]]" commond to send ping request */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+QPING=1,\"%s\",%d,1", host, timeout / RT_TICK_PER_SECOND) < 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_resp_parse_line_args_by_kw(resp, "+QPING:", "+QPING:%d", &response);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
/* Received the ping response from the server */
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (response == 0)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+QPING:", "+QPING:%d,\"%[^\"]\",%d,%d,%d",
|
|
|
|
|
&response, ip_addr, &recv_data_len, &ping_time, &ttl) <= 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* prase response number */
|
2025-01-09 15:29:36 +08:00
|
|
|
|
switch (response)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
case 0:
|
|
|
|
|
inet_aton(ip_addr, &(ping_resp->ip_addr));
|
|
|
|
|
ping_resp->data_len = recv_data_len;
|
|
|
|
|
ping_resp->ticks = ping_time;
|
|
|
|
|
ping_resp->ttl = ttl;
|
|
|
|
|
result = RT_EOK;
|
|
|
|
|
break;
|
|
|
|
|
case 569:
|
|
|
|
|
result = -RT_ETIMEOUT;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
break;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__exit:
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endif /* NETDEV_USING_PING */
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
const struct netdev_ops nt26k_netdev_ops =
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k_netdev_set_up,
|
|
|
|
|
nt26k_netdev_set_down,
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
RT_NULL,
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k_netdev_set_dns_server,
|
2024-12-30 11:50:48 +08:00
|
|
|
|
RT_NULL,
|
|
|
|
|
|
|
|
|
|
#ifdef NETDEV_USING_PING
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k_netdev_ping,
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
RT_NULL,
|
|
|
|
|
};
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static struct netdev *nt26k_netdev_add(const char *netdev_name)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#define ETHERNET_MTU 1380
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define HWADDR_LEN 8
|
2024-12-30 11:50:48 +08:00
|
|
|
|
struct netdev *netdev = RT_NULL;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev = netdev_get_by_name(netdev_name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (netdev != RT_NULL)
|
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return (netdev);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev = (struct netdev *)rt_calloc(1, sizeof(struct netdev));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (netdev == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("no memory for netdev create.");
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev->mtu = ETHERNET_MTU;
|
|
|
|
|
netdev->ops = &nt26k_netdev_ops;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
netdev->hwaddr_len = HWADDR_LEN;
|
|
|
|
|
|
|
|
|
|
#ifdef SAL_USING_AT
|
2025-01-17 13:23:16 +08:00
|
|
|
|
extern int sal_at_netdev_set_pf_info(struct netdev * netdev);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
/* set the network interface socket/netdb operations */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
sal_at_netdev_set_pf_info(netdev);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
netdev_register(netdev, netdev_name, RT_NULL);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
return netdev;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* ============================= nt26k device operations ============================= */
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* initialize for nt26k */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static void nt26k_init_thread_entry(void *parameter)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define INIT_RETRY 5
|
|
|
|
|
#define CPIN_RETRY 20
|
|
|
|
|
#define CSQ_RETRY 30
|
|
|
|
|
#define CEREG_RETRY 60
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#define IPADDR_RETRY 10
|
|
|
|
|
|
|
|
|
|
int i;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_err_t result = RT_EOK;
|
|
|
|
|
at_response_t resp = RT_NULL;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
struct at_device *device = (struct at_device *)parameter;
|
|
|
|
|
struct at_client *client = device->client;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
resp = at_create_resp(128, 0, rt_tick_from_millisecond(300));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("no memory for resp create.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("start init %s device.", device->name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* power on the nt26k device */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device->class->device_ops->control(device, AT_DEVICE_CTRL_POWER_ON, RT_NULL);
|
2025-01-17 10:41:37 +08:00
|
|
|
|
/* wait nt26k startup finish, send AT every 500ms, if recei
|
|
|
|
|
ve OK, SYNC success*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_client_obj_wait_connect(client, RT_WAITING_FOREVER))
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ETIMEOUT;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
/* disable echo */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "ATE0") != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
/* get module version */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CGMR") != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < (int)resp->line_counts - 1; i++)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("%s", at_resp_get_line(resp, i + 1));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
}
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/*AT+QICFG="dataformat" 设置收发模式*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+QICFG=\"dataformat\",%d,%d", AT_NSONMI_MODE_DEFAULT, AT_NSONMI_MODE_DEFAULT) != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/*设置显示模式*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+QICFG=\"viewmode\",1") != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-31 17:48:22 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
/*设置保活信息*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+QICFG=\"tcp/keepalive\",1,1000,100,10") != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-31 17:48:22 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+QICFG=\"passiveclosed\",1") != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2025-01-08 11:43:58 +08:00
|
|
|
|
/* check SIM card */
|
2025-01-09 15:29:36 +08:00
|
|
|
|
for (i = 0; i < CPIN_RETRY; i++)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CPIN?") == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_get_line_by_kw(resp, "+CPIN: READY") != RT_NULL)
|
2025-01-08 11:43:58 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(1000);
|
2025-01-08 11:43:58 +08:00
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (i == CPIN_RETRY)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("%s device SIM card detection failed.", device->name);
|
2025-01-08 11:43:58 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-17 10:41:37 +08:00
|
|
|
|
/* set etwork interface device hardware address(IMEI) */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if ((*(rt_uint16_t *)FLASH_IOT_IMEI_ADDR == 0xE339) || (*(rt_uint16_t *)FLASH_IOT_IMEI_ADDR == 0x39E3)) // 未写入
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-15 09:56:50 +08:00
|
|
|
|
#define NT26K_NETDEV_HWADDR_LEN 8
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define NT26K_IMEI_LEN 15
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-15 09:56:50 +08:00
|
|
|
|
char imei[NT26K_IMEI_LEN] = {0};
|
|
|
|
|
/* send "AT+CGSN" commond to get device IMEI */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CGSN") != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-15 09:56:50 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "86", "%s", imei) <= 0)
|
2025-01-15 09:56:50 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("%s device prase \"AT+CGSN=1\" cmd error.", device->name);
|
2025-01-15 09:56:50 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("%s device IMEI number: %s", device->name, imei);
|
2025-01-15 09:56:50 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_memcpy(nt26k.imei, imei, NT26K_IMEI_LEN);
|
|
|
|
|
Flash_Sys_Cfg(kIotImeiId, nt26k.imei, NT26K_IMEI_LEN);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-15 10:32:56 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-17 10:41:37 +08:00
|
|
|
|
rt_memset((char *)nt26k.imei, 0, NT26K_IMEI_LEN);
|
|
|
|
|
Get_IotImei((char *)&nt26k.imei[0], NT26K_IMEI_LEN);
|
2025-01-15 10:32:56 +08:00
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(1);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
/* set network interface device hardware iccid */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if ((*(rt_uint16_t *)FLASH_IOT_ICCID_ADDR == 0xE339) || (*(rt_uint16_t *)FLASH_IOT_ICCID_ADDR == 0x39E3)) // 未写入
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#define NT26K_ICCID_LEN 20
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
char iccid[NT26K_ICCID_LEN] = {0};
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
/* send "AT+ECICCID" commond to get device iccid */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+QCCID") != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+QCCID:", "+QCCID:%s", iccid) <= 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("%s device prase \"AT+ECICCID\" cmd error.", device->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("%s device iccid number: %s", device->name, iccid);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_memcpy(nt26k.iccid, iccid, NT26K_ICCID_LEN);
|
|
|
|
|
Flash_Sys_Cfg(kIotIccidId, nt26k.iccid, NT26K_ICCID_LEN);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-17 10:41:37 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rt_memset((char *)nt26k.iccid, 0, NT26K_ICCID_LEN);
|
|
|
|
|
Get_IotIccid((char *)&nt26k.iccid[0], NT26K_ICCID_LEN);
|
2025-01-15 10:32:56 +08:00
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(100);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
/* set network interface device hardware imsi */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if ((*(rt_uint16_t *)FLASH_IOT_IMSI_ADDR == 0xE339) || (*(rt_uint16_t *)FLASH_IOT_IMSI_ADDR == 0x39E3)) // 未写入
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#define NT26K_IMSI_LEN 15
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
char imsi[NT26K_IMSI_LEN] = {0};
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
/* send "AT+CIMI" commond to get device imsi */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CIMI") != RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "46", "%s", imsi) <= 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("%s device prase \"AT+CIMI\" cmd error.", device->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("%s device imsi number: %s", device->name, imsi);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_memcpy(nt26k.imsi, imsi, NT26K_IMSI_LEN);
|
|
|
|
|
Flash_Sys_Cfg(kIotImsiId, nt26k.imsi, NT26K_IMSI_LEN);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-17 10:41:37 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
// 已经写入了,将其赋值给结构体
|
2025-01-17 10:41:37 +08:00
|
|
|
|
rt_memset((char *)nt26k.imsi, 0, NT26K_IMSI_LEN);
|
|
|
|
|
Get_IotImei((char *)&nt26k.imsi[0], NT26K_IMSI_LEN);
|
2025-01-15 10:32:56 +08:00
|
|
|
|
}
|
2025-01-17 10:41:37 +08:00
|
|
|
|
/* check signal strength */
|
2025-01-09 15:29:36 +08:00
|
|
|
|
for (i = 0; i < CSQ_RETRY; i++)
|
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CSQ") == RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
int signal_strength = 0, err_rate = 0;
|
|
|
|
|
|
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+CSQ:", "+CSQ: %d,%d", &signal_strength, &err_rate) > 0)
|
|
|
|
|
{
|
|
|
|
|
if ((signal_strength != 99) && (signal_strength != 0))
|
|
|
|
|
{
|
|
|
|
|
LOG_D("%s device signal strength: %d, channel bit err_rate: %d",
|
|
|
|
|
device->name, signal_strength, err_rate);
|
|
|
|
|
nt26k.rssi = signal_strength;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rt_thread_mdelay(1000);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (i == CSQ_RETRY)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("%s device signal strength check failed", device->name);
|
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* check the GPRS network is registered */
|
2025-01-09 15:29:36 +08:00
|
|
|
|
for (i = 0; i < CEREG_RETRY; i++)
|
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CEREG?") == RT_EOK) // 60s内注册CS业务
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
int link_stat = 0;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+CEREG:", "+CEREG: %*d,%d", &link_stat) > 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
|
|
|
|
if ((link_stat == 1) || (link_stat == 5))
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("%s device GPRS is registered", device->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(1000);
|
|
|
|
|
}
|
|
|
|
|
if (i == CEREG_RETRY)
|
|
|
|
|
{
|
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
2025-01-09 15:29:36 +08:00
|
|
|
|
}
|
2025-01-17 10:41:37 +08:00
|
|
|
|
// for (i = 0; i < CEREG_RETRY; i++)
|
|
|
|
|
// {
|
2025-01-09 15:29:36 +08:00
|
|
|
|
|
2025-01-17 10:41:37 +08:00
|
|
|
|
// if (at_obj_exec_cmd (device->client, resp, "AT+QICSGP=1,1,\"cmnet\",\"\",\"\",1") == RT_EOK)
|
|
|
|
|
// {
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// rt_thread_mdelay (20000);
|
|
|
|
|
// }
|
|
|
|
|
// if (i == CEREG_RETRY)
|
|
|
|
|
// {
|
|
|
|
|
// result = -RT_ERROR;
|
|
|
|
|
// goto __exit;
|
|
|
|
|
// }
|
2025-01-09 15:29:36 +08:00
|
|
|
|
for (i = 0; i < CEREG_RETRY; i++)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CGACT=1,1") == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("pdp激活成功");
|
2025-01-09 15:29:36 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// AT+CGACT=0,1 //去激活 PDP
|
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CGACT=0,1") == RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
LOG_D("pdp去激活成功");
|
|
|
|
|
}
|
2025-01-17 10:41:37 +08:00
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(5000);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
}
|
|
|
|
|
if (i == CEREG_RETRY)
|
|
|
|
|
{
|
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CCLK?") == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-08 11:43:58 +08:00
|
|
|
|
TsRtcDateTime rtc_dt;
|
|
|
|
|
int year, mounth, days, hous, min, sec;
|
|
|
|
|
/*+CCLK:24/11/12,06:08:19+32*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+CCLK:", "+CCLK: \"%d/%d/%d,%d:%d:%d+32\"", &year, &mounth, &days, &hous, &min, &sec) > 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rtc_dt.year = (2000 + year);
|
|
|
|
|
rtc_dt.month = mounth;
|
|
|
|
|
rtc_dt.day = days;
|
|
|
|
|
rtc_dt.hour = hous; // 此时为零区时间,需要转化为东八区
|
2025-01-08 11:43:58 +08:00
|
|
|
|
rtc_dt.minute = min;
|
|
|
|
|
rtc_dt.second = sec;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
Time_Zone_Conversion(&rtc_dt); // 时区设置
|
|
|
|
|
rtc_dt.week = RTC_GetWeek(rtc_dt.year, rtc_dt.month, rtc_dt.day);
|
|
|
|
|
RTC_SetTime(rtc_dt.year, rtc_dt.month, rtc_dt.day,
|
|
|
|
|
rtc_dt.hour, rtc_dt.minute, rtc_dt.second); // 设置时间
|
|
|
|
|
LOG_I("RTC时间: %04d-%02d-%02d %02d:%02d:%02d \n",
|
|
|
|
|
rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, rtc_dt.second);
|
2025-01-08 11:43:58 +08:00
|
|
|
|
result = RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-30 11:50:48 +08:00
|
|
|
|
/* initialize successfully */
|
|
|
|
|
result = RT_EOK;
|
|
|
|
|
break;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
|
|
|
|
|
__exit:
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (result != RT_EOK)
|
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* power off the nt26k device */
|
2025-01-17 10:41:37 +08:00
|
|
|
|
nt26k_power_off(device);
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(1000);
|
|
|
|
|
LOG_I("%s device initialize retry...", device->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (result == RT_EOK)
|
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
/* set network interface device status and address information */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
nt26k_netdev_set_info(device->netdev);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
/* check and create link staus sync thread */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
nt26k_netdev_check_link_status(device->netdev);
|
|
|
|
|
LOG_I("%s device network initialize success.", device->name);
|
|
|
|
|
rt_completion_done(&nt26k_init_complate); // 通知初始化完成
|
2025-01-09 15:29:36 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("%s device network initialize failed(%d).", device->name, result);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* nt26k device network initialize */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_net_init(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#ifdef AT_DEVICE_NT26K_INIT_ASYN
|
2024-12-30 11:50:48 +08:00
|
|
|
|
rt_thread_t tid;
|
|
|
|
|
/* 初始化完成量对象 */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_completion_init(&nt26k_init_complate);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
tid = rt_thread_create("nt26k_net", nt26k_init_thread_entry, (void *)device,
|
|
|
|
|
NT26K_THREAD_STACK_SIZE, NT26K_THREAD_PRIORITY, 20);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (tid)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_startup(tid);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("create %s device init thread failed.", device->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
#else
|
2025-01-17 13:23:16 +08:00
|
|
|
|
nt26k_init_thread_entry(device);
|
2024-12-30 18:04:47 +08:00
|
|
|
|
#endif /* AT_DEVICE_NT26K_INIT_ASYN */
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 去除字符串中的 \r 和 \n
|
2025-01-17 13:23:16 +08:00
|
|
|
|
void remove_crlf(char *str)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
char *p = str;
|
2025-01-09 15:29:36 +08:00
|
|
|
|
while (*p)
|
|
|
|
|
{
|
|
|
|
|
if (*p == '\r' || *p == '\n')
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
memmove(p, p + 1, strlen(p));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_err_t Nt26k_Get_Signal_Info(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#define RETRY 10
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_err_t result = RT_EOK;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
at_response_t resp = RT_NULL;
|
|
|
|
|
rt_uint8_t i;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(device);
|
|
|
|
|
resp = at_create_resp(1024, 4, rt_tick_from_millisecond(2000));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("no memory for resp create.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
/* check signal strength */
|
2025-01-09 15:29:36 +08:00
|
|
|
|
for (i = 0; i < RETRY; i++)
|
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CSQ") == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
int signal_strength = 0, err_rate = 0;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+CSQ:", "+CSQ: %d,%d", &signal_strength, &err_rate) > 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
|
|
|
|
if ((signal_strength != 99) && (signal_strength != 0))
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("%s device signal strength: %d, channel bit err_rate: %d",
|
|
|
|
|
device->name, signal_strength, err_rate);
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k.rssi = signal_strength;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(1000);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (i == RETRY)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("%s device signal strength check failed", device->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
|
|
|
|
return result;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
/* check signal strength */
|
|
|
|
|
|
|
|
|
|
//+CESQ:99,99,255,255,28,44
|
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
for (i = 0; i < RETRY; i++)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CESQ") == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
rt_uint8_t rsrp = 0, rsrq = 0;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+CESQ:", "+CESQ:%*[^,],%*[^,],%*[^,],%*[^,],%d,%d", &rsrq, &rsrp) > 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
|
|
|
|
if ((rsrp <= 97) && (rsrp > 0) && ((rsrq <= 34) && (rsrq > 0)))
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_D("%s device signal rsrp: %d, rsrq: %d",
|
|
|
|
|
device->name, rsrp, rsrq);
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k.rsrp = rsrp;
|
|
|
|
|
nt26k.rsrq = rsrq;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_thread_mdelay(1000);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (i == RETRY)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("%s device signal data failed", device->name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
result = -RT_ERROR;
|
|
|
|
|
}
|
2024-12-31 17:48:22 +08:00
|
|
|
|
// /* get signal snr, pci */
|
|
|
|
|
// for (int i = 0; i < RETRY; i++)
|
|
|
|
|
// {
|
|
|
|
|
// if (at_obj_exec_cmd(device->client, resp, "AT+NUESTATS") == RT_EOK)
|
|
|
|
|
// {
|
|
|
|
|
// const char *key1 = "SNR:";
|
|
|
|
|
// const char *key2 = "PCI:";
|
|
|
|
|
// int pci = 0, snr = 0;
|
|
|
|
|
// // show_resp_info(resp);
|
|
|
|
|
|
2025-01-08 11:43:58 +08:00
|
|
|
|
// // 获取第 2 行的响应
|
|
|
|
|
// const char *line = at_resp_get_line(resp, 2);
|
|
|
|
|
|
|
|
|
|
// if (line != NULL)
|
|
|
|
|
// {
|
|
|
|
|
// snr = Extract_Value(line, key1);
|
|
|
|
|
// pci = Extract_Value(line, key2);
|
|
|
|
|
|
|
|
|
|
// if (snr != 0 && pci != 0)
|
|
|
|
|
// {
|
|
|
|
|
// nt26k.pci = pci;
|
|
|
|
|
// nt26k.snr = snr;
|
|
|
|
|
// LOG_D("pci:%d,snr:%d", nt26k.pci, nt26k.snr);
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// LOG_D("Extracted values are invalid: SNR=%d, PCI=%d", snr, pci);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// LOG_D("Failed to get line 2 from response");
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// LOG_D("Failed to execute AT command");
|
|
|
|
|
// }
|
|
|
|
|
// rt_thread_mdelay(2000);
|
2024-12-31 17:48:22 +08:00
|
|
|
|
// }
|
|
|
|
|
// if (i == RETRY)
|
|
|
|
|
// {
|
2025-01-08 11:43:58 +08:00
|
|
|
|
// LOG_E("%s device signal data failed", device->name);
|
|
|
|
|
// result = -RT_ERROR;
|
2024-12-31 17:48:22 +08:00
|
|
|
|
// }
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* nt26k device network interface attach
|
2024-12-30 11:50:48 +08:00
|
|
|
|
* - set network interface device link status
|
|
|
|
|
*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_init(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
struct at_device_nt26k *nt26k = RT_NULL;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(device);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
nt26k = (struct at_device_nt26k *)device->user_data;
|
|
|
|
|
nt26k->power_status = RT_FALSE; // default power is off.
|
|
|
|
|
nt26k->sleep_status = RT_FALSE; // default sleep is disabled.
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
/* initialize AT client */
|
|
|
|
|
#if RT_VER_NUM >= 0x50100
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_client_init(nt26k->client_name, nt26k->recv_line_num, nt26k->recv_line_num);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#else
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_client_init(nt26k->client_name, nt26k->recv_line_num);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device->client = at_client_get(nt26k->client_name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device->client == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("get AT client(%s) failed.", nt26k->client_name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* register URC data execution function */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_obj_set_urc_table(device->client, urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
#ifdef AT_USING_SOCKET
|
2025-01-17 13:23:16 +08:00
|
|
|
|
nt26k_socket_init(device);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* add nt26k device to the netdev list */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
device->netdev = nt26k_netdev_add(nt26k->device_name);
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (device->netdev == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("add netdev(%s) failed.", nt26k->device_name);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* initialize nt26k pin configuration */
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (nt26k->pwr_en_pin != -1)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_pin_mode(nt26k->pwr_en_pin, PIN_MODE_OUTPUT);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (nt26k->rst_pin != -1)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_pin_mode(nt26k->rst_pin, PIN_MODE_OUTPUT);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (nt26k->pwr_key_pin != -1)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rt_pin_mode(nt26k->pwr_key_pin, PIN_MODE_OUTPUT);
|
|
|
|
|
device->class->device_ops->control(device, AT_DEVICE_CTRL_WAKEUP, RT_NULL);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2024-12-30 18:04:47 +08:00
|
|
|
|
/* initialize nt26k device network */
|
2025-01-17 13:23:16 +08:00
|
|
|
|
return nt26k_netdev_set_up(device->netdev);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_deinit(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(device);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
return nt26k_netdev_set_down(device->netdev);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_control(struct at_device *device, int cmd, void *arg)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
int result = -RT_ERROR;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(device);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-09 15:29:36 +08:00
|
|
|
|
switch (cmd)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
case AT_DEVICE_CTRL_SLEEP:
|
|
|
|
|
result = nt26k_sleep(device);
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_CTRL_WAKEUP:
|
|
|
|
|
result = nt26k_wakeup(device);
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_CTRL_NET_CONN:
|
|
|
|
|
result = at_device_nt26k_connect_tcp(device);
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_CTRL_NET_DISCONN:
|
|
|
|
|
result = at_device_nt26k_disconnect_tcp(device); // 直接删除Socket
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_CTRL_GET_SIGNAL:
|
|
|
|
|
result = Nt26k_Get_Signal_Info(device);
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_CTRL_RESET:
|
|
|
|
|
result = Nt26k_Reset(device);
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_CTRL_POWER_ON:
|
|
|
|
|
result = nt26k_power_on(device);
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_CTRL_POWER_OFF:
|
|
|
|
|
result = nt26k_power_off(device);
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_RF_CLOSE:
|
|
|
|
|
result = nt26k_Close_Rf(device);
|
|
|
|
|
break;
|
|
|
|
|
case AT_DEVICE_CTRL_LOW_POWER:
|
|
|
|
|
case AT_DEVICE_CTRL_SET_WIFI_INFO:
|
|
|
|
|
case AT_DEVICE_CTRL_GET_GPS:
|
|
|
|
|
case AT_DEVICE_CTRL_GET_VER:
|
|
|
|
|
LOG_W("not support the control command(%d).", cmd);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
LOG_E("input error control command(%d).", cmd);
|
|
|
|
|
break;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
int Time_Calibration(struct at_device *device)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
at_response_t resp = RT_NULL;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
RT_ASSERT(device);
|
|
|
|
|
resp = at_create_resp(64, 2, rt_tick_from_millisecond(2000));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (resp == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("no memory for resp create.");
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_obj_exec_cmd(device->client, resp, "AT+CCLK?") == RT_EOK)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
TsRtcDateTime rtc_dt;
|
|
|
|
|
int year, mounth, days, hous, min, sec;
|
|
|
|
|
/*+CCLK:24/11/12,06:08:19+32*/
|
2025-01-17 13:23:16 +08:00
|
|
|
|
if (at_resp_parse_line_args_by_kw(resp, "+CCLK:", "+CCLK: \"%d/%d/%d,%d:%d:%d+32\"", &year, &mounth, &days, &hous, &min, &sec) > 0)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
rtc_dt.year = (2000 + year);
|
|
|
|
|
rtc_dt.month = mounth;
|
|
|
|
|
rtc_dt.day = days;
|
|
|
|
|
rtc_dt.hour = hous; // 此时为零区时间,需要转化为东八区
|
2024-12-30 11:50:48 +08:00
|
|
|
|
rtc_dt.minute = min;
|
|
|
|
|
rtc_dt.second = sec;
|
2025-01-17 13:23:16 +08:00
|
|
|
|
Time_Zone_Conversion(&rtc_dt); // 时区设置
|
|
|
|
|
rtc_dt.week = RTC_GetWeek(rtc_dt.year, rtc_dt.month, rtc_dt.day);
|
|
|
|
|
RTC_SetTime(rtc_dt.year, rtc_dt.month, rtc_dt.day,
|
|
|
|
|
rtc_dt.hour, rtc_dt.minute, rtc_dt.second); // 设置时间
|
|
|
|
|
LOG_I("RTC时间: %04d-%02d-%02d %02d:%02d:%02d \n",
|
|
|
|
|
rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, rtc_dt.second);
|
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-17 13:23:16 +08:00
|
|
|
|
at_delete_resp(resp);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 18:04:47 +08:00
|
|
|
|
const struct at_device_ops nt26k_device_ops =
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2024-12-30 18:04:47 +08:00
|
|
|
|
nt26k_init,
|
|
|
|
|
nt26k_deinit,
|
|
|
|
|
nt26k_control,
|
2024-12-30 11:50:48 +08:00
|
|
|
|
};
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
static int nt26k_device_class_register(void)
|
2025-01-09 15:29:36 +08:00
|
|
|
|
{
|
2024-12-30 11:50:48 +08:00
|
|
|
|
struct at_device_class *class = RT_NULL;
|
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
class = (struct at_device_class *)rt_calloc(1, sizeof(struct at_device_class));
|
2025-01-09 15:29:36 +08:00
|
|
|
|
if (class == RT_NULL)
|
|
|
|
|
{
|
2025-01-17 13:23:16 +08:00
|
|
|
|
LOG_E("no memory for device class create.");
|
|
|
|
|
rt_free(class);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
return -RT_ENOMEM;
|
|
|
|
|
}
|
2024-12-30 18:04:47 +08:00
|
|
|
|
class->device_ops = &nt26k_device_ops;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
return at_device_class_register(class, AT_DEVICE_CLASS_NT26K);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-08 11:43:58 +08:00
|
|
|
|
|
2025-01-15 09:56:50 +08:00
|
|
|
|
INIT_DEVICE_EXPORT(nt26k_device_class_register);
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#endif //! IOT_MODULE_SWITCH
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-17 13:23:16 +08:00
|
|
|
|
#endif /* AT_DEVICE_USING_NT26K */
|