Преглед изворни кода

Rewrite ppp_recv thread

Signed-off-by: xiaofan <xfan1024@live.com>
xiaofan пре 6 година
родитељ
комит
da752a13b3

+ 13 - 2
class/air720/ppp_device_air720.c

@@ -43,17 +43,28 @@ static const struct modem_chat_data mcd[] =
 static rt_err_t ppp_air720_open(struct ppp_device *device, rt_uint16_t oflag)
 {
     RT_ASSERT(device != RT_NULL);
+    return RT_EOK;
+}
 
-    return modem_chat(device->uart_name, mcd, sizeof(mcd) / sizeof(mcd[0]));
+static rt_err_t ppp_air720_control(struct ppp_device *device, int cmd, void *args)
+{
+    switch (cmd)
+    {
+    case PPP_CTL_PREPARE:
+        return modem_chat(device->uart_name, mcd, sizeof(mcd) / sizeof(mcd[0]));
+    default:
+        return -RT_ENOSYS;
+    }
 }
 
+
 /* ppp_air720_ops for ppp_device_ops , a common interface */
 static struct ppp_device_ops air720_ops =
 {
     RT_NULL,
     ppp_air720_open,
     RT_NULL,
-    RT_NULL,
+    ppp_air720_control,
 };
 
 /*

+ 50 - 5
class/m6312/ppp_device_m6312.c

@@ -10,6 +10,7 @@
 
 #include <ppp_device_m6312.h>
 #include <ppp_chat.h>
+#include <rtdevice.h>
 
 #define DBG_TAG    "ppp.m6312"
 
@@ -19,19 +20,48 @@
 #define DBG_LVL   DBG_INFO
 #endif
 
+#define M6312_POWER_ON  PIN_HIGH
+#define M6312_POWER_OFF PIN_LOW
+#ifndef M6312_POWER_PIN
+#define M6312_POWER_PIN -1
+#endif
+
 #include <rtdbg.h>
 
-static const struct modem_chat_data mcd[] =
+static const struct modem_chat_data rst_mcd[] =
 {
     {"+++",          MODEM_CHAT_RESP_OK,        10, 1, RT_FALSE},
     {"ATH",          MODEM_CHAT_RESP_OK,        1,  1, RT_FALSE},
     {"AT+CMRESET",   MODEM_CHAT_RESP_NOT_NEED,  1,  1, RT_FALSE},
+};
+
+static const struct modem_chat_data mcd[] =
+{
     {"AT",           MODEM_CHAT_RESP_OK,        10, 1, RT_FALSE},
     {"ATE0",         MODEM_CHAT_RESP_OK,        1,  1, RT_FALSE},
     {PPP_APN_CMD,    MODEM_CHAT_RESP_OK,        1,  5, RT_FALSE},
     {PPP_DAIL_CMD,   MODEM_CHAT_RESP_CONNECT,   2, 30, RT_FALSE},
 };
 
+static rt_err_t m6312_prepare(struct ppp_m6312 *m6312)
+{
+
+    if (m6312->power_pin >= 0)
+    {
+        rt_pin_write(m6312->power_pin, M6312_POWER_OFF);
+        rt_thread_mdelay(500);
+        rt_pin_write(m6312->power_pin, M6312_POWER_ON);
+    }
+    else
+    {
+        rt_err_t err;
+        err = modem_chat(m6312->device.uart_name, rst_mcd, sizeof(rst_mcd) / sizeof(rst_mcd[0]));
+        if (err)
+            return err;
+    }
+    return modem_chat(m6312->device.uart_name, mcd, sizeof(mcd) / sizeof(mcd[0]));
+}
+
 /*
  * Get into PPP modem,using uart
  *
@@ -44,8 +74,18 @@ static const struct modem_chat_data mcd[] =
 static rt_err_t ppp_m6312_open(struct ppp_device *device, rt_uint16_t oflag)
 {
     RT_ASSERT(device != RT_NULL);
+    return RT_EOK;
+}
 
-    return modem_chat(device->uart_name, mcd, sizeof(mcd) / sizeof(mcd[0]));
+static rt_err_t ppp_m6312_control(struct ppp_device *device, int cmd, void *args)
+{
+    switch (cmd)
+    {
+    case PPP_CTL_PREPARE:
+        return m6312_prepare((struct ppp_m6312*)device);
+    default:
+        return -RT_ENOSYS;
+    }
 }
 
 /* ppp_m6312_ops for ppp_device_ops , a common interface */
