// SPDX-License-Identifier: Apache-2.0 // Copyright (c) 2012-2024 Scott Penrose and WII5 Buoy contributors // // This file is part of WII5 Buoy firmware. // See LICENSE for full terms. /** * @file WII5Iridium.cpp * @brief Iridium 9602/9603 SBD modem driver: AT-command state machine. */ /* WII5Iridium: TODO 2024 - Seems fairly stable, check TODO and review code TOOO Status Examoe=oles, abny reference= etc. Foundby=xm ... Daee How to structure a message: * Adding up size of Structs - if < 340 (Iridium Size) WII5_IRIDIUM_BIN_MAX Then just build it up into that binary entry * If larger.... NFI * Receive - assume one - and goes into bin buffer then processed * Where is it proessed Code Source: * WII2_Board/WII2_WaveSim/WII2_WaveSim.ino * NA * WII2_Board/WII2_WaveBuoy/WII2_WaveBuoy.ino * IridiumSBD Library #include IridiumSBD isbd(SerialIridium); // , onPin); * WII2_Board/Iridium/ * NA * States/Iridium_Library * NA * Tracker/IridumData/IridiumData.ino * IridiumSBD Library * WII2_Board/Iridium * NA = What do we want to do = == Automatic processing == * loop() * Processes any mode it is in, including off * == Manual Helpers == * bool off() * Returns true if able to switch off and turns to off mode. * Returns false, if busy and unable to change mode * bool status() * Start status if you can. Will change to off when complete, see lastStatus * Read lastStatus * bool sendSimple(Messaage) * Send a simple message, text or binary * Returns true to say it is prepared * bool sendStart(); - Setup to send messages - only if not already there * uint8_t sendStatus(); - Return status so you can send a message * bool sendMessage(Message); - Return true if buffered and trying, false if not sendStart, or sendStatus is busy * bool sendEnd(); - End send - return true if we can. Will turn off automatically. == Examples == * setup() * loop() iridum.loop(); Want to get the updated status // If older than 5 minutes if (lastStatusMillis > 300000) .status() */ #include #include #include #include #ifdef WII5_COMMS_IRIDIUM void WII5Iridium::begin() { SerialComms.begin(SerialComms_Baud); #ifdef WII5_BUFFER_IRIDIUM setBuffer(wii5BufferIridium, WII5_BUFFER_IRIDIUM); #else console.log(LOG_ERROR, F("Iridium: Error, not setting buffer")); #endif powerSetPin(POWER_COMMS_PIN, POWER_COMMS_ON); powerOff(true); // Forced off at boot step = WII5IRIDIUM_OFF; running = false; initialized = false; imei[0] = '\0'; sigQualRetry = 0; sigQualMin = 2; } void WII5Iridium::start(bool force) { if (debug) console.log(LOG_DEBUG, F("IRIDIUM: start current=%d"), step); if (step == WII5IRIDIUM_OFF) { recordCount = 0; sendCount = 0; step = WII5IRIDIUM_POWER; stepWait = 0; } powerOn(); } void WII5Iridium::stop(bool force) { if (debug) console.log(LOG_DEBUG, F("IRIDIUM: stop current=%d"), step); if (step != WII5IRIDIUM_OFF) { // Delays - request off, that sort of thing... ! YES ! TODO step = WII5IRIDIUM_OFF; stepWait = 0; } powerOff(force); } bool WII5Iridium::isRunning() { return running; } // on void WII5Iridium::powerOn(bool force) { if (!running || force) { if (debug) console.log(LOG_DEBUG, F("IRIDIUM: power ON")); running = true; wii5Controller.shared5On(); WII5Power::powerOn(); SerialComms.begin(SerialComms_Baud); stream = &SerialComms; beginSerialManager(); } } // off void WII5Iridium::powerOff(bool force) { if (running || force) { if (debug) console.log(LOG_DEBUG, F("IRIDIUM: power off")); running = false; SerialComms.end(); stream = NULL; WII5Power::powerOff(); endSerialManager(); wii5Controller.shared5Off(); } } void WII5Iridium::loop() { WII5SerialManager::loop(); bool first = (step != stepLast); stepLast = step; switch (step) { // WII5Iridium_OFF - Completely off, powered down, disabled. case WII5IRIDIUM_OFF: if (first) { currentType = WII5IRIDIUM_REQUEST_NONE; initialized = false; wii5Display.atCommsSend(F("status"), F("off")); powerOff(); /* if (strlen(imei[0]) == 0) { // TODO No IMEI - Turn on Iridium to get // TODO Don't continue to do this. If done - stop, even if we dont' have one requestFirmware(); } */ } break; case WII5IRIDIUM_POWER: initialized = false; powerOn(); // Wait half a second then spin on if (stepWait > 1000) { step = WII5IRIDIUM_ALIVE; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step power->alive")); } break; case WII5IRIDIUM_ALIVE: initialized = false; sendLine(0); // This probably needs to be _AT (not yet written) processMode = WII5SERIALPARSER_OKHUH; // Boot up config last = WII5SERIALLAST_NONE; sendCount = 0; step = WII5IRIDIUM_BOOT; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step boot_stop->boot_wait")); break; // Boot up config case WII5IRIDIUM_BOOT: if (first) { programCount = 0; programTotal = 3; setTimeout(15000); } switch (sendAll()) { // Still waiting case WII5SERIALCMD_WAITING: break; // Error case WII5SERIALCMD_TIMEOUT: console.log(LOG_ERROR, F("SERIAL: TIMEOUT sending (sendAll:0-3): %s"), buffer); case WII5SERIALCMD_ERROR: console.log(LOG_ERROR, F("SERIAL: ERROR sending (sendAll:0-3): %s"), buffer); // TODO Do a retry count here, and possible power cycle // Success case WII5SERIALCMD_OK: default: // TODO - Consider starting again with OFF, then step back to READY etc etc step = WII5IRIDIUM_FIRMWARE; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step program_base->program_start")); break; } break; // Firmware case WII5IRIDIUM_FIRMWARE: if (first) { sendCount = 0; } else if (stepWait > 500) { // TODO This is because we have shared buffer. FFS // TODO also... this could blat half read in data ? if (sendCount == 0) { programLine(4); setTimeout(15000); } switch (sendAndWait(WII5SERIALLAST_BOOTVERSION)) { // Still waiting case WII5SERIALCMD_WAITING: break; // Move on case WII5SERIALCMD_TIMEOUT: console.log(LOG_ERROR, F("SERIAL: TIMEOUT sending (programLine:4): %s"), buffer); case WII5SERIALCMD_ERROR: console.log(LOG_ERROR, F("SERIAL: ERROR sending (programLine:4): %s"), buffer); case WII5SERIALCMD_OK: default: // TODO How to keep the return? step = WII5IRIDIUM_IMEI; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step firmware->signalquality")); break; }; } break; // IMEI case WII5IRIDIUM_IMEI: if (first) { sendCount = 0; } else if (stepWait > 500) { // TODO This is because we have shared buffer. FFS if (sendCount == 0) { programLine(5); setTimeout(15000); } switch (sendAndWait(WII5SERIALLAST_NUMBER)) { // Still waiting case WII5SERIALCMD_WAITING: break; // Move on case WII5SERIALCMD_TIMEOUT: console.log(LOG_ERROR, F("SERIAL: TIMEOUT sending (programLine:5): %s"), buffer); step = WII5IRIDIUM_SIGNALQUALITY; stepWait = 0; break; case WII5SERIALCMD_ERROR: console.log(LOG_ERROR, F("SERIAL: ERROR sending (programLine:5): %s"), buffer); step = WII5IRIDIUM_SIGNALQUALITY; stepWait = 0; break; case WII5SERIALCMD_OK: default: // TODO Woooh.... should be checking length etc. strcpy(imei, buffer); wii5Display.atCommsSend(F("info"), F("imei=%s"), imei); step = WII5IRIDIUM_SIGNALQUALITY; stepWait = 0; } } break; // SYSTEMTIME // case WII5IRIDIUM_SYSTEMTIME: case WII5IRIDIUM_SIGNALQUALITY_WAIT: if (first) { if (debug) console.log(LOG_ERROR, F("Irigin: Waiting n seconds before retry signal quality")); } // 15 second delay to retry Signal Quality // TODO for now 5 seconds, alo... should be able check this // TODO 2024 - Making this 20 seconds else if (stepWait > 20000) { if (debug) console.log(LOG_ERROR, F("Irigin: Waiting complete")); step = WII5IRIDIUM_SIGNALQUALITY; stepWait = 0; } break; // Signal Quality case WII5IRIDIUM_SIGNALQUALITY: if (first) { sendCount = 0; } else if (stepWait > 500) { // TODO This is because we have shared buffer. FFS if (sendCount == 0) { programLine(7); setTimeout(30000); } switch (sendAndWait(WII5SERIALLAST_ATCSQ)) { // Still waiting case WII5SERIALCMD_WAITING: break; // Move on case WII5SERIALCMD_TIMEOUT: console.log(LOG_ERROR, F("SERIAL: TIMEOUT sending (programLine:7): %s"), buffer); case WII5SERIALCMD_ERROR: console.log(LOG_ERROR, F("SERIAL: ERROR sending (programLine:7): %s"), buffer); case WII5SERIALCMD_OK: default: // TODO Keep this data lastCSQ if (lastVal < sigQualMin) { if (sigQualRetry < IRIDIUM_RETRY_MAX) { sigQualRetry++; wii5Display.atCommsSend(F("info"), F("signalquality=%d,retry=%d"), int(lastVal), int(sigQualRetry)); // Setting sendCount to zero, will trigger sending Line 7 again // (not necessary now using signal quality wait) sendCount = 0; step = WII5IRIDIUM_SIGNALQUALITY_WAIT; stepWait = 0; } else { wii5Display.atCommsSend(F("info"), F("signalquality=%d,retry max"), int(lastVal)); lastSince = 0; lastSignalQuality = int(lastVal); step = WII5IRIDIUM_SEND_JUMP; stepWait = 0; } } else { lastSince = 0; lastSignalQuality = lastVal; wii5Display.atCommsSend(F("info"), F("signalquality=%d"), int(lastSignalQuality)); step = WII5IRIDIUM_SEND_JUMP; stepWait = 0; } } } else if (stepWait > 120000) { lastSince = 0; lastSignalQuality = 0; wii5Display.atCommsSend(F("info"), F("signalquality=0,timeout")); step = WII5IRIDIUM_SEND_JUMP; stepWait = 0; } break; // Wait here for a retry. case WII5IRIDIUM_RETRY: if (first) { if (debug) console.log(LOG_ERROR, F("Irigin: Waiting n seconds before retry send")); } // 15 second delay to retry Signal Quality else if (stepWait > 20000) { step = WII5IRIDIUM_SEND_JUMP; stepWait = 0; } break; // Choose - send Text or Binary - always returns data case WII5IRIDIUM_SEND_JUMP: initialized = true; if (currentType == WII5IRIDIUM_REQUEST_SIGNALQUALITY) { // TODO - should be done step = WII5IRIDIUM_WAITING; stepWait = 0; } else if (currentType == WII5IRIDIUM_REQUEST_TIME) { // TODO - should be done step = WII5IRIDIUM_WAITING; stepWait = 0; } else if (currentType == WII5IRIDIUM_REQUEST_FIRMWARE) { // TODO - should be done step = WII5IRIDIUM_WAITING; stepWait = 0; } else if (currentType == WII5IRIDIUM_REQUEST_SENDTEXT) { step = WII5IRIDIUM_PREPARE_TEXT; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step send_jump->prepare_text")); } else if (currentType == WII5IRIDIUM_REQUEST_SENDBIN) { step = WII5IRIDIUM_PREPARE_BIN1; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step send_jump->prepare_bin1")); } else { step = WII5IRIDIUM_OFF; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step send_jump->off")); } break; // Send Text case WII5IRIDIUM_PREPARE_TEXT: if (first) { if (debug) console.log(LOG_DEBUG, F("Iridium: Setting PrepareText Sentence")); wii5Display.atCommsSend(F("send"), F("prepare=text,length=%d"), int(strlen(wii5BinaryIridium))); sendCount = 0; } else if (stepWait > 500) { // // AT+SBDWT=hello - Text send, maxium length = 120 bytes // if (sendCount == 0) { // strncpy_P(buffer ,(PGM_P) F("AT+SBDWT=My first nonBlocking Iridium attempt"), bufMax); // TODO will this be big enough sprintf_P(buffer, PSTR("AT+SBDWT=%s"), wii5BinaryIridium); setTimeout(15000); } switch (sendAndWait()) { // Still waiting case WII5SERIALCMD_WAITING: break; // Move on case WII5SERIALCMD_TIMEOUT: console.log(LOG_ERROR, F("SERIAL: TIMEOUT sending (AT+SBDWT=X): %s"), buffer); case WII5SERIALCMD_ERROR: console.log(LOG_ERROR, F("SERIAL: ERROR sending (AT+SBDWT=X): %s"), buffer); case WII5SERIALCMD_OK: default: if (debug) console.log(LOG_DEBUG, F("SERIAL: OK setting up (AT+SBDWT=X)")); step = WII5IRIDIUM_SEND; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step prepare_text->send_text")); break; }; } break; case WII5IRIDIUM_RECEIVE: if (first) { if (debug) console.log(LOG_DEBUG, F("Iridium: Receiving Data")); sendCount = 0; // Use the shared Binary buffer for incoming now memset(wii5BinaryIridium, 0, 340); binBuffer = wii5BinaryIridium; processMode = WII5SERIALPARSER_BINARY1; binBufferExpect = 0; // Important - must set to 0 // SEND THIS - AT+SBDRB strncpy_P(buffer ,(PGM_P) F("AT+SBDRB"), bufMax); stream->print(buffer); sendNewLine(); wii5Display.atCommsSend(F("receive"), F("start")); } else if (stepWait > 500) { if (processMode != WII5SERIALPARSER_BINARY1) { // OK So we have a message ! // Put it somewhere // Swith process Mode back and move on // - We can send here, no delay, then switch to command wait // - Command wait will be looking for reply in Command TODO // - or Timeout // - At which point it will send a reply, and receive next command // - On receiveing command can be go three ways. // . Didn't understand the command - ignore / log locally // . Understood - got a reply, and send a replly // . Undertsood but timeout... send reply timeout lastReceive = WII5IRIDIUMRECEIVERESULT_OK; lastReceiveLen = binBufferExpect; lastReceiveBuff = wii5BinaryIridium[0]; // First 2 are length; wii5BinaryIridium[lastReceiveLen] = '\0'; // TODO Should we strip last 2 to zero? // TODO - What if the queue says there is more to receive. Maybe just wait // since we are alwqys sending lots, and receiving little ? processMode = WII5SERIALPARSER_OKHUH; wii5Display.atCommsSend(F("receive"), F("complete,size=%d"), lastReceiveLen); step = WII5IRIDIUM_WAITING; stepWait = 0; } } else if (stepWait > 5000) { wii5Display.atCommsSend(F("receive"), F("timeout")); // TODO Timeout... Force back clear etc (how to clear buffers etc // TODO Show errors processMode = WII5SERIALPARSER_OKHUH; step = WII5IRIDIUM_WAITING; stepWait = 0; } break; case WII5IRIDIUM_SEND: if (first) { if (debug) console.log(LOG_DEBUG, F("Iridium: Setting SendToSat Sentence")); sendCount = 0; } else if (stepWait > 500) { if (sendCount == 0) { strncpy_P(buffer ,(PGM_P) F("AT+SBDI"), bufMax); setTimeout(45000); } switch (sendAndWait(WII5SERIALLAST_ATSBDI)) { // Still waiting case WII5SERIALCMD_WAITING: break; // Move on case WII5SERIALCMD_TIMEOUT: console.log(LOG_ERROR, F("SERIAL: TIMEOUT sending (AT+SBDI): %s"), buffer); case WII5SERIALCMD_ERROR: console.log(LOG_ERROR, F("SERIAL: ERROR sending (AT+SBDI): %s"), buffer); wii5Display.atCommsSend(F("send"), F("failed,during +SBDI")); lastSend = WII5IRIDIUMSENDRESULT_FAILED_OTHER; step = WII5IRIDIUM_WAITING; stepWait = 0; currentType = WII5IRIDIUM_REQUEST_NONE; break; case WII5SERIALCMD_OK: default: // TODO CHeck for return value of +SBDI or +SBDIX incase we need to retry wii5Display.atCommsSend(F("send"), F("success,mo_status=%lu,mo_MSN=%lu,mt_status=%lu,mt_MSN=%lu,mt_len=%lu,mt_queued=%lu"), recordVals[0], recordVals[1], recordVals[2], recordVals[3], recordVals[4], recordVals[5] ); lastMOMSN = recordVals[1]; lastSince = 0; switch(recordVals[0]) { // Success fully sent or nothing to send case 0: case 1: // LOG SUCCESS !!! console.log(LOG_INFO, F("Iridium: SEND: Success")); lastSend = WII5IRIDIUMSENDRESULT_OK; currentType = WII5IRIDIUM_REQUEST_NONE; // Do we have a waiting message, download it off the Iridium // 2 = Number of messages, 4 = Length of this one if ( (recordVals[2] > 0) && (recordVals[4] > 0) ) { wii5Display.atCommsSend(F("receive"), F("mt_len=%lu"), recordVals[4] ); step = WII5IRIDIUM_RECEIVE; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step send_text->receive`")); } // No waiting messages. else { step = WII5IRIDIUM_WAITING; stepWait = 0; // TODO Include Iridium message ID etc etc wii5Display.atCommsSend(F("send"), F("complete")); // TODO Capture etc if (debug) console.log(LOG_DEBUG, F("step send_text->waiting`")); } break; // Other error case 2: default: // Retry retry++; if (retry < IRIDIUM_RETRY_MAX) { // LOG RETRY !!! wii5Display.atCommsSend(F("send"), F("failed,retry=%d"), int(retry)); step = WII5IRIDIUM_RETRY; stepWait = 0; } else { // LOG FAILED !!! wii5Display.atCommsSend(F("send"), F("failed,exit")); lastSend = WII5IRIDIUMSENDRESULT_FAILED_OTHER; step = WII5IRIDIUM_WAITING; stepWait = 0; currentType = WII5IRIDIUM_REQUEST_NONE; } break; }; // TODO - check for receive stuff break; }; } break; // Send Binary case WII5IRIDIUM_PREPARE_BIN1: // // +SBDWB= // // {binary SBD message} + {2-byte checksum} // // The checksum is the least signi cant 2-bytes of the summation of the entire SBD message. The high order byte will be sent rst. For example if the 9602 were to send the word “hello” encoded in ASCII to the DTE the binary stream would be hex 00 05 68 65 6c 6c 6f 02 14. // // Response: // 0 SBD message successfully written to the 9602. // 1 SBD message write timeout. An insu cient number of bytes were transferred to 9602 during the transfer period of 60 seconds. // 2 SBD message checksum sent from DTE does not match the checksum calculated by the 9602. // 3 SBD message size is not correct. The maximum mobile originated SBD message length is 340 bytes. The minimum mobile originated SBD message length is 1 byte. // if (first) { if (debug) console.log(LOG_DEBUG, F("Iridium: Setting PrepareBin Sentence")); wii5Display.atCommsSend(F("send"), F("prepare=binary,length=%d"), int(binSize)); sendCount = 0; } else if (stepWait > 500) { // // AT+SBDWB=bytes // if (sendCount == 0) { sprintf_P(buffer, PSTR("AT+SBDWB=%d"), int(binSize)); setTimeout(15000); } switch (sendAndWait(WII5SERIALLAST_READY)) { case WII5SERIALCMD_WAITING: break; case WII5SERIALCMD_TIMEOUT: console.log(LOG_ERROR, F("SERIAL: TIMEOUT sending (AT+SBDWB=X): %s"), buffer); case WII5SERIALCMD_ERROR: console.log(LOG_ERROR, F("SERIAL: ERROR sending (AT+SBDWB=X): %s"), buffer); case WII5SERIALCMD_OK: default: if (debug) console.log(LOG_INFO, F("SERIAL: OK setting up (AT+SBDWB=X)")); step = WII5IRIDIUM_PREPARE_BIN2; stepWait = 0; if (debug) console.log(LOG_DEBUG, F("step prepare_text->prepare_bin2")); break; }; } break; case WII5IRIDIUM_PREPARE_BIN2: if (first) { // Logging? } else if (stepWait > 500) { checksum = 0; if (passthrough) console.printBinary(wii5BinaryIridium, binSize); for (loopcount = 0; loopcount < binSize; loopcount++) { stream->write(wii5BinaryIridium[loopcount]); checksum += (uint8_t)wii5BinaryIridium[loopcount]; } stream->write(checksum >> 8); stream->write(checksum & 0xFF); // TODO how to find Status // 0 success // 1 TIMEOUT // 2 checksum errors // 3 size errors step = WII5IRIDIUM_SEND; stepWait = 0; } break; // Complete case WII5IRIDIUM_STOP_PREPARE: break; case WII5IRIDIUM_END: break; // Wait here... just in case Maths wants to do some more. Give them 1 min case WII5IRIDIUM_WAITING: // TODO Configure time etc (should we send reminder?) if (first) { wii5Display.atCommsSend(F("status"), F("waiting")); } if (stepWait > 60000) { step = WII5IRIDIUM_OFF; stepWait = 0; currentType = WII5IRIDIUM_REQUEST_NONE; if (debug) console.log(LOG_DEBUG, F("step waiting->off`")); } break; default: console.log(LOG_FATAL, F("IRIDIUM: Default step... step=%d"), step); step = WII5IRIDIUM_OFF; break; } return; } // Manually set the binary data - note, we have no buffer, so must have external for hhis void WII5Iridium::setBinary(uint8_t *buf, uint16_t size) { // Memcopy data size or max iridium size binSize = size <= WII5_IRIDIUM_BIN_MAX ? size : WII5_IRIDIUM_BIN_MAX; memcpy(wii5BinaryIridium, buf, binSize); } void WII5Iridium::setBinSize(uint16_t size) { binSize = size <= WII5_IRIDIUM_BIN_MAX ? size : WII5_IRIDIUM_BIN_MAX; } void WII5Iridium::setText(char *str) { strncpy(wii5BinaryIridium, *(char *)str, WII5_IRIDIUM_BIN_MAX); // WII5_STORAGE_FILENAME_LEN); } // Allow fprintf params like console etc. void WII5Iridium::setText(const __FlashStringHelper *str) { strncpy_P(wii5BinaryIridium, (const char *)str, WII5_IRIDIUM_BIN_MAX); } // Get current WII5IRIDIUM_REQUEST WII5Iridium::currentRequest() { return currentType; } bool WII5Iridium::requestSendText() { // If no text, faile - return false, currentType = WII5IRIDIUM_REQUEST_SENDTEXT; recordCount = 0; sendCount = 0; stepWait = 0; lastSend = WII5IRIDIUMSENDRESULT_NONE; lastReceive = WII5IRIDIUMRECEIVERESULT_NONE; retry = 0; sigQualRetry = 0; if (initialized) step = WII5IRIDIUM_SEND_JUMP; else step = WII5IRIDIUM_POWER; return true; } bool WII5Iridium::requestSendBinary() { // If we have binary data.... else return false currentType = WII5IRIDIUM_REQUEST_SENDBIN; lastSend = WII5IRIDIUMSENDRESULT_NONE; lastReceive = WII5IRIDIUMRECEIVERESULT_NONE; recordCount = 0; sendCount = 0; stepWait = 0; retry = 0; sigQualRetry = 0; if (initialized) step = WII5IRIDIUM_SEND_JUMP; else step = WII5IRIDIUM_POWER; return true; } bool WII5Iridium::requestFirmware() { currentType = WII5IRIDIUM_REQUEST_FIRMWARE; lastSend = WII5IRIDIUMSENDRESULT_NONE; lastReceive = WII5IRIDIUMRECEIVERESULT_NONE; recordCount = 0; sendCount = 0; stepWait = 0; step = WII5IRIDIUM_POWER; retry = 0; sigQualRetry = 0; } // Waiting - Feel free to check the last status and send another bool WII5Iridium::waiting() { return ((step == WII5IRIDIUM_OFF) || (step == WII5IRIDIUM_WAITING)); } /* void WII5Iridium::clearLast() { } */ void WII5Iridium::programLine(uint16_t l) { // Main Programming switch (l) { // BOOT=0..3, case 0: strncpy_P(buffer ,(PGM_P) F("ATE0"), bufMax); break; case 1: strncpy_P(buffer ,(PGM_P) F("AT&D0"), bufMax); break; case 2: strncpy_P(buffer ,(PGM_P) F("AT&K0"), bufMax); break; case 3: strncpy_P(buffer ,(PGM_P) F("AT+SBDMTA=0"), bufMax); break; // Firmware case 4: strncpy_P(buffer ,(PGM_P) F("AT+CGMR"), bufMax); break; // IMEI case 5: strncpy_P(buffer ,(PGM_P) F("AT+CGSN"), bufMax); break; // System Time case 6: strncpy_P(buffer ,(PGM_P) F("AT-MSSTM"), bufMax); break; // Signal Quality case 7: strncpy_P(buffer ,(PGM_P) F("AT+CSQ"), bufMax); break; case 8: strncpy_P(buffer ,(PGM_P) F("AT"), bufMax); break; // send Text // send Binary // HOW TO: Retries // HOW TO: Work around firmware issues default: console.log(LOG_FATAL, F("IRIDIUM: request invalid programming string")); buffer[0] = '\0'; break; } if (debug) console.log(LOG_DEBUG, F("IRIDIUM: set command=%d buffer=%s"), l, buffer); } void WII5Iridium::sendNewLine() { stream->print(F("\r")); } WII5Iridium wii5Iridium; #endif