diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2015-03-11 07:53:04 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2015-03-11 07:53:04 -0600 |
commit | 55c6a5ce38c1433e984ee5c209d893ceb8ce2312 (patch) | |
tree | f4d1b0ea9a094f746d3af4d4a4978fcf25b3c293 /apps/netutils/pppd/chat.c | |
parent | 566ed4018ab7d5b95b29f76daca454385756e578 (diff) | |
download | px4-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.c | 136 |
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 |