瀏覽代碼

Merge pull request #182 from xiangxistu/master

[add] implement about "AT server"
guo 3 年之前
父節點
當前提交
877b8c0614
共有 2 個文件被更改,包括 148 次插入11 次删除
  1. 147 10
      class/esp8266/at_socket_esp8266.c
  2. 1 1
      inc/at_device.h

+ 147 - 10
class/esp8266/at_socket_esp8266.c

@@ -7,6 +7,7 @@
  * Date           Author       Notes
  * 2018-06-20     chenyong     first version
  * 2019-05-09     chenyong     multi AT socket client support
+ * 2022-06-02     xiangxistu   add AT server mode
  */
 
 #include <stdio.h>
@@ -19,6 +20,7 @@
 
 #if defined(AT_DEVICE_USING_ESP8266) && defined(AT_USING_SOCKET)
 
+#define ESP8266_MODULE_SERVER_SUPPORT_NUM 1
 #define ESP8266_MODULE_SEND_MAX_SIZE   2048
 /* set real event by current socket and current state */
 #define SET_EVENT(socket, event)       (((socket + 1) << 16) | (event))
@@ -34,8 +36,44 @@
 static at_evt_cb_t at_evt_cb_set[] = {
         [AT_SOCKET_EVT_RECV] = NULL,
         [AT_SOCKET_EVT_CLOSED] = NULL,
+#ifdef AT_USING_SOCKET_SERVER
+        [AT_SOCKET_EVT_CONNECTED] = NULL,
+#endif
+};
+
+static void urc_send_func(struct at_client *client, const char *data, rt_size_t size);
+static void urc_send_bfsz_func(struct at_client *client, const char *data, rt_size_t size);
+static void urc_close_func(struct at_client *client, const char *data, rt_size_t size);
+#ifdef AT_USING_SOCKET_SERVER
+static void urc_connected_func(struct at_client *client, const char *data, rt_size_t size);
+#endif
+static void urc_recv_func(struct at_client *client, 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},
+    {"Recv",             "bytes\r\n",      urc_send_bfsz_func},
+    {"",                 ",CLOSED\r\n",    urc_close_func},
+    {"+IPD",             ":",              urc_recv_func},
 };
 
+#ifdef AT_USING_SOCKET_SERVER
+static const struct at_urc urc_table_with_server[] =
+{
+    {"SEND OK",          "\r\n",           urc_send_func},
+    {"SEND FAIL",        "\r\n",           urc_send_func},
+    {"Recv",             "bytes\r\n",      urc_send_bfsz_func},
+    {"",                 ",CONNECT\r\n",   urc_connected_func},
+    {"",                 ",CLOSED\r\n",    urc_close_func},
+    {"+IPD",             ":",              urc_recv_func},
+};
+#endif
+
+#ifdef AT_USING_SOCKET_SERVER
+static int esp8266_server_number = 0;
+#endif
+
 static int esp8266_socket_event_send(struct at_device *device, uint32_t event)
 {
     return (int) rt_event_send(device->socket_event, event);
@@ -172,6 +210,68 @@ __exit:
     return result;
 }
 
+#ifdef AT_USING_SOCKET_SERVER
+/**
+ * create TCP/UDP or server connect by AT commands.
+ *
+ * @param socket current socket
+ * @param backlog waiting to handdle work, useless in "at mode"
+ *
+ * @return   0: connect success
+ *          -1: connect failed, send commands error or type error
+ *          -2: wait socket event timeout
+ *          -5: no memory
+ */
+int esp8266_socket_listen(struct at_socket *socket, int backlog)
+{
+    int result = RT_EOK;
+    at_response_t resp = RT_NULL;
+    struct at_device *device = RT_NULL;
+    int listen_port;
+
+    listen_port = (int)socket->listen.port;
+
+    device = at_device_get_first_initialized();
+    if (device == RT_NULL)
+    {
+        LOG_E("get first init device failed.");
+        return -RT_ERROR;
+    }
+
+    resp = at_create_resp(128, 0, 20 * RT_TICK_PER_SECOND);
+    if (resp == RT_NULL)
+    {
+        LOG_E("no memory for resp create.");
+        return -RT_ENOMEM;
+    }
+
+    if(esp8266_server_number >= ESP8266_MODULE_SERVER_SUPPORT_NUM)
+    {
+
+        LOG_E("no memory for server to listen(%05d).", socket->listen.port);
+        return -RT_ENOMEM;
+    }
+    esp8266_server_number++;
+
+    /* AT+CIPSERVER=1,<port> */
+    if (at_obj_exec_cmd(device->client, resp, "AT+CIPSERVER=1,%d", listen_port) < 0)
+    {
+        result = -RT_ERROR;
+        goto __exit;
+    }
+
+    at_obj_set_urc_table(device->client, urc_table_with_server, sizeof(urc_table_with_server) / sizeof(urc_table_with_server[0]));
+
+__exit:
+    if (resp)
+    {
+        at_delete_resp(resp);
+    }
+
+    return result;
+}
+#endif
+
 /**
  * send data to server or client by AT commands.
  *
@@ -211,6 +311,8 @@ static int esp8266_socket_send(struct at_socket *socket, const char *buff, size_
     /* set current socket for send URC event */
     esp8266->user_data = (void *) device_socket;
 