@@ -54,7 +94,7 @@ static struct ppp_device_ops m6312_ops =
     RT_NULL,
     ppp_m6312_open,
     RT_NULL,
-    RT_NULL,
+    ppp_m6312_control,
 };
 
 /*
@@ -79,11 +119,16 @@ int ppp_m6312_register(void)
         return -RT_ENOMEM;
     }
 
+    m6312->power_pin = M6312_POWER_PIN;
+    if (m6312->power_pin >= 0)
+    {
+        rt_pin_mode(m6312->power_pin, PIN_MODE_OUTPUT);
+        rt_pin_write(m6312->power_pin, M6312_POWER_OFF);
+    }
+
     ppp_device = &(m6312->device);
     ppp_device->ops = &m6312_ops;
-
     LOG_D("ppp m6312 is registering ppp_device");
-
     return ppp_device_register(ppp_device, PPP_DEVICE_NAME, RT_NULL, RT_NULL);
 }
 INIT_COMPONENT_EXPORT(ppp_m6312_register);

+ 1 - 0
class/m6312/ppp_device_m6312.h

@@ -18,6 +18,7 @@ struct ppp_m6312
 {
     struct ppp_device  device;          /* ppp_device struct in ppp_m6312 */
     enum ppp_trans_type type;           /* the type is used to establish a ppp connection */
+    rt_base_t power_pin;
 };
 
 extern int ppp_m6312_register(void);

+ 12 - 2
class/sim800/ppp_device_sim800.c

@@ -43,8 +43,18 @@ static const struct modem_chat_data mcd[] =
 static rt_err_t ppp_sim800_open(struct ppp_device *device, rt_uint16_t oflag)
 {
     RT_ASSERT(device != RT_NULL);
+    return RT_EOK;
+}
 
-    return modem_chat(device->uart_name, mcd, sizeof(mcd) / sizeof(mcd[0]));
+static rt_err_t ppp_sim800_control(struct ppp_device *device, int cmd, void *args)
+{
+    switch (cmd)
+    {
+    case PPP_CTL_PREPARE:
+        return modem_chat(device->uart_name, mcd, sizeof(mcd) / sizeof(mcd[0]));
+    default:
+        return -RT_ENOSYS;
+    }
 }
 
 /* ppp_sim800_ops for ppp_device_ops , a common interface */
@@ -53,7 +63,7 @@ static struct ppp_device_ops sim800_ops =
     RT_NULL,
     ppp_sim800_open,
     RT_NULL,
-    RT_NULL,
+    ppp_sim800_control,
 };
 
 /*

+ 8 - 6
inc/ppp_device.h

@@ -36,6 +36,9 @@
 #define PPP_CTL_GET_CSQ      1
 #define PPP_CTL_GET_IEMI     2
 #define PPP_CTL_GET_TYPE     3
+#define PPP_CTL_PREPARE      10
+
+#define PPP_FRAME_MAX       1550
 
 enum ppp_trans_type
 {
@@ -56,6 +59,7 @@ enum ppp_conn_type
 struct ppp_device
 {
     struct rt_device parent;                    /* join rt_device frame */
+    rt_device_t uart;
     char *uart_name;                            /* the name of the low-level driver device */
     const struct ppp_device_ops *ops;           /* ppp device ops interface */
     enum ppp_conn_type conn_type;               /* using usb or uart */
@@ -63,15 +67,13 @@ struct ppp_device
     ppp_pcb *pcb;                               /* ppp protocol control block */
     struct netif pppif;
 
