Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: aconno_I2C Lis2dh12 WatchdogTimer
modem.cpp@38:476a9b5629a1, 2019-01-16 (annotated)
- Committer:
- pathfindr
- Date:
- Wed Jan 16 23:06:39 2019 +0000
- Revision:
- 38:476a9b5629a1
- Parent:
- 37:505ef618f06c
- Child:
- 39:f767b8037475
updates
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| pathfindr | 7:e9a19750700d | 1 | #include "modem.h" |
| pathfindr | 7:e9a19750700d | 2 | |
| pathfindr | 34:4493c9f6d707 | 3 | char ATinBuffer[200]; |
| pathfindr | 7:e9a19750700d | 4 | |
| pathfindr | 34:4493c9f6d707 | 5 | Modem::Modem(PinName pwrkey, PinName vreg_en, PinName w_disable): _pwrkey(pwrkey), _vreg_en(vreg_en), _w_disable(w_disable) |
| pathfindr | 34:4493c9f6d707 | 6 | { |
| pathfindr | 7:e9a19750700d | 7 | } |
| pathfindr | 7:e9a19750700d | 8 | |
| pathfindr | 7:e9a19750700d | 9 | void Modem::ATsendCMD(char* cmd) |
| pathfindr | 7:e9a19750700d | 10 | { |
| pathfindr | 34:4493c9f6d707 | 11 | NRFuart_flush(); |
| pathfindr | 34:4493c9f6d707 | 12 | NRFuart_puts(cmd); |
| pathfindr | 34:4493c9f6d707 | 13 | NRFuart_puts("\r"); |
| pathfindr | 7:e9a19750700d | 14 | } |
| pathfindr | 7:e9a19750700d | 15 | |
| pathfindr | 12:8345612bf867 | 16 | bool Modem::ATwaitForWord(char* word, uint32_t timeout) |
| pathfindr | 7:e9a19750700d | 17 | { |
| pathfindr | 7:e9a19750700d | 18 | int targetIndex = 0; |
| pathfindr | 7:e9a19750700d | 19 | bool havefullmatch = false; |
| pathfindr | 7:e9a19750700d | 20 | char captured[32]; |
| pathfindr | 31:c84fc6d8eaa3 | 21 | memset(captured,0,sizeof(captured)); |
| pathfindr | 7:e9a19750700d | 22 | Timer t; |
| pathfindr | 7:e9a19750700d | 23 | t.start(); |
| pathfindr | 12:8345612bf867 | 24 | uint32_t startmillis = t.read_ms(); |
| pathfindr | 12:8345612bf867 | 25 | uint32_t runtime = 0; |
| pathfindr | 7:e9a19750700d | 26 | while(!havefullmatch && runtime < timeout) { |
| pathfindr | 7:e9a19750700d | 27 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 34:4493c9f6d707 | 28 | if(NRFuart_readable()) { |
| pathfindr | 34:4493c9f6d707 | 29 | char c = NRFuart_getc(); |
| pathfindr | 7:e9a19750700d | 30 | if (c != word[targetIndex]) { //no match, reset |
| pathfindr | 7:e9a19750700d | 31 | targetIndex = 0; |
| pathfindr | 7:e9a19750700d | 32 | } |
| pathfindr | 7:e9a19750700d | 33 | if (c == word[targetIndex]) { //we have a match |
| pathfindr | 7:e9a19750700d | 34 | captured[targetIndex] = c; |
| pathfindr | 7:e9a19750700d | 35 | targetIndex ++; |
| pathfindr | 7:e9a19750700d | 36 | //check for full match |
| pathfindr | 7:e9a19750700d | 37 | if ( strcmp(word, captured) == 0 ) { |
| pathfindr | 7:e9a19750700d | 38 | havefullmatch = true; |
| pathfindr | 7:e9a19750700d | 39 | } |
| pathfindr | 7:e9a19750700d | 40 | } |
| pathfindr | 12:8345612bf867 | 41 | } |
| pathfindr | 7:e9a19750700d | 42 | } |
| pathfindr | 7:e9a19750700d | 43 | t.stop(); |
| pathfindr | 7:e9a19750700d | 44 | t.reset(); |
| pathfindr | 7:e9a19750700d | 45 | if (havefullmatch) { |
| pathfindr | 7:e9a19750700d | 46 | return true; |
| pathfindr | 7:e9a19750700d | 47 | } else { |
| pathfindr | 7:e9a19750700d | 48 | return false; |
| pathfindr | 7:e9a19750700d | 49 | } |
| pathfindr | 7:e9a19750700d | 50 | } |
| pathfindr | 7:e9a19750700d | 51 | |
| pathfindr | 34:4493c9f6d707 | 52 | |
| pathfindr | 34:4493c9f6d707 | 53 | bool Modem::ATgetResponse(char terminator, uint32_t timeout) |
| pathfindr | 34:4493c9f6d707 | 54 | { |
| pathfindr | 36:8e359069192b | 55 | memset(ATinBuffer,0x00,sizeof(ATinBuffer)); |
| pathfindr | 34:4493c9f6d707 | 56 | int charindex = 0; |
| pathfindr | 34:4493c9f6d707 | 57 | bool gotTerminator = false; |
| pathfindr | 34:4493c9f6d707 | 58 | Timer t; |
| pathfindr | 34:4493c9f6d707 | 59 | t.start(); |
| pathfindr | 34:4493c9f6d707 | 60 | uint32_t startmillis = t.read_ms(); |
| pathfindr | 34:4493c9f6d707 | 61 | uint32_t runtime = 0; |
| pathfindr | 34:4493c9f6d707 | 62 | while(!gotTerminator && runtime < timeout) { |
| pathfindr | 34:4493c9f6d707 | 63 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 34:4493c9f6d707 | 64 | if(NRFuart_readable()) { |
| pathfindr | 34:4493c9f6d707 | 65 | char c = NRFuart_getc(); |
| pathfindr | 34:4493c9f6d707 | 66 | if (c == terminator) { |
| pathfindr | 34:4493c9f6d707 | 67 | gotTerminator = true; |
| pathfindr | 34:4493c9f6d707 | 68 | } else { |
| pathfindr | 34:4493c9f6d707 | 69 | ATinBuffer[charindex] = c; |
| pathfindr | 34:4493c9f6d707 | 70 | charindex++; |
| pathfindr | 34:4493c9f6d707 | 71 | } |
| pathfindr | 34:4493c9f6d707 | 72 | } |
| pathfindr | 34:4493c9f6d707 | 73 | } |
| pathfindr | 34:4493c9f6d707 | 74 | t.stop(); |
| pathfindr | 34:4493c9f6d707 | 75 | t.reset(); |
| pathfindr | 34:4493c9f6d707 | 76 | ATinBuffer[charindex] = '\n'; //make sure we end with whitespace lf |
| pathfindr | 34:4493c9f6d707 | 77 | return gotTerminator; |
| pathfindr | 34:4493c9f6d707 | 78 | } |
| pathfindr | 34:4493c9f6d707 | 79 | |
| pathfindr | 34:4493c9f6d707 | 80 | |
| pathfindr | 38:476a9b5629a1 | 81 | bool Modem::on(bool force2G) |
| pathfindr | 12:8345612bf867 | 82 | { |
| pathfindr | 34:4493c9f6d707 | 83 | NRFuart_init_nohwfc(); |
| pathfindr | 34:4493c9f6d707 | 84 | |
| pathfindr | 23:a3b0ccf75ca5 | 85 | if (!GLOBAL_modemOn) { |
| pathfindr | 23:a3b0ccf75ca5 | 86 | _w_disable = 0; // this sets the modem to airplane mode |
| pathfindr | 23:a3b0ccf75ca5 | 87 | _vreg_en = 1; |
| pathfindr | 23:a3b0ccf75ca5 | 88 | Thread::wait(200); |
| pathfindr | 23:a3b0ccf75ca5 | 89 | _pwrkey = 0; |
| pathfindr | 23:a3b0ccf75ca5 | 90 | Thread::wait(200); |
| pathfindr | 23:a3b0ccf75ca5 | 91 | _pwrkey = 1; |
| pathfindr | 23:a3b0ccf75ca5 | 92 | |
| pathfindr | 23:a3b0ccf75ca5 | 93 | GLOBAL_modemOn = true; |
| pathfindr | 22:810425eb76e1 | 94 | |
| pathfindr | 23:a3b0ccf75ca5 | 95 | //CONFIGURE |
| pathfindr | 23:a3b0ccf75ca5 | 96 | if (ATwaitForWord("RDY",ATTIMEOUT_MED)) { |
| pathfindr | 34:4493c9f6d707 | 97 | |
| pathfindr | 23:a3b0ccf75ca5 | 98 | //TURN OFF ECHO |
| pathfindr | 38:476a9b5629a1 | 99 | //ATsendCMD("ATE0"); |
| pathfindr | 38:476a9b5629a1 | 100 | //ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 34:4493c9f6d707 | 101 | |
| pathfindr | 23:a3b0ccf75ca5 | 102 | //ENABLE AIRPLANE MODE CONTROL WITH PIN |
| pathfindr | 23:a3b0ccf75ca5 | 103 | ATsendCMD("AT+QCFG=\"airplanecontrol\",1"); |
| pathfindr | 23:a3b0ccf75ca5 | 104 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 38:476a9b5629a1 | 105 | |
| pathfindr | 27:fa76f5a08195 | 106 | //CONNECTION TYPE |
| pathfindr | 32:dff4858bdf37 | 107 | //ATsendCMD("AT+QCFG=\"nwscanmode\",2"); //3G only connection |
| pathfindr | 38:476a9b5629a1 | 108 | if (force2G) { |
| pathfindr | 38:476a9b5629a1 | 109 | ATsendCMD("AT+QCFG=\"nwscanmode\",1"); //2G only connection |
| pathfindr | 38:476a9b5629a1 | 110 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 38:476a9b5629a1 | 111 | } else { |
| pathfindr | 38:476a9b5629a1 | 112 | //PRIORITISE 2G connection (reason being uses less power in some instances and can get cell tower tirangulation) |
| pathfindr | 38:476a9b5629a1 | 113 | ATsendCMD("AT+QCFG=\"nwscanseq\",1"); //2G priority |
| pathfindr | 38:476a9b5629a1 | 114 | //ATsendCMD("AT+QCFG=\"nwscanseq\",2"); //3G priority |
| pathfindr | 38:476a9b5629a1 | 115 | //ATsendCMD("AT+QCFG=\"nwscanseq\",0"); //AUTO - default |
| pathfindr | 38:476a9b5629a1 | 116 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 38:476a9b5629a1 | 117 | } |
| pathfindr | 23:a3b0ccf75ca5 | 118 | |
| pathfindr | 23:a3b0ccf75ca5 | 119 | return true; |
| pathfindr | 23:a3b0ccf75ca5 | 120 | } else { |
| pathfindr | 23:a3b0ccf75ca5 | 121 | return false; |
| pathfindr | 23:a3b0ccf75ca5 | 122 | } |
| pathfindr | 12:8345612bf867 | 123 | } else { |
| pathfindr | 23:a3b0ccf75ca5 | 124 | return true; |
| pathfindr | 12:8345612bf867 | 125 | } |
| pathfindr | 12:8345612bf867 | 126 | } |
| pathfindr | 12:8345612bf867 | 127 | |
| pathfindr | 12:8345612bf867 | 128 | void Modem::off(bool soft) |
| pathfindr | 12:8345612bf867 | 129 | { |
| pathfindr | 12:8345612bf867 | 130 | if (soft) { |
| pathfindr | 23:a3b0ccf75ca5 | 131 | //ATsendCMD("AT+QPOWD"); |
| pathfindr | 24:c161db07557f | 132 | //_pwrkey = 0; |
| pathfindr | 24:c161db07557f | 133 | //Thread::wait(800); |
| pathfindr | 24:c161db07557f | 134 | //_pwrkey = 1; |
| pathfindr | 23:a3b0ccf75ca5 | 135 | //ATwaitForWord("POWERED DOWN",ATTIMEOUT_SHORT); |
| pathfindr | 12:8345612bf867 | 136 | } |
| pathfindr | 34:4493c9f6d707 | 137 | GLOBAL_modemOn = false; |
| pathfindr | 22:810425eb76e1 | 138 | GLOBAL_registeredOnNetwork = false; |
| pathfindr | 37:505ef618f06c | 139 | _w_disable = 0; //enable airplane mode |
| pathfindr | 34:4493c9f6d707 | 140 | _pwrkey = 0; |
| pathfindr | 12:8345612bf867 | 141 | _vreg_en = 0; |
| pathfindr | 12:8345612bf867 | 142 | } |
| pathfindr | 12:8345612bf867 | 143 | |
| pathfindr | 13:29f67f256709 | 144 | long long Modem::getIMEI() |
| pathfindr | 13:29f67f256709 | 145 | { |
| pathfindr | 13:29f67f256709 | 146 | long long imei = 0; |
| pathfindr | 13:29f67f256709 | 147 | ATsendCMD("AT+GSN"); |
| pathfindr | 34:4493c9f6d707 | 148 | if (ATwaitForWord("\r",ATTIMEOUT_SHORT)) { |
| pathfindr | 34:4493c9f6d707 | 149 | if (ATgetResponse('\r',ATTIMEOUT_SHORT)) { |
| pathfindr | 34:4493c9f6d707 | 150 | imei = atoll(ATinBuffer); |
| pathfindr | 34:4493c9f6d707 | 151 | } |
| pathfindr | 34:4493c9f6d707 | 152 | }; |
| pathfindr | 34:4493c9f6d707 | 153 | |
| pathfindr | 34:4493c9f6d707 | 154 | NRFuart_flush(); |
| pathfindr | 13:29f67f256709 | 155 | return imei; |
| pathfindr | 13:29f67f256709 | 156 | } |
| pathfindr | 13:29f67f256709 | 157 | |
| pathfindr | 23:a3b0ccf75ca5 | 158 | char* Modem::getModemModel() |
| pathfindr | 23:a3b0ccf75ca5 | 159 | { |
| pathfindr | 23:a3b0ccf75ca5 | 160 | char* modemModel; |
| pathfindr | 23:a3b0ccf75ca5 | 161 | ATsendCMD("AT+GMM"); |
| pathfindr | 34:4493c9f6d707 | 162 | if (ATwaitForWord("\r",ATTIMEOUT_SHORT)) { |
| pathfindr | 34:4493c9f6d707 | 163 | if (ATgetResponse('\r',ATTIMEOUT_SHORT)) { |
| pathfindr | 34:4493c9f6d707 | 164 | sscanf(ATinBuffer,"%s", modemModel); |
| pathfindr | 34:4493c9f6d707 | 165 | } |
| pathfindr | 34:4493c9f6d707 | 166 | }; |
| pathfindr | 34:4493c9f6d707 | 167 | NRFuart_flush(); |
| pathfindr | 23:a3b0ccf75ca5 | 168 | return modemModel; |
| pathfindr | 23:a3b0ccf75ca5 | 169 | } |
| pathfindr | 23:a3b0ccf75ca5 | 170 | |
| pathfindr | 12:8345612bf867 | 171 | bool Modem::registerOnNetwork(int maxAttempts, uint32_t timeout) |
| pathfindr | 12:8345612bf867 | 172 | { |
| pathfindr | 22:810425eb76e1 | 173 | //CHECK WE ARE NOT ALREADY ON NETOWRK |
| pathfindr | 22:810425eb76e1 | 174 | if (!GLOBAL_registeredOnNetwork) { |
| pathfindr | 22:810425eb76e1 | 175 | int attempt = 0; |
| pathfindr | 22:810425eb76e1 | 176 | Timer t; |
| pathfindr | 22:810425eb76e1 | 177 | t.start(); |
| pathfindr | 22:810425eb76e1 | 178 | //DISABLE AIRPLANE MODE |
| pathfindr | 22:810425eb76e1 | 179 | _w_disable = 1; |
| pathfindr | 34:4493c9f6d707 | 180 | NRFuart_flush(); |
| pathfindr | 26:fa3579737329 | 181 | while (attempt < maxAttempts) { |
| pathfindr | 22:810425eb76e1 | 182 | watchdogKick(); |
| pathfindr | 22:810425eb76e1 | 183 | t.reset(); |
| pathfindr | 22:810425eb76e1 | 184 | uint32_t startmillis = t.read_ms(); |
| pathfindr | 22:810425eb76e1 | 185 | uint32_t runtime = 0; |
| pathfindr | 22:810425eb76e1 | 186 | while(!GLOBAL_registeredOnNetwork && runtime < timeout) { |
| pathfindr | 22:810425eb76e1 | 187 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 22:810425eb76e1 | 188 | Thread::wait(1000); |
| pathfindr | 22:810425eb76e1 | 189 | ATsendCMD("AT+CREG?"); |
| pathfindr | 22:810425eb76e1 | 190 | if (ATwaitForWord("+CREG: 0,5",3000)) { |
| pathfindr | 34:4493c9f6d707 | 191 | NRFuart_flush(); |
| pathfindr | 22:810425eb76e1 | 192 | GLOBAL_registeredOnNetwork = true; |
| pathfindr | 22:810425eb76e1 | 193 | }; |
| pathfindr | 22:810425eb76e1 | 194 | } |
| pathfindr | 22:810425eb76e1 | 195 | if (!GLOBAL_registeredOnNetwork) { |
| pathfindr | 22:810425eb76e1 | 196 | off(true); |
| pathfindr | 33:760005331b4c | 197 | Thread::wait(1000); |
| pathfindr | 38:476a9b5629a1 | 198 | on(RET_force2G); |
| pathfindr | 22:810425eb76e1 | 199 | } |
| pathfindr | 26:fa3579737329 | 200 | attempt ++; |
| pathfindr | 12:8345612bf867 | 201 | } |
| pathfindr | 22:810425eb76e1 | 202 | t.stop(); |
| pathfindr | 12:8345612bf867 | 203 | } |
| pathfindr | 34:4493c9f6d707 | 204 | NRFuart_flush(); |
| pathfindr | 13:29f67f256709 | 205 | if (GLOBAL_registeredOnNetwork) { |
| pathfindr | 12:8345612bf867 | 206 | return true; |
| pathfindr | 12:8345612bf867 | 207 | } else { |
| pathfindr | 12:8345612bf867 | 208 | return false; |
| pathfindr | 12:8345612bf867 | 209 | } |
| pathfindr | 12:8345612bf867 | 210 | } |
| pathfindr | 12:8345612bf867 | 211 | |
| pathfindr | 12:8345612bf867 | 212 | bool Modem::USSDsend(char* message, int maxAttempts) |
| pathfindr | 12:8345612bf867 | 213 | { |
| pathfindr | 12:8345612bf867 | 214 | bool sent = false; |
| pathfindr | 12:8345612bf867 | 215 | int attempt = 0; |
| pathfindr | 12:8345612bf867 | 216 | //TRY X NUMBER OF TIMES |
| pathfindr | 26:fa3579737329 | 217 | while (!sent && attempt < maxAttempts) { |
| pathfindr | 12:8345612bf867 | 218 | char bytestosend[160]; |
| pathfindr | 13:29f67f256709 | 219 | snprintf(bytestosend, sizeof(bytestosend), "AT+CUSD=1,\"#469*%s#\"", message); |
| pathfindr | 12:8345612bf867 | 220 | ATsendCMD(bytestosend); |
| pathfindr | 22:810425eb76e1 | 221 | if (ATwaitForWord("+CUSD: 0",ATTIMEOUT_MED)) { |
| pathfindr | 34:4493c9f6d707 | 222 | NRFuart_flush(); |
| pathfindr | 12:8345612bf867 | 223 | sent = true; |
| pathfindr | 12:8345612bf867 | 224 | }; |
| pathfindr | 26:fa3579737329 | 225 | attempt ++; |
| pathfindr | 12:8345612bf867 | 226 | } |
| pathfindr | 12:8345612bf867 | 227 | if (sent) { |
| pathfindr | 12:8345612bf867 | 228 | return true; |
| pathfindr | 12:8345612bf867 | 229 | } else { |
| pathfindr | 12:8345612bf867 | 230 | return false; |
| pathfindr | 12:8345612bf867 | 231 | } |
| pathfindr | 12:8345612bf867 | 232 | } |
| pathfindr | 12:8345612bf867 | 233 | |
| pathfindr | 14:9a54b1b65bc8 | 234 | char* Modem::USSDreceive(int messageIndex) |
| pathfindr | 12:8345612bf867 | 235 | { |
| pathfindr | 12:8345612bf867 | 236 | bool received = false; |
| pathfindr | 22:810425eb76e1 | 237 | uint32_t timeout = ATTIMEOUT_MED; |
| pathfindr | 14:9a54b1b65bc8 | 238 | int USSDmessageIndex = 0; |
| pathfindr | 14:9a54b1b65bc8 | 239 | int matchCount = 0; |
| pathfindr | 12:8345612bf867 | 240 | Timer t; |
| pathfindr | 12:8345612bf867 | 241 | t.start(); |
| pathfindr | 12:8345612bf867 | 242 | //TRY UNTIL TIMEOUT |
| pathfindr | 12:8345612bf867 | 243 | uint32_t startmillis = t.read_ms(); |
| pathfindr | 12:8345612bf867 | 244 | uint32_t runtime = 0; |
| pathfindr | 12:8345612bf867 | 245 | while(!received && runtime < timeout) { |
| pathfindr | 13:29f67f256709 | 246 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 38:476a9b5629a1 | 247 | if (ATwaitForWord("+CUSD: 0",ATTIMEOUT_LONG)) { |
| pathfindr | 12:8345612bf867 | 248 | led1 = 0; |
| pathfindr | 34:4493c9f6d707 | 249 | if (ATgetResponse('\r',ATTIMEOUT_SHORT)) { |
| pathfindr | 34:4493c9f6d707 | 250 | if ( (matchCount = sscanf(ATinBuffer,",\"%d#%[^#]",USSDmessageIndex,ATinBuffer) ) > 0 ) { |
| pathfindr | 34:4493c9f6d707 | 251 | if (USSDmessageIndex == messageIndex) { |
| pathfindr | 34:4493c9f6d707 | 252 | //NEED TO GET THIS WORKING SO WE KNOW WE ARE DEALING WITH THE RIGHT MESSAGE |
| pathfindr | 34:4493c9f6d707 | 253 | //MOVE THE BELOW INTO THIS IF STAEMEBNTS |
| pathfindr | 34:4493c9f6d707 | 254 | } |
| pathfindr | 34:4493c9f6d707 | 255 | led1 = 1; |
| pathfindr | 34:4493c9f6d707 | 256 | received = true; |
| pathfindr | 12:8345612bf867 | 257 | } |
| pathfindr | 12:8345612bf867 | 258 | } |
| pathfindr | 12:8345612bf867 | 259 | } |
| pathfindr | 12:8345612bf867 | 260 | } |
| pathfindr | 34:4493c9f6d707 | 261 | NRFuart_flush(); |
| pathfindr | 12:8345612bf867 | 262 | if (received) { |
| pathfindr | 12:8345612bf867 | 263 | return ATinBuffer; |
| pathfindr | 12:8345612bf867 | 264 | } else { |
| pathfindr | 34:4493c9f6d707 | 265 | return "err"; |
| pathfindr | 12:8345612bf867 | 266 | } |
| pathfindr | 12:8345612bf867 | 267 | } |
| pathfindr | 12:8345612bf867 | 268 | |
| pathfindr | 12:8345612bf867 | 269 | |
| pathfindr | 15:7aad9a7f970c | 270 | char* Modem::USSDmessage(char* message, bool needResponse, int maxAttempts, char* api) |
| pathfindr | 16:3bf5f1a5f869 | 271 | { |
| pathfindr | 15:7aad9a7f970c | 272 | uint8_t messageIndex = 1; |
| pathfindr | 16:3bf5f1a5f869 | 273 | bool result; |
| pathfindr | 13:29f67f256709 | 274 | int messageLength = strlen(message); |
| pathfindr | 13:29f67f256709 | 275 | if (messageLength > USSD_MAXLENGTH) { |
| pathfindr | 17:ba55c026b1d6 | 276 | char message_failsafe[100]; |
| pathfindr | 32:dff4858bdf37 | 277 | snprintf(message_failsafe,sizeof(message_failsafe),"(%s,z:TOOBIG,s:1,c:%d)\0",api,messageIndex); |
| pathfindr | 16:3bf5f1a5f869 | 278 | result = USSDsend(message_failsafe, maxAttempts); |
| pathfindr | 15:7aad9a7f970c | 279 | } else { |
| pathfindr | 16:3bf5f1a5f869 | 280 | result = USSDsend(message, maxAttempts); |
| pathfindr | 13:29f67f256709 | 281 | } |
| pathfindr | 16:3bf5f1a5f869 | 282 | if (result) { |
| pathfindr | 14:9a54b1b65bc8 | 283 | if (needResponse) { |
| pathfindr | 14:9a54b1b65bc8 | 284 | char* response = USSDreceive(messageIndex); |
| pathfindr | 34:4493c9f6d707 | 285 | if (strcmp(response, "err") != 0) { |
| pathfindr | 14:9a54b1b65bc8 | 286 | return response; |
| pathfindr | 14:9a54b1b65bc8 | 287 | } else { |
| pathfindr | 15:7aad9a7f970c | 288 | return "sendonly"; |
| pathfindr | 14:9a54b1b65bc8 | 289 | } |
| pathfindr | 14:9a54b1b65bc8 | 290 | } else { |
| pathfindr | 14:9a54b1b65bc8 | 291 | return "ok"; |
| pathfindr | 14:9a54b1b65bc8 | 292 | } |
| pathfindr | 13:29f67f256709 | 293 | } else { |
| pathfindr | 14:9a54b1b65bc8 | 294 | return "err"; |
| pathfindr | 13:29f67f256709 | 295 | } |
| pathfindr | 13:29f67f256709 | 296 | } |
| pathfindr | 13:29f67f256709 | 297 | |
| pathfindr | 20:5404841fdd2b | 298 | |
| pathfindr | 22:810425eb76e1 | 299 | char* Modem::getLocation(uint8_t accuracy, uint16_t timeout_seconds) |
| pathfindr | 20:5404841fdd2b | 300 | { |
| pathfindr | 34:4493c9f6d707 | 301 | NRFuart_flush(); |
| pathfindr | 20:5404841fdd2b | 302 | bool haveGPSFix = false; |
| pathfindr | 23:a3b0ccf75ca5 | 303 | bool haveCellFix = false; |
| pathfindr | 34:4493c9f6d707 | 304 | static char locDataOut[100]; |
| pathfindr | 36:8e359069192b | 305 | memset(locDataOut,0x00,sizeof(locDataOut)); |
| pathfindr | 30:7e90ddd7ed12 | 306 | Timer t; |
| pathfindr | 30:7e90ddd7ed12 | 307 | t.start(); |
| pathfindr | 30:7e90ddd7ed12 | 308 | uint32_t startmillis; |
| pathfindr | 30:7e90ddd7ed12 | 309 | uint32_t runtime; |
| pathfindr | 30:7e90ddd7ed12 | 310 | |
| pathfindr | 22:810425eb76e1 | 311 | if (accuracy >= 2) { |
| pathfindr | 20:5404841fdd2b | 312 | //Enable External LNA power - IS DISABLED BY DEFAULT |
| pathfindr | 20:5404841fdd2b | 313 | ATsendCMD("AT+QGPSCFG=\"lnacontrol\",1"); |
| pathfindr | 20:5404841fdd2b | 314 | ATwaitForWord("OK",5000); |
| pathfindr | 20:5404841fdd2b | 315 | |
| pathfindr | 22:810425eb76e1 | 316 | //TURN ON GPS |
| pathfindr | 22:810425eb76e1 | 317 | ATsendCMD("AT+QGPS=1"); |
| pathfindr | 22:810425eb76e1 | 318 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 22:810425eb76e1 | 319 | |
| pathfindr | 20:5404841fdd2b | 320 | //TRY UNTIL TIMEOUT |
| pathfindr | 20:5404841fdd2b | 321 | uint8_t GPS_fixstage = 0; |
| pathfindr | 20:5404841fdd2b | 322 | uint8_t GPS_fixcount = 0; |
| pathfindr | 30:7e90ddd7ed12 | 323 | startmillis = t.read_ms(); |
| pathfindr | 30:7e90ddd7ed12 | 324 | runtime = 0; |
| pathfindr | 20:5404841fdd2b | 325 | while(!haveGPSFix && runtime < (timeout_seconds*1000)) { |
| pathfindr | 22:810425eb76e1 | 326 | watchdogKick(); |
| pathfindr | 21:e0b866630c27 | 327 | Thread::wait(5000); //this goes first |
| pathfindr | 20:5404841fdd2b | 328 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 20:5404841fdd2b | 329 | ATsendCMD("AT+QGPSLOC=2"); |
| pathfindr | 22:810425eb76e1 | 330 | if (ATwaitForWord("+QGPSLOC: ",ATTIMEOUT_SHORT)) { |
| pathfindr | 20:5404841fdd2b | 331 | GPS_fixstage = 1; |
| pathfindr | 20:5404841fdd2b | 332 | GPS_fixcount ++; |
| pathfindr | 21:e0b866630c27 | 333 | if (GPS_fixcount == 2) { //wait 10 seconds to get a better fix // need to improve this logic |
| pathfindr | 20:5404841fdd2b | 334 | haveGPSFix = true; |
| pathfindr | 22:810425eb76e1 | 335 | } else { |
| pathfindr | 34:4493c9f6d707 | 336 | NRFuart_flush(); |
| pathfindr | 22:810425eb76e1 | 337 | } |
| pathfindr | 22:810425eb76e1 | 338 | } else { |
| pathfindr | 34:4493c9f6d707 | 339 | NRFuart_flush(); |
| pathfindr | 22:810425eb76e1 | 340 | } |
| pathfindr | 22:810425eb76e1 | 341 | if (haveGPSFix) { |
| pathfindr | 22:810425eb76e1 | 342 | //+QGPSLOC: 233510.0,52.55415,1.24021,1.2,59.2,2,0.00,0.0,0.0,201218,05 |
| pathfindr | 22:810425eb76e1 | 343 | int matchCount = 0; |
| pathfindr | 22:810425eb76e1 | 344 | float utc; |
| pathfindr | 22:810425eb76e1 | 345 | float lat; |
| pathfindr | 22:810425eb76e1 | 346 | float lng; |
| pathfindr | 22:810425eb76e1 | 347 | float hdp; |
| pathfindr | 22:810425eb76e1 | 348 | float alt; |
| pathfindr | 22:810425eb76e1 | 349 | uint8_t fix; |
| pathfindr | 22:810425eb76e1 | 350 | float cog; |
| pathfindr | 22:810425eb76e1 | 351 | float spkm; |
| pathfindr | 22:810425eb76e1 | 352 | float spkn; |
| pathfindr | 22:810425eb76e1 | 353 | uint32_t date; |
| pathfindr | 22:810425eb76e1 | 354 | uint8_t sat; |
| pathfindr | 22:810425eb76e1 | 355 | |
| pathfindr | 23:a3b0ccf75ca5 | 356 | //Example data |
| pathfindr | 23:a3b0ccf75ca5 | 357 | //115757.0,52.62091,1.29536,0.8,58.2,2,0.00,0.0,0.0,211218,07 |
| pathfindr | 34:4493c9f6d707 | 358 | if (ATgetResponse('\r',ATTIMEOUT_SHORT)) { |
| pathfindr | 34:4493c9f6d707 | 359 | if ((matchCount = sscanf(ATinBuffer,"%f,%f,%f,%f,%f,%d,%f,%f,%f,%d,%d",&utc,&lat,&lng,&hdp,&alt,&fix,&cog,&spkm,&spkn,&date,&sat)) == 11 ) { |
| pathfindr | 34:4493c9f6d707 | 360 | //{“fix”:“GPS”,“sat”:“9",“lat”:“52.913254",“lng”:“-1.455289",“hdp”:“89.0",“spd”:“0.0"} |
| pathfindr | 34:4493c9f6d707 | 361 | sprintf(locDataOut,",g:(fix:GPS,sat:%d,lat:%.6f,lng:%.6f,hdp:%.1f,spd:%.1f)\0",sat,lat,lng,hdp,spkm); |
| pathfindr | 34:4493c9f6d707 | 362 | //DEBUG("\nGPSOut:%s\n",locDataOut); |
| pathfindr | 34:4493c9f6d707 | 363 | } |
| pathfindr | 20:5404841fdd2b | 364 | } |
| pathfindr | 20:5404841fdd2b | 365 | } |
| pathfindr | 20:5404841fdd2b | 366 | } |
| pathfindr | 20:5404841fdd2b | 367 | //TURN OFF GPS |
| pathfindr | 20:5404841fdd2b | 368 | ATsendCMD("AT+QGPSEND"); |
| pathfindr | 22:810425eb76e1 | 369 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 20:5404841fdd2b | 370 | } |
| pathfindr | 22:810425eb76e1 | 371 | |
| pathfindr | 22:810425eb76e1 | 372 | //SHALL WE GET CELL LOCATION |
| pathfindr | 22:810425eb76e1 | 373 | if (!haveGPSFix && accuracy >= 1) { |
| pathfindr | 30:7e90ddd7ed12 | 374 | |
| pathfindr | 23:a3b0ccf75ca5 | 375 | _w_disable = 1; //turn off airplane mode |
| pathfindr | 23:a3b0ccf75ca5 | 376 | registerOnNetwork(2, 90000); |
| pathfindr | 22:810425eb76e1 | 377 | |
| pathfindr | 23:a3b0ccf75ca5 | 378 | int matchCount; |
| pathfindr | 23:a3b0ccf75ca5 | 379 | char type[6]; |
| pathfindr | 23:a3b0ccf75ca5 | 380 | char cellID[6]; |
| pathfindr | 23:a3b0ccf75ca5 | 381 | char lac[6]; |
| pathfindr | 23:a3b0ccf75ca5 | 382 | int mcc; |
| pathfindr | 23:a3b0ccf75ca5 | 383 | int mnc; |
| pathfindr | 23:a3b0ccf75ca5 | 384 | |
| pathfindr | 30:7e90ddd7ed12 | 385 | startmillis = t.read_ms(); |
| pathfindr | 30:7e90ddd7ed12 | 386 | runtime = 0; |
| pathfindr | 30:7e90ddd7ed12 | 387 | while(!haveCellFix && runtime < 15000) { |
| pathfindr | 30:7e90ddd7ed12 | 388 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 30:7e90ddd7ed12 | 389 | ATsendCMD("AT+QENG=\"servingcell\""); |
| pathfindr | 30:7e90ddd7ed12 | 390 | if (ATwaitForWord("+QENG: \"servingcell\",\"NOCONN\",",ATTIMEOUT_SHORT)) { |
| pathfindr | 34:4493c9f6d707 | 391 | if (ATgetResponse('\r',ATTIMEOUT_SHORT)) { |
| pathfindr | 34:4493c9f6d707 | 392 | if ((matchCount = sscanf(ATinBuffer,"\"%[^\"]\",%d,%d,%[^,],%[^,]",&type,&mcc,&mnc,&lac,&cellID)) == 5 ) { |
| pathfindr | 34:4493c9f6d707 | 393 | sprintf(locDataOut,",h:%s.%s.%d.%d\0",cellID,lac,mcc,mnc); |
| pathfindr | 34:4493c9f6d707 | 394 | //sprintf(locDataOut,",h:41806.2252.234.30\0"); |
| pathfindr | 34:4493c9f6d707 | 395 | haveCellFix = true; |
| pathfindr | 34:4493c9f6d707 | 396 | } |
| pathfindr | 30:7e90ddd7ed12 | 397 | } |
| pathfindr | 30:7e90ddd7ed12 | 398 | } |
| pathfindr | 23:a3b0ccf75ca5 | 399 | } |
| pathfindr | 23:a3b0ccf75ca5 | 400 | |
| pathfindr | 23:a3b0ccf75ca5 | 401 | //example from mulbs |
| pathfindr | 22:810425eb76e1 | 402 | /* |
| pathfindr | 32:dff4858bdf37 | 403 | 2g |
| pathfindr | 22:810425eb76e1 | 404 | +QENG: "servingcell","NOCONN","2G",234,30,8CC,A34E,20,668,0,-80,0,5,4,26,26,1,-,-,-,-,-,-,-,-,-,"-" |
| pathfindr | 32:dff4858bdf37 | 405 | 3g |
| pathfindr | 32:dff4858bdf37 | 406 | +QENG: "servingcell","NOCONN","3G",234,20,8A,CE735F,10588,52,-97,-99,11,25,16,128,-,-,-,-,-,"-",- |
| pathfindr | 32:dff4858bdf37 | 407 | |
| pathfindr | 22:810425eb76e1 | 408 | +QENG: "neighbourcell","2G",234,30,8CC,A34D,20,656,-89,17,17,0,0 |
| pathfindr | 22:810425eb76e1 | 409 | +QENG: "neighbourcell","2G",234,30,8CC,678,61,686,-104,2,2,0,0 |
| pathfindr | 22:810425eb76e1 | 410 | +QENG: "neighbourcell","2G",234,30,8CC,4303,32,676,-104,2,2,0,0 |
| pathfindr | 22:810425eb76e1 | 411 | +QENG: "neighbourcell","2G",234,30,8CC,B2B2,16,692,-107,-1,-1,0,0 |
| pathfindr | 22:810425eb76e1 | 412 | https://www.neilson.co.za/mobile-network-geolocation-obtaining-the-cell-ids-the-signal-strength-of-surrounding-towers-from-a-gsm-modem/ |
| pathfindr | 22:810425eb76e1 | 413 | */ |
| pathfindr | 22:810425eb76e1 | 414 | |
| pathfindr | 23:a3b0ccf75ca5 | 415 | //ATsendCMD("AT+QENG=\"neighbourcell\""); |
| pathfindr | 23:a3b0ccf75ca5 | 416 | //ATwaitForWord("OK",ATTIMEOUT_LONG); |
| pathfindr | 20:5404841fdd2b | 417 | } |
| pathfindr | 22:810425eb76e1 | 418 | |
| pathfindr | 22:810425eb76e1 | 419 | //RETURN |
| pathfindr | 31:c84fc6d8eaa3 | 420 | if (accuracy == 0) { |
| pathfindr | 31:c84fc6d8eaa3 | 421 | sprintf(locDataOut,"\0"); |
| pathfindr | 31:c84fc6d8eaa3 | 422 | } else if (!haveGPSFix && !haveCellFix) { |
| pathfindr | 32:dff4858bdf37 | 423 | sprintf(locDataOut,"\0"); |
| pathfindr | 31:c84fc6d8eaa3 | 424 | } |
| pathfindr | 23:a3b0ccf75ca5 | 425 | return locDataOut; |
| pathfindr | 20:5404841fdd2b | 426 | } |
| pathfindr | 20:5404841fdd2b | 427 | |
| pathfindr | 7:e9a19750700d | 428 | Modem::~Modem(){}; |