library for Bluetooth Shield from Seeed Studio
Fork of BluetoothSerial by
BluetoothSerial.cpp@0:f56002898ee8, 2014-02-20 (annotated)
- Committer:
- yihui
- Date:
- Thu Feb 20 03:30:43 2014 +0000
- Revision:
- 0:f56002898ee8
initial
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yihui | 0:f56002898ee8 | 1 | |
yihui | 0:f56002898ee8 | 2 | #include "BluetoothSerial.h" |
yihui | 0:f56002898ee8 | 3 | #include <string.h> |
yihui | 0:f56002898ee8 | 4 | |
yihui | 0:f56002898ee8 | 5 | #define LOG(args...) // std::printf(args) |
yihui | 0:f56002898ee8 | 6 | |
yihui | 0:f56002898ee8 | 7 | BluetoothSerial::BluetoothSerial(PinName tx, PinName rx) : _serial(tx, rx) |
yihui | 0:f56002898ee8 | 8 | { |
yihui | 0:f56002898ee8 | 9 | |
yihui | 0:f56002898ee8 | 10 | } |
yihui | 0:f56002898ee8 | 11 | |
yihui | 0:f56002898ee8 | 12 | void BluetoothSerial::setup() |
yihui | 0:f56002898ee8 | 13 | { |
yihui | 0:f56002898ee8 | 14 | _serial.baud(BLUETOOTH_SERIAL_DEFAULT_BAUD); |
yihui | 0:f56002898ee8 | 15 | } |
yihui | 0:f56002898ee8 | 16 | |
yihui | 0:f56002898ee8 | 17 | |
yihui | 0:f56002898ee8 | 18 | void BluetoothSerial::master(const char *name, uint8_t autoc) |
yihui | 0:f56002898ee8 | 19 | { |
yihui | 0:f56002898ee8 | 20 | _serial.puts("\r\n+STWMOD=1\r\n"); |
yihui | 0:f56002898ee8 | 21 | _serial.printf("\r\n+STNA=%s\r\n", name); |
yihui | 0:f56002898ee8 | 22 | _serial.printf("\r\n+STAUTO=%d\r\n", autoc ? 1 : 0); |
yihui | 0:f56002898ee8 | 23 | } |
yihui | 0:f56002898ee8 | 24 | |
yihui | 0:f56002898ee8 | 25 | |
yihui | 0:f56002898ee8 | 26 | void BluetoothSerial::slave(const char *name, uint8_t autoc, uint8_t oaut) |
yihui | 0:f56002898ee8 | 27 | { |
yihui | 0:f56002898ee8 | 28 | _serial.puts("\r\n+STWMOD=0\r\n"); |
yihui | 0:f56002898ee8 | 29 | _serial.printf("\r\n+STNA=%s\r\n", name); |
yihui | 0:f56002898ee8 | 30 | _serial.printf("\r\n+STOAUT=%d\r\n", oaut ? 1 : 0); |
yihui | 0:f56002898ee8 | 31 | _serial.printf("\r\n+STAUTO=%d\r\n", autoc ? 1 : 0); |
yihui | 0:f56002898ee8 | 32 | } |
yihui | 0:f56002898ee8 | 33 | |
yihui | 0:f56002898ee8 | 34 | int BluetoothSerial::connect() |
yihui | 0:f56002898ee8 | 35 | { |
yihui | 0:f56002898ee8 | 36 | clear(); |
yihui | 0:f56002898ee8 | 37 | _serial.puts("\r\n+INQ=1\r\n"); // Make the bluetooth module inquirable |
yihui | 0:f56002898ee8 | 38 | LOG("BT: INQUIRING\r\n"); |
yihui | 0:f56002898ee8 | 39 | |
yihui | 0:f56002898ee8 | 40 | const char *prefix = "CONNECT:"; |
yihui | 0:f56002898ee8 | 41 | uint8_t prefix_len = sizeof("CONNECT:") - 1; |
yihui | 0:f56002898ee8 | 42 | for (uint8_t i = 0; i < 12; i++) { |
yihui | 0:f56002898ee8 | 43 | int len = readline(_buf, sizeof(_buf)); |
yihui | 0:f56002898ee8 | 44 | if (len > 0) { |
yihui | 0:f56002898ee8 | 45 | LOG("%s\r\n", _buf); |
yihui | 0:f56002898ee8 | 46 | if (!memcmp(_buf, prefix, prefix_len)) { // check prefix |
yihui | 0:f56002898ee8 | 47 | const char *suffix = "OK"; |
yihui | 0:f56002898ee8 | 48 | uint8_t suffix_len = sizeof("OK") - 1; |
yihui | 0:f56002898ee8 | 49 | |
yihui | 0:f56002898ee8 | 50 | if (!memcmp(_buf + prefix_len, suffix, suffix_len)) { // check suffix |
yihui | 0:f56002898ee8 | 51 | LOG("BT: CONNECTED\r\n"); |
yihui | 0:f56002898ee8 | 52 | return 1; |
yihui | 0:f56002898ee8 | 53 | } |
yihui | 0:f56002898ee8 | 54 | |
yihui | 0:f56002898ee8 | 55 | suffix = "FAIL"; |
yihui | 0:f56002898ee8 | 56 | suffix_len = sizeof("FAIL") - 1; |
yihui | 0:f56002898ee8 | 57 | |
yihui | 0:f56002898ee8 | 58 | if (!memcmp(_buf + prefix_len, suffix, suffix_len)) { // check suffix |
yihui | 0:f56002898ee8 | 59 | return 0; |
yihui | 0:f56002898ee8 | 60 | } |
yihui | 0:f56002898ee8 | 61 | } |
yihui | 0:f56002898ee8 | 62 | } |
yihui | 0:f56002898ee8 | 63 | } |
yihui | 0:f56002898ee8 | 64 | |
yihui | 0:f56002898ee8 | 65 | return 0; |
yihui | 0:f56002898ee8 | 66 | } |
yihui | 0:f56002898ee8 | 67 | |
yihui | 0:f56002898ee8 | 68 | int BluetoothSerial::connect(const char *name) |
yihui | 0:f56002898ee8 | 69 | { |
yihui | 0:f56002898ee8 | 70 | char *mac; |
yihui | 0:f56002898ee8 | 71 | int name_len = strlen(name); |
yihui | 0:f56002898ee8 | 72 | |
yihui | 0:f56002898ee8 | 73 | clear(); |
yihui | 0:f56002898ee8 | 74 | _serial.puts("\r\n+INQ=1\r\n"); |
yihui | 0:f56002898ee8 | 75 | LOG("BT: INQUERING\r\n"); |
yihui | 0:f56002898ee8 | 76 | while (1) { |
yihui | 0:f56002898ee8 | 77 | int len = readline(_buf, sizeof(_buf)); // +RTINQ=XX,XX,X,X,X,X;DEVICE_NAME |
yihui | 0:f56002898ee8 | 78 | if (len > 0) { |
yihui | 0:f56002898ee8 | 79 | LOG("%s\r\n", _buf); |
yihui | 0:f56002898ee8 | 80 | if (!memcmp(_buf, "+RTINQ=", sizeof("+RTINQ=") - 1)) { // check prefix |
yihui | 0:f56002898ee8 | 81 | |
yihui | 0:f56002898ee8 | 82 | if (!memcmp(_buf + len - name_len, name, name_len)) { // check suffix |
yihui | 0:f56002898ee8 | 83 | _buf[len - name_len - 1] = '\0'; |
yihui | 0:f56002898ee8 | 84 | mac = (char*)_buf + sizeof("+RTINQ=") - 1; |
yihui | 0:f56002898ee8 | 85 | LOG("Connecting device: %s\r\n", mac); |
yihui | 0:f56002898ee8 | 86 | |
yihui | 0:f56002898ee8 | 87 | break; |
yihui | 0:f56002898ee8 | 88 | } |
yihui | 0:f56002898ee8 | 89 | } |
yihui | 0:f56002898ee8 | 90 | |
yihui | 0:f56002898ee8 | 91 | } |
yihui | 0:f56002898ee8 | 92 | |
yihui | 0:f56002898ee8 | 93 | } |
yihui | 0:f56002898ee8 | 94 | |
yihui | 0:f56002898ee8 | 95 | LOG("BT: CONNECTING\r\n"); |
yihui | 0:f56002898ee8 | 96 | _serial.printf("\r\n+CONN=%s\r\n", mac); |
yihui | 0:f56002898ee8 | 97 | |
yihui | 0:f56002898ee8 | 98 | const char *prefix = "CONNECT:"; |
yihui | 0:f56002898ee8 | 99 | int prefix_len = sizeof("CONNECT:") - 1; |
yihui | 0:f56002898ee8 | 100 | for (uint8_t i = 0; i < 6; i++) { |
yihui | 0:f56002898ee8 | 101 | int len = readline(_buf, sizeof(_buf), 0); |
yihui | 0:f56002898ee8 | 102 | if (len >= 0) { |
yihui | 0:f56002898ee8 | 103 | LOG("%s\r\n", _buf); |
yihui | 0:f56002898ee8 | 104 | if (!memcmp(_buf, prefix, prefix_len)) { // check prefix |
yihui | 0:f56002898ee8 | 105 | const char *suffix = "OK"; |
yihui | 0:f56002898ee8 | 106 | uint8_t suffix_len = sizeof("OK") - 1; |
yihui | 0:f56002898ee8 | 107 | |
yihui | 0:f56002898ee8 | 108 | if (!memcmp(_buf + prefix_len, suffix, suffix_len)) { // check suffix |
yihui | 0:f56002898ee8 | 109 | LOG("BT: CONNECTED\r\n"); |
yihui | 0:f56002898ee8 | 110 | return 1; |
yihui | 0:f56002898ee8 | 111 | } |
yihui | 0:f56002898ee8 | 112 | |
yihui | 0:f56002898ee8 | 113 | suffix = "FAIL"; |
yihui | 0:f56002898ee8 | 114 | suffix_len = sizeof("FAIL") - 1; |
yihui | 0:f56002898ee8 | 115 | |
yihui | 0:f56002898ee8 | 116 | if (!memcmp(_buf + prefix_len, suffix, suffix_len)) { // check suffix |
yihui | 0:f56002898ee8 | 117 | LOG("TB: CONNECTION FAILED\r\n"); |
yihui | 0:f56002898ee8 | 118 | return 0; |
yihui | 0:f56002898ee8 | 119 | } |
yihui | 0:f56002898ee8 | 120 | } |
yihui | 0:f56002898ee8 | 121 | } |
yihui | 0:f56002898ee8 | 122 | } |
yihui | 0:f56002898ee8 | 123 | |
yihui | 0:f56002898ee8 | 124 | return 0; |
yihui | 0:f56002898ee8 | 125 | } |
yihui | 0:f56002898ee8 | 126 | |
yihui | 0:f56002898ee8 | 127 | |
yihui | 0:f56002898ee8 | 128 | int BluetoothSerial::_getc() |
yihui | 0:f56002898ee8 | 129 | { |
yihui | 0:f56002898ee8 | 130 | return _serial.getc(); |
yihui | 0:f56002898ee8 | 131 | } |
yihui | 0:f56002898ee8 | 132 | |
yihui | 0:f56002898ee8 | 133 | int BluetoothSerial::_putc(int c) |
yihui | 0:f56002898ee8 | 134 | { |
yihui | 0:f56002898ee8 | 135 | return _serial.putc(c); |
yihui | 0:f56002898ee8 | 136 | } |
yihui | 0:f56002898ee8 | 137 | |
yihui | 0:f56002898ee8 | 138 | int BluetoothSerial::readline(uint8_t *buf, int len, uint32_t timeout) |
yihui | 0:f56002898ee8 | 139 | { |
yihui | 0:f56002898ee8 | 140 | int get = 0; |
yihui | 0:f56002898ee8 | 141 | int count = timeout; |
yihui | 0:f56002898ee8 | 142 | while (count >= 0) { |
yihui | 0:f56002898ee8 | 143 | if (_serial.readable()) { |
yihui | 0:f56002898ee8 | 144 | char c = _serial.getc(); |
yihui | 0:f56002898ee8 | 145 | buf[get] = c; |
yihui | 0:f56002898ee8 | 146 | if (c == '\n' && get && buf[get - 1] == '\r') { |
yihui | 0:f56002898ee8 | 147 | buf[get - 1] = '\0'; |
yihui | 0:f56002898ee8 | 148 | return get - 1; |
yihui | 0:f56002898ee8 | 149 | } |
yihui | 0:f56002898ee8 | 150 | get++; |
yihui | 0:f56002898ee8 | 151 | if (get >= len) { |
yihui | 0:f56002898ee8 | 152 | LOG("Too long line, the buffer is not enough\r\n"); |
yihui | 0:f56002898ee8 | 153 | return -(get + 1); |
yihui | 0:f56002898ee8 | 154 | } |
yihui | 0:f56002898ee8 | 155 | |
yihui | 0:f56002898ee8 | 156 | count = timeout; |
yihui | 0:f56002898ee8 | 157 | } |
yihui | 0:f56002898ee8 | 158 | |
yihui | 0:f56002898ee8 | 159 | if (timeout != 0) { |
yihui | 0:f56002898ee8 | 160 | count--; |
yihui | 0:f56002898ee8 | 161 | } |
yihui | 0:f56002898ee8 | 162 | } |
yihui | 0:f56002898ee8 | 163 | |
yihui | 0:f56002898ee8 | 164 | return -(get + 1); |
yihui | 0:f56002898ee8 | 165 | } |
yihui | 0:f56002898ee8 | 166 | |
yihui | 0:f56002898ee8 | 167 | void BluetoothSerial::clear() |
yihui | 0:f56002898ee8 | 168 | { |
yihui | 0:f56002898ee8 | 169 | int count = 0; |
yihui | 0:f56002898ee8 | 170 | |
yihui | 0:f56002898ee8 | 171 | LOG("Clear previous command output\r\n"); |
yihui | 0:f56002898ee8 | 172 | do { |
yihui | 0:f56002898ee8 | 173 | count++; |
yihui | 0:f56002898ee8 | 174 | if (_serial.readable()) { |
yihui | 0:f56002898ee8 | 175 | int get = _serial.getc(); |
yihui | 0:f56002898ee8 | 176 | count = 0; |
yihui | 0:f56002898ee8 | 177 | |
yihui | 0:f56002898ee8 | 178 | LOG("%c", get); |
yihui | 0:f56002898ee8 | 179 | } |
yihui | 0:f56002898ee8 | 180 | } while (count < BLUETOOTH_SERIAL_TIMEOUT); |
yihui | 0:f56002898ee8 | 181 | LOG("done\r\n"); |
yihui | 0:f56002898ee8 | 182 | } |
yihui | 0:f56002898ee8 | 183 | |
yihui | 0:f56002898ee8 | 184 | |
yihui | 0:f56002898ee8 | 185 |