-    char *recv_line_buf;                        /* the current received one line data buffer */
-    rt_size_t recv_line_len;                    /* The length of the currently received one line data */
-    rt_size_t recv_bufsz;                       /* The maximum supported receive data length */
+    rt_size_t  rxpos;
+    rt_uint8_t rxbuf[PPP_FRAME_MAX];
+    rt_uint8_t state;
 
-    rt_sem_t rx_notice;                         /* attention uart to recieve data delivery to tcpip */
-    rt_mutex_t lock;                            /* protect uart */
+    struct rt_event event;
 
     rt_thread_t recv_tid;                       /* recieve thread point */
-    rt_bool_t ppp_link_status;                  /* if ppp link is shut down, close recieve thread and shut down */
     void *user_data;                            /* reserve */
 };
 

+ 1 - 4
src/ppp_chat.c

@@ -268,12 +268,9 @@ rt_err_t modem_chat(char *uart_name, const struct modem_chat_data *data, rt_size
     LOG_I("(%s) has control by modem_chat.", serial->parent.name);
     err = modem_chat_internal(serial, data, len);
     if (err != RT_EOK)
-    {
         LOG_E("chat failed");
-        goto __exit;
-    }
 
-    serial->rx_indicate = old_rx_ind;
 __exit:
+    serial->rx_indicate = old_rx_ind;
     return err;
 }

+ 148 - 178
src/ppp_device.c

@@ -21,10 +21,25 @@
 
 #include <rtdbg.h>
 
+enum {
+    PPP_STATE_PREPARE,
+    PPP_STATE_WAIT_HEAD,
+    PPP_STATE_WAIT_ADDR,
+    PPP_STATE_RECV_DATA,
+};
+
 #define PPP_DATA_BEGIN_END       0x7e
+#define PPP_DATA_ADDR            0xff
 #define DATA_EFFECTIVE_FLAG      0x00
 #define RECON_ERR_COUNTS         0x02
 #define PPP_RECONNECT_TIME       2500
+#define PPP_RECV_READ_MAX        32
+
+
+#define PPP_EVENT_RX_NOTIFY 1   // serial incoming a byte
+#define PPP_EVENT_LOST      2   // PPP connection is lost
+#define PPP_EVENT_CLOSE_REQ 4   // user want close ppp_device
+#define PPP_EVENT_CLOSED    8   // ppp_recv thread will send CLOSED event when ppp_recv thread is safe exit
 
 #if RT_LWIP_TCPTHREAD_STACKSIZE < 2048
 #error "tcpip stack is too small, should greater than 2048."
@@ -48,28 +63,11 @@ static rt_err_t ppp_device_rx_ind(rt_device_t dev, rt_size_t size)
     struct ppp_device *ppp_dev = _g_ppp_device;
 
     /* when recieve data from uart , release semphone to wake up recieve thread */
-    rt_sem_release(ppp_dev->rx_notice);
+    rt_event_send(&ppp_dev->event, PPP_EVENT_RX_NOTIFY);
 
     return RT_EOK;
 }
 
-static rt_err_t ppp_device_getchar(rt_device_t recv_dev,rt_sem_t rx_notice, char *ch, rt_int32_t timeout)
-{
-    rt_err_t result = RT_EOK;
-
-    while (rt_device_read(recv_dev, 0, ch, 1) == 0)
-    {
-        rt_sem_control(rx_notice, RT_IPC_CMD_RESET, RT_NULL);
-
-        result = rt_sem_take(rx_notice, rt_tick_from_millisecond(timeout));
-        if (result != RT_EOK)
-        {
-            return result;
-        }
-    }
-    return RT_EOK;
-}
-
 /*
  *  using ppp_data_send send data to lwIP procotol stack     PPPoS serial output callback
  *
@@ -86,33 +84,13 @@ static uint32_t ppp_data_send(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *p
     RT_ASSERT(pcb != RT_NULL);
     RT_ASSERT(ppp_device != RT_NULL);
 
-    int result = RT_EOK;
     struct ppp_device *device = (struct ppp_device *)ppp_device;
-    rt_device_t recv_device = RT_NULL;
 
-    RT_ASSERT(device != RT_NULL);
-
-    if(device->ppp_link_status != RT_TRUE)
-        goto __exit;
-
-    /* recv_device is rt_device , find recv_device through device name */
-    recv_device = rt_device_find(device->uart_name);
-    if (recv_device == RT_NULL)
-    {
-        LOG_E("Can find device (%s), ppp send data execute failed.",device->uart_name);
-        result = -RT_ERROR;
-        goto __exit;
-    }
+    if (device->state == PPP_STATE_PREPARE)
+        return 0;
 
     /* the return data is the actually written size on successful */
