summaryrefslogtreecommitdiff
path: root/apps/netutils/pppd/chat.c
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-03-11 07:53:04 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-03-11 07:53:04 -0600
commit55c6a5ce38c1433e984ee5c209d893ceb8ce2312 (patch)
treef4d1b0ea9a094f746d3af4d4a4978fcf25b3c293 /apps/netutils/pppd/chat.c
parent566ed4018ab7d5b95b29f76daca454385756e578 (diff)
downloadpx4-nuttx-55c6a5ce38c1433e984ee5c209d893ceb8ce2312.tar.gz
px4-nuttx-55c6a5ce38c1433e984ee5c209d893ceb8ce2312.tar.bz2
px4-nuttx-55c6a5ce38c1433e984ee5c209d893ceb8ce2312.zip
Add a PPP daemon. From Max Neklyudov
Diffstat (limited to 'apps/netutils/pppd/chat.c')
-rw-r--r--apps/netutils/pppd/chat.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/apps/netutils/pppd/chat.c b/apps/netutils/pppd/chat.c
new file mode 100644
index 000000000..9042437dc
--- /dev/null
+++ b/apps/netutils/pppd/chat.c
@@ -0,0 +1,136 @@
+#include "ppp_conf.h"
+#include "ppp_arch.h"
+#include "chat.h"
+
+#include <poll.h>
+
+#define CHAT_MAX_SKIP 8
+#define CHAT_ECHO_TIMEOUT 500
+
+static int chat_read_byte(int fd, char* c, int timeout)
+{
+ int ret;
+ struct pollfd fds;
+
+ fds.fd = fd;
+ fds.events = POLLIN;
+ fds.revents = 0;
+
+ ret = poll(&fds, 1, timeout);
+ if (ret <= 0)
+ {
+ return -1;
+ }
+
+ ret = read(fd, c, 1);
+ if (ret != 1)
+ {
+ return -1;
+ }
+
+ printf("chat: char = %c (0x%02X)\n", *c, *c);
+
+ return 0;
+}
+
+static void chat_flush(int fd)
+{
+ char tmp;
+ while (chat_read_byte(fd, &tmp, 0) == 0);
+}
+
+static int chat_check_response(int fd, const char* response, int timeout)
+{
+ char c;
+ int ret;
+ int skip = CHAT_MAX_SKIP;
+
+ while (*response)
+ {
+ ret = chat_read_byte(fd, &c, timeout);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (skip > 0 && (c == '\r' || c == '\n'))
+ {
+ --skip;
+ continue;
+ }
+
+ if (c == *response)
+ {
+ ++response;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int ppp_chat(int fd, struct chat_script_s *script, int echo)
+{
+ int ret;
+ size_t len;
+ struct chat_line_s *line = script->lines;
+ const char* request = line->request;
+ const char* response = line->response;
+
+ while (request)
+ {
+ chat_flush(fd);
+
+ printf("chat: send '%s`\n", request);
+ len = strlen(request);
+ ret = write(fd, request, len);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ else if ((size_t)ret != len)
+ {
+ return -1;
+ }
+
+ ret = write(fd, "\r\n", 2);
+ if (ret != 2)
+ {
+ return -1;
+ }
+
+ /* Check echo if enabled */
+
+ if (echo)
+ {
+ ret = chat_check_response(fd, request, CHAT_ECHO_TIMEOUT);
+ if (ret < 0)
+ {
+ printf("chat: invalid echo\n");
+ return ret;
+ }
+ }
+
+ if (response)
+ {
+ printf("chat: wait for '%s`\n", response);
+ ret = chat_check_response(fd, response, script->timeout * 1000);
+ if (ret < 0)
+ {
+ printf("chat: bad response\n");
+ return ret;
+ }
+
+ printf("chat: got it!\n");
+ }
+
+ ++line;
+ request = line->request;
+ response = line->response;
+ }
+
+ return 0;
+} \ No newline at end of file