Skip to content

[WIP] Baud autodetect #355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
510 changes: 321 additions & 189 deletions libraries/WiFiS3/src/Modem.cpp
Original file line number Diff line number Diff line change
@@ -1,118 +1,119 @@
#include "Modem.h"

#define RESULT_OK "OK\r\n"
#define RESULT_ERROR "ERROR\r\n"
#define RESULT_DATA "DATA\r\n"
#define OK_TOKEN "OK"
#define ERROR_TOKEN "ERROR"
#define TERM_TOKEN "\r\n"
#define RESULT_OK OK_TOKEN TERM_TOKEN
#define RESULT_ERROR OK_TOKEN TERM_TOKEN
#define RESULT_DATA "DATA" TERM_TOKEN

using namespace std;

/* -------------------------------------------------------------------------- */
ModemClass::ModemClass(int tx, int rx) : beginned(false), delete_serial(false), _timeout(MODEM_TIMEOUT), trim_results(true), read_by_size(false) {
ModemClass::ModemClass(int tx, int rx) : beginned(false), delete_serial(false), _timeout(MODEM_TIMEOUT), trim_results(true) {
/* -------------------------------------------------------------------------- */
_serial = new UART(tx,rx);
_serial = new UART(tx,rx);
}

/* -------------------------------------------------------------------------- */
ModemClass::ModemClass(UART * serial) : beginned(false) , delete_serial(true) , _serial(serial), _timeout(MODEM_TIMEOUT), trim_results(true), read_by_size(false) {
/* -------------------------------------------------------------------------- */
ModemClass::ModemClass(UART * serial) : beginned(false) , delete_serial(true) , _serial(serial), _timeout(MODEM_TIMEOUT), trim_results(true) {
/* -------------------------------------------------------------------------- */
}

/* -------------------------------------------------------------------------- */
ModemClass::~ModemClass() {
/* -------------------------------------------------------------------------- */
if(_serial != nullptr && !delete_serial){
/* -------------------------------------------------------------------------- */
if(_serial != nullptr && !delete_serial){
delete _serial;
_serial = nullptr;
}
}
}

/* -------------------------------------------------------------------------- */
void ModemClass::begin(int badurate){
/* -------------------------------------------------------------------------- */
if(_serial != nullptr && !beginned) {
/* -------------------------------------------------------------------------- */
if(_serial != nullptr && !beginned) {
_serial->begin(badurate);

if(_serial_debug && _debug_level >= 2) {
_serial_debug->println("Baudrate autodetection started");
}
// auto baudrate detection algorithm
do {
_serial->write(0x55);
// delay(1);
} while(!_serial->available() || _serial->read() != 0x55); // TODO put timeout

if(_serial_debug && _debug_level >= 2) {
_serial_debug->print("Baudrate autodetection terminated");
}

beginned = true;
string res = "";
_serial->flush();
modem.write(string(PROMPT(_SOFTRESETWIFI)),res, "%s" , CMD(_SOFTRESETWIFI));
}
}
}

/* -------------------------------------------------------------------------- */
void ModemClass::end(){
/* -------------------------------------------------------------------------- */
_serial->end();
/* -------------------------------------------------------------------------- */
_serial->end();
}

/* -------------------------------------------------------------------------- */
bool ModemClass::passthrough(const uint8_t *data, size_t size) {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
_serial->write(data,size);
bool res = false;
bool found = false;
string data_res = "";

unsigned long start_time = millis();
while(millis() - start_time < _timeout && !found){
while(_serial->available()){
char c = _serial->read();
data_res += c;

if(string::npos != data_res.rfind(RESULT_OK)){
found = true;
res = true;
break;
}
else if (string::npos != data_res.rfind(RESULT_ERROR)) {
found = true;
res = false;
break;
}
}
}

if(_serial_debug && _debug_level >= 2) {

std::string prompt = DO_NOT_CHECK_CMD, data_res;
auto res = buf_read(prompt, data_res);

if(_serial_debug && _debug_level >= 2) {
_serial_debug->print(" ANSWER (passthrough): ");
_serial_debug->println(data_res.c_str());
if(res) {
if(res == Ok) {
_serial_debug->println(" Result: OK");
} else if(res == Error) {
_serial_debug->println(" Result: ERROR");
} else if(res == Timeout) {
_serial_debug->println(" Result: TIMEOUT");
} else {
_serial_debug->println(" Result: ParseError");
}
else {
_serial_debug->println(" Result: FAILED");
}
}

return res;
}

return res == Ok;
}

/* -------------------------------------------------------------------------- */
void ModemClass::write_nowait(const string &cmd, string &str, const char * fmt, ...) {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
va_list va;
va_start (va, fmt);
vsnprintf((char *)tx_buff, MAX_BUFF_SIZE, fmt, va);
va_end (va);
if(_serial_debug && _debug_level >= 2) {

if(_serial_debug && _debug_level >= 2) {
_serial_debug->print("REQUEST (passthrough): ");
_serial_debug->write(tx_buff,strlen((char *)tx_buff));
_serial_debug->println();
}

_serial->write(tx_buff,strlen((char *)tx_buff));
return;
}


/* -------------------------------------------------------------------------- */
bool ModemClass::write(const string &prompt, string &data_res, const char * fmt, ...){
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
data_res.clear();
va_list va;
va_start (va, fmt);
vsnprintf((char *)tx_buff, MAX_BUFF_SIZE, fmt, va);
va_end (va);

if(_serial_debug) {
_serial_debug->println();
_serial_debug->print("REQUEST: ");
@@ -121,175 +122,306 @@ bool ModemClass::write(const string &prompt, string &data_res, const char * fmt,
}

_serial->write(tx_buff,strlen((char *)tx_buff));
return buf_read(prompt,data_res);;
}
auto res = buf_read(prompt, data_res);

if(_serial_debug) {
_serial_debug->print(" ANSWER: ");
_serial_debug->println(data_res.c_str());
if(res == Ok) {
_serial_debug->println(" Result: OK");
} else if(res == Error) {
_serial_debug->println(" Result: ERROR");
} else if(res == Timeout) {
_serial_debug->println(" Result: TIMEOUT");
} else {
_serial_debug->println(" Result: ParseError");
}
}

typedef enum {
IDLE,
WAIT_FOR_SIZE,
WAIT_FOR_DATA
} ReadBySizeSt_t;
return res == Ok;
}


/* -------------------------------------------------------------------------- */
bool ModemClass::read_by_size_finished(string &rx) {
/* -------------------------------------------------------------------------- */
bool rv = false;
static bool first_call = true;
static ReadBySizeSt_t st = IDLE;
static int data_to_be_received = 0;
static int data_received = 0;
if(first_call) {
first_call = false;
st = WAIT_FOR_SIZE;
}
ModemClass::ParseResult ModemClass::buf_read(const string &prompt, string &data_res) {
/* -------------------------------------------------------------------------- */
/*
* This function implements as FSM that parses basic AT command responses
* The expected syntax should match the following regex
* - (?:\+(\w+)[:=][ ]?(\w*))?(?:\r\n)?(ERROR\r\n|OK\r\n)
* + "ERROR<CR><LF>" "OK<CR><LF>"
* + "+COMMAND: <CR><LF>OK<CR><LF>"
* + "+COMMAND: <CR><LF>ERROR<CR><LF>"
* + "+COMMAND: 1231231<CR><LF>OK<CR><LF>" (NOTE only one parameter supported)
* + "+COMMAND: 1231231<CR><LF>ERROR<CR><LF>" (NOTE only one parameter supported)
* - custom sized response:
* + "+COMMAND: 4| 123OK<CR><LF>"
*/
enum class at_parse_state_t {
Begin = 0,
Cmd = 1,
Data = 2,
Sized = 3,
ResWaitLF = 4,
Res = 5,
Error = 6,
ParseError = 7,
Ok = 8,
Completed = 9,
};

switch(st) {
case IDLE:

break;
case WAIT_FOR_SIZE: {
int pos = rx.find("|");
int pos_space = rx.find(" ");
if(pos != string::npos && pos_space != string::npos) {
string n = rx.substr(pos_space,pos);
int to_be_rx = atoi(n.c_str());
if(to_be_rx <= 0) {
while( _serial->available() ){
_serial->read();
}
rv = true;
first_call = true;
st = IDLE;
}
else {
/* add 4 because OK\r\n is always added at the end of data */
data_to_be_received = to_be_rx + 4;
data_received = 0;
st = WAIT_FOR_DATA;
}
rx.clear();
}
}
break;

case WAIT_FOR_DATA:
data_received++;
if(data_received == data_to_be_received) {
rv = true;
first_call = true;
st = IDLE;
}
break;
at_parse_state_t state = at_parse_state_t::Begin;
std::string commandName;

default:
st = IDLE;
break;
}
return rv;
}
ModemClass::ParseResult res = Error;
unsigned int sized_read_size = 0;
unsigned int sized_read_count = 0;
unsigned int result_parse = 0;
bool restart = false,
consume_char = true; // This flag is used to indicate to consume another character from the stream

char c;

// I expect the answer to be in this form: "ERROR<CR><LF>" "OK<CR><LF>"
// if prompt == DO_NOT_CHECK_CMD
const bool check_prompt = (prompt != DO_NOT_CHECK_CMD);

/* -------------------------------------------------------------------------- */
bool ModemClass::buf_read(const string &prompt, string &data_res) {
/* -------------------------------------------------------------------------- */
bool res = false;
bool found = false;

if(_serial_debug && _debug_level >= 1) {
_serial_debug->print("RAW: ");
}

unsigned long start_time = millis();
while((millis() - start_time < _timeout) && !found){
while( _serial->available() ){
char c = _serial->read();
data_res += c;

if(_serial_debug && _debug_level >= 1) {
while(state != at_parse_state_t::Completed) {

if(millis() - start_time > _timeout) {
res = Timeout;
break;
}

if(consume_char && !_serial->available()) {
// if there is nothing available, go to the beginning of the cycle
continue;
} else if(consume_char) { // available is true
c = _serial->read();
} else if(!consume_char) {
// reset consume_char to true
consume_char = true;
}

if(_serial_debug && _debug_level >= 1 && consume_char) {
if(c == '\n') {
_serial_debug->print("<LF>");
} else if (c == '\r') {
_serial_debug->print("<CR>");
} else if (c == ' ') {
_serial_debug->print("<SP>");
} else if(c < ' ') {
_serial_debug->print("<");
_serial_debug->print((unsigned int)c);
_serial_debug->print(">");
} else {
_serial_debug->print(c);
}


if(read_by_size) {
if(read_by_size_finished(data_res)) {
found = true;
read_by_size = false;
res = true;
if(data_res.size() > 0) {
data_res = data_res.substr(0, data_res.length() - (sizeof(RESULT_OK) - 1));
}
else {
break;
}
}
}
if(_serial_debug && _debug_level >= 3) {
_serial_debug->print(" State ");
_serial_debug->println((int)state);
}

switch(state) {
case at_parse_state_t::Begin:
/*
* In this state we wait for a '+' character, which will mark the beginning of a response
* or the status response code "ERROR<CR><LF>" or "OK<CR><LF>"
* we need to consume the available buffer if it doesn't match the expected response,
* in order to avoiding dealing with previous responses which were not parsed successfully
*/

if(c == '+') {
// the answer doesn't match the expected form, we need to restart
restart = !check_prompt;

commandName += c; // prompt includes also '+'
state = at_parse_state_t::Cmd;
} else if(c == RESULT_OK[result_parse]) {
// the answer doesn't match the expected form, we need to restart
restart = check_prompt;

state = at_parse_state_t::Ok;
result_parse++;
} else if(c == RESULT_ERROR[result_parse]) {
// the answer doesn't match the expected form, we need to restart
restart = check_prompt;

state = at_parse_state_t::Error;
result_parse++;
}
else {
if(string::npos != data_res.rfind(RESULT_DATA)) {
found = true;
data_res = data_res.substr(0, data_res.length() - (sizeof(RESULT_DATA) - 1));
if(prompt != DO_NOT_CHECK_CMD) {
if(removeAtBegin(data_res, prompt)) {
res = true;
}
}
else {
res = true;
}
break;
}
else if(string::npos != data_res.rfind(RESULT_OK)){
found = true;
data_res = data_res.substr(0, data_res.length() - (sizeof(RESULT_OK) - 1) );
if(prompt != DO_NOT_CHECK_CMD) {
if(removeAtBegin(data_res, prompt)) {
res = true;
}
}
else {
res = true;
}
break;
}
else if (string::npos != data_res.rfind(RESULT_ERROR)) {
found = true;
data_res.substr(0, data_res.length() - (sizeof(RESULT_ERROR) - 1));
res = false;
break;
// if we uncomment this we can force strict response matching
// else {
// state = at_parse_state_t::ParseError;
// }

break;
case at_parse_state_t::Cmd:
/*
* In this state we parse the command prompt and wait for either ':' or '=' characters
* in order to go the next state
*/

if(c == ':' || c == '=') {
commandName += c; // prompt includes also ':'

if (check_prompt && commandName != prompt) {
// the response we got is not the one we were expecting, parse the wrong response till the end
// and start the parse of the next response
restart = true;
commandName = "";
}
state = at_parse_state_t::Data;

data_res = "";
// state = at_parse_state_t::Data;
} else { // no space should be present in the prompt response
commandName += c;
}

break;
case at_parse_state_t::Data:
/*
* In this state we parse response parameters and push them into data_res
* in case multiple parameters separated by ',' are sent, they will be present in data_res
* - if we encounter <CR> we need to wait for <LF>
* - if we encounter <LF> we need to parse the response status
* - if we encounter '|', the next token will contain binary sized data, the current value in
* in data_res contains the length of the next token
*/

if(c == '|') { // sized read, the previous parameter is the length
state = at_parse_state_t::Sized;

sized_read_size = atoi(data_res.c_str());
data_res.clear();
} else if(c == '\r') {
state = at_parse_state_t::ResWaitLF;
} else if(c == '\n') {
state = at_parse_state_t::Res;
} else if(trim_results && c != ' ') {
data_res += c; // in case trim_result is true, avoid adding spaces
} else if(!trim_results) {
data_res += c;
}

break;
case at_parse_state_t::Sized:
/*
* In this state we collect exactly sized_read_size characters into data_res
* when we consume all of them we go into Result parse state, where we supposedly
* wait for 'OK'
*/
data_res += c;

if(++sized_read_count == sized_read_size) {
state = at_parse_state_t::Res;
}
break;
case at_parse_state_t::ResWaitLF:
if(c == '\n') {
state = at_parse_state_t::Res;
}

/*
* break is volountary not present, to cover for cases where the response status is in the
* following form: '...<CR>OK<CR><LF>' '<CR>ERROR<CR><LF>'
*/
case at_parse_state_t::Res:
/*
* In this state we wait for either an 'O' or an 'E', in order to get an 'OK<CR><LF>'
* or 'ERROR<CR><LF>'
* The first two cases is when there is no parameter in the response, but just the OK and ERROR tokens
*/

if(data_res == OK_TOKEN) {
res = Ok;
state = at_parse_state_t::Completed;
} else if(data_res == ERROR_TOKEN) {
res = Error;
state = at_parse_state_t::Completed;
} if(c == RESULT_OK[0]) { // OK response
state = at_parse_state_t::Ok;
result_parse = 1;
} else if(c == RESULT_ERROR[0]) { // Error response
state = at_parse_state_t::Error;
result_parse = 1;
}
// if we uncomment this we can force strict response matching
// else {
// state = at_parse_state_t::ParseError;
// }
break;
case at_parse_state_t::Ok:
/*
* In this state we want to match the exact 'K<CR><LF>' response
*/

if(c != RESULT_OK[result_parse++]) {
state = at_parse_state_t::ParseError;
}

if(result_parse == strlen(RESULT_OK)) {
res = Ok;
state = at_parse_state_t::Completed;
}
break;
case at_parse_state_t::Error:
/*
* In this state we want to match the exact 'RROR<CR><LF>' response
*/

if(c != RESULT_ERROR[result_parse++]) {
state = at_parse_state_t::ParseError;
}

if(result_parse == strlen(RESULT_ERROR)) {
res = Error;
state = at_parse_state_t::Completed;
}
break;
case at_parse_state_t::ParseError:
res = ParseError;
// if we get a parseError, we go back from the beginning and try again to parse, unitl the timeout expires
state = at_parse_state_t::Begin;
restart = false;
consume_char = false;
break;
case at_parse_state_t::Completed:
break;
}

if(restart && state == at_parse_state_t::Completed) {
state = at_parse_state_t::Begin;
restart = false;
}
}
if(trim_results) {
trim(data_res);

if(_serial_debug && _debug_level >= 3) {
_serial_debug->print("Final State ");
_serial_debug->print((int)state);
_serial_debug->print(" res ");
_serial_debug->println((int)res);
}

trim_results = true;
read_by_size = false;

if(_serial_debug && _debug_level >= 1) {
_serial_debug->print("<-RAW END");
_serial_debug->println();
}

if(_serial_debug) {
_serial_debug->print(" ANSWER: ");
_serial_debug->println(data_res.c_str());
if(res) {
_serial_debug->println(" Result: OK");
}
else {
_serial_debug->println(" Result: FAILED");
}
}


return res;
}

#ifdef ARDUINO_UNOWIFIR4
ModemClass modem = ModemClass(&Serial2);
ModemClass modem = ModemClass(&Serial2);
#else
ModemClass modem = ModemClass(D24,D25);
ModemClass modem = ModemClass(D24,D25);
#endif
23 changes: 14 additions & 9 deletions libraries/WiFiS3/src/Modem.h
Original file line number Diff line number Diff line change
@@ -35,21 +35,21 @@ class ModemClass {
}

void read_using_size() {
read_by_size = true;
}
// read_by_size = true; // deprecated
}
bool beginned;

/* calling this function with no argument will enable debug message to be printed
on Serial
use first parameter UART *u to redirect debug output to a different serial
use first parameter UART *u to redirect debug output to a different serial
level from 0 defaul to 2 (maximum) */

void debug(Stream &u, uint8_t level = 0) {
_serial_debug = &u;
if(level > 2) {
level = 2;

if(level > 3) {
level = 3;
}
_debug_level = level;
}
@@ -66,14 +66,19 @@ class ModemClass {
void timeout(size_t timeout_ms) {_timeout = timeout_ms;}

private:
bool buf_read(const std::string &cmd, std::string &data_res);
enum ParseResult {
Ok,
Error,
ParseError,
Timeout
};

ParseResult buf_read(const std::string &cmd, std::string &data_res);
bool delete_serial;
UART * _serial;
unsigned long _timeout;
uint8_t tx_buff[MAX_BUFF_SIZE];
bool trim_results;
bool read_by_size;
bool read_by_size_finished(std::string &rx);
Stream * _serial_debug;
uint8_t _debug_level = 0;
};
131 changes: 65 additions & 66 deletions libraries/WiFiS3/src/WiFi.cpp
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@ const char* CWifi::firmwareVersion() {
return fw_version;
}
return "99.99.99";

}


@@ -54,7 +53,7 @@ int CWifi::begin(const char* ssid, const char *passphrase) {
return WL_CONNECTED;
}
}
return WL_CONNECT_FAILED;
return WL_CONNECT_FAILED;
}

/* passphrase is needed so a default one will be set */
@@ -78,7 +77,7 @@ uint8_t CWifi::beginAP(const char *ssid, const char* passphrase) {

/* -------------------------------------------------------------------------- */
uint8_t CWifi::beginAP(const char *ssid, const char* passphrase, uint8_t channel) {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string res = "";
modem.begin();
modem.write(string(PROMPT(_MODE)),res, "%s%d\r\n" , CMD_WRITE(_MODE), 2);
@@ -97,10 +96,10 @@ uint8_t CWifi::beginAP(const char *ssid, const char* passphrase, uint8_t channel
/* -------------------------------------------------------------------------- */
void CWifi::config(IPAddress local_ip) {
/* -------------------------------------------------------------------------- */
IPAddress _gw(local_ip[0],local_ip[1], local_ip[2], 1);
IPAddress _sm(255,255,255,0);
IPAddress dns(0,0,0,0);
return _config(local_ip, _gw, _sm, _gw, dns);
IPAddress _gw(local_ip[0],local_ip[1], local_ip[2], 1);
IPAddress _sm(255,255,255,0);
IPAddress dns(0,0,0,0);
return _config(local_ip, _gw, _sm, _gw, dns);
}

/* -------------------------------------------------------------------------- */
@@ -116,7 +115,7 @@ void CWifi::_config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPA
string gw = to_string(gateway[0]) + ".";
gw += to_string(gateway[1]) + ".";
gw += to_string(gateway[2]) + ".";
gw += to_string(gateway[3]);
gw += to_string(gateway[3]);

string nm = to_string(subnet[0]) + ".";
nm += to_string(subnet[1]) + ".";
@@ -127,18 +126,18 @@ void CWifi::_config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPA
_dns1 += to_string(dns1[1]) + ".";
_dns1 += to_string(dns1[2]) + ".";
_dns1 += to_string(dns1[3]);

string _dns2 = to_string(dns2[0]) + ".";
_dns2 += to_string(dns2[1]) + ".";
_dns2 += to_string(dns2[2]) + ".";
_dns2 += to_string(dns2[3]);
_dns2 += to_string(dns2[3]);

ip_ap = local_ip;
gw_ap = gateway;
nm_ap = subnet;

modem.write(PROMPT(_SOFTAPCONFIG),res, "%s%s,%s,%s\r\n" , CMD_WRITE(_SOFTAPCONFIG), ip.c_str(), ip.c_str(), nm.c_str());
modem.write(string(PROMPT(_SETIP)),res, "%s%s,%s,%s,%s,%s\r\n" , CMD_WRITE(_SETIP), ip.c_str(), gw.c_str(), nm.c_str(),_dns1.c_str(),_dns2.c_str());
modem.write(string(PROMPT(_SETIP)),res, "%s%s,%s,%s,%s,%s\r\n" , CMD_WRITE(_SETIP), ip.c_str(), gw.c_str(), nm.c_str(),_dns1.c_str(),_dns2.c_str());
}

/* -------------------------------------------------------------------------- */
@@ -152,32 +151,32 @@ void CWifi::config(IPAddress local_ip, IPAddress dns_server) {

/* -------------------------------------------------------------------------- */
void CWifi::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway) {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

IPAddress _sm(255,255,255,0);
IPAddress dns(0,0,0,0);
return _config(local_ip, gateway, _sm,dns_server,dns);
return _config(local_ip, gateway, _sm,dns_server,dns);
}

/* -------------------------------------------------------------------------- */
void CWifi::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet) {
/* -------------------------------------------------------------------------- */

IPAddress dns(0,0,0,0);
return _config(local_ip, gateway, subnet,dns_server,dns);
return _config(local_ip, gateway, subnet,dns_server,dns);
}

/* -------------------------------------------------------------------------- */
void CWifi::setDNS(IPAddress dns_server1) {
/* -------------------------------------------------------------------------- */
IPAddress dns(0,0,0,0);
return _config(localIP(), gatewayIP(), subnetMask(),dns_server1,dns);
return _config(localIP(), gatewayIP(), subnetMask(),dns_server1,dns);
}

/* -------------------------------------------------------------------------- */
void CWifi::setDNS(IPAddress dns_server1, IPAddress dns_server2) {
/* -------------------------------------------------------------------------- */
return _config(localIP(), gatewayIP(), subnetMask(),dns_server1,dns_server2);
return _config(localIP(), gatewayIP(), subnetMask(),dns_server1,dns_server2);
}

/* -------------------------------------------------------------------------- */
@@ -189,20 +188,20 @@ void CWifi::setHostname(const char* name) {

/* -------------------------------------------------------------------------- */
int CWifi::disconnect() {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string res = "";
modem.begin();

if(modem.write(string(PROMPT(_DISCONNECT)),res,CMD(_DISCONNECT))) {
return 1;
}
}
return 0;

}

/* -------------------------------------------------------------------------- */
void CWifi::end(void) {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string res = "";
modem.begin();

@@ -211,7 +210,7 @@ void CWifi::end(void) {


static bool macStr2macArray(uint8_t *mac_out, const char *mac_in) {
if(mac_in[2] != ':' ||
if(mac_in[2] != ':' ||
mac_in[5] != ':' ||
mac_in[8] != ':' ||
mac_in[11] != ':' ||
@@ -230,10 +229,10 @@ static bool macStr2macArray(uint8_t *mac_out, const char *mac_in) {

/* -------------------------------------------------------------------------- */
uint8_t* CWifi::macAddress(uint8_t* _mac) {
/* -------------------------------------------------------------------------- */
string res = "";
modem.begin();
if(modem.write(string(PROMPT(_MODE)),res, "%s" , CMD_READ(_MODE))) {
/* -------------------------------------------------------------------------- */
string res = "";
modem.begin();
if(modem.write(string(PROMPT(_MODE)),res, "%s" , CMD_READ(_MODE))) {
if(atoi(res.c_str()) == 1) {
if(modem.write(string(PROMPT(_MACSTA)),res, "%s" , CMD_READ(_MACSTA))) {
macStr2macArray(_mac, res.c_str());
@@ -280,7 +279,7 @@ int8_t CWifi::scanNetworks() {
ap.encryption_mode = tokens[4];
access_points.push_back(ap);
}
}
}
}

return (int8_t)access_points.size();
@@ -317,7 +316,7 @@ IPAddress CWifi::dnsIP(int n) {
return dns_IP;
}
}
return IPAddress(0,0,0,0);
return IPAddress(0,0,0,0);
}


@@ -334,14 +333,14 @@ IPAddress CWifi::localIP() {
if(modem.write(string(PROMPT(_MODE)),res, "%s" , CMD_READ(_MODE))) {
if(atoi(res.c_str()) == 1) {
if(modem.write(string(PROMPT(_IPSTA)),res, "%s%d\r\n" , CMD_WRITE(_IPSTA), IP_ADDR)) {

local_IP.fromString(res.c_str());

}
}
else if(atoi(res.c_str()) == 2) {
if(modem.write(string(PROMPT(_IPSOFTAP)),res, CMD(_IPSOFTAP))) {

local_IP.fromString(res.c_str());
}
}
@@ -376,27 +375,27 @@ IPAddress CWifi::gatewayIP() {
gateway_IP.fromString(res.c_str());
return gateway_IP;
}
return IPAddress(0,0,0,0);
return IPAddress(0,0,0,0);
}

/* -------------------------------------------------------------------------- */
const char* CWifi::SSID(uint8_t networkItem) {
/* -------------------------------------------------------------------------- */
if(networkItem < access_points.size()) {
return access_points[networkItem].ssid.c_str();
}
return nullptr;
if(networkItem < access_points.size()) {
return access_points[networkItem].ssid.c_str();
}
return nullptr;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------- */
int32_t CWifi::RSSI(uint8_t networkItem) {
if(networkItem < access_points.size()) {
return atoi(access_points[networkItem].rssi.c_str());
}
return -1000;
if(networkItem < access_points.size()) {
return atoi(access_points[networkItem].rssi.c_str());
}
return -1000;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

static uint8_t Encr2wl_enc(string e) {
if (e == string("open")) {
@@ -418,17 +417,17 @@ static uint8_t Encr2wl_enc(string e) {
} else {
return ENC_TYPE_UNKNOWN;
}
}
}


/* -------------------------------------------------------------------------- */
uint8_t CWifi::encryptionType() {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
scanNetworks();
string myssid(SSID());
for(unsigned int i = 0; i < access_points.size(); i++) {
if(myssid == access_points[i].ssid) {
return Encr2wl_enc(access_points[i].encryption_mode);
return Encr2wl_enc(access_points[i].encryption_mode);
}
}
return ENC_TYPE_UNKNOWN;
@@ -437,35 +436,35 @@ uint8_t CWifi::encryptionType() {

/* -------------------------------------------------------------------------- */
uint8_t CWifi::encryptionType(uint8_t networkItem) {
if(networkItem < access_points.size()) {
return Encr2wl_enc(access_points[networkItem].encryption_mode);
}
return 0;
if(networkItem < access_points.size()) {
return Encr2wl_enc(access_points[networkItem].encryption_mode);
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------- */
uint8_t* CWifi::BSSID(uint8_t networkItem, uint8_t* bssid) {
if(networkItem < access_points.size()) {
for(int i = 0; i < 6; i++) {
*(bssid + i) = access_points[networkItem].uint_bssid[i];
}
return bssid;
return bssid;
}
return nullptr;
return nullptr;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------- */
uint8_t CWifi::channel(uint8_t networkItem) {
uint8_t CWifi::channel(uint8_t networkItem) {
if(networkItem < access_points.size()) {
return atoi(access_points[networkItem].channel.c_str());
return atoi(access_points[networkItem].channel.c_str());
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char* CWifi::SSID() {
/* -------------------------------------------------------------------------- */
string res = "";
@@ -486,9 +485,9 @@ const char* CWifi::SSID() {
return "";
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
uint8_t* CWifi::BSSID(uint8_t* bssid) {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string res = "";
if(modem.write(string(PROMPT(_GETBSSID)), res, CMD_READ(_GETBSSID))) {
macStr2macArray(bssid, res.c_str());
@@ -497,7 +496,7 @@ uint8_t* CWifi::BSSID(uint8_t* bssid) {
return nullptr;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int32_t CWifi::RSSI() {
/* -------------------------------------------------------------------------- */
string res = "";
@@ -507,9 +506,9 @@ int32_t CWifi::RSSI() {
return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char* CWifi::softAPSSID() {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string res = "";
if(modem.write(string(PROMPT(_GETSOFTAPSSID)), res, CMD_READ(_GETSOFTAPSSID))) {
apssid = res;
@@ -520,7 +519,7 @@ const char* CWifi::softAPSSID() {

/* -------------------------------------------------------------------------- */
uint8_t CWifi::status() {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
modem.begin();
string res = "";
if(modem.write(string(PROMPT(_GETSTATUS)), res, CMD_READ(_GETSTATUS))) {
@@ -532,7 +531,7 @@ uint8_t CWifi::status() {

/* -------------------------------------------------------------------------- */
int CWifi::hostByName(const char* aHostname, IPAddress& aResult) {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
modem.begin();
string res = "";
if(modem.write(string(PROMPT(_GETHOSTBYNAME)),res, "%s%s\r\n" , CMD_WRITE(_GETHOSTBYNAME), aHostname)) {
@@ -545,11 +544,11 @@ int CWifi::hostByName(const char* aHostname, IPAddress& aResult) {


uint8_t CWifi::reasonCode() {
return 0;
return 0;
}

unsigned long CWifi::getTime() {
return 0;
return 0;
}