-    len = rt_device_write(recv_device,0,data,len);
-
-    /* must be return data length , or will get warning like "pppos_write[0]: output failed len=24" */
-    return len;
-
-__exit:
-
-    return result;
+    return rt_device_write(device->uart, 0, data, len);
 }
 
 /*
@@ -129,16 +107,10 @@ static void ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx)
 {
     struct ppp_device *pppdev = (struct ppp_device *)ctx;
     struct netif *pppif = ppp_netif(pcb);
-    static uint8_t re_count = 0;
     switch (err_code)
     {
     case PPPERR_NONE:                /* Connected */
         pppdev->pppif.mtu = pppif->mtu;
-        if (pppdev->ppp_link_status == 1)
-        {
-            ppp_netdev_add(&pppdev->pppif);
-        }
-        re_count = 0;
         LOG_I("ppp connect successful.");
         break;
     case PPPERR_PARAM:
@@ -154,12 +126,10 @@ static void ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx)
         LOG_E("Unable to allocate resources.");
         break;
     case PPPERR_USER:
-        pppapi_free(pcb);           /* Free the PPP control block */
+        LOG_D("User interrupt");
         break;
     case PPPERR_CONNECT:            /* Connection lost */
         LOG_E("ppp connect lost.");
-        pppapi_connect(pcb, 0);
-        LOG_I("Reconnection.");
         break;
     case PPPERR_AUTHFAIL:
         LOG_E("Failed authentication challenge.");
@@ -169,20 +139,6 @@ static void ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx)
         break;
     case PPPERR_PEERDEAD:
         LOG_E("Connection timeout.");
-        pppapi_connect(pcb, 0);
-        if (re_count++ == RECON_ERR_COUNTS)
-        {
-            re_count = 0;
-            pppdev->ppp_link_status = 0;
-            if (!(pppdev->parent.close && pppdev->parent.close((rt_device_t)pppdev)))
-            {
-                LOG_E("ppp_device close failed.");
-            }
-        }
-        else
-        {
-             LOG_I("Reconnection.");
-        }
         break;
     case PPPERR_IDLETIMEOUT:
         LOG_E("Idle Timeout.");
@@ -197,6 +153,79 @@ static void ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx)
         LOG_E("Unknown error code %d.", err_code);
         break;
     }
