Merge pull request #40 from Lawlieta/master
【修改】AT device 适配 netdev 组件改动
This commit is contained in:
commit
77290933c4
704
at_socket_ec20.c
704
at_socket_ec20.c
|
@ -32,6 +32,8 @@
|
|||
#include <at.h>
|
||||
#include <at_socket.h>
|
||||
|
||||
#include <netdev.h>
|
||||
|
||||
#if !defined(AT_SW_VERSION_NUM) || AT_SW_VERSION_NUM < 0x10200
|
||||
#error "This AT Client version is older, please check and update latest AT Client!"
|
||||
#endif
|
||||
|
@ -41,6 +43,8 @@
|
|||
|
||||
#ifdef AT_DEVICE_EC20
|
||||
|
||||
#define EC20_NETDEV_NAME "ec20"
|
||||
|
||||
#define EC20_MODULE_SEND_MAX_SIZE 1460
|
||||
#define EC20_WAIT_CONNECT_TIME 5000
|
||||
#define EC20_THREAD_STACK_SIZE 1024
|
||||
|
@ -58,8 +62,6 @@
|
|||
#define EC20_EVENT_SEND_FAIL (1L << 5)
|
||||
#define EC20_EVENT_DOMAIN_OK (1L << 6)
|
||||
|
||||
|
||||
|
||||
/* AT+QICSGP command default*/
|
||||
char *QICSGP_CHINA_MOBILE = "AT+QICSGP=1,1,\"CMNET\",\"\",\"\",0";
|
||||
char *QICSGP_CHINA_UNICOM = "AT+QICSGP=1,1,\"UNINET\",\"\",\"\",0";
|
||||
|
@ -214,11 +216,11 @@ static void at_tcp_ip_errcode_parse(int result)//TCP/IP_QIGETERROR
|
|||
case 560 : LOG_E("%d : Socket accept failed", result); break;
|
||||
case 561 : LOG_E("%d : Open PDP context failed", result); break;
|
||||
case 562 : LOG_E("%d : Close PDP context failed", result); break;
|
||||
case 563 : LOG_E("%d : Socket identity has been used", result); break;
|
||||
case 563 : LOG_W("%d : Socket identity has been used", result); break;
|
||||
case 564 : LOG_E("%d : DNS busy", result); break;
|
||||
case 565 : LOG_E("%d : DNS parse failed", result); break;
|
||||
case 566 : LOG_E("%d : Socket connect failed", result); break;
|
||||
case 567 : LOG_E("%d : Socket has been closed", result); break;
|
||||
case 567 : LOG_W("%d : Socket has been closed", result); break;
|
||||
case 568 : LOG_E("%d : Operation busy", result); break;
|
||||
case 569 : LOG_E("%d : Operation timeout", result); break;
|
||||
case 570 : LOG_E("%d : PDP context broken down", result); break;
|
||||
|
@ -447,26 +449,18 @@ static int at_socket_event_recv(uint32_t event, uint32_t timeout, rt_uint8_t opt
|
|||
static int ec20_socket_close(int socket)
|
||||
{
|
||||
int result = 0;
|
||||
at_response_t resp = RT_NULL;
|
||||
|
||||
resp = at_create_resp(64, 2, rt_tick_from_millisecond(2 * 1000));
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* default connection timeout is 10 seconds, but it set to 1 seconds is convenient to use.*/
|
||||
result = at_exec_cmd(resp, "AT+QICLOSE=%d,1", socket);
|
||||
result = at_exec_cmd(RT_NULL, "AT+QICLOSE=%d,1", socket);
|
||||
if (result < 0)
|
||||
{
|
||||
LOG_E("socket (%d) close failed, wait close OK timeout or ERROR.", socket);
|
||||
return result;
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -496,6 +490,9 @@ static int ec20_socket_connect(int socket, char *ip, int32_t port, enum at_socke
|
|||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
__retry:
|
||||
|
||||
/* Clear socket connect event */
|
||||
at_socket_event_recv(SET_EVENT(socket, EC20_EVENT_CONN_OK | EC20_EVENT_CONN_FAIL), 0, RT_EVENT_FLAG_OR);
|
||||
|
||||
if (is_client)
|
||||
{
|
||||
|
@ -528,14 +525,14 @@ __retry:
|
|||
}
|
||||
|
||||
/* waiting result event from AT URC, the device default connection timeout is 75 seconds, but it set to 10 seconds is convenient to use.*/
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), rt_tick_from_millisecond(10 * 1000), RT_EVENT_FLAG_OR) < 0)
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) connect failed, wait connect result timeout.", socket);
|
||||
result = -RT_ETIMEOUT;
|
||||
goto __exit;
|
||||
}
|
||||
/* waiting OK or failed result */
|
||||
if ((event_result = at_socket_event_recv(EC20_EVENT_CONN_OK | EC20_EVENT_CONN_FAIL, rt_tick_from_millisecond(1 * 1000),
|
||||
if ((event_result = at_socket_event_recv(EC20_EVENT_CONN_OK | EC20_EVENT_CONN_FAIL, 1 * RT_TICK_PER_SECOND,
|
||||
RT_EVENT_FLAG_OR)) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) connect failed, wait connect OK|FAIL timeout.", socket);
|
||||
|
@ -547,11 +544,9 @@ __retry:
|
|||
{
|
||||
if (!retryed)
|
||||
{
|
||||
LOG_E("socket (%d) connect failed, maybe the socket was not be closed at the last time and now will retry.", socket);
|
||||
if (ec20_socket_close(socket) < 0)
|
||||
{
|
||||
goto __exit;
|
||||
}
|
||||
LOG_W("socket (%d) connect failed, maybe the socket was not be closed at the last time and now will retry.", socket);
|
||||
/* default connection timeout is 10 seconds, but it set to 1 seconds is convenient to use.*/
|
||||
at_exec_cmd(RT_NULL, "AT+QICLOSE=%d,1", socket);
|
||||
retryed = RT_TRUE;
|
||||
goto __retry;
|
||||
}
|
||||
|
@ -569,7 +564,7 @@ __exit:
|
|||
|
||||
static int at_get_send_size(int socket, size_t *size, size_t *acked, size_t *nacked)
|
||||
{
|
||||
at_response_t resp = at_create_resp(128, 0, rt_tick_from_millisecond(5000));
|
||||
at_response_t resp = at_create_resp(128, 0, 5 * RT_TICK_PER_SECOND);
|
||||
int result = 0;
|
||||
|
||||
if (!resp)
|
||||
|
@ -614,7 +609,7 @@ static int at_wait_send_finish(int socket, size_t settings_size)
|
|||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(50));
|
||||
rt_thread_mdelay(50);
|
||||
}
|
||||
|
||||
return -RT_ETIMEOUT;
|
||||
|
@ -641,7 +636,7 @@ static int ec20_socket_send(int socket, const char *buff, size_t bfsz, enum at_s
|
|||
|
||||
RT_ASSERT(buff);
|
||||
|
||||
resp = at_create_resp(128, 2, rt_tick_from_millisecond(5000));
|
||||
resp = at_create_resp(128, 2, 5 * RT_TICK_PER_SECOND);
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
|
@ -650,6 +645,9 @@ static int ec20_socket_send(int socket, const char *buff, size_t bfsz, enum at_s
|
|||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* Clear socket send event */
|
||||
at_socket_event_recv(SET_EVENT(socket, EC20_EVENT_SEND_OK | EC20_EVENT_SEND_FAIL), 0, RT_EVENT_FLAG_OR);
|
||||
|
||||
/* set current socket for send URC event */
|
||||
cur_socket = socket;
|
||||
/* set AT client end sign to deal with '>' sign.*/
|
||||
|
@ -682,14 +680,13 @@ static int ec20_socket_send(int socket, const char *buff, size_t bfsz, enum at_s
|
|||
}
|
||||
|
||||
/* waiting result event from AT URC */
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), rt_tick_from_millisecond(300*3), RT_EVENT_FLAG_OR) < 0)
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) send failed, wait connect result timeout.", socket);
|
||||
result = -RT_ETIMEOUT;
|
||||
goto __exit;
|
||||
}
|
||||
/* waiting OK or failed result */
|
||||
if ((event_result = at_socket_event_recv(EC20_EVENT_SEND_OK | EC20_EVENT_SEND_FAIL, rt_tick_from_millisecond(1 * 1000),
|
||||
if ((event_result = at_socket_event_recv(EC20_EVENT_SEND_OK | EC20_EVENT_SEND_FAIL, 1 * RT_TICK_PER_SECOND,
|
||||
RT_EVENT_FLAG_OR)) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) send failed, wait connect OK|FAIL timeout.", socket);
|
||||
|
@ -740,18 +737,17 @@ __exit:
|
|||
*/
|
||||
static int ec20_domain_resolve(const char *name, char ip[16])
|
||||
{
|
||||
#define RESOLVE_RETRY 5
|
||||
#define RESOLVE_RETRY 3
|
||||
|
||||
int i, result;
|
||||
// char recv_ip[16] = { 0 };
|
||||
at_response_t resp = RT_NULL;
|
||||
|
||||
|
||||
RT_ASSERT(name);
|
||||
RT_ASSERT(ip);
|
||||
|
||||
/* The maximum response time is 60 seconds, but it set to 10 seconds is convenient to use. */
|
||||
resp = at_create_resp(128, 0, rt_tick_from_millisecond(10 * 1000));
|
||||
resp = at_create_resp(128, 0, 10 * RT_TICK_PER_SECOND);
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
|
@ -759,38 +755,30 @@ static int ec20_domain_resolve(const char *name, char ip[16])
|
|||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* Clear EC20_EVENT_DOMAIN_OK */
|
||||
at_socket_event_recv(EC20_EVENT_DOMAIN_OK, 0, RT_EVENT_FLAG_OR);
|
||||
for(i = 0; i < RESOLVE_RETRY; i++)
|
||||
|
||||
result = at_exec_cmd(resp, "AT+QIDNSGIP=1,\"%s\"", name);
|
||||
if (result < 0)
|
||||
{
|
||||
if (at_exec_cmd(resp, "AT+QIDNSGIP=1,\"%s\"", name) < 0)
|
||||
{
|
||||
LOG_E("Domain \"%s\" resolve return ERROR (%d).", name, i);
|
||||
result = -RT_ERROR;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = RT_EOK;
|
||||
break;
|
||||
}
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (result == RT_EOK)
|
||||
{
|
||||
for(i = 0; i < RESOLVE_RETRY; i++)
|
||||
{
|
||||
/* waiting result event from AT URC, the device default connection timeout is 60 seconds.*/
|
||||
if (at_socket_event_recv(EC20_EVENT_DOMAIN_OK, rt_tick_from_millisecond(10 * 1000), RT_EVENT_FLAG_OR) < 0)
|
||||
if (at_socket_event_recv(EC20_EVENT_DOMAIN_OK, 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
|
||||
{
|
||||
LOG_E("Domain \"%s\" resolve failed, wait dns result timeout.", name);
|
||||
result = -RT_ETIMEOUT;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(recv_ip) < 8)
|
||||
{
|
||||
rt_thread_delay(rt_tick_from_millisecond(100));
|
||||
rt_thread_mdelay(100);
|
||||
/* resolve failed, maybe receive an URC CRLF */
|
||||
result = -RT_ERROR;
|
||||
continue;
|
||||
|
@ -804,8 +792,15 @@ static int ec20_domain_resolve(const char *name, char ip[16])
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* response timeout */
|
||||
if (i == RESOLVE_RETRY)
|
||||
{
|
||||
result = -RT_ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
__exit:
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
if (resp)
|
||||
|
@ -831,41 +826,6 @@ static void ec20_socket_set_event_cb(at_socket_evt_t event, at_evt_cb_t cb)
|
|||
}
|
||||
}
|
||||
|
||||
static void urc_ping_func(const char *data, rt_size_t size)
|
||||
{
|
||||
static int icmp_seq = 0;
|
||||
int i, j = 0;
|
||||
int result, recv_len, time, ttl;
|
||||
int sent, rcvd, lost, min, max, avg;
|
||||
char dst_ip[16] = { 0 };
|
||||
|
||||
RT_ASSERT(data);
|
||||
|
||||
for (i=0;i<size;i++)
|
||||
{
|
||||
if(*(data+i) == '.')
|
||||
j++;
|
||||
}
|
||||
if (j != 0)
|
||||
{
|
||||
sscanf(data, "+QPING: %d,%[^,],%d,%d,%d", &result, dst_ip, &recv_len, &time, &ttl);
|
||||
if (result == 0)
|
||||
LOG_I("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms", recv_len, dst_ip, icmp_seq++, ttl, time);
|
||||
}
|
||||
else
|
||||
{
|
||||
sscanf(data, "+QPING: %d,%d,%d,%d,%d,%d,%d", &result, &sent, &rcvd, &lost, &min, &max, &avg);
|
||||
if (result == 0)
|
||||
LOG_I("%d sent %d received %d lost, min=%dms max=%dms average=%dms", sent, rcvd, lost, min, max, avg);
|
||||
}
|
||||
if (result != 0)
|
||||
{
|
||||
LOG_E("ping: ");
|
||||
at_tcp_ip_errcode_parse(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void urc_connect_func(const char *data, rt_size_t size)
|
||||
{
|
||||
int socket = 0;
|
||||
|
@ -916,7 +876,7 @@ static void urc_close_func(const char *data, rt_size_t size)
|
|||
|
||||
/* when TCP socket service is closed, host must send "AT+QICLOSE= <connID>,0" command to close socket */
|
||||
at_exec_cmd(RT_NULL, "AT+QICLOSE=%d,0\r\n", socket);
|
||||
rt_thread_delay(rt_tick_from_millisecond(100));
|
||||
rt_thread_mdelay(100);
|
||||
}
|
||||
|
||||
static void urc_recv_func(const char *data, rt_size_t size)
|
||||
|
@ -986,28 +946,25 @@ static void urc_dnsqip_func(const char *data, rt_size_t size)
|
|||
{
|
||||
int i = 0, j = 0;
|
||||
int result, ip_count, dns_ttl;
|
||||
static uint8_t resolved = 0;
|
||||
|
||||
RT_ASSERT(data && size);
|
||||
|
||||
for(i=0;i<size;i++)
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if(*(data+i) == '.')
|
||||
if (*(data + i) == '.')
|
||||
j++;
|
||||
}
|
||||
/* There would be several dns result, we just pickup one*/
|
||||
if(j == 3 && resolved == 0)
|
||||
/* There would be several dns result, we just pickup one */
|
||||
if (j == 3)
|
||||
{
|
||||
resolved = 1;
|
||||
sscanf(data, "+QIURC: \"dnsgip\",\"%[^\"]", recv_ip);
|
||||
recv_ip[15] = '\0';
|
||||
at_socket_event_send(EC20_EVENT_DOMAIN_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
resolved = 0;
|
||||
sscanf(data, "+QIURC: \"dnsgip\",%d,%d,%d", &result, &ip_count, &dns_ttl);
|
||||
if(result)
|
||||
if (result)
|
||||
{
|
||||
at_tcp_ip_errcode_parse(result);
|
||||
}
|
||||
|
@ -1039,7 +996,6 @@ static void urc_qiurc_func(const char *data, rt_size_t size)
|
|||
static const struct at_urc urc_table[] = {
|
||||
{"SEND OK", "\r\n", urc_send_func},
|
||||
{"SEND FAIL", "\r\n", urc_send_func},
|
||||
{"+QPING:", "\r\n", urc_ping_func},
|
||||
{"+QIOPEN:", "\r\n", urc_connect_func},
|
||||
{"+QIURC:", "\r\n", urc_qiurc_func},
|
||||
};
|
||||
|
@ -1054,6 +1010,9 @@ static const struct at_urc urc_table[] = {
|
|||
} \
|
||||
} while(0); \
|
||||
|
||||
static int ec20_netdev_set_info(struct netdev *netdev);
|
||||
static int ec20_netdev_check_link_status(struct netdev *netdev);
|
||||
|
||||
/* init for EC20 */
|
||||
static void ec20_init_thread_entry(void *parameter)
|
||||
{
|
||||
|
@ -1111,7 +1070,7 @@ static void ec20_init_thread_entry(void *parameter)
|
|||
goto __exit;
|
||||
}
|
||||
/* waiting for dirty data to be digested */
|
||||
rt_thread_delay(rt_tick_from_millisecond(10));
|
||||
rt_thread_mdelay(10);
|
||||
|
||||
|
||||
/* Use AT+CIMI to query the IMSI of SIM card */
|
||||
|
@ -1127,7 +1086,7 @@ static void ec20_init_thread_entry(void *parameter)
|
|||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
|
||||
/* Use AT+QCCID to query ICCID number of SIM card */
|
||||
|
@ -1142,7 +1101,7 @@ static void ec20_init_thread_entry(void *parameter)
|
|||
LOG_D("Signal strength: %d Channel bit error rate: %d", qi_arg[0], qi_arg[1]);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CSQ_RETRY)
|
||||
{
|
||||
|
@ -1160,7 +1119,7 @@ static void ec20_init_thread_entry(void *parameter)
|
|||
LOG_D("GSM network is registered (%s)", parsed_data);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CREG_RETRY)
|
||||
{
|
||||
|
@ -1178,7 +1137,7 @@ static void ec20_init_thread_entry(void *parameter)
|
|||
LOG_D("GPRS network is registered (%s)", parsed_data);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CGREG_RETRY)
|
||||
{
|
||||
|
@ -1222,23 +1181,29 @@ static void ec20_init_thread_entry(void *parameter)
|
|||
AT_SEND_CMD(resp, 0, 150 * 1000, "AT+QIACT?");
|
||||
at_resp_parse_line_args_by_kw(resp, "+QIACT:", "+QIACT: %*[^\"]\"%[^\"]", &parsed_data);
|
||||
LOG_I("%s", parsed_data);
|
||||
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
LOG_I("AT network initialize success!");
|
||||
/* set network interface device status and address information */
|
||||
ec20_netdev_set_info(netdev_get_by_name(EC20_NETDEV_NAME));
|
||||
ec20_netdev_check_link_status(netdev_get_by_name(EC20_NETDEV_NAME));
|
||||
|
||||
LOG_I("AT network initialize success!");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("AT network initialize failed (%d)!", result);
|
||||
LOG_E("AT network initialize failed (%d)!", result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* EC20 device network initialize */
|
||||
void ec20_net_init(void)
|
||||
{
|
||||
#ifdef PKG_AT_INIT_BY_THREAD
|
||||
|
@ -1250,134 +1215,16 @@ void ec20_net_init(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
LOG_E("Create AT initialization thread fail!");
|
||||
LOG_E("Create AT initialization thread failed!");
|
||||
}
|
||||
#else
|
||||
ec20_init_thread_entry(RT_NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
int ec20_ping(int argc, char **argv)
|
||||
{
|
||||
at_response_t resp = RT_NULL;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
rt_kprintf("Please input: at_ping <host address>\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
resp = at_create_resp(128, 0, rt_tick_from_millisecond(5000));
|
||||
if (!resp)
|
||||
{
|
||||
rt_kprintf("No memory for response structure!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
if (at_exec_cmd(resp, "AT+QPING=1,\"%s\"", argv[1]) < 0)
|
||||
{
|
||||
rt_kprintf("AT send ping commands error!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int ec20_connect(int argc, char **argv)
|
||||
{
|
||||
int32_t port;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
rt_kprintf("Please input: at_connect <host address>\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
sscanf(argv[2],"%d",&port);
|
||||
ec20_socket_connect(0, argv[1], port, AT_SOCKET_TCP, 1);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int ec20_close(int argc, char **argv)
|
||||
{
|
||||
if (ec20_socket_close(0) < 0)
|
||||
{
|
||||
rt_kprintf("ec20_socket_close fail\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("ec20_socket_closeed\n");
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int ec20_send(int argc, char **argv)
|
||||
{
|
||||
const char *buff = "1234567890\n";
|
||||
if (ec20_socket_send(0, buff, 11, AT_SOCKET_TCP) < 0)
|
||||
{
|
||||
rt_kprintf("ec20_socket_send fail\n");
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int ec20_domain(int argc, char **argv)
|
||||
{
|
||||
char ip[16];
|
||||
if (ec20_domain_resolve("baidu.com", ip) < 0)
|
||||
{
|
||||
rt_kprintf("ec20_socket_send fail\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("baidu.com : %s\n", ip);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int ec20_ifconfig(void)
|
||||
{
|
||||
at_response_t resp = RT_NULL;
|
||||
char resp_arg[AT_CMD_MAX_LEN] = { 0 };
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
resp = at_create_resp(128, 2, rt_tick_from_millisecond(300));
|
||||
if (!resp)
|
||||
{
|
||||
rt_kprintf("No memory for response structure!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
/* Query the status of the context profile */
|
||||
AT_SEND_CMD(resp, 0, 150 * 1000, "AT+QIACT?");
|
||||
at_resp_parse_line_args_by_kw(resp, "+QIACT:", "+QIACT: %*[^\"]\"%[^\"]", &resp_arg);
|
||||
rt_kprintf("IP adress : %s\n", resp_arg);
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
#include <finsh.h>
|
||||
MSH_CMD_EXPORT_ALIAS(ec20_net_init, at_net_init, initialize AT network);
|
||||
MSH_CMD_EXPORT_ALIAS(ec20_ping, at_ping, AT ping network host);
|
||||
MSH_CMD_EXPORT_ALIAS(ec20_ifconfig, at_ifconfig, list the information of network interfaces);
|
||||
MSH_CMD_EXPORT_ALIAS(ec20_connect, at_connect, AT connect network host);
|
||||
MSH_CMD_EXPORT_ALIAS(ec20_close, at_close, AT close a socket);
|
||||
MSH_CMD_EXPORT_ALIAS(ec20_send, at_send, AT send a pack);
|
||||
MSH_CMD_EXPORT_ALIAS(ec20_domain, at_domain, AT domain resolve);
|
||||
#endif
|
||||
|
||||
static const struct at_device_ops ec20_socket_ops = {
|
||||
|
@ -1388,6 +1235,406 @@ static const struct at_device_ops ec20_socket_ops = {
|
|||
ec20_socket_set_event_cb,
|
||||
};
|
||||
|
||||
/* set ec20 network interface device status and address information */
|
||||
static int ec20_netdev_set_info(struct netdev *netdev)
|
||||
{
|
||||
#define EC20_IEMI_RESP_SIZE 32
|
||||
#define EC20_IPADDR_RESP_SIZE 64
|
||||
#define EC20_DNS_RESP_SIZE 96
|
||||
#define EC20_INFO_RESP_TIMO rt_tick_from_millisecond(300)
|
||||
|
||||
int result = RT_EOK;
|
||||
at_response_t resp = RT_NULL;
|
||||
ip_addr_t addr;
|
||||
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
LOG_E("Input network interface device is NULL.\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* set network interface device status */
|
||||
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);
|
||||
|
||||
resp = at_create_resp(EC20_IEMI_RESP_SIZE, 0, EC20_INFO_RESP_TIMO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("EC20 set netdev information failed, no memory for response object.");
|
||||
result = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* set network interface device hardware address(IEMI) */
|
||||
{
|
||||
#define EC20_NETDEV_HWADDR_LEN 8
|
||||
#define EC20_IEMI_LEN 15
|
||||
|
||||
char iemi[EC20_IEMI_LEN] = {0};
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* send "AT+GSN" commond to get device IEMI */
|
||||
if (at_exec_cmd(resp, "AT+GSN") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 2, "%s", iemi) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+GSN\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("EC20 IEMI number: %s", iemi);
|
||||
|
||||
netdev->hwaddr_len = EC20_NETDEV_HWADDR_LEN;
|
||||
/* get hardware address by IEMI */
|
||||
for (i = 0, j = 0; i < EC20_NETDEV_HWADDR_LEN && j < EC20_IEMI_LEN; i++, j+=2)
|
||||
{
|
||||
if (j != EC20_IEMI_LEN - 1)
|
||||
{
|
||||
netdev->hwaddr[i] = (iemi[j] - '0') * 10 + (iemi[j + 1] - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev->hwaddr[i] = (iemi[j] - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set network interface device IP address */
|
||||
{
|
||||
#define IP_ADDR_SIZE_MAX 16
|
||||
char ipaddr[IP_ADDR_SIZE_MAX] = {0};
|
||||
|
||||
at_resp_set_info(resp, EC20_IPADDR_RESP_SIZE, 0, EC20_INFO_RESP_TIMO);
|
||||
|
||||
/* send "AT+QIACT?" commond to get IP address */
|
||||
if (at_exec_cmd(resp, "AT+QIACT?") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* parse response data "+QIACT: 1,<context_state>,<context_type>[,<IP_address>]" */
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+QIACT:", "+QIACT: %*[^\"]\"%[^\"]", ipaddr) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+QIACT?\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("EC20 IP address: %s", ipaddr);
|
||||
|
||||
/* set network interface address information */
|
||||
inet_aton(ipaddr, &addr);
|
||||
netdev_low_level_set_ipaddr(netdev, &addr);
|
||||
}
|
||||
|
||||
/* set network interface device dns server */
|
||||
{
|
||||
#define DNS_ADDR_SIZE_MAX 16
|
||||
char dns_server1[DNS_ADDR_SIZE_MAX] = {0}, dns_server2[DNS_ADDR_SIZE_MAX] = {0};
|
||||
|
||||
at_resp_set_info(resp, EC20_DNS_RESP_SIZE, 0, EC20_INFO_RESP_TIMO);
|
||||
|
||||
/* send "AT+QIDNSCFG=1" commond to get DNS servers address */
|
||||
if (at_exec_cmd(resp, "AT+QIDNSCFG=1") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* parse response data "+QIDNSCFG: <contextID>,<pridnsaddr>,<secdnsaddr>" */
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+QIDNSCFG:", "+QIDNSCFG: 1,\"%[^\"]\",\"%[^\"]\"",
|
||||
dns_server1, dns_server2) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+QIDNSCFG=1\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("EC20 primary DNS server address: %s", dns_server1);
|
||||
LOG_D("EC20 secondary DNS server address: %s", dns_server2);
|
||||
|
||||
inet_aton(dns_server1, &addr);
|
||||
netdev_low_level_set_dns_server(netdev, 0, &addr);
|
||||
|
||||
inet_aton(dns_server2, &addr);
|
||||
netdev_low_level_set_dns_server(netdev, 1, &addr);
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ec20_check_link_status_entry(void *parameter)
|
||||
{
|
||||
#define EC20_LINK_RESP_SIZE 64
|
||||
#define EC20_LINK_RESP_TIMO (3 * RT_TICK_PER_SECOND)
|
||||
#define EC20_LINK_DELAY_TIME (30 * RT_TICK_PER_SECOND)
|
||||
|
||||
int link_stat = 0;
|
||||
at_response_t resp = RT_NULL;
|
||||
struct netdev *netdev = (struct netdev *) parameter;
|
||||
|
||||
resp = at_create_resp(EC20_LINK_RESP_SIZE, 0, EC20_LINK_RESP_TIMO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("EC20 set check link status failed, no memory for response object.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send "AT+CGREG" commond to check netweork interface device link status */
|
||||
if (at_exec_cmd(resp, "AT+CGREG?") < 0)
|
||||
{
|
||||
if (netdev_is_link_up(netdev))
|
||||
{
|
||||
netdev_low_level_set_link_status(netdev, RT_FALSE);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
rt_thread_mdelay(EC20_LINK_DELAY_TIME);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
at_resp_parse_line_args_by_kw(resp, "+CGREG:", "+CGREG: %*d,%d", &link_stat);
|
||||
|
||||
/* 1 Registered, home network,5 Registered, roaming */
|
||||
if (link_stat == 1 || link_stat == 5)
|
||||
{
|
||||
if (netdev_is_link_up(netdev) == RT_FALSE)
|
||||
{
|
||||
netdev_low_level_set_link_status(netdev, RT_TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (netdev_is_link_up(netdev))
|
||||
{
|
||||
netdev_low_level_set_link_status(netdev, RT_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
rt_thread_mdelay(EC20_LINK_DELAY_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
static int ec20_netdev_check_link_status(struct netdev *netdev)
|
||||
{
|
||||
#define EC20_LINK_THREAD_STACK_SIZE 1024
|
||||
#define EC20_LINK_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX - 2)
|
||||
#define EC20_LINK_THREAD_TICK 20
|
||||
|
||||
rt_thread_t tid;
|
||||
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
LOG_E("Input network interface device is NULL.\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
/* create WIZnet link status Polling thread */
|
||||
tid = rt_thread_create("ec20_link", ec20_check_link_status_entry, (void *) netdev,
|
||||
EC20_LINK_THREAD_STACK_SIZE, EC20_LINK_THREAD_PRIORITY, EC20_LINK_THREAD_TICK);
|
||||
if (tid != RT_NULL)
|
||||
{
|
||||
rt_thread_startup(tid);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int ec20_netdev_set_up(struct netdev *netdev)
|
||||
{
|
||||
netdev_low_level_set_status(netdev, RT_TRUE);
|
||||
LOG_D("EC20 network interface set up status.");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int ec20_netdev_set_down(struct netdev *netdev)
|
||||
{
|
||||
netdev_low_level_set_status(netdev, RT_FALSE);
|
||||
LOG_D("EC20 network interface set down status.");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int ec20_netdev_set_dns_server(struct netdev *netdev, ip_addr_t *dns_server)
|
||||
{
|
||||
#define EC20_DNS_RESP_LEN 8
|
||||
#define EC20_DNS_RESP_TIMEO rt_tick_from_millisecond(300)
|
||||
|
||||
at_response_t resp = RT_NULL;
|
||||
int result = RT_EOK;
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(dns_server);
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
resp = at_create_resp(EC20_DNS_RESP_LEN, 0, EC20_DNS_RESP_TIMEO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("EC20 set dns server failed, no memory for response object.");
|
||||
result = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* send "AT+QIDNSCFG=<pri_dns>[,<sec_dns>]" commond to set dns servers */
|
||||
if (at_exec_cmd(resp, "AT+QIDNSCFG=1,\"%s\"", inet_ntoa(dns_server)) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
netdev_low_level_set_dns_server(netdev, 0, dns_server);
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ec20_netdev_ping(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp)
|
||||
{
|
||||
#define EC20_PING_RESP_SIZE 128
|
||||
#define EC20_PING_IP_SIZE 16
|
||||
#define EC20_PING_TIMEO (5 * RT_TICK_PER_SECOND)
|
||||
|
||||
at_response_t resp = RT_NULL;
|
||||
rt_err_t result = RT_EOK;
|
||||
int response = -1, recv_data_len, ping_time, ttl;
|
||||
char ip_addr[EC20_PING_IP_SIZE] = {0};
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(host);
|
||||
RT_ASSERT(ping_resp);
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
resp = at_create_resp(EC20_PING_RESP_SIZE, 4, EC20_PING_TIMEO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("No memory for response structure!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
/* send "AT+QPING="<host>"[,[<timeout>][,<pingnum>]]" commond to send ping request */
|
||||
if (at_exec_cmd(resp, "AT+QPING=1,\"%s\",%d,1", host, timeout / RT_TICK_PER_SECOND) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
at_resp_parse_line_args_by_kw(resp, "+QPING:", "+QPING:%d", &response);
|
||||
/* Received the ping response from the server */
|
||||
if (response == 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* prase response number */
|
||||
switch (response)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ec20_netdev_netstat(struct netdev *netdev)
|
||||
{
|
||||
// TODO
|
||||
return;
|
||||
}
|
||||
|
||||
const struct netdev_ops ec20_netdev_ops =
|
||||
{
|
||||
ec20_netdev_set_up,
|
||||
ec20_netdev_set_down,
|
||||
|
||||
RT_NULL,
|
||||
ec20_netdev_set_dns_server,
|
||||
RT_NULL,
|
||||
|
||||
ec20_netdev_ping,
|
||||
ec20_netdev_netstat,
|
||||
};
|
||||
|
||||
static int ec20_netdev_add(const char *netdev_name)
|
||||
{
|
||||
#define ETHERNET_MTU 1500
|
||||
#define HWADDR_LEN 6
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
netdev = (struct netdev *)rt_calloc(1, sizeof(struct netdev));
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
netdev->mtu = ETHERNET_MTU;
|
||||
netdev->ops = &ec20_netdev_ops;
|
||||
netdev->hwaddr_len = HWADDR_LEN;
|
||||
|
||||
#ifdef SAL_USING_AT
|
||||
extern int sal_at_netdev_set_pf_info(struct netdev *netdev);
|
||||
/* set the network interface socket/netdb operations */
|
||||
sal_at_netdev_set_pf_info(netdev);
|
||||
#endif
|
||||
|
||||
return netdev_register(netdev, netdev_name, RT_NULL);
|
||||
}
|
||||
|
||||
static int at_socket_device_init(void)
|
||||
{
|
||||
/* create current AT socket event */
|
||||
|
@ -1412,14 +1659,21 @@ static int at_socket_device_init(void)
|
|||
|
||||
/* register URC data execution function */
|
||||
at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
|
||||
|
||||
|
||||
/* Add ec20 network inetrface device to the netdev list */
|
||||
if (ec20_netdev_add(EC20_NETDEV_NAME) < 0)
|
||||
{
|
||||
LOG_E("EC20 network interface device(%d) add failed.", EC20_NETDEV_NAME);
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
/* initialize EC20 network */
|
||||
ec20_net_init();
|
||||
|
||||
/* set EC20 AT Socket options */
|
||||
at_socket_device_register(&ec20_socket_ops);
|
||||
|
||||
return 0;
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_APP_EXPORT(at_socket_device_init);
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
#include <at_socket.h>
|
||||
|
||||
#include <netdev.h>
|
||||
|
||||
#if !defined(AT_SW_VERSION_NUM) || AT_SW_VERSION_NUM < 0x10200
|
||||
#error "This AT Client version is older, please check and update latest AT Client!"
|
||||
#endif
|
||||
|
@ -56,8 +58,11 @@
|
|||
#define ESP8266_EVENT_CONN_FAIL (1L << 4)
|
||||
#define ESP8266_EVENT_SEND_FAIL (1L << 5)
|
||||
|
||||
#define ESP8266_NETDEV_NAME "esp8266"
|
||||
|
||||
static int cur_socket;
|
||||
static int cur_send_bfsz;
|
||||
static struct rt_delayed_work esp8266_net_work;
|
||||
static rt_event_t at_socket_event;
|
||||
static rt_mutex_t at_event_lock;
|
||||
static at_evt_cb_t at_evt_cb_set[] = {
|
||||
|
@ -114,7 +119,7 @@ static int esp8266_socket_close(int socket)
|
|||
goto __exit;
|
||||
}
|
||||
|
||||
__exit:
|
||||
__exit:
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
if (resp)
|
||||
|
@ -345,7 +350,7 @@ static int esp8266_domain_resolve(const char *name, char ip[16])
|
|||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
for(i = 0; i < RESOLVE_RETRY; i++)
|
||||
for (i = 0; i < RESOLVE_RETRY; i++)
|
||||
{
|
||||
if (at_exec_cmd(resp, "AT+CIPDOMAIN=\"%s\"", name) < 0)
|
||||
{
|
||||
|
@ -354,7 +359,7 @@ static int esp8266_domain_resolve(const char *name, char ip[16])
|
|||
}
|
||||
|
||||
/* parse the third line of response data, get the IP address */
|
||||
if(at_resp_parse_line_args_by_kw(resp, "+CIPDOMAIN:", "+CIPDOMAIN:%s", recv_ip) < 0)
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+CIPDOMAIN:", "+CIPDOMAIN:%s", recv_ip) < 0)
|
||||
{
|
||||
rt_thread_delay(rt_tick_from_millisecond(100));
|
||||
/* resolve failed, maybe receive an URC CRLF */
|
||||
|
@ -510,12 +515,15 @@ static void urc_func(const char *data, rt_size_t size)
|
|||
{
|
||||
RT_ASSERT(data && size);
|
||||
|
||||
if(strstr(data, "WIFI CONNECTED"))
|
||||
if (strstr(data, "WIFI CONNECTED"))
|
||||
{
|
||||
netdev_low_level_set_link_status(netdev_get_by_name(ESP8266_NETDEV_NAME), RT_TRUE);
|
||||
rt_work_submit(&(esp8266_net_work.work), RT_TICK_PER_SECOND);
|
||||
LOG_I("ESP8266 WIFI is connected.");
|
||||
}
|
||||
else if(strstr(data, "WIFI DISCONNECT"))
|
||||
else if (strstr(data, "WIFI DISCONNECT"))
|
||||
{
|
||||
netdev_low_level_set_link_status(netdev_get_by_name(ESP8266_NETDEV_NAME), RT_FALSE);
|
||||
LOG_I("ESP8266 WIFI is disconnect.");
|
||||
}
|
||||
}
|
||||
|
@ -543,6 +551,134 @@ static struct at_urc urc_table[] = {
|
|||
} \
|
||||
} while(0); \
|
||||
|
||||
static void exp8266_get_netdev_info(struct rt_work *work, void *work_data)
|
||||
{
|
||||
#define AT_ADDR_LEN 32
|
||||
at_response_t resp = RT_NULL;
|
||||
char ip[AT_ADDR_LEN], mac[AT_ADDR_LEN];
|
||||
char gateway[AT_ADDR_LEN], netmask[AT_ADDR_LEN];
|
||||
char dns_server1[AT_ADDR_LEN] = {0}, dns_server2[AT_ADDR_LEN] = {0};
|
||||
const char *resp_expr = "%*[^\"]\"%[^\"]\"";
|
||||
const char *resp_dns = "+CIPDNS_CUR:%s";
|
||||
const char *resp_dhcp = "+CWDHCP_CUR:%d";
|
||||
ip_addr_t sal_ip_addr;
|
||||
rt_uint8_t mac_addr[6] = {0};
|
||||
rt_uint8_t dhcp_stat = 0;
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
netdev = (struct netdev *)work_data;
|
||||
|
||||
rt_memset(ip, 0x00, sizeof(ip));
|
||||
rt_memset(mac, 0x00, sizeof(mac));
|
||||
rt_memset(gateway, 0x00, sizeof(gateway));
|
||||
rt_memset(netmask, 0x00, sizeof(netmask));
|
||||
|
||||
resp = at_create_resp(512, 0, rt_tick_from_millisecond(300));
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
return;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
/* send mac addr query commond "AT+CIFSR" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CIFSR") < 0)
|
||||
{
|
||||
LOG_E("AT send \"AT+CIFSR\" commands error!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 2, resp_expr, mac) <= 0)
|
||||
{
|
||||
LOG_E("Parse error, current line buff : %s", at_resp_get_line(resp, 2));
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* send addr info query commond "AT+CIPSTA?" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CIPSTA?") < 0)
|
||||
{
|
||||
LOG_E("AT send \"AT+CIPSTA?\" commands error!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 1, resp_expr, ip) <= 0 ||
|
||||
at_resp_parse_line_args(resp, 2, resp_expr, gateway) <= 0 ||
|
||||
at_resp_parse_line_args(resp, 3, resp_expr, netmask) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+CIPSTA?\" commands resposne data error!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* set netdev info */
|
||||
inet_aton(ip, &sal_ip_addr);
|
||||
netdev_low_level_set_ipaddr(netdev, &sal_ip_addr);
|
||||
inet_aton(gateway, &sal_ip_addr);
|
||||
netdev_low_level_set_gw(netdev, &sal_ip_addr);
|
||||
inet_aton(netmask, &sal_ip_addr);
|
||||
netdev_low_level_set_netmask(netdev, &sal_ip_addr);
|
||||
sscanf(mac, "%x:%x:%x:%x:%x:%x", (rt_uint32_t *)&mac_addr[0], (rt_uint32_t *)&mac_addr[1], (rt_uint32_t *)&mac_addr[2], (rt_uint32_t *)&mac_addr[3], (rt_uint32_t *)&mac_addr[4], (rt_uint32_t *)&mac_addr[5]);
|
||||
memcpy(netdev->hwaddr, (const void *)mac_addr, netdev->hwaddr_len);
|
||||
|
||||
/* send dns server query commond "AT+CIPDNS_CUR?" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CIPDNS_CUR?") < 0)
|
||||
{
|
||||
LOG_E("AT send \"AT+CIPDNS_CUR?\" commands error!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 1, resp_dns, dns_server1) <= 0 &&
|
||||
at_resp_parse_line_args(resp, 2, resp_dns, dns_server2) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+CIPDNS_CUR?\" commands resposne data error!");
|
||||
LOG_E("get dns server failed! Please check whether your firmware supports the \"AT+CIPDNS_CUR?\" command.");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (strlen(dns_server1) > 0)
|
||||
{
|
||||
inet_aton(dns_server1, &sal_ip_addr);
|
||||
netdev_low_level_set_dns_server(netdev, 0, &sal_ip_addr);
|
||||
}
|
||||
|
||||
if (strlen(dns_server2) > 0)
|
||||
{
|
||||
inet_aton(dns_server2, &sal_ip_addr);
|
||||
netdev_low_level_set_dns_server(netdev, 1, &sal_ip_addr);
|
||||
}
|
||||
|
||||
/* send DHCP query commond " AT+CWDHCP_CUR?" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CWDHCP_CUR?") < 0)
|
||||
{
|
||||
LOG_E("AT send \"AT+CWDHCP_CUR?\" commands error!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* parse response data, get the DHCP status */
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+CWDHCP_CUR:", "+CWDHCP_CUR:%d", &dhcp_stat) < 0)
|
||||
{
|
||||
LOG_E("get DHCP status failed!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* Bit0: SoftAP DHCP status, Bit1: Station DHCP status */
|
||||
if (dhcp_stat & 0x02)
|
||||
{
|
||||
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev_low_level_set_dhcp_status(netdev, RT_FALSE);
|
||||
}
|
||||
|
||||
__exit:
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
}
|
||||
|
||||
static void esp8266_init_thread_entry(void *parameter)
|
||||
{
|
||||
at_response_t resp = RT_NULL;
|
||||
|
@ -592,10 +728,12 @@ __exit:
|
|||
|
||||
if (!result)
|
||||
{
|
||||
netdev_low_level_set_status(netdev_get_by_name(ESP8266_NETDEV_NAME), RT_TRUE);
|
||||
LOG_I("AT network initialize success!");
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev_low_level_set_status(netdev_get_by_name(ESP8266_NETDEV_NAME), RT_FALSE);
|
||||
LOG_E("AT network initialize failed (%d)!", result);
|
||||
}
|
||||
}
|
||||
|
@ -605,7 +743,7 @@ int esp8266_net_init(void)
|
|||
#ifdef PKG_AT_INIT_BY_THREAD
|
||||
rt_thread_t tid;
|
||||
|
||||
tid = rt_thread_create("esp8266_net_init", esp8266_init_thread_entry, RT_NULL,ESP8266_THREAD_STACK_SIZE, ESP8266_THREAD_PRIORITY, 20);
|
||||
tid = rt_thread_create("esp8266_net_init", esp8266_init_thread_entry, RT_NULL, ESP8266_THREAD_STACK_SIZE, ESP8266_THREAD_PRIORITY, 20);
|
||||
if (tid)
|
||||
{
|
||||
rt_thread_startup(tid);
|
||||
|
@ -620,121 +758,93 @@ int esp8266_net_init(void)
|
|||
|
||||
return RT_EOK;
|
||||
}
|
||||
#ifdef FINSH_USING_MSH
|
||||
#include <finsh.h>
|
||||
MSH_CMD_EXPORT_ALIAS(esp8266_net_init, at_net_init, initialize AT network);
|
||||
#endif
|
||||
|
||||
int esp8266_ping(int argc, char **argv)
|
||||
static const struct at_device_ops esp8266_socket_ops =
|
||||
{
|
||||
at_response_t resp = RT_NULL;
|
||||
static int icmp_seq;
|
||||
int req_time;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
rt_kprintf("Please input: at_ping <host address>\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
resp = at_create_resp(64, 0, rt_tick_from_millisecond(5000));
|
||||
if (!resp)
|
||||
{
|
||||
rt_kprintf("No memory for response structure!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
for(icmp_seq = 1; icmp_seq <= 4; icmp_seq++)
|
||||
{
|
||||
if (at_exec_cmd(resp, "AT+PING=\"%s\"", argv[1]) < 0)
|
||||
{
|
||||
rt_kprintf("ping: unknown remote server host\n");
|
||||
at_delete_resp(resp);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
if(at_resp_parse_line_args_by_kw(resp, "+", "+%d", &req_time) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (req_time)
|
||||
{
|
||||
rt_kprintf("32 bytes from %s icmp_seq=%d time=%d ms\n", argv[1], icmp_seq, req_time);
|
||||
}
|
||||
}
|
||||
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
esp8266_socket_connect,
|
||||
esp8266_socket_close,
|
||||
esp8266_socket_send,
|
||||
esp8266_domain_resolve,
|
||||
esp8266_socket_set_event_cb,
|
||||
};
|
||||
|
||||
static int esp8266_netdev_set_up(struct netdev *netdev)
|
||||
{
|
||||
netdev_low_level_set_status(netdev, RT_TRUE);
|
||||
LOG_D("esp8266 network interface set up status.");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int esp8266_ifconfig(int argc, char **argv)
|
||||
static int esp8266_netdev_set_down(struct netdev *netdev)
|
||||
{
|
||||
#define AT_ADDR_LEN 128
|
||||
int result = RT_EOK;
|
||||
at_response_t resp = RT_NULL;
|
||||
char ip[AT_ADDR_LEN], mac[AT_ADDR_LEN];
|
||||
char gateway[AT_ADDR_LEN], netmask[AT_ADDR_LEN];
|
||||
const char *resp_expr = "%*[^\"]\"%[^\"]\"";
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
rt_kprintf("Please input: at_ifconfig\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_memset(ip, 0x00, sizeof(ip));
|
||||
rt_memset(mac, 0x00, sizeof(mac));
|
||||
rt_memset(gateway, 0x00, sizeof(gateway));
|
||||
rt_memset(netmask, 0x00, sizeof(netmask));
|
||||
netdev_low_level_set_status(netdev, RT_FALSE);
|
||||
LOG_D("esp8266 network interface set down status.");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
resp = at_create_resp(512, 0, rt_tick_from_millisecond(300));
|
||||
static int esp8266_netdev_set_addr_info(struct netdev *netdev, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw)
|
||||
{
|
||||
#define RESP_SIZE 128
|
||||
#define IPV4_ADDR_STRLEN_MAX 16
|
||||
at_response_t resp = RT_NULL;
|
||||
int result = RT_EOK;
|
||||
char esp8266_ip_addr[IPV4_ADDR_STRLEN_MAX] = {0};
|
||||
char esp8266_gw_addr[IPV4_ADDR_STRLEN_MAX] = {0};
|
||||
char esp8266_netmask_addr[IPV4_ADDR_STRLEN_MAX] = {0};
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(ip_addr || netmask || gw);
|
||||
|
||||
resp = at_create_resp(RESP_SIZE, 0, rt_tick_from_millisecond(300));
|
||||
if (!resp)
|
||||
{
|
||||
rt_kprintf("No memory for response structure!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
if (at_exec_cmd(resp, "AT+CIFSR") < 0)
|
||||
{
|
||||
rt_kprintf("AT send \"AT+CIFSR\" commands error!\n");
|
||||
result = -RT_ERROR;
|
||||
LOG_E("No memory for response structure!");
|
||||
result = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 2, resp_expr, mac) <= 0)
|
||||
{
|
||||
rt_kprintf("Parse error, current line buff : %s\n", at_resp_get_line(resp, 2));
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
/* Convert numeric IP address into decimal dotted ASCII representation. */
|
||||
if (ip_addr)
|
||||
rt_memcpy(esp8266_ip_addr, inet_ntoa(*ip_addr), IPV4_ADDR_STRLEN_MAX);
|
||||
else
|
||||
rt_memcpy(esp8266_ip_addr, inet_ntoa(netdev->ip_addr), IPV4_ADDR_STRLEN_MAX);
|
||||
|
||||
if (at_exec_cmd(resp, "AT+CIPSTA?") < 0)
|
||||
{
|
||||
rt_kprintf("AT send \"AT+CIPSTA?\" commands error!\n");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 1, resp_expr, ip) <= 0 ||
|
||||
at_resp_parse_line_args(resp, 2, resp_expr, gateway) <= 0 ||
|
||||
at_resp_parse_line_args(resp, 3, resp_expr, netmask) <= 0)
|
||||
{
|
||||
rt_kprintf("Prase \"AT+CIPSTA?\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
if (gw)
|
||||
rt_memcpy(esp8266_gw_addr, inet_ntoa(*gw), IPV4_ADDR_STRLEN_MAX);
|
||||
else
|
||||
rt_memcpy(esp8266_gw_addr, inet_ntoa(netdev->gw), IPV4_ADDR_STRLEN_MAX);
|
||||
|
||||
rt_kprintf("network interface: esp8266\n");
|
||||
rt_kprintf("MAC: %s\n", mac);
|
||||
rt_kprintf("ip address: %s\n", ip);
|
||||
rt_kprintf("gw address: %s\n", gateway);
|
||||
rt_kprintf("net mask : %s\n", netmask);
|
||||
if (netmask)
|
||||
rt_memcpy(esp8266_netmask_addr, inet_ntoa(*netmask), IPV4_ADDR_STRLEN_MAX);
|
||||
else
|
||||
rt_memcpy(esp8266_netmask_addr, inet_ntoa(netdev->netmask), IPV4_ADDR_STRLEN_MAX);
|
||||
|
||||
/* send addr info set commond "AT+CIPSTA_CUR=<ip>[,<gateway>,<netmask>]" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CIPSTA_CUR=\"%s\",\"%s\",\"%s\"", esp8266_ip_addr, esp8266_gw_addr, esp8266_netmask_addr) < 0)
|
||||
{
|
||||
LOG_E("esp8266 set addr info failed.");
|
||||
result = -RT_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update netdev information */
|
||||
if (ip_addr)
|
||||
netdev_low_level_set_ipaddr(netdev, ip_addr);
|
||||
|
||||
if (gw)
|
||||
netdev_low_level_set_gw(netdev, gw);
|
||||
|
||||
if (netmask)
|
||||
netdev_low_level_set_netmask(netdev, netmask);
|
||||
|
||||
LOG_D("esp8266 set addr info successfully.");
|
||||
}
|
||||
|
||||
__exit:
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
|
@ -743,20 +853,273 @@ __exit:
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
#include <finsh.h>
|
||||
MSH_CMD_EXPORT_ALIAS(esp8266_net_init, at_net_init, initialize AT network);
|
||||
MSH_CMD_EXPORT_ALIAS(esp8266_ping, at_ping, AT ping network host);
|
||||
MSH_CMD_EXPORT_ALIAS(esp8266_ifconfig, at_ifconfig, list the information of network interfaces);
|
||||
static int esp8266_netdev_set_dns_server(struct netdev *netdev, ip_addr_t *dns_server)
|
||||
{
|
||||
#define RESP_SIZE 128
|
||||
at_response_t resp = RT_NULL;
|
||||
int result = RT_EOK;
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(dns_server);
|
||||
|
||||
resp = at_create_resp(RESP_SIZE, 0, rt_tick_from_millisecond(300));
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send dns server set commond "AT+CIPDNS_CUR=<enable>[,<DNS server0>,<DNS server1>]" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CIPDNS_CUR=1,\"%s\"", inet_ntoa(dns_server)) < 0)
|
||||
{
|
||||
LOG_E("set dns server(%s) failed", inet_ntoa(dns_server));
|
||||
result = -RT_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev_low_level_set_dns_server(netdev, 0, dns_server);
|
||||
LOG_D("esp8266 set dns server successfully.");
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int esp8266_netdev_set_dhcp(struct netdev *netdev, rt_bool_t is_enabled)
|
||||
{
|
||||
#define ESP8266_STATION 1
|
||||
#define RESP_SIZE 128
|
||||
|
||||
at_response_t resp = RT_NULL;
|
||||
int result = RT_EOK;
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
|
||||
resp = at_create_resp(RESP_SIZE, 0, rt_tick_from_millisecond(300));
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send dhcp set commond "AT+CWDHCP_CUR=<mode>,<en>" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CWDHCP_CUR=%d,%d", ESP8266_STATION, is_enabled) < 0)
|
||||
{
|
||||
LOG_E("set dhcp status(%d) failed", is_enabled);
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev_low_level_set_dhcp_status(netdev, is_enabled);
|
||||
LOG_D("esp8266 set dhcp successfully.");
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int esp8266_netdev_ping(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp)
|
||||
{
|
||||
#define ESP8266_PING_IP_SIZE 16
|
||||
|
||||
at_response_t resp = RT_NULL;
|
||||
rt_err_t result = RT_EOK;
|
||||
int req_time;
|
||||
char ip_addr[ESP8266_PING_IP_SIZE] = {0};
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(host);
|
||||
RT_ASSERT(ping_resp);
|
||||
|
||||
resp = at_create_resp(64, 0, rt_tick_from_millisecond(5000));
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send domain commond "AT+CIPDOMAIN=<domain name>" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CIPDOMAIN=\"%s\"", host) < 0)
|
||||
{
|
||||
LOG_E("ping: send commond AT+CIPDOMAIN=<domain name> failed");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* parse the third line of response data, get the IP address */
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+CIPDOMAIN:", "+CIPDOMAIN:%s", ip_addr) < 0)
|
||||
{
|
||||
LOG_E("ping: get the IP address failed");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* send ping commond "AT+PING=<IP>" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+PING=\"%s\"", host) < 0)
|
||||
{
|
||||
LOG_E("ping: unknown remote server host");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+", "+%d", &req_time) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (req_time)
|
||||
{
|
||||
inet_aton(ip_addr, &(ping_resp->ip_addr));
|
||||
ping_resp->data_len = data_len;
|
||||
ping_resp->ttl = 0;
|
||||
ping_resp->ticks = req_time;
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void esp8266_netdev_netstat(struct netdev *netdev)
|
||||
{
|
||||
#define ESP8266_NETSTAT_RESP_SIZE 320
|
||||
#define ESP8266_NETSTAT_TYPE_SIZE 4
|
||||
#define ESP8266_NETSTAT_IPADDR_SIZE 17
|
||||
#define ESP8266_NETSTAT_EXPRESSION "+CIPSTATUS:%*d,\"%[^\"]\",\"%[^\"]\",%d,%d,%*d"
|
||||
|
||||
at_response_t resp = RT_NULL;
|
||||
rt_err_t result = RT_EOK;
|
||||
int remote_ip, remote_port, local_port, i;
|
||||
char *type = RT_NULL;
|
||||
char *ipaddr = RT_NULL;
|
||||
|
||||
type = rt_calloc(1, ESP8266_NETSTAT_TYPE_SIZE);
|
||||
ipaddr = rt_calloc(1, ESP8266_NETSTAT_IPADDR_SIZE);
|
||||
if ((type && ipaddr) == RT_NULL)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
resp = at_create_resp(ESP8266_NETSTAT_RESP_SIZE, 0, rt_tick_from_millisecond(5000));
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send network connection information commond "AT+CIPSTATUS" and wait response */
|
||||
if (at_exec_cmd(resp, "AT+CIPSTATUS") < 0)
|
||||
{
|
||||
LOG_E("netstat: send commond AT+CIPSTATUS failed");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
for (i = 1; i <= resp->line_counts; i++)
|
||||
{
|
||||
if (strstr(at_resp_get_line(resp, i), "+CIPSTATUS"))
|
||||
{
|
||||
/* parse the third line of response data, get the network connection information */
|
||||
if (at_resp_parse_line_args(resp, i, ESP8266_NETSTAT_EXPRESSION, type, ipaddr, &remote_port, &local_port) < 0)
|
||||
goto __exit;
|
||||
else
|
||||
{
|
||||
LOG_RAW("%s: %s:%d ==> %s:%d\n", type, inet_ntoa(netdev->ip_addr), local_port, ipaddr, remote_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
if (type)
|
||||
{
|
||||
rt_free(type);
|
||||
}
|
||||
|
||||
if (ipaddr)
|
||||
{
|
||||
rt_free(ipaddr);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
}
|
||||
|
||||
const struct netdev_ops esp8266_netdev_ops =
|
||||
{
|
||||
esp8266_netdev_set_up,
|
||||
esp8266_netdev_set_down,
|
||||
|
||||
esp8266_netdev_set_addr_info,
|
||||
esp8266_netdev_set_dns_server,
|
||||
esp8266_netdev_set_dhcp,
|
||||
|
||||
esp8266_netdev_ping,
|
||||
esp8266_netdev_netstat,
|
||||
};
|
||||
|
||||
static struct netdev *esp8266_netdev_add(const char *netdev_name)
|
||||
{
|
||||
#define ETHERNET_MTU 1500
|
||||
#define HWADDR_LEN 6
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
RT_ASSERT(netdev_name);
|
||||
|
||||
netdev = (struct netdev *) rt_calloc(1, sizeof(struct netdev));
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
netdev->mtu = ETHERNET_MTU;
|
||||
netdev->ops = &esp8266_netdev_ops;
|
||||
netdev->hwaddr_len = HWADDR_LEN;
|
||||
|
||||
#ifdef SAL_USING_AT
|
||||
extern int sal_at_netdev_set_pf_info(struct netdev *netdev);
|
||||
/* set the network interface socket/netdb operations */
|
||||
sal_at_netdev_set_pf_info(netdev);
|
||||
#endif
|
||||
|
||||
static const struct at_device_ops esp8266_socket_ops = {
|
||||
esp8266_socket_connect,
|
||||
esp8266_socket_close,
|
||||
esp8266_socket_send,
|
||||
esp8266_domain_resolve,
|
||||
esp8266_socket_set_event_cb,
|
||||
};
|
||||
netdev_register(netdev, netdev_name, RT_NULL);
|
||||
|
||||
return netdev;
|
||||
}
|
||||
|
||||
static int at_socket_device_init(void)
|
||||
{
|
||||
|
@ -783,6 +1146,12 @@ static int at_socket_device_init(void)
|
|||
/* register URC data execution function */
|
||||
at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
|
||||
|
||||
/* Add esp8266 to the netdev list */
|
||||
esp8266_netdev_add(ESP8266_NETDEV_NAME);
|
||||
|
||||
/* initialize esp8266 net workqueue */
|
||||
rt_delayed_work_init(&esp8266_net_work, exp8266_get_netdev_info, (void *)netdev_get_by_name(ESP8266_NETDEV_NAME));
|
||||
|
||||
/* initialize esp8266 network */
|
||||
esp8266_net_init();
|
||||
|
||||
|
|
556
at_socket_m26.c
556
at_socket_m26.c
|
@ -28,6 +28,8 @@
|
|||
#include <rtthread.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netdev.h>
|
||||
|
||||
#include <at.h>
|
||||
#include <at_socket.h>
|
||||
|
||||
|
@ -40,6 +42,8 @@
|
|||
|
||||
#ifdef AT_DEVICE_M26
|
||||
|
||||
#define M26_NETDEV_NAME "m26"
|
||||
|
||||
#define M26_MODULE_SEND_MAX_SIZE 1460
|
||||
#define M26_WAIT_CONNECT_TIME 5000
|
||||
#define M26_THREAD_STACK_SIZE 1024
|
||||
|
@ -100,6 +104,9 @@ static int m26_socket_close(int socket)
|
|||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
cur_socket = socket;
|
||||
|
||||
/* Clear socket close event */
|
||||
at_socket_event_recv(SET_EVENT(socket, M26_EVNET_CLOSE_OK), 0, RT_EVENT_FLAG_OR);
|
||||
|
||||
if (at_exec_cmd(RT_NULL, "AT+QICLOSE=%d", socket) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
|
@ -147,6 +154,9 @@ static int m26_socket_connect(int socket, char *ip, int32_t port, enum at_socket
|
|||
|
||||
__retry:
|
||||
|
||||
/* Clear socket connect event */
|
||||
at_socket_event_recv(SET_EVENT(socket, M26_EVENT_CONN_OK | M26_EVENT_CONN_FAIL), 0, RT_EVENT_FLAG_OR);
|
||||
|
||||
if (is_client)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -175,14 +185,14 @@ __retry:
|
|||
}
|
||||
|
||||
/* waiting result event from AT URC, the device default connection timeout is 75 seconds, but it set to 10 seconds is convenient to use.*/
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), rt_tick_from_millisecond(10 * 1000), RT_EVENT_FLAG_OR) < 0)
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) connect failed, wait connect result timeout.", socket);
|
||||
result = -RT_ETIMEOUT;
|
||||
goto __exit;
|
||||
}
|
||||
/* waiting OK or failed result */
|
||||
if ((event_result = at_socket_event_recv(M26_EVENT_CONN_OK | M26_EVENT_CONN_FAIL, rt_tick_from_millisecond(1 * 1000),
|
||||
if ((event_result = at_socket_event_recv(M26_EVENT_CONN_OK | M26_EVENT_CONN_FAIL, 1 * RT_TICK_PER_SECOND,
|
||||
RT_EVENT_FLAG_OR)) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) connect failed, wait connect OK|FAIL timeout.", socket);
|
||||
|
@ -216,7 +226,7 @@ __exit:
|
|||
|
||||
static int at_get_send_size(int socket, size_t *size, size_t *acked, size_t *nacked)
|
||||
{
|
||||
at_response_t resp = at_create_resp(64, 0, rt_tick_from_millisecond(5000));
|
||||
at_response_t resp = at_create_resp(64, 0, 5 * RT_TICK_PER_SECOND);
|
||||
int result = 0;
|
||||
|
||||
if (!resp)
|
||||
|
@ -288,7 +298,7 @@ static int m26_socket_send(int socket, const char *buff, size_t bfsz, enum at_so
|
|||
|
||||
RT_ASSERT(buff);
|
||||
|
||||
resp = at_create_resp(128, 2, rt_tick_from_millisecond(5000));
|
||||
resp = at_create_resp(128, 2, 5 * RT_TICK_PER_SECOND);
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
|
@ -297,6 +307,9 @@ static int m26_socket_send(int socket, const char *buff, size_t bfsz, enum at_so
|
|||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* Clear socket send event */
|
||||
at_socket_event_recv(SET_EVENT(socket, M26_EVENT_SEND_OK | M26_EVENT_SEND_FAIL), 0, RT_EVENT_FLAG_OR);
|
||||
|
||||
/* set current socket for send URC event */
|
||||
cur_socket = socket;
|
||||
/* set AT client end sign to deal with '>' sign.*/
|
||||
|
@ -329,14 +342,14 @@ static int m26_socket_send(int socket, const char *buff, size_t bfsz, enum at_so
|
|||
}
|
||||
|
||||
/* waiting result event from AT URC */
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), rt_tick_from_millisecond(300*3), RT_EVENT_FLAG_OR) < 0)
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), 1 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) send failed, wait connect result timeout.", socket);
|
||||
result = -RT_ETIMEOUT;
|
||||
goto __exit;
|
||||
}
|
||||
/* waiting OK or failed result */
|
||||
if ((event_result = at_socket_event_recv(M26_EVENT_SEND_OK | M26_EVENT_SEND_FAIL, rt_tick_from_millisecond(1 * 1000),
|
||||
if ((event_result = at_socket_event_recv(M26_EVENT_SEND_OK | M26_EVENT_SEND_FAIL, 1 * RT_TICK_PER_SECOND,
|
||||
RT_EVENT_FLAG_OR)) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) send failed, wait connect OK|FAIL timeout.", socket);
|
||||
|
@ -397,7 +410,7 @@ static int m26_domain_resolve(const char *name, char ip[16])
|
|||
RT_ASSERT(ip);
|
||||
|
||||
/* The maximum response time is 14 seconds, affected by network status */
|
||||
resp = at_create_resp(128, 4, rt_tick_from_millisecond(14 * 1000));
|
||||
resp = at_create_resp(128, 4, 14 * RT_TICK_PER_SECOND);
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
|
@ -417,14 +430,14 @@ static int m26_domain_resolve(const char *name, char ip[16])
|
|||
/* parse the third line of response data, get the IP address */
|
||||
if(at_resp_parse_line_args_by_kw(resp, ".", "%s", recv_ip) < 0)
|
||||
{
|
||||
rt_thread_delay(rt_tick_from_millisecond(100));
|
||||
rt_thread_mdelay(100);
|
||||
/* resolve failed, maybe receive an URC CRLF */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen(recv_ip) < 8)
|
||||
{
|
||||
rt_thread_delay(rt_tick_from_millisecond(100));
|
||||
rt_thread_mdelay(100);
|
||||
/* resolve failed, maybe receive an URC CRLF */
|
||||
continue;
|
||||
}
|
||||
|
@ -567,39 +580,6 @@ static void urc_recv_func(const char *data, rt_size_t size)
|
|||
}
|
||||
}
|
||||
|
||||
static void urc_ping_func(const char *data, rt_size_t size)
|
||||
{
|
||||
static int icmp_seq = 0;
|
||||
int result, recv_len, time, ttl;
|
||||
char dst_ip[16] = { 0 };
|
||||
|
||||
RT_ASSERT(data);
|
||||
|
||||
sscanf(data, "+QPING: %d,%[^,],%d,%d,%d", &result, dst_ip, &recv_len, &time, &ttl);
|
||||
|
||||
switch(result)
|
||||
{
|
||||
case 0:
|
||||
rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", recv_len, dst_ip, icmp_seq++, ttl, time);
|
||||
break;
|
||||
case 1:
|
||||
rt_kprintf("ping request timeout!\n");
|
||||
break;
|
||||
case 2:
|
||||
icmp_seq = 0;
|
||||
break;
|
||||
case 3:
|
||||
rt_kprintf("ping: TCP/IP protocol stack is busy\n");
|
||||
break;
|
||||
case 4:
|
||||
rt_kprintf("ping: unknown remote server host\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void urc_func(const char *data, rt_size_t size)
|
||||
{
|
||||
RT_ASSERT(data);
|
||||
|
@ -619,7 +599,6 @@ static const struct at_urc urc_table[] = {
|
|||
{"", ", CLOSE OK\r\n", urc_close_func},
|
||||
{"", ", CLOSED\r\n", urc_close_func},
|
||||
{"+RECEIVE:", "\r\n", urc_recv_func},
|
||||
{"+QPING:", "\r\n", urc_ping_func},
|
||||
};
|
||||
|
||||
#define AT_SEND_CMD(resp, resp_line, timeout, cmd) \
|
||||
|
@ -632,6 +611,9 @@ static const struct at_urc urc_table[] = {
|
|||
} \
|
||||
} while(0); \
|
||||
|
||||
static int m26_netdev_set_info(struct netdev *netdev);
|
||||
static int m26_netdev_check_link_status(struct netdev *netdev);
|
||||
|
||||
/* init for M26 or MC20 */
|
||||
static void m26_init_thread_entry(void *parameter)
|
||||
{
|
||||
|
@ -656,6 +638,7 @@ static void m26_init_thread_entry(void *parameter)
|
|||
/* wait M26 startup finish */
|
||||
if (at_client_wait_connect(M26_WAIT_CONNECT_TIME))
|
||||
{
|
||||
LOG_E("AT device connection error.");
|
||||
result = -RT_ETIMEOUT;
|
||||
goto __exit;
|
||||
}
|
||||
|
@ -671,14 +654,14 @@ static void m26_init_thread_entry(void *parameter)
|
|||
/* check SIM card */
|
||||
for (i = 0; i < CPIN_RETRY; i++)
|
||||
{
|
||||
at_exec_cmd(at_resp_set_info(resp, 128, 2, rt_tick_from_millisecond(5000)), "AT+CPIN?");
|
||||
at_exec_cmd(at_resp_set_info(resp, 128, 2, 5 * RT_TICK_PER_SECOND), "AT+CPIN?");
|
||||
|
||||
if (at_resp_get_line_by_kw(resp, "READY"))
|
||||
{
|
||||
LOG_D("SIM card detection success");
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CPIN_RETRY)
|
||||
{
|
||||
|
@ -687,7 +670,7 @@ static void m26_init_thread_entry(void *parameter)
|
|||
goto __exit;
|
||||
}
|
||||
/* waiting for dirty data to be digested */
|
||||
rt_thread_delay(rt_tick_from_millisecond(10));
|
||||
rt_thread_mdelay(10);
|
||||
/* check signal strength */
|
||||
for (i = 0; i < CSQ_RETRY; i++)
|
||||
{
|
||||
|
@ -698,7 +681,7 @@ static void m26_init_thread_entry(void *parameter)
|
|||
LOG_D("Signal strength: %s", parsed_data);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CSQ_RETRY)
|
||||
{
|
||||
|
@ -716,7 +699,7 @@ static void m26_init_thread_entry(void *parameter)
|
|||
LOG_D("GSM network is registered (%s)", parsed_data);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CREG_RETRY)
|
||||
{
|
||||
|
@ -734,7 +717,7 @@ static void m26_init_thread_entry(void *parameter)
|
|||
LOG_D("GPRS network is registered (%s)", parsed_data);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CGREG_RETRY)
|
||||
{
|
||||
|
@ -779,13 +762,15 @@ __exit:
|
|||
|
||||
if (!result)
|
||||
{
|
||||
m26_netdev_set_info(netdev_get_by_name(M26_NETDEV_NAME));
|
||||
m26_netdev_check_link_status(netdev_get_by_name(M26_NETDEV_NAME));
|
||||
|
||||
LOG_I("AT network initialize success!");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("AT network initialize failed (%d)!", result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int m26_net_init(void)
|
||||
|
@ -809,83 +794,9 @@ int m26_net_init(void)
|
|||
return RT_EOK;
|
||||
}
|
||||
|
||||
int m26_ping(int argc, char **argv)
|
||||
{
|
||||
at_response_t resp = RT_NULL;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
rt_kprintf("Please input: at_ping <host address>\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
resp = at_create_resp(64, 0, rt_tick_from_millisecond(5000));
|
||||
if (!resp)
|
||||
{
|
||||
rt_kprintf("No memory for response structure!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
if (at_exec_cmd(resp, "AT+QPING=\"%s\"", argv[1]) < 0)
|
||||
{
|
||||
rt_kprintf("AT send ping commands error!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int m26_ifconfig(void)
|
||||
{
|
||||
at_response_t resp = RT_NULL;
|
||||
char resp_arg[AT_CMD_MAX_LEN] = { 0 };
|
||||
const char * resp_expr = "%s";
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
resp = at_create_resp(64, 2, rt_tick_from_millisecond(300));
|
||||
if (!resp)
|
||||
{
|
||||
rt_kprintf("No memory for response structure!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
if (at_exec_cmd(resp, "AT+QILOCIP") < 0)
|
||||
{
|
||||
rt_kprintf("AT send ip commands error!\n");
|
||||
result = RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 2, resp_expr, resp_arg) == 1)
|
||||
{
|
||||
rt_kprintf("IP address : %s\n", resp_arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("Parse error, current line buff : %s\n", at_resp_get_line(resp, 2));
|
||||
result = RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
#include <finsh.h>
|
||||
MSH_CMD_EXPORT_ALIAS(m26_net_init, at_net_init, initialize AT network);
|
||||
MSH_CMD_EXPORT_ALIAS(m26_ping, at_ping, AT ping network host);
|
||||
MSH_CMD_EXPORT_ALIAS(m26_ifconfig, at_ifconfig, list the information of network interfaces);
|
||||
#endif
|
||||
|
||||
static const struct at_device_ops m26_socket_ops = {
|
||||
|
@ -896,6 +807,396 @@ static const struct at_device_ops m26_socket_ops = {
|
|||
m26_socket_set_event_cb,
|
||||
};
|
||||
|
||||
|
||||
/* set m26 network interface device status and address information */
|
||||
static int m26_netdev_set_info(struct netdev *netdev)
|
||||
{
|
||||
#define M26_IEMI_RESP_SIZE 32
|
||||
#define M26_IPADDR_RESP_SIZE 32
|
||||
#define M26_DNS_RESP_SIZE 96
|
||||
#define M26_INFO_RESP_TIMO rt_tick_from_millisecond(300)
|
||||
|
||||
int result = RT_EOK;
|
||||
at_response_t resp = RT_NULL;
|
||||
ip_addr_t addr;
|
||||
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
LOG_E("Input network interface device is NULL.\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* set network interface device up status */
|
||||
netdev_low_level_set_status(netdev, RT_TRUE);
|
||||
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
|
||||
|
||||
resp = at_create_resp(M26_IEMI_RESP_SIZE, 0, M26_INFO_RESP_TIMO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("M26 set IP address failed, no memory for response object.");
|
||||
result = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* set network interface device hardware address(IEMI) */
|
||||
{
|
||||
#define M26_NETDEV_HWADDR_LEN 8
|
||||
#define M26_IEMI_LEN 15
|
||||
|
||||
char iemi[M26_IEMI_LEN] = {0};
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* send "AT+GSN" commond to get device IEMI */
|
||||
if (at_exec_cmd(resp, "AT+GSN") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 2, "%s", iemi) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+GSN\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("M26 IEMI number: %s", iemi);
|
||||
|
||||
netdev->hwaddr_len = M26_NETDEV_HWADDR_LEN;
|
||||
/* get hardware address by IEMI */
|
||||
for (i = 0, j = 0; i < M26_NETDEV_HWADDR_LEN && j < M26_IEMI_LEN; i++, j+=2)
|
||||
{
|
||||
if (j != M26_IEMI_LEN - 1)
|
||||
{
|
||||
netdev->hwaddr[i] = (iemi[j] - '0') * 10 + (iemi[j + 1] - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev->hwaddr[i] = (iemi[j] - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set network interface device IP address */
|
||||
{
|
||||
#define IP_ADDR_SIZE_MAX 16
|
||||
char ipaddr[IP_ADDR_SIZE_MAX] = {0};
|
||||
|
||||
at_resp_set_info(resp, M26_IPADDR_RESP_SIZE, 2, M26_INFO_RESP_TIMO);
|
||||
|
||||
/* send "AT+QILOCIP" commond to get IP address */
|
||||
if (at_exec_cmd(resp, "AT+QILOCIP") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args_by_kw(resp, ".", "%s", ipaddr) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+QILOCIP\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("M26 IP address: %s", ipaddr);
|
||||
|
||||
/* set network interface address information */
|
||||
inet_aton(ipaddr, &addr);
|
||||
netdev_low_level_set_ipaddr(netdev, &addr);
|
||||
}
|
||||
|
||||
/* set network interface device dns server */
|
||||
{
|
||||
#define DNS_ADDR_SIZE_MAX 16
|
||||
char dns_server1[DNS_ADDR_SIZE_MAX] = {0}, dns_server2[DNS_ADDR_SIZE_MAX] = {0};
|
||||
|
||||
at_resp_set_info(resp, M26_DNS_RESP_SIZE, 0, M26_INFO_RESP_TIMO);
|
||||
|
||||
/* send "AT+QIDNSCFG?" commond to get DNS servers address */
|
||||
if (at_exec_cmd(resp, "AT+QIDNSCFG?") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args_by_kw(resp, "PrimaryDns:", "PrimaryDns:%s", dns_server1) <= 0 ||
|
||||
at_resp_parse_line_args_by_kw(resp, "SecondaryDns:", "SecondaryDns:%s", dns_server2) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+QIDNSCFG?\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("M26 primary DNS server address: %s", dns_server1);
|
||||
LOG_D("M26 secondary DNS server address: %s", dns_server2);
|
||||
|
||||
inet_aton(dns_server1, &addr);
|
||||
netdev_low_level_set_dns_server(netdev, 0, &addr);
|
||||
|
||||
inet_aton(dns_server2, &addr);
|
||||
netdev_low_level_set_dns_server(netdev, 1, &addr);
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void check_link_status_entry(void *parameter)
|
||||
{
|
||||
#define M26_LINK_STATUS_OK 0
|
||||
#define M26_LINK_RESP_SIZE 64
|
||||
#define M26_LINK_RESP_TIMO (3 * RT_TICK_PER_SECOND)
|
||||
#define M26_LINK_DELAY_TIME (30 * RT_TICK_PER_SECOND)
|
||||
|
||||
struct netdev *netdev = (struct netdev *)parameter;
|
||||
at_response_t resp = RT_NULL;
|
||||
int link_status;
|
||||
|
||||
resp = at_create_resp(M26_LINK_RESP_SIZE, 0, M26_LINK_RESP_TIMO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("m26 set check link status failed, no memory for response object.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send "AT+QNSTATUS" commond to check netweork interface device link status */
|
||||
if (at_exec_cmd(resp, "AT+QNSTATUS") < 0)
|
||||
{
|
||||
rt_mutex_release(at_event_lock);
|
||||
rt_thread_mdelay(M26_LINK_DELAY_TIME);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
link_status = -1;
|
||||
at_resp_parse_line_args_by_kw(resp, "+QNSTATUS:", "+QNSTATUS: %d", &link_status);
|
||||
|
||||
/* check the network interface device link status */
|
||||
if ((M26_LINK_STATUS_OK == link_status) != netdev_is_link_up(netdev))
|
||||
{
|
||||
netdev_low_level_set_link_status(netdev, (M26_LINK_STATUS_OK == link_status));
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
rt_thread_mdelay(M26_LINK_DELAY_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
static int m26_netdev_check_link_status(struct netdev *netdev)
|
||||
{
|
||||
#define M26_LINK_THREAD_STACK_SIZE 512
|
||||
#define M26_LINK_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX - 2)
|
||||
#define M26_LINK_THREAD_TICK 20
|
||||
|
||||
rt_thread_t tid;
|
||||
char tname[RT_NAME_MAX];
|
||||
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
LOG_E("Input network interface device is NULL.\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_memset(tname, 0x00, sizeof(tname));
|
||||
rt_snprintf(tname, RT_NAME_MAX, "%s_link", netdev->name);
|
||||
|
||||
tid = rt_thread_create(tname, check_link_status_entry, (void *)netdev,
|
||||
M26_LINK_THREAD_STACK_SIZE, M26_LINK_THREAD_PRIORITY, M26_LINK_THREAD_TICK);
|
||||
if (tid)
|
||||
{
|
||||
rt_thread_startup(tid);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int m26_netdev_set_up(struct netdev *netdev)
|
||||
{
|
||||
netdev_low_level_set_status(netdev, RT_TRUE);
|
||||
LOG_D("The network interface device(%s) set up status", netdev->name);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int m26_netdev_set_down(struct netdev *netdev)
|
||||
{
|
||||
netdev_low_level_set_status(netdev, RT_FALSE);
|
||||
LOG_D("The network interface device(%s) set down status", netdev->name);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int m26_netdev_set_dns_server(struct netdev *netdev, ip_addr_t *dns_server)
|
||||
{
|
||||
#define M26_DNS_RESP_LEN 8
|
||||
#define M26_DNS_RESP_TIMEO rt_tick_from_millisecond(300)
|
||||
|
||||
at_response_t resp = RT_NULL;
|
||||
int result = RT_EOK;
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(dns_server);
|
||||
|
||||
resp = at_create_resp(M26_DNS_RESP_LEN, 0, M26_DNS_RESP_TIMEO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("m26 set dns server failed, no memory for response object.");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send "AT+QIDNSCFG=<pri_dns>[,<sec_dns>]" commond to set dns servers */
|
||||
if (at_exec_cmd(resp, "AT+QIDNSCFG=\"%s\"", inet_ntoa(dns_server)) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
netdev_low_level_set_dns_server(netdev, 0, dns_server);
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int m26_netdev_ping(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp)
|
||||
{
|
||||
#define M26_PING_RESP_SIZE 128
|
||||
#define M26_PING_IP_SIZE 16
|
||||
#define M26_PING_TIMEO (5 * RT_TICK_PER_SECOND)
|
||||
|
||||
int result = RT_EOK;
|
||||
at_response_t resp = RT_NULL;
|
||||
char ip_addr[M26_PING_IP_SIZE] = {0};
|
||||
int response, recv_data_len, time, ttl;
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(host);
|
||||
RT_ASSERT(ping_resp);
|
||||
|
||||
resp = at_create_resp(M26_PING_RESP_SIZE, 5, M26_PING_TIMEO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("m26 set dns server failed, no memory for response object.");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send "AT+QPING="<host>"[,[<timeout>][,<pingnum>]]" commond to send ping request */
|
||||
if (at_exec_cmd(resp, "AT+QPING=\"%s\",%d,1", host, M26_PING_TIMEO / RT_TICK_PER_SECOND) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
at_resp_parse_line_args_by_kw(resp, "+QPING:","+QPING:%d", &response);
|
||||
/* Received the ping response from the server */
|
||||
if (response == 0)
|
||||
{
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+QPING:", "+QPING:%d,%[^,],%d,%d,%d",
|
||||
&response, ip_addr, &recv_data_len, &time, &ttl) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+QPING\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* prase response number */
|
||||
switch (response)
|
||||
{
|
||||
case 0:
|
||||
inet_aton(ip_addr, &(ping_resp->ip_addr));
|
||||
ping_resp->data_len = recv_data_len;
|
||||
ping_resp->ticks = time;
|
||||
ping_resp->ttl = ttl;
|
||||
result = RT_EOK;
|
||||
break;
|
||||
case 1:
|
||||
result = -RT_ETIMEOUT;
|
||||
break;
|
||||
default:
|
||||
result = -RT_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void m26_netdev_netstat(struct netdev *netdev)
|
||||
{
|
||||
// TODO netstat support
|
||||
}
|
||||
|
||||
const struct netdev_ops m26_netdev_ops =
|
||||
{
|
||||
m26_netdev_set_up,
|
||||
m26_netdev_set_down,
|
||||
|
||||
RT_NULL, /* not support set ip, netmask, gatway address */
|
||||
m26_netdev_set_dns_server,
|
||||
RT_NULL, /* not support set DHCP status */
|
||||
|
||||
m26_netdev_ping,
|
||||
m26_netdev_netstat,
|
||||
};
|
||||
|
||||
static int m26_netdev_add(const char *netdev_name)
|
||||
{
|
||||
#define M26_NETDEV_MTU 1500
|
||||
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
RT_ASSERT(netdev_name);
|
||||
|
||||
netdev = (struct netdev *) rt_calloc(1, sizeof(struct netdev));
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
netdev->mtu = M26_NETDEV_MTU;
|
||||
netdev->ops = &m26_netdev_ops;
|
||||
|
||||
#ifdef SAL_USING_AT
|
||||
extern int sal_at_netdev_set_pf_info(struct netdev *netdev);
|
||||
/* set the network interface socket/netdb operations */
|
||||
sal_at_netdev_set_pf_info(netdev);
|
||||
#endif
|
||||
|
||||
return netdev_register(netdev, netdev_name, RT_NULL);
|
||||
}
|
||||
|
||||
static int at_socket_device_init(void)
|
||||
{
|
||||
/* create current AT socket event */
|
||||
|
@ -921,6 +1222,13 @@ static int at_socket_device_init(void)
|
|||
/* register URC data execution function */
|
||||
at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
|
||||
|
||||
/* add network interface device to netdev list */
|
||||
if (m26_netdev_add(M26_NETDEV_NAME) < 0)
|
||||
{
|
||||
LOG_E("M26 network interface device(%d) add failed.", M26_NETDEV_NAME);
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
/* initialize m26 network */
|
||||
m26_net_init();
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <rtthread.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netdev.h>
|
||||
#include <at_socket.h>
|
||||
|
||||
#if !defined(AT_SW_VERSION_NUM) || AT_SW_VERSION_NUM < 0x10200
|
||||
|
@ -40,6 +41,8 @@
|
|||
|
||||
#ifdef AT_DEVICE_RW007
|
||||
|
||||
#define RW007_NETDEV_NAME "rw007"
|
||||
|
||||
#define RW007_MODULE_SEND_MAX_SIZE 2048
|
||||
#define RW007_WAIT_CONNECT_TIME 5000
|
||||
#define RW007_THREAD_STACK_SIZE 1024
|
||||
|
@ -682,6 +685,43 @@ static const struct at_device_ops rw007_socket_ops = {
|
|||
rw007_socket_set_event_cb,
|
||||
};
|
||||
|
||||
static int rw007_netdev_add(const char *netdev_name)
|
||||
{
|
||||
#define ETHERNET_MTU 1500
|
||||
#define HWADDR_LEN 8
|
||||
struct netdev *netdev = RT_NULL;
|
||||
int result = 0;
|
||||
|
||||
RT_ASSERT(netdev_name);
|
||||
|
||||
netdev = (struct netdev *) rt_calloc(1, sizeof(struct netdev));
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
/* TODO: improve netdev adaptation */
|
||||
netdev->mtu = ETHERNET_MTU;
|
||||
netdev->hwaddr_len = HWADDR_LEN;
|
||||
netdev->ops = RT_NULL;
|
||||
|
||||
#ifdef SAL_USING_AT
|
||||
extern int sal_at_netdev_set_pf_info(struct netdev *netdev);
|
||||
/* set the network interface socket/netdb operations */
|
||||
sal_at_netdev_set_pf_info(netdev);
|
||||
#endif
|
||||
|
||||
result = netdev_register(netdev, netdev_name, RT_NULL);
|
||||
|
||||
/*TODO: improve netdev adaptation */
|
||||
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);
|
||||
netdev->flags |= NETDEV_FLAG_INTERNET_UP;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int at_socket_device_init(void)
|
||||
{
|
||||
/* create current AT socket event */
|
||||
|
@ -707,6 +747,13 @@ static int at_socket_device_init(void)
|
|||
/* register URC data execution function */
|
||||
at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
|
||||
|
||||
/* add network interface device to netdev list */
|
||||
if (rw007_netdev_add(RW007_NETDEV_NAME) < 0)
|
||||
{
|
||||
LOG_E("RW007 network interface device(%d) add failed.", RW007_NETDEV_NAME);
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
/* initialize rw007 network */
|
||||
rw007_net_init();
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <rtthread.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netdev.h>
|
||||
#include <at_socket.h>
|
||||
|
||||
#if !defined(AT_SW_VERSION_NUM) || AT_SW_VERSION_NUM < 0x10200
|
||||
|
@ -42,6 +43,8 @@
|
|||
|
||||
#ifdef AT_DEVICE_SIM76XX
|
||||
|
||||
#define SIM76XX_NETDEV_NAME "sim76xx"
|
||||
|
||||
#define SIM76XX_MODULE_SEND_MAX_SIZE 1500
|
||||
#define SIM76XX_WAIT_CONNECT_TIME 5000
|
||||
#define SIM76XX_THREAD_STACK_SIZE 1024
|
||||
|
@ -129,7 +132,6 @@ static int sim76xx_socket_close(int socket)
|
|||
at_response_t resp = RT_NULL;
|
||||
int result = RT_EOK;
|
||||
int activated;
|
||||
uint8_t s;
|
||||
uint8_t lnk_stat[10];
|
||||
|
||||
resp = at_create_resp(128, 0, rt_tick_from_millisecond(500));
|
||||
|
@ -1132,6 +1134,42 @@ static const struct at_device_ops sim76xx_socket_ops = {
|
|||
sim76xx_socket_set_event_cb,
|
||||
};
|
||||
|
||||
static int sim76xx_netdev_add(const char *netdev_name)
|
||||
{
|
||||
#define ETHERNET_MTU 1500
|
||||
#define HWADDR_LEN 8
|
||||
struct netdev *netdev = RT_NULL;
|
||||
int result = 0;
|
||||
|
||||
RT_ASSERT(netdev_name);
|
||||
|
||||
netdev = (struct netdev *) rt_calloc(1, sizeof(struct netdev));
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
netdev->mtu = ETHERNET_MTU;
|
||||
netdev->hwaddr_len = HWADDR_LEN;
|
||||
netdev->ops = RT_NULL;
|
||||
|
||||
#ifdef SAL_USING_AT
|
||||
extern int sal_at_netdev_set_pf_info(struct netdev *netdev);
|
||||
/* set the network interface socket/netdb operations */
|
||||
sal_at_netdev_set_pf_info(netdev);
|
||||
#endif
|
||||
|
||||
result = netdev_register(netdev, netdev_name, RT_NULL);
|
||||
|
||||
/*TODO: improve netdev adaptation */
|
||||
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);
|
||||
netdev->flags |= NETDEV_FLAG_INTERNET_UP;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int at_socket_device_init(void)
|
||||
{
|
||||
/* create current AT socket event */
|
||||
|
@ -1157,6 +1195,13 @@ static int at_socket_device_init(void)
|
|||
/* register URC data execution function */
|
||||
at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
|
||||
|
||||
/* add network interface device to netdev list */
|
||||
if (sim76xx_netdev_add(SIM76XX_NETDEV_NAME) < 0)
|
||||
{
|
||||
LOG_E("SIM76xx network interface device(%d) add failed.", SIM76XX_NETDEV_NAME);
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
/* initialize sim76xx pin config */
|
||||
rt_pin_mode(AT_DEVICE_POWER_PIN, PIN_MODE_OUTPUT);
|
||||
rt_pin_mode(AT_DEVICE_STATUS_PIN, PIN_MODE_INPUT);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
* Date Author Notes
|
||||
* 2018-06-12 malongwei first version
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -28,6 +29,8 @@
|
|||
#include <rtdevice.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netdev.h>
|
||||
|
||||
#include <at.h>
|
||||
#include <at_socket.h>
|
||||
|
||||
|
@ -40,6 +43,7 @@
|
|||
|
||||
#ifdef AT_DEVICE_SIM800C
|
||||
|
||||
#define SIM800C_NETDEV_NAME "sim800c"
|
||||
|
||||
#define SIM800C_MODULE_SEND_MAX_SIZE 1000
|
||||
#define SIM800C_WAIT_CONNECT_TIME 5000
|
||||
|
@ -107,6 +111,9 @@ static int sim800c_socket_close(int socket)
|
|||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
cur_socket = socket;
|
||||
|
||||
/* Clear socket close event */
|
||||
at_socket_event_recv(SET_EVENT(socket, SIM800C_EVNET_CLOSE_OK), 0, RT_EVENT_FLAG_OR);
|
||||
|
||||
if (at_exec_cmd(RT_NULL, "AT+CIPCLOSE=%d", socket) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
|
@ -154,6 +161,9 @@ static int sim800c_socket_connect(int socket, char *ip, int32_t port, enum at_so
|
|||
|
||||
__retry:
|
||||
|
||||
/* Clear socket connect event */
|
||||
at_socket_event_recv(SET_EVENT(socket, SIM800C_EVENT_CONN_OK | SIM800C_EVENT_CONN_FAIL), 0, RT_EVENT_FLAG_OR);
|
||||
|
||||
if (is_client)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -179,19 +189,18 @@ __retry:
|
|||
LOG_E("Not supported connect type : %d.", type);
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* waiting result event from AT URC, the device default connection timeout is 75 seconds, but it set to 10 seconds is convenient to use.*/
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), rt_tick_from_millisecond(10 * 1000), RT_EVENT_FLAG_OR) < 0)
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) connect failed, wait connect result timeout.", socket);
|
||||
result = -RT_ETIMEOUT;
|
||||
goto __exit;
|
||||
}
|
||||
/* waiting OK or failed result */
|
||||
if ((event_result = at_socket_event_recv(SIM800C_EVENT_CONN_OK | SIM800C_EVENT_CONN_FAIL, rt_tick_from_millisecond(1 * 1000),
|
||||
if ((event_result = at_socket_event_recv(SIM800C_EVENT_CONN_OK | SIM800C_EVENT_CONN_FAIL, 1 * RT_TICK_PER_SECOND,
|
||||
RT_EVENT_FLAG_OR)) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) connect failed, wait connect OK|FAIL timeout.", socket);
|
||||
|
@ -244,7 +253,7 @@ static int sim800c_socket_send(int socket, const char *buff, size_t bfsz, enum a
|
|||
|
||||
RT_ASSERT(buff);
|
||||
|
||||
resp = at_create_resp(128, 2, rt_tick_from_millisecond(5000));
|
||||
resp = at_create_resp(128, 2, 5 * RT_TICK_PER_SECOND);
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
|
@ -253,6 +262,9 @@ static int sim800c_socket_send(int socket, const char *buff, size_t bfsz, enum a
|
|||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* Clear socket connect event */
|
||||
at_socket_event_recv(SET_EVENT(socket, SIM800C_EVENT_SEND_OK | SIM800C_EVENT_SEND_FAIL), 0, RT_EVENT_FLAG_OR);
|
||||
|
||||
/* set current socket for send URC event */
|
||||
cur_socket = socket;
|
||||
/* set AT client end sign to deal with '>' sign.*/
|
||||
|
@ -285,14 +297,14 @@ static int sim800c_socket_send(int socket, const char *buff, size_t bfsz, enum a
|
|||
}
|
||||
|
||||
/* waiting result event from AT URC */
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), rt_tick_from_millisecond(5 * 1000), RT_EVENT_FLAG_OR) < 0)
|
||||
if (at_socket_event_recv(SET_EVENT(socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) send failed, wait connect result timeout.", socket);
|
||||
result = -RT_ETIMEOUT;
|
||||
goto __exit;
|
||||
}
|
||||
/* waiting OK or failed result */
|
||||
if ((event_result = at_socket_event_recv(SIM800C_EVENT_SEND_OK | SIM800C_EVENT_SEND_FAIL, rt_tick_from_millisecond(5 * 1000),
|
||||
if ((event_result = at_socket_event_recv(SIM800C_EVENT_SEND_OK | SIM800C_EVENT_SEND_FAIL, 5 * RT_TICK_PER_SECOND,
|
||||
RT_EVENT_FLAG_OR)) < 0)
|
||||
{
|
||||
LOG_E("socket (%d) send failed, wait connect OK|FAIL timeout.", socket);
|
||||
|
@ -353,7 +365,7 @@ static int sim800c_domain_resolve(const char *name, char ip[16])
|
|||
RT_ASSERT(ip);
|
||||
|
||||
/* The maximum response time is 14 seconds, affected by network status */
|
||||
resp = at_create_resp(128, 4, rt_tick_from_millisecond(14 * 1000));
|
||||
resp = at_create_resp(128, 4, 14 * RT_TICK_PER_SECOND);
|
||||
if (!resp)
|
||||
{
|
||||
LOG_E("No memory for response structure!");
|
||||
|
@ -362,25 +374,38 @@ static int sim800c_domain_resolve(const char *name, char ip[16])
|
|||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
for(i = 0; i < RESOLVE_RETRY; i++)
|
||||
for (i = 0; i < RESOLVE_RETRY; i++)
|
||||
{
|
||||
int err_code = 0;
|
||||
|
||||
if (at_exec_cmd(resp, "AT+CDNSGIP=\"%s\"", name) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* parse the third line of response data, get the IP address */
|
||||
if(at_resp_parse_line_args_by_kw(resp, "+CDNSGIP:", "%*[^,],%*[^,],\"%[^\"]", recv_ip) < 0)
|
||||
/* domain name prase error options */
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+CDNSGIP: 0", "+CDNSGIP: 0,%d", &err_code) > 0)
|
||||
{
|
||||
rt_thread_delay(rt_tick_from_millisecond(100));
|
||||
/* 3 - network error, 8 - dns common error */
|
||||
if (err_code == 3 || err_code == 8)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse the third line of response data, get the IP address */
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+CDNSGIP:", "%*[^,],%*[^,],\"%[^\"]", recv_ip) < 0)
|
||||
{
|
||||
rt_thread_mdelay(100);
|
||||
/* resolve failed, maybe receive an URC CRLF */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen(recv_ip) < 8)
|
||||
{
|
||||
rt_thread_delay(rt_tick_from_millisecond(100));
|
||||
rt_thread_mdelay(100);
|
||||
/* resolve failed, maybe receive an URC CRLF */
|
||||
continue;
|
||||
}
|
||||
|
@ -560,7 +585,7 @@ static void sim800c_power_on(void)
|
|||
rt_pin_write(AT_DEVICE_POWER_PIN, PIN_HIGH);
|
||||
while (rt_pin_read(AT_DEVICE_STATUS_PIN) == PIN_LOW)
|
||||
{
|
||||
rt_thread_delay(rt_tick_from_millisecond(10));
|
||||
rt_thread_mdelay(10);
|
||||
}
|
||||
rt_pin_write(AT_DEVICE_POWER_PIN, PIN_LOW);
|
||||
}
|
||||
|
@ -572,11 +597,14 @@ static void sim800c_power_off(void)
|
|||
rt_pin_write(AT_DEVICE_POWER_PIN, PIN_HIGH);
|
||||
while (rt_pin_read(AT_DEVICE_STATUS_PIN) == PIN_HIGH)
|
||||
{
|
||||
rt_thread_delay(rt_tick_from_millisecond(10));
|
||||
rt_thread_mdelay(10);
|
||||
}
|
||||
rt_pin_write(AT_DEVICE_POWER_PIN, PIN_LOW);
|
||||
}
|
||||
|
||||
static int sim800c_netdev_set_info(struct netdev *netdev);
|
||||
static int sim800c_netdev_check_link_status(struct netdev *netdev);
|
||||
|
||||
/* init for SIM800C */
|
||||
static void sim800c_init_thread_entry(void *parameter)
|
||||
{
|
||||
|
@ -596,9 +624,9 @@ static void sim800c_init_thread_entry(void *parameter)
|
|||
{
|
||||
result = RT_EOK;
|
||||
rt_memset(parsed_data, 0, sizeof(parsed_data));
|
||||
rt_thread_delay(rt_tick_from_millisecond(500));
|
||||
rt_thread_mdelay(500);
|
||||
sim800c_power_on();
|
||||
rt_thread_delay(rt_tick_from_millisecond(2000));
|
||||
rt_thread_mdelay(2000);
|
||||
resp = at_create_resp(128, 0, rt_tick_from_millisecond(300));
|
||||
if (!resp)
|
||||
{
|
||||
|
@ -625,14 +653,14 @@ static void sim800c_init_thread_entry(void *parameter)
|
|||
/* check SIM card */
|
||||
for (i = 0; i < CPIN_RETRY; i++)
|
||||
{
|
||||
at_exec_cmd(at_resp_set_info(resp, 128, 2, rt_tick_from_millisecond(5000)), "AT+CPIN?");
|
||||
at_exec_cmd(at_resp_set_info(resp, 128, 2, 5 * RT_TICK_PER_SECOND), "AT+CPIN?");
|
||||
|
||||
if (at_resp_get_line_by_kw(resp, "READY"))
|
||||
{
|
||||
LOG_D("SIM card detection success");
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CPIN_RETRY)
|
||||
{
|
||||
|
@ -641,7 +669,7 @@ static void sim800c_init_thread_entry(void *parameter)
|
|||
goto __exit;
|
||||
}
|
||||
/* waiting for dirty data to be digested */
|
||||
rt_thread_delay(rt_tick_from_millisecond(10));
|
||||
rt_thread_mdelay(10);
|
||||
|
||||
/* check the GSM network is registered */
|
||||
for (i = 0; i < CREG_RETRY; i++)
|
||||
|
@ -653,7 +681,7 @@ static void sim800c_init_thread_entry(void *parameter)
|
|||
LOG_D("GSM network is registered (%s)", parsed_data);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CREG_RETRY)
|
||||
{
|
||||
|
@ -671,7 +699,7 @@ static void sim800c_init_thread_entry(void *parameter)
|
|||
LOG_D("GPRS network is registered (%s)", parsed_data);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CGREG_RETRY)
|
||||
{
|
||||
|
@ -690,7 +718,7 @@ static void sim800c_init_thread_entry(void *parameter)
|
|||
LOG_D("Signal strength: %s", parsed_data);
|
||||
break;
|
||||
}
|
||||
rt_thread_delay(rt_tick_from_millisecond(1000));
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
if (i == CSQ_RETRY)
|
||||
{
|
||||
|
@ -759,7 +787,13 @@ static void sim800c_init_thread_entry(void *parameter)
|
|||
LOG_E("AT network initialize failed (%d)!", result);
|
||||
sim800c_power_off();
|
||||
}
|
||||
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
|
||||
/* set network interface device status and address information */
|
||||
sim800c_netdev_set_info(netdev_get_by_name(SIM800C_NETDEV_NAME));
|
||||
sim800c_netdev_check_link_status(netdev_get_by_name(SIM800C_NETDEV_NAME));
|
||||
}
|
||||
|
||||
int sim800c_net_init(void)
|
||||
|
@ -783,61 +817,9 @@ int sim800c_net_init(void)
|
|||
return RT_EOK;
|
||||
}
|
||||
|
||||
int sim800c_ping(int argc, char **argv)
|
||||
{
|
||||
LOG_E("This device does not support Ping!");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int sim800c_ifconfig(void)
|
||||
{
|
||||
at_response_t resp = RT_NULL;
|
||||
char resp_arg[AT_CMD_MAX_LEN] = { 0 };
|
||||
const char * resp_expr = "%s";
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
resp = at_create_resp(64, 2, rt_tick_from_millisecond(300));
|
||||
if (!resp)
|
||||
{
|
||||
rt_kprintf("No memory for response structure!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
if (at_exec_cmd(resp, "AT+CIFSR") < 0)
|
||||
{
|
||||
rt_kprintf("AT send ip commands error!\n");
|
||||
result = RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 2, resp_expr, resp_arg) == 1)
|
||||
{
|
||||
rt_kprintf("IP address : %s\n", resp_arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("Parse error, current line buff : %s\n", at_resp_get_line(resp, 2));
|
||||
result = RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
__exit:
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
#include <finsh.h>
|
||||
MSH_CMD_EXPORT_ALIAS(sim800c_net_init, at_net_init, initialize AT network);
|
||||
MSH_CMD_EXPORT_ALIAS(sim800c_ping, at_ping, AT ping network host);
|
||||
MSH_CMD_EXPORT_ALIAS(sim800c_ifconfig, at_ifconfig, list the information of network interfaces);
|
||||
#endif
|
||||
|
||||
static const struct at_device_ops sim800c_socket_ops = {
|
||||
|
@ -848,6 +830,400 @@ static const struct at_device_ops sim800c_socket_ops = {
|
|||
sim800c_socket_set_event_cb,
|
||||
};
|
||||
|
||||
/* set sim800c network interface device status and address information */
|
||||
static int sim800c_netdev_set_info(struct netdev *netdev)
|
||||
{
|
||||
#define SIM800C_IEMI_RESP_SIZE 32
|
||||
#define SIM800C_IPADDR_RESP_SIZE 32
|
||||
#define SIM800C_DNS_RESP_SIZE 96
|
||||
#define SIM800C_INFO_RESP_TIMO rt_tick_from_millisecond(300)
|
||||
|
||||
int result = RT_EOK;
|
||||
at_response_t resp = RT_NULL;
|
||||
ip_addr_t addr;
|
||||
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
LOG_E("Input network interface device is NULL.\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* set network interface device status */
|
||||
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);
|
||||
|
||||
resp = at_create_resp(SIM800C_IEMI_RESP_SIZE, 0, SIM800C_INFO_RESP_TIMO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("SIM800C set IP address failed, no memory for response object.");
|
||||
result = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* set network interface device hardware address(IEMI) */
|
||||
{
|
||||
#define SIM800C_NETDEV_HWADDR_LEN 8
|
||||
#define SIM800C_IEMI_LEN 15
|
||||
|
||||
char iemi[SIM800C_IEMI_LEN] = {0};
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* send "AT+GSN" commond to get device IEMI */
|
||||
if (at_exec_cmd(resp, "AT+GSN") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args(resp, 2, "%s", iemi) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+GSN\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("SIM800C IEMI number: %s", iemi);
|
||||
|
||||
netdev->hwaddr_len = SIM800C_NETDEV_HWADDR_LEN;
|
||||
/* get hardware address by IEMI */
|
||||
for (i = 0, j = 0; i < SIM800C_NETDEV_HWADDR_LEN && j < SIM800C_IEMI_LEN; i++, j+=2)
|
||||
{
|
||||
if (j != SIM800C_IEMI_LEN - 1)
|
||||
{
|
||||
netdev->hwaddr[i] = (iemi[j] - '0') * 10 + (iemi[j + 1] - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev->hwaddr[i] = (iemi[j] - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set network interface device IP address */
|
||||
{
|
||||
#define IP_ADDR_SIZE_MAX 16
|
||||
char ipaddr[IP_ADDR_SIZE_MAX] = {0};
|
||||
|
||||
at_resp_set_info(resp, SIM800C_IPADDR_RESP_SIZE, 2, SIM800C_INFO_RESP_TIMO);
|
||||
|
||||
/* send "AT+CIFSR" commond to get IP address */
|
||||
if (at_exec_cmd(resp, "AT+CIFSR") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args_by_kw(resp, ".", "%s", ipaddr) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+CIFSR\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("SIM800C IP address: %s", ipaddr);
|
||||
|
||||
/* set network interface address information */
|
||||
inet_aton(ipaddr, &addr);
|
||||
netdev_low_level_set_ipaddr(netdev, &addr);
|
||||
}
|
||||
|
||||
/* set network interface device dns server */
|
||||
{
|
||||
#define DNS_ADDR_SIZE_MAX 16
|
||||
char dns_server1[DNS_ADDR_SIZE_MAX] = {0}, dns_server2[DNS_ADDR_SIZE_MAX] = {0};
|
||||
|
||||
at_resp_set_info(resp, SIM800C_DNS_RESP_SIZE, 0, SIM800C_INFO_RESP_TIMO);
|
||||
|
||||
/* send "AT+CDNSCFG?" commond to get DNS servers address */
|
||||
if (at_exec_cmd(resp, "AT+CDNSCFG?") < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args_by_kw(resp, "PrimaryDns:", "PrimaryDns:%s", dns_server1) <= 0 ||
|
||||
at_resp_parse_line_args_by_kw(resp, "SecondaryDns:", "SecondaryDns:%s", dns_server2) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+CDNSCFG?\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
LOG_D("SIM800C primary DNS server address: %s", dns_server1);
|
||||
LOG_D("SIM800C secondary DNS server address: %s", dns_server2);
|
||||
|
||||
inet_aton(dns_server1, &addr);
|
||||
netdev_low_level_set_dns_server(netdev, 0, &addr);
|
||||
|
||||
inet_aton(dns_server2, &addr);
|
||||
netdev_low_level_set_dns_server(netdev, 1, &addr);
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void check_link_status_entry(void *parameter)
|
||||
{
|
||||
#define SIM800C_LINK_STATUS_OK 1
|
||||
#define SIM800C_LINK_RESP_SIZE 64
|
||||
#define SIM800C_LINK_RESP_TIMO (3 * RT_TICK_PER_SECOND)
|
||||
#define SIM800C_LINK_DELAY_TIME (30 * RT_TICK_PER_SECOND)
|
||||
|
||||
struct netdev *netdev = (struct netdev *)parameter;
|
||||
at_response_t resp = RT_NULL;
|
||||
int result_code, link_status;
|
||||
|
||||
resp = at_create_resp(SIM800C_LINK_RESP_SIZE, 0, SIM800C_LINK_RESP_TIMO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("sim800c set check link status failed, no memory for response object.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
/* send "AT+CGREG?" commond to check netweork interface device link status */
|
||||
if (at_exec_cmd(resp, "AT+CGREG?") < 0)
|
||||
{
|
||||
rt_mutex_release(at_event_lock);
|
||||
rt_thread_mdelay(SIM800C_LINK_DELAY_TIME);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
link_status = -1;
|
||||
at_resp_parse_line_args_by_kw(resp, "+CGREG:", "+CGREG: %d,%d", &result_code, &link_status);
|
||||
|
||||
/* check the network interface device link status */
|
||||
if ((SIM800C_LINK_STATUS_OK == link_status) != netdev_is_link_up(netdev))
|
||||
{
|
||||
netdev_low_level_set_link_status(netdev, (SIM800C_LINK_STATUS_OK == link_status));
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
rt_thread_mdelay(SIM800C_LINK_DELAY_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
static int sim800c_netdev_check_link_status(struct netdev *netdev)
|
||||
{
|
||||
#define SIM800C_LINK_THREAD_STACK_SIZE 512
|
||||
#define SIM800C_LINK_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX - 2)
|
||||
#define SIM800C_LINK_THREAD_TICK 20
|
||||
|
||||
rt_thread_t tid;
|
||||
char tname[RT_NAME_MAX];
|
||||
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
LOG_E("Input network interface device is NULL.\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_memset(tname, 0x00, sizeof(tname));
|
||||
rt_snprintf(tname, RT_NAME_MAX, "%s_link", netdev->name);
|
||||
|
||||
tid = rt_thread_create(tname, check_link_status_entry, (void *)netdev,
|
||||
SIM800C_LINK_THREAD_STACK_SIZE, SIM800C_LINK_THREAD_PRIORITY, SIM800C_LINK_THREAD_TICK);
|
||||
if (tid)
|
||||
{
|
||||
rt_thread_startup(tid);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int sim800c_netdev_set_up(struct netdev *netdev)
|
||||
{
|
||||
netdev_low_level_set_status(netdev, RT_TRUE);
|
||||
LOG_D("The network interface device(%s) set up status", netdev->name);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int sim800c_netdev_set_down(struct netdev *netdev)
|
||||
{
|
||||
netdev_low_level_set_status(netdev, RT_FALSE);
|
||||
LOG_D("The network interface device(%s) set down status", netdev->name);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int sim800c_netdev_set_dns_server(struct netdev *netdev, ip_addr_t *dns_server)
|
||||
{
|
||||
#define SIM800C_DNS_RESP_LEN 8
|
||||
#define SIM800C_DNS_RESP_TIMEO rt_tick_from_millisecond(300)
|
||||
|
||||
at_response_t resp = RT_NULL;
|
||||
int result = RT_EOK;
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(dns_server);
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
resp = at_create_resp(SIM800C_DNS_RESP_LEN, 0, SIM800C_DNS_RESP_TIMEO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("sim800c set dns server failed, no memory for response object.");
|
||||
result = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* send "AT+CDNSCFG=<pri_dns>[,<sec_dns>]" commond to set dns servers */
|
||||
if (at_exec_cmd(resp, "AT+CDNSCFG=\"%s\"", inet_ntoa(dns_server)) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
netdev_low_level_set_dns_server(netdev, 0, dns_server);
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sim800c_netdev_ping(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp)
|
||||
{
|
||||
#define SIM800C_PING_RESP_SIZE 128
|
||||
#define SIM800C_PING_IP_SIZE 16
|
||||
#define SIM800C_PING_TIMEO (5 * RT_TICK_PER_SECOND)
|
||||
|
||||
#define SIM800C_PING_ERR_TIME 600
|
||||
#define SIM800C_PING_ERR_TTL 255
|
||||
|
||||
int result = RT_EOK;
|
||||
at_response_t resp = RT_NULL;
|
||||
char ip_addr[SIM800C_PING_IP_SIZE] = {0};
|
||||
int response, time, ttl, i;
|
||||
|
||||
RT_ASSERT(netdev);
|
||||
RT_ASSERT(host);
|
||||
RT_ASSERT(ping_resp);
|
||||
|
||||
for (i = 0; i < rt_strlen(host) && !isalpha(host[i]); i++);
|
||||
|
||||
if (i < strlen(host))
|
||||
{
|
||||
/* check domain name is usable */
|
||||
if (sim800c_domain_resolve(host, ip_addr) < 0)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
rt_memset(ip_addr, 0x00, SIM800C_PING_IP_SIZE);
|
||||
}
|
||||
|
||||
rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
|
||||
|
||||
resp = at_create_resp(SIM800C_PING_RESP_SIZE, 0, SIM800C_PING_TIMEO);
|
||||
if (resp == RT_NULL)
|
||||
{
|
||||
LOG_E("sim800c set dns server failed, no memory for response object.");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* send "AT+CIPPING=<IP addr>[,<retryNum>[,<dataLen>[,<timeout>[,<ttl>]]]]" commond to send ping request */
|
||||
if (at_exec_cmd(resp, "AT+CIPPING=%s,1,%d,%d,64", host, data_len, SIM800C_PING_TIMEO / (RT_TICK_PER_SECOND / 10)) < 0)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (at_resp_parse_line_args_by_kw(resp, "+CIPPING:", "+CIPPING:%d,\"%[^\"]\",%d,%d",
|
||||
&response, ip_addr, &time, &ttl) <= 0)
|
||||
{
|
||||
LOG_E("Prase \"AT+CIPPING\" commands resposne data error!");
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* the ping request timeout expires, the response time settting to 600 and ttl setting to 255 */
|
||||
if (time == SIM800C_PING_ERR_TIME && ttl == SIM800C_PING_ERR_TTL)
|
||||
{
|
||||
result = -RT_ETIMEOUT;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
inet_aton(ip_addr, &(ping_resp->ip_addr));
|
||||
ping_resp->data_len = data_len;
|
||||
/* reply time, in units of 100 ms */
|
||||
ping_resp->ticks = time * 100;
|
||||
ping_resp->ttl = ttl;
|
||||
|
||||
__exit:
|
||||
if (resp)
|
||||
{
|
||||
at_delete_resp(resp);
|
||||
}
|
||||
|
||||
rt_mutex_release(at_event_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void sim800c_netdev_netstat(struct netdev *netdev)
|
||||
{
|
||||
// TODO netstat support
|
||||
}
|
||||
|
||||
const struct netdev_ops sim800c_netdev_ops =
|
||||
{
|
||||
sim800c_netdev_set_up,
|
||||
sim800c_netdev_set_down,
|
||||
|
||||
RT_NULL, /* not support set ip, netmask, gatway address */
|
||||
sim800c_netdev_set_dns_server,
|
||||
RT_NULL, /* not support set DHCP status */
|
||||
|
||||
sim800c_netdev_ping,
|
||||
sim800c_netdev_netstat,
|
||||
};
|
||||
|
||||
static int sim800c_netdev_add(const char *netdev_name)
|
||||
{
|
||||
#define SIM800C_NETDEV_MTU 1500
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
RT_ASSERT(netdev_name);
|
||||
|
||||
netdev = (struct netdev *) rt_calloc(1, sizeof(struct netdev));
|
||||
if (netdev == RT_NULL)
|
||||
{
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
netdev->mtu = SIM800C_NETDEV_MTU;
|
||||
netdev->ops = &sim800c_netdev_ops;
|
||||
|
||||
#ifdef SAL_USING_AT
|
||||
extern int sal_at_netdev_set_pf_info(struct netdev *netdev);
|
||||
/* set the network interface socket/netdb operations */
|
||||
sal_at_netdev_set_pf_info(netdev);
|
||||
#endif
|
||||
|
||||
return netdev_register(netdev, netdev_name, RT_NULL);
|
||||
}
|
||||
|
||||
static int at_socket_device_init(void)
|
||||
{
|
||||
/* create current AT socket event */
|
||||
|
@ -873,6 +1249,13 @@ static int at_socket_device_init(void)
|
|||
/* register URC data execution function */
|
||||
at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
|
||||
|
||||
/* add network interface device to netdev list */
|
||||
if (sim800c_netdev_add(SIM800C_NETDEV_NAME) < 0)
|
||||
{
|
||||
LOG_E("SIM800C network interface device(%d) add failed.", SIM800C_NETDEV_NAME);
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
/* initialize sim800c network */
|
||||
rt_pin_mode(AT_DEVICE_POWER_PIN, PIN_MODE_OUTPUT);
|
||||
rt_pin_mode(AT_DEVICE_STATUS_PIN, PIN_MODE_INPUT);
|
||||
|
|
Loading…
Reference in New Issue