a library to use GPRS like ethernet or wifi, which makes it possible to connect to the internet with your GPRS module
Dependencies: BufferedSerial
Dependents: ThinkSpeak_Test roam_v1 roam_v2 finalv3
Fork of GPRSInterface by
GPRS/modem/modem.cpp@14:3c6454f033ac, 2015-04-03 (annotated)
- Committer:
- yihui
- Date:
- Fri Apr 03 09:51:13 2015 +0000
- Revision:
- 14:3c6454f033ac
- Parent:
- 13:379ce1d51b88
bugfix
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lawliet | 0:8ccbd963e74d | 1 | /* |
lawliet | 0:8ccbd963e74d | 2 | modem.cpp |
Yihui Xiong |
13:379ce1d51b88 | 3 | 2015 Copyright (c) Seeed Technology Limited. All right reserved. |
lawliet | 0:8ccbd963e74d | 4 | */ |
lawliet | 0:8ccbd963e74d | 5 | |
lawliet | 0:8ccbd963e74d | 6 | #include "modem.h" |
Yihui Xiong |
13:379ce1d51b88 | 7 | #include <stdarg.h> |
Yihui Xiong |
13:379ce1d51b88 | 8 | |
Yihui Xiong |
13:379ce1d51b88 | 9 | #define DEBUG |
Yihui Xiong |
13:379ce1d51b88 | 10 | |
Yihui Xiong |
13:379ce1d51b88 | 11 | #ifdef DEBUG |
Yihui Xiong |
13:379ce1d51b88 | 12 | #include "USBSerial.h" |
Yihui Xiong |
13:379ce1d51b88 | 13 | extern USBSerial pc; |
Yihui Xiong |
13:379ce1d51b88 | 14 | #define LOG(args...) pc.printf(args) |
Yihui Xiong |
13:379ce1d51b88 | 15 | #else |
Yihui Xiong |
13:379ce1d51b88 | 16 | #define LOG(args...) |
Yihui Xiong |
13:379ce1d51b88 | 17 | #endif |
lawliet | 0:8ccbd963e74d | 18 | |
Yihui Xiong |
13:379ce1d51b88 | 19 | int Modem::readline(char *buf, int len, uint32_t timeout) |
Yihui Xiong |
13:379ce1d51b88 | 20 | { |
Yihui Xiong |
13:379ce1d51b88 | 21 | int bytes = 0; |
Yihui Xiong |
13:379ce1d51b88 | 22 | uint32_t start = us_ticker_read(); |
Yihui Xiong |
13:379ce1d51b88 | 23 | timeout = timeout * 1000; // ms to us |
Yihui Xiong |
13:379ce1d51b88 | 24 | |
Yihui Xiong |
13:379ce1d51b88 | 25 | while (bytes < len) { |
Yihui Xiong |
13:379ce1d51b88 | 26 | if (readable()) { |
Yihui Xiong |
13:379ce1d51b88 | 27 | char ch = getc(); |
Yihui Xiong |
13:379ce1d51b88 | 28 | if (ch == '\n') { |
Yihui Xiong |
13:379ce1d51b88 | 29 | if (bytes > 0 && buf[bytes - 1] == '\r') { |
Yihui Xiong |
13:379ce1d51b88 | 30 | bytes--; |
Yihui Xiong |
13:379ce1d51b88 | 31 | } |
Yihui Xiong |
13:379ce1d51b88 | 32 | |
Yihui Xiong |
13:379ce1d51b88 | 33 | if (bytes > 0) { |
Yihui Xiong |
13:379ce1d51b88 | 34 | buf[bytes] = '\0'; |
Yihui Xiong |
13:379ce1d51b88 | 35 | |
Yihui Xiong |
13:379ce1d51b88 | 36 | return bytes; |
Yihui Xiong |
13:379ce1d51b88 | 37 | } |
Yihui Xiong |
13:379ce1d51b88 | 38 | } else { |
Yihui Xiong |
13:379ce1d51b88 | 39 | buf[bytes] = ch; |
Yihui Xiong |
13:379ce1d51b88 | 40 | bytes++; |
Yihui Xiong |
13:379ce1d51b88 | 41 | } |
Yihui Xiong |
13:379ce1d51b88 | 42 | } else { |
Yihui Xiong |
13:379ce1d51b88 | 43 | if ((uint32_t)(us_ticker_read() - start) > timeout) { |
Yihui Xiong |
13:379ce1d51b88 | 44 | LOG("wait for a line - timeout\r\n"); |
Yihui Xiong |
13:379ce1d51b88 | 45 | return -1; |
Yihui Xiong |
13:379ce1d51b88 | 46 | } |
Yihui Xiong |
13:379ce1d51b88 | 47 | } |
Yihui Xiong |
13:379ce1d51b88 | 48 | } |
Yihui Xiong |
13:379ce1d51b88 | 49 | |
Yihui Xiong |
13:379ce1d51b88 | 50 | // buffer is not enough |
Yihui Xiong |
13:379ce1d51b88 | 51 | LOG("%s %d line buffer is not enough (max_buf_size: %d)!\r\n", __FILE__, __LINE__, len); |
Yihui Xiong |
13:379ce1d51b88 | 52 | |
Yihui Xiong |
13:379ce1d51b88 | 53 | return 0; |
Yihui Xiong |
13:379ce1d51b88 | 54 | } |
Yihui Xiong |
13:379ce1d51b88 | 55 | |
Yihui Xiong |
13:379ce1d51b88 | 56 | int Modem::command(const char* format, ...) |
Yihui Xiong |
13:379ce1d51b88 | 57 | { |
Yihui Xiong |
13:379ce1d51b88 | 58 | |
Yihui Xiong |
13:379ce1d51b88 | 59 | char buffer[64]; |
Yihui Xiong |
13:379ce1d51b88 | 60 | memset(buffer, 0, sizeof(buffer)); |
Yihui Xiong |
13:379ce1d51b88 | 61 | int r = 0; |
Yihui Xiong |
13:379ce1d51b88 | 62 | |
Yihui Xiong |
13:379ce1d51b88 | 63 | va_list arg; |
Yihui Xiong |
13:379ce1d51b88 | 64 | va_start(arg, format); |
Yihui Xiong |
13:379ce1d51b88 | 65 | r = vsprintf(buffer, format, arg); |
Yihui Xiong |
13:379ce1d51b88 | 66 | // this may not hit the heap but should alert the user anyways |
Yihui Xiong |
13:379ce1d51b88 | 67 | if(r > sizeof(buffer)) { |
Yihui Xiong |
13:379ce1d51b88 | 68 | error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__, sizeof(buffer), r); |
Yihui Xiong |
13:379ce1d51b88 | 69 | va_end(arg); |
Yihui Xiong |
13:379ce1d51b88 | 70 | return 0; |
Yihui Xiong |
13:379ce1d51b88 | 71 | } |
Yihui Xiong |
13:379ce1d51b88 | 72 | va_end(arg); |
Yihui Xiong |
13:379ce1d51b88 | 73 | |
Yihui Xiong |
13:379ce1d51b88 | 74 | |
Yihui Xiong |
13:379ce1d51b88 | 75 | while (!writeable()) { |
Yihui Xiong |
13:379ce1d51b88 | 76 | } |
Yihui Xiong |
13:379ce1d51b88 | 77 | flush(); |
Yihui Xiong |
13:379ce1d51b88 | 78 | |
Yihui Xiong |
13:379ce1d51b88 | 79 | r = BufferedSerial::write(buffer, r); // send command |
Yihui Xiong |
13:379ce1d51b88 | 80 | |
Yihui Xiong |
13:379ce1d51b88 | 81 | char response[64] = {0,}; |
Yihui Xiong |
13:379ce1d51b88 | 82 | readline(response, sizeof(response)); // echo enabled |
Yihui Xiong |
13:379ce1d51b88 | 83 | |
Yihui Xiong |
13:379ce1d51b88 | 84 | readline(response, sizeof(response)); |
Yihui Xiong |
13:379ce1d51b88 | 85 | |
Yihui Xiong |
13:379ce1d51b88 | 86 | if (strcmp(response, "OK") == 0) { |
Yihui Xiong |
13:379ce1d51b88 | 87 | return 0; |
Yihui Xiong |
13:379ce1d51b88 | 88 | } |
Yihui Xiong |
13:379ce1d51b88 | 89 | |
Yihui Xiong |
13:379ce1d51b88 | 90 | LOG("cmd failed - w(%s), r(%s)\r\n", buffer, response); |
Yihui Xiong |
13:379ce1d51b88 | 91 | |
Yihui Xiong |
13:379ce1d51b88 | 92 | return -1; |
Yihui Xiong |
13:379ce1d51b88 | 93 | } |
Yihui Xiong |
13:379ce1d51b88 | 94 | |
Yihui Xiong |
13:379ce1d51b88 | 95 | int Modem::match(const char *str, uint32_t timeout) |
Yihui Xiong |
13:379ce1d51b88 | 96 | { |
Yihui Xiong |
13:379ce1d51b88 | 97 | const char *ptr = str; |
Yihui Xiong |
13:379ce1d51b88 | 98 | uint32_t start = us_ticker_read(); |
Yihui Xiong |
13:379ce1d51b88 | 99 | timeout = timeout * 1000; // ms to us |
Yihui Xiong |
13:379ce1d51b88 | 100 | |
Yihui Xiong |
13:379ce1d51b88 | 101 | while(*ptr) { |
Yihui Xiong |
13:379ce1d51b88 | 102 | if(readable()) { |
Yihui Xiong |
13:379ce1d51b88 | 103 | char c = getc(); |
Yihui Xiong |
13:379ce1d51b88 | 104 | if (*ptr == c) { |
Yihui Xiong |
13:379ce1d51b88 | 105 | ptr++; |
Yihui Xiong |
13:379ce1d51b88 | 106 | } else { |
Yihui Xiong |
13:379ce1d51b88 | 107 | ptr = str; |
Yihui Xiong |
13:379ce1d51b88 | 108 | } |
Yihui Xiong |
13:379ce1d51b88 | 109 | } else { |
Yihui Xiong |
13:379ce1d51b88 | 110 | if ((uint32_t)(us_ticker_read() - start) > timeout) { |
Yihui Xiong |
13:379ce1d51b88 | 111 | LOG("wait for [%s] - timeout\r\n", str); |
Yihui Xiong |
13:379ce1d51b88 | 112 | return -1; |
Yihui Xiong |
13:379ce1d51b88 | 113 | } |
Yihui Xiong |
13:379ce1d51b88 | 114 | } |
Yihui Xiong |
13:379ce1d51b88 | 115 | } |
Yihui Xiong |
13:379ce1d51b88 | 116 | |
Yihui Xiong |
13:379ce1d51b88 | 117 | return 0; |
Yihui Xiong |
13:379ce1d51b88 | 118 | } |
Yihui Xiong |
13:379ce1d51b88 | 119 | |
Yihui Xiong |
13:379ce1d51b88 | 120 | void Modem::flush() |
Yihui Xiong |
13:379ce1d51b88 | 121 | { |
Yihui Xiong |
13:379ce1d51b88 | 122 | while (readable()) { // flush |
Yihui Xiong |
13:379ce1d51b88 | 123 | getc(); |
Yihui Xiong |
13:379ce1d51b88 | 124 | } |
Yihui Xiong |
13:379ce1d51b88 | 125 | } |
Yihui Xiong |
13:379ce1d51b88 | 126 | |
Yihui Xiong |
13:379ce1d51b88 | 127 | uint8_t Modem::read() |
Yihui Xiong |
13:379ce1d51b88 | 128 | { |
Yihui Xiong |
13:379ce1d51b88 | 129 | while (!readable()) { |
Yihui Xiong |
13:379ce1d51b88 | 130 | } |
Yihui Xiong |
13:379ce1d51b88 | 131 | |
Yihui Xiong |
13:379ce1d51b88 | 132 | return getc(); |
Yihui Xiong |
13:379ce1d51b88 | 133 | } |
lawliet | 0:8ccbd963e74d | 134 |