+    if (err_code != PPPERR_NONE)
+        rt_event_send(&pppdev->event, PPP_EVENT_LOST);
+}
+
+static inline void ppp_savebyte(struct ppp_device *device, rt_uint8_t dat)
+{
+    RT_ASSERT(device->rxpos < sizeof(device->rxbuf));
+    device->rxbuf[device->rxpos++] = dat;
+}
+
+static inline void ppp_start_receive_frame(struct ppp_device *device)
+{
+    device->rxpos = 0;
+    device->state = PPP_STATE_WAIT_HEAD;
+}
+
+static void ppp_recv_processdata(struct ppp_device *device, const rt_uint8_t *buf, rt_size_t len)
+{
+    rt_uint8_t dat;
+
+    // LOG_D("%s: %u bytes", __func__, (unsigned)len);
+    while (len--)
+    {
+        dat = *buf++;
+process_dat:
+        ppp_savebyte(device, dat);
+        switch (device->state)
+        {
+        case PPP_STATE_WAIT_HEAD:
+            // LOG_D("want PPP_DATA_BEGIN");
+            if (dat == PPP_DATA_BEGIN_END)
+            {
+                device->state++;
+                // LOG_I("got PPP_DATA_BEGIN");
+            }
+            else
+            {
+                ppp_start_receive_frame(device);
+            }
+            break;
+        case PPP_STATE_WAIT_ADDR:
+            // LOG_D("want PPP_DATA_ADDR");
+            if (dat == PPP_DATA_ADDR)
+            {
+                device->state++;
+                // LOG_D("GOT PPP_DATA_ADDR");
+            }
+            else
+            {
+                ppp_start_receive_frame(device);
+                goto process_dat;
+            }
+
+            break;
+        case PPP_STATE_RECV_DATA:
+            if (dat == PPP_DATA_BEGIN_END)
+            {
+                // LOG_D("GOT FRAME: %u bytes", (unsigned)device->rxpos);
+                rt_enter_critical();
+                pppos_input_tcpip(device->pcb, (u8_t *)device->rxbuf, device->rxpos);
+                rt_exit_critical();
+                ppp_start_receive_frame(device);
+            }
+            break;
+        default:
+            LOG_E("BUG: unexpect state: %u", (unsigned int)device->state);
+        }
+        if (device->rxpos == sizeof(device->rxbuf))
+        {
+            LOG_W("receive ppp frame is lagger than %u", (unsigned int)sizeof(device->rxbuf));
+            ppp_start_receive_frame(device);
+        }
+    }
 }
 
 /*
@@ -210,97 +239,65 @@ static void ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx)
  */
 static int ppp_recv_entry(struct ppp_device *device)
 {
-    RT_ASSERT(device != RT_NULL);
-
-    char ch = 0, old_ch = 0;
-    int result = RT_EOK;
-    static char thrans_flag = 0;
-    rt_device_t recv_dev = RT_NULL;
-    device->recv_line_len = 0;
+    const rt_uint32_t interested_event = PPP_EVENT_RX_NOTIFY | PPP_EVENT_LOST | PPP_EVENT_CLOSE_REQ;
+    rt_uint32_t event;
+    rt_size_t len;
+    rt_uint8_t buffer[PPP_RECV_READ_MAX];
+    rt_bool_t closing = RT_FALSE;
 
-    /* alloc buff to store uart data */
-    device->recv_line_buf = (char *)rt_calloc(1, 1550);
-    if (device->recv_line_buf == RT_NULL)
-    {
-        LOG_E("ppp_recv_line_buff alloc memory failed! No memory for receive buffer.");
-        result = -RT_ENOMEM;
-        goto __exit;
-    }
-
-    /* use name to find rt_devcie */
-    recv_dev = rt_device_find(device->uart_name);
-    if (recv_dev == RT_NULL)
-    {
-        LOG_E("Can find device (%s), ppp recv entry creat failed.",device->uart_name);
-        result = -RT_ERROR;
-        goto __exit;
-    }
+    rt_event_control(&device->event, RT_IPC_CMD_RESET, NULL);
+    device->state = PPP_STATE_PREPARE;
 
     while (1)
     {
-        /* ppp link is closed, the recieve thread also need to exit */
-        if (device->ppp_link_status != RT_TRUE)
+        if (device->state == PPP_STATE_PREPARE)
         {
-            break;
-        }
-
-        /* waitting for get data, more secure way to deal information */
-        ppp_device_getchar(recv_dev, device->rx_notice, &ch, RT_WAITING_FOREVER);
-
-        /* begin to recieve data from uart */
-        if (thrans_flag == PPP_DATA_START)
-        {
-            /* if recieve 0x7e twice */
-            if (ch == PPP_DATA_BEGIN_END && old_ch == PPP_DATA_BEGIN_END)
-            {
-                /* choice the least 0x7e as frame head */
-                device->recv_line_buf[0] = ch;
-                device->recv_line_len = 1;
-
-                old_ch = ch;
-            }
-            else if (ch == PPP_DATA_BEGIN_END && old_ch == DATA_EFFECTIVE_FLAG)
+            if (device->ops->control(device, PPP_CTL_PREPARE, NULL) == RT_EOK)
             {
-                thrans_flag = PPP_DATA_END;
-                device->recv_line_buf[device->recv_line_len] = ch;
+                ppp_start_receive_frame(device);
+                pppapi_connect(device->pcb, 0);
             }
             else
             {
-                old_ch = DATA_EFFECTIVE_FLAG;
-                device->recv_line_buf[device->recv_line_len] = ch;
-                device->recv_line_len++;
+                LOG_E("%s prepare fail, try again later", device->parent.parent.name);
+                rt_thread_mdelay(10*1000);
             }
+            continue;
+        }
+
+        rt_event_recv(&device->event, interested_event, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &event);
 
-            /* when a frame is end, put data into tcpip */
-            if (thrans_flag == PPP_DATA_END)
+        if (event & PPP_EVENT_RX_NOTIFY)
+        {
+            do
             {
-                rt_enter_critical();
-                pppos_input_tcpip(device->pcb, (u8_t *)device->recv_line_buf, device->recv_line_len + 1);
-                rt_exit_critical();
+                len = rt_device_read(device->uart, 0, buffer, PPP_RECV_READ_MAX);
+                if (len)
+                    ppp_recv_processdata(device, buffer, len);
+            } while (len);
+        }
 
-                thrans_flag = PPP_DATA_VERIFY;
-                device->recv_line_len = 0;
-            }
+        if (event & PPP_EVENT_CLOSE_REQ)
+        {
+            LOG_D("user request close ppp");
+            closing = RT_TRUE;
+            pppapi_close(device->pcb, 0);
         }
-        else
+
+        if (event & PPP_EVENT_LOST)
         {
-            /* if recieve 0x7e, begin to recieve data */
-            if (ch == PPP_DATA_BEGIN_END)
+            if (closing)
             {
-                thrans_flag = PPP_DATA_START;
-                old_ch = ch;
-                device->recv_line_buf[0] = ch;
-                device->recv_line_len = 1;
+                LOG_W("ppp closing success");
+                rt_event_send(&device->event, PPP_EVENT_CLOSED);
+                break;
             }
+            LOG_W("ppp lost, try reconnect");
+            device->state = PPP_STATE_PREPARE;
         }
     }
 
