|
|
@@ -6,6 +6,7 @@
|
|
|
* Change Logs:
|
|
|
* Date Author Notes
|
|
|
* 2019-08-15 xiangxistu the first version
|
|
|
+ * 2019-10-01 xiaofan rewrite ppp_recv thread
|
|
|
*/
|
|
|
|
|
|
#include <ppp_device.h>
|
|
|
@@ -21,10 +22,23 @@
|
|
|
|
|
|
#include <rtdbg.h>
|
|
|
|
|
|
+enum {
|
|
|
+ PPP_STATE_PREPARE,
|
|
|
+ PPP_STATE_WAIT_HEAD,
|
|
|
+ PPP_STATE_RECV_DATA,
|
|
|
+};
|
|
|
+
|
|
|
#define PPP_DATA_BEGIN_END 0x7e
|
|
|
#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."
|
|
|
@@ -33,6 +47,42 @@
|
|
|
|
|
|
static struct ppp_device *_g_ppp_device = RT_NULL;
|
|
|
|
|
|
+static void ppp_debug_hexdump(const void *data, size_t len)
|
|
|
+{
|
|
|
+#ifdef PPP_DEVICE_DEBUG
|
|
|
+ const size_t maxlen = 16;
|
|
|
+ rt_uint32_t offset = 0;
|
|
|
+ size_t curlen;
|
|
|
+ char line[maxlen*4+3];
|
|
|
+ char *p;
|
|
|
+ const unsigned char *src = data;
|
|
|
+
|
|
|
+ while (len > 0)
|
|
|
+ {
|
|
|
+ curlen = len < maxlen ? len : maxlen;
|
|
|
+ p = line;
|
|
|
+ for (size_t i = 0; i < curlen; i++)
|
|
|
+ {
|
|
|
+ rt_sprintf(p, "%02x ", (unsigned char)src[i]);
|
|
|
+ p += 3;
|
|
|
+ }
|
|
|
+ memset(p, ' ', (maxlen - curlen) * 3);
|
|
|
+ p += (maxlen - curlen) * 3;
|
|
|
+ *p++ = '|';
|
|
|
+ *p++ = ' ';
|
|
|
+ for (size_t i = 0; i < curlen; i++)
|
|
|
+ {
|
|
|
+ *p++ = (0x20 < src[i] && src[i] < 0x7e) ? src[i] : '.';
|
|
|
+ }
|
|
|
+ *p++ = '\0';
|
|
|
+ LOG_D("[%04x] %s", offset, line);
|
|
|
+ len -= curlen;
|
|
|
+ src += curlen;
|
|
|
+ offset += curlen;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Receive callback function , release rx_notice when uart acquire data
|
|
|
*
|
|
|
@@ -48,25 +98,8 @@ 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);
|
|
|
-
|
|
|
- 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);
|
|
|
+ rt_event_send(&ppp_dev->event, PPP_EVENT_RX_NOTIFY);
|
|
|
|
|
|
- result = rt_sem_take(rx_notice, rt_tick_from_millisecond(timeout));
|
|
|
- if (result != RT_EOK)
|
|
|
- {
|
|
|
- return result;
|
|
|
- }
|
|
|
- }
|
|
|
return RT_EOK;
|
|
|
}
|
|
|
|
|
|
@@ -86,33 +119,17 @@ 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;
|
|
|
|
|
|
+#ifdef PPP_DEVICE_DEBUG_TX
|
|
|
+ LOG_D("TX:");
|
|
|
+ ppp_debug_hexdump(data, len);
|
|
|
+#endif
|
|
|
/* 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 +146,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 +165,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 +178,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,110 +192,216 @@ 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);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Receive thread , store uart data and transform tcpip stack
|
|
|
- *
|
|
|
- * @param ppp_device *device
|
|
|
- *
|
|
|
- *
|
|
|
- * @return 0: execute successful
|
|
|
- *
|
|
|
- */
|
|
|
-static int ppp_recv_entry(struct ppp_device *device)
|
|
|
+static inline void ppp_start_receive_frame(struct ppp_device *device)
|
|
|
{
|
|
|
- RT_ASSERT(device != RT_NULL);
|
|
|
+ device->rxpos = 0;
|
|
|
+ device->state = PPP_STATE_WAIT_HEAD;
|
|
|
+}
|
|
|
|
|
|
- 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;
|
|
|
+#ifdef PPP_DEVICE_DEBUG_DROP
|
|
|
+static inline void ppp_show_dropbuf(struct ppp_device *device)
|
|
|
+{
|
|
|
+ if (!device->droppos)
|
|
|
+ return;
|
|
|
+ LOG_D("DROP: ");
|
|
|
+ ppp_debug_hexdump(device->dropbuf, device->droppos);
|
|
|
+ device->dropcnt += device->droppos;
|
|
|
+ device->droppos = 0;
|
|
|
+}
|
|
|
|
|
|
- /* 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;
|
|
|
- }
|
|
|
+static inline void ppp_show_rxbuf_as_drop(struct ppp_device *device)
|
|
|
+{
|
|
|
+ if (!device->rxpos)
|
|
|
+ return;
|
|
|
+ LOG_D("DROP: ");
|
|
|
+ ppp_debug_hexdump(device->rxbuf, device->rxpos);
|
|
|
+ device->dropcnt += device->rxpos;
|
|
|
+ device->rxpos = 0;
|
|
|
+}
|
|
|
|
|
|
- /* use name to find rt_devcie */
|
|
|
- recv_dev = rt_device_find(device->uart_name);
|
|
|
- if (recv_dev == RT_NULL)
|
|
|
+static inline void ppp_rxbuf_drop(struct ppp_device *device)
|
|
|
+{
|
|
|
+ // if we have no enough drop-buffer, we should display and clear drop-buffer
|
|
|
+ if (PPP_DROP_BUF - device->droppos < device->rxpos)
|
|
|
{
|
|
|
- LOG_E("Can find device (%s), ppp recv entry creat failed.",device->uart_name);
|
|
|
- result = -RT_ERROR;
|
|
|
- goto __exit;
|
|
|
+ ppp_show_dropbuf(device);
|
|
|
+ // if our drop-buffer size less than or equal current valid size of rx-buffer, we should display and clear rx-buffer
|
|
|
+ if (PPP_DROP_BUF <= device->rxpos)
|
|
|
+ {
|
|
|
+ ppp_show_rxbuf_as_drop(device);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- while (1)
|
|
|
+ if (device->rxpos)
|
|
|
{
|
|
|
- /* ppp link is closed, the recieve thread also need to exit */
|
|
|
- if (device->ppp_link_status != RT_TRUE)
|
|
|
+ rt_memcpy(&device->dropbuf[device->droppos], device->rxbuf, device->rxpos);
|
|
|
+ device->droppos += device->rxpos;
|
|
|
+ device->rxpos = 0;
|
|
|
+
|
|
|
+ if (device->droppos == PPP_DROP_BUF)
|
|
|
{
|
|
|
- break;
|
|
|
+ ppp_show_dropbuf(device);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- /* waitting for get data, more secure way to deal information */
|
|
|
- ppp_device_getchar(recv_dev, device->rx_notice, &ch, RT_WAITING_FOREVER);
|
|
|
+ ppp_start_receive_frame(device);
|
|
|
+}
|
|
|
+
|
|
|
+#else
|
|
|
+static inline void ppp_show_dropbuf(struct ppp_device *device) {}
|
|
|
+#define ppp_rxbuf_drop(device) ppp_start_receive_frame(device)
|
|
|
+#endif // !PPP_DEVICE_DEBUG_DROP
|
|
|
|
|
|
- /* begin to recieve data from uart */
|
|
|
- if (thrans_flag == PPP_DATA_START)
|
|
|
+static inline void ppp_processdata_enter(struct ppp_device *device)
|
|
|
+{
|
|
|
+ ppp_start_receive_frame(device);
|
|
|
+#ifdef PPP_DEVICE_DEBUG_DROP
|
|
|
+ device->droppos = 0;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+static inline void ppp_processdata_leave(struct ppp_device *device)
|
|
|
+{
|
|
|
+ ppp_rxbuf_drop(device);
|
|
|
+ ppp_show_dropbuf(device);
|
|
|
+}
|
|
|
+
|
|
|
+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 void ppp_recv_processdata(struct ppp_device *device, const rt_uint8_t *buf, rt_size_t len)
|
|
|
+{
|
|
|
+ rt_uint8_t dat;
|
|
|
+
|
|
|
+ while (len--)
|
|
|
+ {
|
|
|
+ dat = *buf++;
|
|
|
+
|
|
|
+process_dat:
|
|
|
+ switch (device->state)
|
|
|
{
|
|
|
- /* if recieve 0x7e twice */
|
|
|
- if (ch == PPP_DATA_BEGIN_END && old_ch == PPP_DATA_BEGIN_END)
|
|
|
+ case PPP_STATE_WAIT_HEAD:
|
|
|
+ ppp_savebyte(device, dat);
|
|
|
+ if (dat == 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;
|
|
|
+ ppp_show_dropbuf(device);
|
|
|
+ device->state = PPP_STATE_RECV_DATA;
|
|
|
}
|
|
|
- else if (ch == PPP_DATA_BEGIN_END && old_ch == DATA_EFFECTIVE_FLAG)
|
|
|
+ else
|
|
|
{
|
|
|
- thrans_flag = PPP_DATA_END;
|
|
|
- device->recv_line_buf[device->recv_line_len] = ch;
|
|
|
+ ppp_rxbuf_drop(device);
|
|
|
}
|
|
|
- else
|
|
|
+ break;
|
|
|
+ case PPP_STATE_RECV_DATA:
|
|
|
+ if (dat == PPP_DATA_BEGIN_END && device->rxpos == 1)
|
|
|
{
|
|
|
- old_ch = DATA_EFFECTIVE_FLAG;
|
|
|
- device->recv_line_buf[device->recv_line_len] = ch;
|
|
|
- device->recv_line_len++;
|
|
|
+ LOG_D("found continuous 0x7e");
|
|
|
+ // start receive a new frame
|
|
|
+ ppp_rxbuf_drop(device);
|
|
|
+ goto process_dat;
|
|
|
}
|
|
|
-
|
|
|
- /* when a frame is end, put data into tcpip */
|
|
|
- if (thrans_flag == PPP_DATA_END)
|
|
|
+ ppp_savebyte(device, dat);
|
|
|
+ if (dat == PPP_DATA_BEGIN_END)
|
|
|
{
|
|
|
+#ifdef PPP_DEVICE_DEBUG_RX
|
|
|
+ LOG_D("RX:");
|
|
|
+ ppp_debug_hexdump(device->rxbuf, device->rxpos);
|
|
|
+#endif
|
|
|
rt_enter_critical();
|
|
|
- pppos_input_tcpip(device->pcb, (u8_t *)device->recv_line_buf, device->recv_line_len + 1);
|
|
|
+ pppos_input_tcpip(device->pcb, (u8_t *)device->rxbuf, device->rxpos);
|
|
|
rt_exit_critical();
|
|
|
-
|
|
|
- thrans_flag = PPP_DATA_VERIFY;
|
|
|
- device->recv_line_len = 0;
|
|
|
+ ppp_start_receive_frame(device);
|
|
|
}
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ LOG_E("BUG: unexpect state: %u", (unsigned int)device->state);
|
|
|
}
|
|
|
- else
|
|
|
+ if (device->rxpos == sizeof(device->rxbuf))
|
|
|
{
|
|
|
- /* if recieve 0x7e, begin to recieve data */
|
|
|
- if (ch == PPP_DATA_BEGIN_END)
|
|
|
+ LOG_W("receive ppp frame is lagger than %u", (unsigned int)sizeof(device->rxbuf));
|
|
|
+ ppp_rxbuf_drop(device);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Receive thread , store uart data and transform tcpip stack
|
|
|
+ *
|
|
|
+ * @param ppp_device *device
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * @return 0: execute successful
|
|
|
+ *
|
|
|
+ */
|
|
|
+static int ppp_recv_entry(struct ppp_device *device)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+
|
|
|
+ rt_event_control(&device->event, RT_IPC_CMD_RESET, RT_NULL);
|
|
|
+ device->state = PPP_STATE_PREPARE;
|
|
|
+
|
|
|
+ while (1)
|
|
|
+ {
|
|
|
+ if (device->state == PPP_STATE_PREPARE)
|
|
|
+ {
|
|
|
+ if (!device->ops->prepare || device->ops->prepare(device) == RT_EOK)
|
|
|
+ {
|
|
|
+ ppp_processdata_enter(device);
|
|
|
+ pppapi_connect(device->pcb, 0);
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- thrans_flag = PPP_DATA_START;
|
|
|
- old_ch = ch;
|
|
|
- device->recv_line_buf[0] = ch;
|
|
|
- device->recv_line_len = 1;
|
|
|
+ LOG_E("%s prepare fail, try again later", device->parent.parent.name);
|
|
|
+ rt_thread_mdelay(10*1000);
|
|
|
}
|
|
|
+ continue;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
-__exit:
|
|
|
+ rt_event_recv(&device->event, interested_event, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &event);
|
|
|
|
|
|
- rt_free(device->recv_line_buf);
|
|
|
- rt_free(device->rx_notice);
|
|
|
+ if (event & PPP_EVENT_RX_NOTIFY)
|
|
|
+ {
|
|
|
+ do
|
|
|
+ {
|
|
|
+ len = rt_device_read(device->uart, 0, buffer, PPP_RECV_READ_MAX);
|
|
|
+ if (len)
|
|
|
+ ppp_recv_processdata(device, buffer, len);
|
|
|
+ } while (len);
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
+ if (event & PPP_EVENT_CLOSE_REQ)
|
|
|
+ {
|
|
|
+ LOG_D("user request close ppp");
|
|
|
+ closing = RT_TRUE;
|
|
|
+ pppapi_close(device->pcb, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (event & PPP_EVENT_LOST)
|
|
|
+ {
|
|
|
+ ppp_processdata_leave(device);
|
|
|
+ if (closing)
|
|
|
+ {
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return RT_EOK;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -316,20 +417,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 +434,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;
|
|
|
}
|
|
|
@@ -374,12 +458,11 @@ static rt_err_t ppp_device_init(struct rt_device *device)
|
|
|
|
|
|
struct ppp_device *ppp_device = (struct ppp_device *)device;
|
|
|
RT_ASSERT(ppp_device != RT_NULL);
|
|
|
-
|
|
|
- if(ppp_device->ops->init && ppp_device->ops->init(ppp_device) != RT_EOK)
|
|
|
- {
|
|
|
- LOG_E("ppp_device->ops->init failed.");
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
+ device->flag |= RT_DEVICE_FLAG_STANDALONE;
|
|
|
+#ifdef PPP_DEVICE_DEBUG_DROP
|
|
|
+ ppp_device->dropcnt = 0;
|
|
|
+ ppp_device->droppos = 0;
|
|
|
+#endif
|
|
|
return RT_EOK;
|
|
|
}
|
|
|
|
|
|
@@ -395,46 +478,37 @@ static rt_err_t ppp_device_init(struct rt_device *device)
|
|
|
static rt_err_t ppp_device_open(struct rt_device *device, rt_uint16_t oflag)
|
|
|
{
|
|
|
int result = RT_EOK;
|
|
|
+ rt_uint16_t uart_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)
|
|
|
+ uart_oflag = RT_DEVICE_OFLAG_RDWR;
|
|
|
+ if (ppp_device->uart->flag & RT_DEVICE_FLAG_DMA_RX)
|
|
|
+ uart_oflag |= RT_DEVICE_FLAG_DMA_RX;
|
|
|
+ else if (ppp_device->uart->flag & RT_DEVICE_FLAG_INT_RX)
|
|
|
+ uart_oflag = RT_DEVICE_FLAG_INT_RX;
|
|
|
+ if (ppp_device->uart->flag & RT_DEVICE_FLAG_DMA_TX)
|
|
|
+ uart_oflag |= RT_DEVICE_FLAG_DMA_TX;
|
|
|
+ else if (ppp_device->uart->flag & RT_DEVICE_FLAG_INT_TX)
|
|
|
+ uart_oflag |= RT_DEVICE_FLAG_INT_TX;
|
|
|
+
|
|
|
+ if (rt_device_open(ppp_device->uart, uart_oflag) != RT_EOK)
|
|
|
{
|
|
|
- LOG_E("Creat a thread to creat ppp recieve function failed.");
|
|
|
+ LOG_E("ppp device open 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)
|
|
|
- {
|
|
|
- LOG_E("ppp device open failed.");
|
|
|
- result = -RT_ERROR;
|
|
|
- goto __exit;
|
|
|
- }
|
|
|
|
|
|
- /* uart conversion into ppp device , find and open command device */
|
|
|
- serial = rt_device_find(ppp_device->uart_name);
|
|
|
- if (serial != RT_NULL)
|
|
|
- {
|
|
|
- RT_ASSERT(serial->type == RT_Device_Class_Char);
|
|
|
+ RT_ASSERT(ppp_device->uart && ppp_device->uart->type == RT_Device_Class_Char);
|
|
|
+
|
|
|
+ /* uart transfer into tcpip protocol stack */
|
|
|
+ rt_device_set_rx_indicate(ppp_device->uart, ppp_device_rx_ind);
|
|
|
+ LOG_I("(%s) is used by ppp_device.", ppp_device->uart->parent.name);
|
|
|
|
|
|
- /* uart transfer into tcpip protocol stack */
|
|
|
- rt_device_set_rx_indicate(serial, ppp_device_rx_ind);
|
|
|
- LOG_I("(%s) is used by ppp_device.", ppp_device->uart_name);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- LOG_E("Cannot find %s device.", ppp_device->uart_name);
|
|
|
- result = -RT_ERROR;
|
|
|
- goto __exit;
|
|
|
- }
|
|
|
|
|
|
/* creat pppos */
|
|
|
ppp_device->pcb = pppapi_pppos_create(&(ppp_device->pppif), ppp_data_send, ppp_status_changed, ppp_device);
|
|
|
@@ -445,6 +519,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 +551,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,26 +576,23 @@ __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);
|
|
|
+ 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);
|
|
|
|
|
|
- ppp_device->ppp_link_status = RT_FALSE;
|
|
|
-
|
|
|
- /* delete netdev from netdev frame */
|
|
|
+ rt_device_set_rx_indicate(ppp_device->uart, RT_NULL);
|
|
|
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)
|
|
|
- {
|
|
|
- LOG_E("ppp_device->ops->close failed.");
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
+ rt_device_close(ppp_device->uart);
|
|
|
/* cut down piont to piont at data link layer */
|
|
|
LOG_I("ppp_device has been closed.");
|
|
|
return RT_EOK;
|
|
|
@@ -539,16 +611,7 @@ static rt_err_t ppp_device_control(struct rt_device *device,int cmd, void *args)
|
|
|
{
|
|
|
RT_ASSERT(device != RT_NULL);
|
|
|
|
|
|
- struct ppp_device *ppp_device = (struct ppp_device *)device;
|
|
|
- RT_ASSERT(ppp_device != RT_NULL);
|
|
|
-
|
|
|
- /* use ppp_device_control function */
|
|
|
- if(ppp_device->ops->control && ppp_device->ops->control(ppp_device, cmd, args) != RT_EOK)
|
|
|
- {
|
|
|
- LOG_E("ppp_device->ops->control failed.");
|
|
|
- return -RT_ERROR;
|
|
|
- }
|
|
|
- return RT_EOK;
|
|
|
+ return -RT_ENOSYS;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -611,17 +674,6 @@ int ppp_device_register(struct ppp_device *ppp_device, const char *dev_name, con
|
|
|
LOG_I("ppp_device has registered rt_device frame successful.");
|
|
|
}
|
|
|
|
|
|
- /* when ppp device has register rt_device frame, start up it */
|
|
|
- do
|
|
|
- {
|
|
|
- if (device->init && device->init((rt_device_t)ppp_device) != RT_EOK)
|
|
|
- {
|
|
|
- LOG_E("ppp device init failed.try it in %ds", PPP_RECONNECT_TIME / 100);
|
|
|
- rt_thread_mdelay(PPP_RECONNECT_TIME);
|
|
|
- result = -RT_ERROR;
|
|
|
- }
|
|
|
- } while (result != RT_EOK);
|
|
|
-
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -635,14 +687,19 @@ int ppp_device_register(struct ppp_device *ppp_device, const char *dev_name, con
|
|
|
* -1: error
|
|
|
*
|
|
|
*/
|
|
|
-int ppp_device_attach(struct ppp_device *ppp_device, char *uart_name, void *user_data)
|
|
|
+int ppp_device_attach(struct ppp_device *ppp_device, const char *uart_name, void *user_data)
|
|
|
{
|
|
|
RT_ASSERT(ppp_device != RT_NULL);
|
|
|
|
|
|
- ppp_device->uart_name = uart_name;
|
|
|
+ ppp_device->uart = rt_device_find(uart_name);
|
|
|
+ if (!ppp_device->uart)
|
|
|
+ {
|
|
|
+ LOG_E("ppp_device_attach, cannot found %s", uart_name);
|
|
|
+ return -RT_ERROR;
|
|
|
+ }
|
|
|
ppp_device->user_data = user_data;
|
|
|
|
|
|
- if (ppp_device->parent.open && ppp_device->parent.open((rt_device_t)ppp_device, RT_TRUE) != RT_EOK)
|
|
|
+ if (rt_device_open(&ppp_device->parent, 0) != RT_EOK)
|
|
|
{
|
|
|
LOG_E("ppp_device_attach failed. Can't open device(%d)");
|
|
|
return -RT_ERROR;
|
|
|
@@ -664,13 +721,13 @@ int ppp_device_detach(struct ppp_device *ppp_device)
|
|
|
{
|
|
|
RT_ASSERT(ppp_device != RT_NULL);
|
|
|
|
|
|
- if (ppp_device->parent.close && ppp_device->parent.close((rt_device_t)ppp_device) != RT_EOK)
|
|
|
+ if (rt_device_close(&ppp_device->parent) != RT_EOK)
|
|
|
{
|
|
|
LOG_E("ppp_device_detach failed. Can't open device.");
|
|
|
return -RT_ERROR;
|
|
|
}
|
|
|
|
|
|
- ppp_device->uart_name = RT_NULL;
|
|
|
+ ppp_device->uart = RT_NULL;
|
|
|
ppp_device->user_data = RT_NULL;
|
|
|
|
|
|
return RT_EOK;
|