+    at_obj_set_urc_table(device->client, urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
+
     /* set AT client end sign to deal with '>' sign */
     at_obj_set_end_sign(device->client, '>');
 
@@ -279,6 +381,10 @@ __exit:
         at_delete_resp(resp);
     }
 
+#ifdef AT_USING_SOCKET_SERVER
+    at_obj_set_urc_table(device->client, urc_table_with_server, sizeof(urc_table_with_server) / sizeof(urc_table_with_server[0]));
+#endif
+
     return result > 0 ? sent_size : result;
 }
 
@@ -372,7 +478,7 @@ static void esp8266_socket_set_event_cb(at_socket_evt_t event, at_evt_cb_t cb)
     }
 }
 
-static const struct at_socket_ops esp8266_socket_ops =
+static struct at_socket_ops esp8266_socket_ops =
 {
     esp8266_socket_connect,
     esp8266_socket_close,
@@ -381,6 +487,9 @@ static const struct at_socket_ops esp8266_socket_ops =
     esp8266_socket_set_event_cb,
 #if defined(AT_SW_VERSION_NUM) && AT_SW_VERSION_NUM > 0x10300
     RT_NULL,
+#ifdef AT_USING_SOCKET_SERVER
+    esp8266_socket_listen,
+#endif
 #endif
 };
 
@@ -438,7 +547,11 @@ static void urc_close_func(struct at_client *client, const char *data, rt_size_t
     }
 
     sscanf(data, "%d,CLOSED", &index);
+#ifdef AT_USING_SOCKET_SERVER
+    socket = at_get_base_socket(index);
+#else
     socket = &(device->sockets[index]);
+#endif
 
     /* notice the socket is disconnect by remote */
     if (at_evt_cb_set[AT_SOCKET_EVT_CLOSED])
@@ -447,6 +560,35 @@ static void urc_close_func(struct at_client *client, const char *data, rt_size_t
     }
 }
 
+#ifdef AT_USING_SOCKET_SERVER
+static void urc_connected_func(struct at_client *client, const char *data, rt_size_t size)
+{
+    int socket;
+    struct at_device *device = RT_NULL;
+    char socket_info[AT_SOCKET_INFO_LEN] = {0};
+    char *client_name = client->device->parent.name;
+
+    RT_ASSERT(data && size);
+
+    device = at_device_get_by_name(AT_DEVICE_NAMETYPE_CLIENT, client_name);
+    if (device == RT_NULL)
+    {
+        LOG_E("get device(%s) failed.", client_name);
+        return;
+    }
+
+    sscanf(data, "%d,CONNECT", &socket);
+    rt_memset(&socket_info[0], 0, AT_SOCKET_INFO_LEN);
+    rt_sprintf(&socket_info[0], "SOCKET:%d", socket);
+
+    /* notice at socket to alloc a new socket */
+    if (at_evt_cb_set[AT_SOCKET_EVT_CONNECTED])
+    {
+        at_evt_cb_set[AT_SOCKET_EVT_CONNECTED](RT_NULL, AT_SOCKET_EVT_CONNECTED, &socket_info[0], AT_SOCKET_INFO_LEN);
+    }
+}
+#endif
+
 static void urc_recv_func(struct at_client *client, const char *data, rt_size_t size)
 {
     int device_socket = 0;
@@ -504,7 +646,11 @@ static void urc_recv_func(struct at_client *client, const char *data, rt_size_t
     }
 
     /* get at socket object by device socket descriptor */
+#ifdef AT_USING_SOCKET_SERVER
+    socket = at_get_base_socket(device_socket);
+#else
     socket = &(device->sockets[device_socket]);
+#endif
 
     /* notice the receive buffer and buffer size */
     if (at_evt_cb_set[AT_SOCKET_EVT_RECV])
@@ -513,15 +659,6 @@ static void urc_recv_func(struct at_client *client, const char *data, rt_size_t
     }
 }
 
-static const struct at_urc urc_table[] =
-{
-    {"SEND OK",          "\r\n",           urc_send_func},
-    {"SEND FAIL",        "\r\n",           urc_send_func},
-    {"Recv",             "bytes\r\n",      urc_send_bfsz_func},
-    {"",                 ",CLOSED\r\n",    urc_close_func},
-    {"+IPD",             ":",              urc_recv_func},
-};
-
 int esp8266_socket_init(struct at_device *device)
 {
     RT_ASSERT(device);

+ 1 - 1
inc/at_device.h

@@ -94,7 +94,7 @@ struct at_device_class
     const struct at_device_ops *device_ops;      /* AT device operaiotns */
 #ifdef AT_USING_SOCKET
     uint32_t socket_num;                         /* The maximum number of sockets support */
-    const struct at_socket_ops *socket_ops;      /* AT device socket operations */
+    struct at_socket_ops *socket_ops;            /* AT device socket operations */
 #endif
     rt_slist_t list;                             /* AT device class list */
 };