-__exit:
-
-    rt_free(device->recv_line_buf);
-    rt_free(device->rx_notice);
-
-    return result;
+    return RT_EOK;
 }
 
 /*
@@ -316,20 +313,11 @@ static int ppp_recv_entry_creat(struct ppp_device *device)
 {
     rt_int8_t result = RT_EOK;
 
-    /* when recieve rx_notice, come to recieve a data from uart */
-    device->rx_notice = rt_sem_create("sem_ppp_recv", 0, RT_IPC_FLAG_FIFO);
-    if (device->rx_notice == RT_NULL)
-    {
-        LOG_E("PPP device initialize failed! ppp_device_recv_notice create failed!");
-        result = -RT_ENOMEM;
-        goto __exit;
-    }
-
     /* dynamic creat a recv_thread */
     device->recv_tid = rt_thread_create("ppp_recv",
                                         (void (*)(void *parameter))ppp_recv_entry,
                                         device,
-                                        512,
+                                        768,
                                         8,
                                         20);
     if (device->recv_tid == RT_NULL)
@@ -342,19 +330,11 @@ static int ppp_recv_entry_creat(struct ppp_device *device)
     /* if you create a thread, never forget to start it */
     result = rt_thread_startup(device->recv_tid);
     if(result != RT_EOK)
-    {
         goto __exit;
-    }
 
     return result;
 
 __exit:
-
-    if (device->rx_notice)
-    {
-        rt_sem_delete(device->rx_notice);
-    }
-
     rt_memset(device, 0x00, sizeof(struct ppp_device));
     return result;
 }
@@ -398,19 +378,8 @@ static rt_err_t ppp_device_open(struct rt_device *device, rt_uint16_t oflag)
     RT_ASSERT(device != RT_NULL);
 
     struct ppp_device *ppp_device = (struct ppp_device *)device;
