// Waits for the given string. Returns true if the string is received before a timeout. // Returns false if a timeout occurs or if another string is received. bool Sodaq_RN2483::expectString(const char* str, uint16_t timeout) { debugPrint("[expectString] expecting "); debugPrint(str); unsigned long end = millis() + timeout; while (millis() < end) { debugPrint("."); uint16_t len = readLn(); if (len > 0) { debugPrint("("); debugWrite((uint8_t*)this->inputBuffer, len); debugPrint(")"); if (strstr(this->inputBuffer, str) != NULL) { debugPrintLn(" found a match!"); return true; } //return false; } } return false; }
/** * @brief Gets the preprogrammed EUI node address from the module in HEX. * @param Buffer to read into. * @param Buffer size. * @return Returns the number of bytes written or 0 in case of error.. */ uint8_t RN2483::getHWEUI(uint8_t* buffer, uint8_t size) { _RN2483.printf(STR_CMD_GET_HWEUI); _RN2483.printf(CRLF); // TODO move to general "read hex" method uint8_t inputIndex = 0; uint8_t outputIndex = 0; Timer t; t.start(); int start = t.read_ms (); while (t.read_ms () < start + DEFAULT_TIMEOUT) { if (readLn() > 0) { while (outputIndex < size && inputIndex + 1 < this->inputBufferSize && this->inputBuffer[inputIndex] != 0 && this->inputBuffer[inputIndex + 1] != 0) { buffer[outputIndex] = HEX_PAIR_TO_BYTE( this->inputBuffer[inputIndex], this->inputBuffer[inputIndex + 1]); inputIndex += 2; outputIndex++; } t.stop(); return outputIndex; } } t.stop(); return 0; }
// waits for string, if str is found returns ok, if other string is found returns false, if timeout returns false bool ATTDevice::expectString(const char* str, unsigned short timeout, bool report) { unsigned long start = millis(); bool pointsDrawn = false; while (timeout == 0 || millis() < start + timeout) //if timeout = 0, we wait indefinetly { if (readLn() > 0) { if (strstr(this->inputBuffer, str) != NULL) //the serial modem can return debug statements or the expected string, allow for both. return true; else if (strstr(this->inputBuffer, STR_RESULT_NOK) != NULL) //the serial modem can return debug statements or the expected string, allow for both. return false; if(report){ if(pointsDrawn){ //for some pretty printing: if ... were drawn, start a new line for logging pointsDrawn = false; Serial.println(""); } Serial.println(this->inputBuffer); //only show on screen if it's not an 'ok' response. } } #ifdef DEBUG else{ Serial.print("."); pointsDrawn = true; } #endif } return false; }
//check for any new mqtt messages. void ATTDevice::Process() { _stream->println(CMD_RECEIVE); unsigned long start = millis(); while (millis() < start + DEFAULT_TIMEOUT) { if (readLn() > 0) { if (strstr(this->inputBuffer, STR_RESULT_OK) != NULL) return; //we received 'ok', so nothing to process else{ #ifdef DEBUG Serial.print("received: "); Serial.println(this->inputBuffer); #endif // Split the command in two values char* separator = strchr(this->inputBuffer, ';'); *separator = 0; int pin = atoi(this->inputBuffer); ++separator; String value = String(separator); _callback(pin, value); return; } } } }
bool ATTDevice::expectAny(unsigned short timeout) { unsigned long start = millis(); while (timeout == 0 || millis() < start + timeout) //if timeout = 0, we wait indefinetly { #ifdef DEBUG Serial.print("."); #endif if (readLn() > 0){ delay(500); while(Serial.available() > 0){ readLn(); delay(500); } return true; } } return false; }
uint8_t Sodaq_RN2483::macTransmit(const char* type, uint8_t port, const uint8_t* payload, uint8_t size) { debugPrintLn("[macTransmit]"); this->loraStream->print(STR_CMD_MAC_TX); this->loraStream->print(type); this->loraStream->print(port); this->loraStream->print(" "); for (int i = 0; i < size; ++i) { this->loraStream->print(static_cast<char>(NIBBLE_TO_HEX_CHAR(HIGH_NIBBLE(payload[i])))); this->loraStream->print(static_cast<char>(NIBBLE_TO_HEX_CHAR(LOW_NIBBLE(payload[i])))); } this->loraStream->print(CRLF); if (!expectOK()) { return lookupMacTransmitError(this->inputBuffer); // inputBuffer still has the last line read } this->packetReceived = false; // prepare for receiving a new packet debugPrint("Waiting for server response"); unsigned long timeout = millis() + RECEIVE_TIMEOUT; // hard timeout while (millis() < timeout) { sodaq_wdt_reset(); debugPrint("."); if (readLn() > 0) { debugPrintLn(".");debugPrint("(");debugPrint(this->inputBuffer);debugPrintLn(")"); if (strstr(this->inputBuffer, " ") != NULL) // to avoid double delimiter search { // there is a splittable line -only case known is mac_rx debugPrintLn("Splittable response found"); return onMacRX(); } else if (strstr(this->inputBuffer, STR_RESULT_MAC_TX_OK)) { // done debugPrintLn("Received mac_tx_ok"); return NoError; } else { // lookup the error message debugPrintLn("Some other string received (error)"); return lookupMacTransmitError(this->inputBuffer); } } } debugPrintLn("Timed-out waiting for a response!"); return Timeout; }
/** * @brief Waits for the given string. * @param String to look for. * @param Timeout Period * @param Position to start from. * @return Returns true if the string is received before a timeout. * Returns false if a timeout occurs or if another string is received. */ bool RN2483::expectString(const char* str, uint16_t timeout) { Timer t; t.start(); int start = t.read_ms(); while (t.read_ms() < start + timeout) { if (readLn() > 0) { if (strstr(this->inputBuffer, str) != NULL) { t.stop(); return true; } t.stop(); return false; } } t.stop(); return false; }
/** * @brief Sends a a payload and blocks until there is a response back, * or the receive windows have closed or the hard timeout has passed. * @param Transmit type * @param Port to use for transmit * @param Payload buffer * @param Size of payload buffer * @return Returns if sucessfull or if a MAC transmit error. */ uint8_t RN2483::macTransmit(const char* type, uint8_t port, const uint8_t* payload, uint8_t size) { _RN2483.printf(STR_CMD_MAC_TX); _RN2483.printf(type); _RN2483.printf("%u",port); _RN2483.printf(" "); for (int i = 0; i < size; ++i) { _RN2483.putc(static_cast<char>(NIBBLE_TO_HEX_CHAR(HIGH_NIBBLE(payload[i])))); _RN2483.putc(static_cast<char>(NIBBLE_TO_HEX_CHAR(LOW_NIBBLE(payload[i])))); } _RN2483.printf(CRLF); if (!expectOK()) { return lookupMacTransmitError(this->inputBuffer); // inputBuffer still has the last line read } this->packetReceived = false; // prepare for receiving a new packet Timer t; t.start(); int timeout = t.read_ms() + RECEIVE_TIMEOUT; // hard timeouts while (t.read_ms() < timeout) { if (readLn() > 0) { if (strstr(this->inputBuffer, " ") != NULL) { // to avoid double delimiter search // there is a splittable line -only case known is mac_rx t.stop(); return onMacRX(); } else if (strstr(this->inputBuffer, STR_RESULT_MAC_TX_OK)) { // done t.stop(); return NoError; } else { // lookup the error message t.stop(); return lookupMacTransmitError(this->inputBuffer); } } } t.stop(); return Timedout; }
bool Sodaq_RN2483::getMacParam(const char* paramName, char* paramValue, uint8_t size) { debugPrint("[getMacParam] "); debugPrint(paramName); debugPrint("? "); this->loraStream->print(STR_CMD_GET); this->loraStream->print(paramName); this->loraStream->print(CRLF); if (readLn() > 0) { strncpy (paramValue, this->inputBuffer, size-1); paramValue[size-1] = 0x00; debugPrintLn(paramValue); return true; } debugPrintLn(" ERROR!"); return false; }
bool Sodaq_RN2483::getSysParam(const char* paramName, uint8_t* paramValue, uint8_t size) { debugPrint("[getSysParam] "); debugPrint(paramName); debugPrint("? "); this->loraStream->print(STR_SYS_GET); this->loraStream->print(paramName); this->loraStream->print(CRLF); uint16_t len = readLn(); if (len > 0) { for (uint16_t i = 0; i < len; i+=2) { paramValue[i/2] = HEX_PAIR_TO_BYTE(this->inputBuffer[i],this->inputBuffer[i+1]); } return true; } debugPrintLn(" ERROR!"); return false; }
/* Read request file into new, non-queued Reqserv. Save new Reqserv in "rsz" and return TRUE on success. Returns FALSE on failure, see errno. If the file doesn't exist, an empty Reqserv is returned. */ static Bool readRequestfile(const char* serv, Reqserv** rsz) { Str filename; Str line; FILE* file; Reqserv* rs; fileRequest(filename, serv); Log_dbg("reading request file %s", filename); file = fopen(filename, "r"); if (!file && (errno == ENOENT)) { *rsz = newReqserv(serv); (*rsz)->mtime = get_mtime(serv); return TRUE; } if (Log_check(file != 0, "could not open %s for reading: %s", filename, strerror(errno))) return FALSE; rs = *rsz = newReqserv(serv); while( readLn(line, file) == TRUE) { char* line1 = Utl_stripWhiteSpace(line); if (*line1) storeMsgId(rs, line1); } rs->dirty = FALSE; if (Log_check(fclose(file) != EOF, "could not close %s properly: %s\n", filename, strerror(errno))) return FALSE; return TRUE; }
// Waits for the given string. Returns true if the string is received before a timeout. // Returns false if a timeout occurs or if another string is received. bool Sodaq_RN2483::expectString(const char* str, uint16_t timeout) { debugPrint("[expectString] expecting "); debugPrint(str); unsigned long start = millis(); while (millis() < start + timeout) { debugPrint("."); if (readLn() > 0) { debugPrint("("); debugPrint(this->inputBuffer); debugPrint(")"); if (strstr(this->inputBuffer, str) != NULL) { debugPrintLn(" found a match!"); return true; } return false; } } return false; }
// Gets the preprogrammed EUI node address from the module. // Returns the number of bytes written or 0 in case of error. uint8_t Sodaq_RN2483::getHWEUI(uint8_t* buffer, uint8_t size) { debugPrintLn("[getHWEUI]"); this->loraStream->print(STR_CMD_GET_HWEUI); this->loraStream->print(CRLF); // TODO move to general "read hex" method uint8_t inputIndex = 0; uint8_t outputIndex = 0; unsigned long start = millis(); while (millis() < start + DEFAULT_TIMEOUT) { sodaq_wdt_reset(); debugPrint("."); if (readLn() > 0) { debugPrintLn(this->inputBuffer); while (outputIndex < size && inputIndex + 1 < this->inputBufferSize && this->inputBuffer[inputIndex] != 0 && this->inputBuffer[inputIndex + 1] != 0) { buffer[outputIndex] = HEX_PAIR_TO_BYTE( this->inputBuffer[inputIndex], this->inputBuffer[inputIndex + 1]); inputIndex += 2; outputIndex++; } debugPrint("[getHWEUI] count: "); debugPrintLn(outputIndex); return outputIndex; } } debugPrint("[getHWEUI] Timed out without a response!"); return 0; }
/** * @brief Informs the RN2483 to do an ADC conversion on the VDD. * @param Pass pointer to long for conversion to read into. * @return Returns if a value was sucessfully read into the long. */ bool RN2483::getVDD(long *vdd) { _RN2483.printf(STR_CMD_GET_VDD); _RN2483.printf(CRLF); Timer t; t.start(); int timeout = t.read_ms() + RECEIVE_TIMEOUT; // hard timeouts while (t.read_ms() < timeout) { if (readLn() > 0) { char *temp; bool rc = true; errno = 0; *vdd = strtol(this->inputBuffer, &temp, 10); if (temp == this->inputBuffer || *temp != '\0' || ((*vdd == LONG_MIN || *vdd == LONG_MAX) && errno == ERANGE)){ rc = false; } t.stop(); return rc; } } t.stop(); return false; }