-    static rt_device_t serial = RT_NULL;
-
-    ppp_device->ppp_link_status = RT_TRUE;
-    /* Creat a thread to creat ppp recieve function */
-    result = ppp_recv_entry_creat(ppp_device);
-    if (result != RT_EOK)
-    {
-        LOG_E("Creat a thread to creat ppp recieve function failed.");
-        result = -RT_ERROR;
-        goto __exit;
-    }
-    LOG_D("Creat a thread to creat ppp recieve function successful.");
 
+    rt_event_init(&ppp_device->event, "pppev", RT_IPC_FLAG_FIFO);
     /* we can do nothing */
     if (ppp_device->ops->open && ppp_device->ops->open(ppp_device, oflag) != RT_EOK)
     {
@@ -420,13 +389,13 @@ static rt_err_t ppp_device_open(struct rt_device *device, rt_uint16_t oflag)
     }
 
     /* uart conversion into ppp device , find and open command device */
-    serial = rt_device_find(ppp_device->uart_name);
-    if (serial  != RT_NULL)
+    ppp_device->uart = rt_device_find(ppp_device->uart_name);
+    if (ppp_device->uart  != RT_NULL)
     {
-        RT_ASSERT(serial->type == RT_Device_Class_Char);
+        RT_ASSERT(ppp_device->uart->type == RT_Device_Class_Char);
 
         /* uart transfer into tcpip protocol stack */
-        rt_device_set_rx_indicate(serial, ppp_device_rx_ind);
+        rt_device_set_rx_indicate(ppp_device->uart, ppp_device_rx_ind);
         LOG_I("(%s) is used by ppp_device.", ppp_device->uart_name);
     }
     else
@@ -445,6 +414,7 @@ static rt_err_t ppp_device_open(struct rt_device *device, rt_uint16_t oflag)
         goto __exit;
     }
     LOG_D("pppapi_pppos_create has created a protocol control block.");
+    ppp_netdev_add(&ppp_device->pppif);
 
     /* set netif name */
     ppp_device->pppif.name[0] = ppp_device->parent.parent.name[0];
@@ -476,15 +446,15 @@ static rt_err_t ppp_device_open(struct rt_device *device, rt_uint16_t oflag)
     LOG_D("ppp_set_auth has passed verification.");
  #endif /* PPP_AUTHORIZE */
 
-    /* ppp connect */
-    result = pppapi_connect(ppp_device->pcb, 0);
+    /* Creat a thread to creat ppp recieve function */
+    result = ppp_recv_entry_creat(ppp_device);
     if (result != RT_EOK)
     {
-        LOG_E("pppapi_connect execute failed.");
+        LOG_E("Creat a thread to creat ppp recieve function failed.");
         result = -RT_ERROR;
         goto __exit;
     }
-    LOG_D("pppapi_connect execute successful, waitting connect.");
+    LOG_D("Creat a thread to creat ppp recieve function successful.");
 
 __exit:
 
@@ -501,20 +471,20 @@ __exit:
  */
 static rt_err_t ppp_device_close(struct rt_device *device)
 {
+    rt_uint32_t event;
     RT_ASSERT(device != RT_NULL);
 	extern void ppp_netdev_del(struct netif *ppp_netif);
 
     struct ppp_device *ppp_device = (struct ppp_device *)device;
     RT_ASSERT(ppp_device != RT_NULL);
 
-    /* use pppapi_close to shutdown ppp link status */
-    pppapi_close(ppp_device->pcb, 0);
-
-    ppp_device->ppp_link_status = RT_FALSE;
+    rt_event_send(&ppp_device->event, PPP_EVENT_CLOSE_REQ);
+    rt_event_recv(&ppp_device->event, PPP_EVENT_CLOSED, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &event);
 
-    /* delete netdev from netdev frame */
     ppp_netdev_del(&ppp_device->pppif);
+    ppp_free(ppp_device->pcb);
     LOG_D("ppp netdev has been detach.");
+    rt_event_detach(&ppp_device->event);
 
     if (ppp_device->ops->close && ppp_device->ops->close(ppp_device) != RT_EOK)
     {