GloboSondaV1/globoSonda/src/SIM808Manager.cpp

851 lines
17 KiB
C++

#include "Sim808Manager.h"
//--------------------------------------------------------------------------------------------------------
DataGPSSimManager::DataGPSSimManager()
{
initValues();
}
char* DataGPSSimManager::getPrecision(char*buf)
{
if (hdop <= 0)
strcpy(buf, "NoValido");
else if (hdop < 1)
strcpy(buf, "Perfecta");
else if (hdop < 2)
strcpy(buf, "Excelente");
else if (hdop < 5)
strcpy(buf, "Buena");
else if (hdop < 10)
strcpy(buf, "Media");
else if (hdop < 20)
strcpy(buf, "Mala");
else
strcpy(buf, "MuyMala");
return buf;
}
char* DataGPSSimManager::getFecha(char*buf)
{
sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d", year, month, day, hour, minute, second);
return buf;
}
char* DataGPSSimManager::getTimeStamp(char*buf)
{
sprintf(buf, "%02d%02d%02d%02d", day, hour, minute, second);
return buf;
}
void DataGPSSimManager::initValues()
{
year = 0;
month = 0;
day = 0;
hour = 0;
minute = 0;
second = 0;
centisecond = 0;
speed_kmh = 0;
heading = 0;
altitude = 0;
nSatelites = 0;
IsValid = false;
}
//--------------------------------------------------------------------------------------------------------------------
Sim808Manager::Sim808Manager()
{
pk = -1;
simIniciada = false;
gpsIniciada = false;
AjusteHora = 1;
}
bool Sim808Manager::inicia(HardwareSerial *mySerial, int powerKey = -1, int baud=0)
{
pSeria = mySerial;
pk = powerKey;
if (pk >= 0)
pinMode(pk, OUTPUT);
if(baud)
return checkeaConfig(baud);
return checkea();
/* if (!CheckAt())
enciende();
return CheckAt();*/
}
bool Sim808Manager::EnviaSMS(char* tlf, char *sms)
{
Utiles::printCOM("env sms");
if (!checkea())
return false;
if (!iniciaSIM())
return false;
//envia numero telefono----------------------
sprintf(buffer, "AT+CMGS=\"%s\",145", tlf);
//sprintf(buffer,"AT+CMGS=\"%s\"",tlf);
int kk = strlen(buffer);
envia(buffer);
char * res = recibe();
if (!strstr(res, ">"))
{
Utiles::printCOM(res);
return false;
}
//envia sms---------------------------------
kk = strlen(sms);
enviaSolo(sms, kk);
buffer[0] = (char)26; //0x1A;//(ctrl-z)
buffer[1] = 0;
enviaSolo(buffer, 1);
for (int i = 0; i < 70; i++)
{
res = recibe();
if (strstr(res, "ERROR"))
{
Utiles::printCOM(res);
buffer[0] = (char)0x1B; //enviamos Esc
buffer[1] = 0;
enviaSolo(buffer, 1);
recibe();
return false;
}
if (strstr(res, "OK"))
return true;
delay(1000);
}
Utiles::printCOM("fin espera env sms");
return false;
}
DataGPSSimManager* Sim808Manager::GetGPSValid()
{
GetGPS();
while (!dataGPS.IsValid)
{
delay(1000);
GetGPS();
}
return &dataGPS;
}
char* Sim808Manager::GetFecha(char *buf)
{
GetGPSValid();
return dataGPS.getFecha(buf);
}
DataGPSSimManager* Sim808Manager::GetUltGPS()
{
return &dataGPS;
}
DataGPSSimManager* Sim808Manager::GetGPS()
{
dataGPS.initValues();
if (!checkea())
return &dataGPS;
if (!iniciaGPS())
return &dataGPS;
if (!recibeGPRMC())
Utiles::printCOM("GPRMC no valido");
if (!recibeCGPSINF_0())
Utiles::printCOM("info 0 no valido");
if (!recibeGPGSA())
{
Utiles::printCOM("GPGSA no valida");
}
return &dataGPS;
}
//funciones auxiliares----------------------
bool Sim808Manager::iniciaGPS()
{
if (gpsIniciada)
return true;
envia("AT+CGPSPWR=1");
if (!reciveOK())
return false;
envia("AT+CGPSRST=1");
if (!reciveOK())
return false;
gpsIniciada = true;
return true;
}
bool Sim808Manager::iniciaSIM()
{
if (simIniciada)
return true;
Utiles::printCOM("inicia sim");
//verifica que no este configurado el pin
envia("AT+CPIN?");
char* res = recibe();
if (!strstr(res, "+CPIN: READY"))
{
Utiles::printCOM("Sim Necesita Pin");
return false;
}
//configura sms en modo texto
envia("AT+CMGF=1");
if (!reciveOK())
return false;
simIniciada = true;
return true;
}
char* Sim808Manager::recibeDatos()
{
return recibe();
}
char* Sim808Manager::recibe()
{
unsigned long start = millis();
char d;
char *buff = buffer;
char *buf = buffer;
int len = 0;
while (millis() - start < 100)
{
while (pSeria->available() > 0 && len< (LEN_BUFFER_DATA_SIMMANAGER-3))
{
start = millis();
d = pSeria->read();
*buf = d;
buf++;
len++;
}
}
*buf = 0;
//log sim
/*
if(*buff)
Utiles::printCOM(buff);
*/
return buff;
}
void Sim808Manager::envia(const char* dat)
{
pSeria->println(dat);
//Utiles::printCOM(dat);
}
void Sim808Manager::enviaSolo(const char* dat, int ndata)
{
for ( int i = 0; i < ndata; i++)
{
pSeria->write(dat[i]);
}
//Utiles::printCOM(dat);
}
bool Sim808Manager::CheckAt()
{
envia("AT");
bool res = reciveOK();
return res;
}
void Sim808Manager::enciende()
{
if (pk < 0)
return;
digitalWrite(pk, HIGH);
delay (2000);
digitalWrite (pk, LOW);
delay (2000);
}
bool Sim808Manager::reciveOK()
{
char* resp = recibe();
if (strstr(resp, "OK"))
return true;
return false;
}
//traza nmea gprmc
bool Sim808Manager::recibeGPRMC()
{
bool datoValido = true;
char buf[16];
envia("AT+CGPSINF=32");
char *res = recibe();
if (!strstr(res, "+CGPSINF:"))
{
Utiles::printCOM("info no valido\n");
return false;
}
StringSplit sp(res, ",");
sp.get();
char* res2 = sp.get();
if (!res2 || strlen(res2) < 6)
{
Utiles::printCOM("longitud hora\n");
return false;
}
int i = 0;
//HORA----------------
buf[0] = res2[i++];
buf[1] = res2[i++];
buf[2] = 0;
dataGPS.hour = atoi(buf) + AjusteHora;
//MIN---------------
buf[0] = res2[i++];
buf[1] = res2[i++];
buf[2] = 0;
dataGPS.minute = atoi(buf);
//SEG---------------
buf[0] = res2[i++];
buf[1] = res2[i++];
buf[2] = 0;
dataGPS.second = atoi(buf);
//dato valido-------
res2 = sp.get();
if (!res2 || strlen(res2) < 1)
{
Utiles::printCOM("longitud valido\n");
return false;
}
if (!strstr(res2, "A"))
{
//Utiles::printCOM("Dato no valido\n");
datoValido = false;
}
//latitud----------
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 5)
{
return false;
}
//grados
buf[0] = res2[i++];
buf[1] = res2[i++];
buf[2] = 0;
dataGPS.lat = atof(buf) + (atof(&res2[i]) / 60.);
//hemisferio
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
{
return false;
}
if (!strstr(res2, "N"))
dataGPS.lat = -dataGPS.lat;
//longitud----------
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 5)
{
return false;
}
//grados
buf[0] = res2[i++];
buf[1] = res2[i++];
buf[2] = res2[i++];
buf[3] = 0;
dataGPS.lon = atof(buf) + (atof(&res2[i]) / 60.);
//Signo
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
return false;
if (res2[0] != 'E')
dataGPS.lon = -dataGPS.lon;
//velocidad---------
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
return false;
dataGPS.speed_kmh = atof(res2) * 1.852;
//direccion--------
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
return false;
dataGPS.heading = atof(res2);
//fecha------------
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 6)
return false;
//dia
buf[0] = res2[i++];
buf[1] = res2[i++];
buf[2] = 0;
dataGPS.day = atoi(buf);
//mes
buf[0] = res2[i++];
buf[1] = res2[i++];
buf[2] = 0;
dataGPS.month = atoi(buf);
//anio
buf[0] = res2[i++];
buf[1] = res2[i++];
buf[2] = 0;
dataGPS.year = 2000 + atoi(buf);
dataGPS.IsValid = datoValido;
return true;
}
bool Sim808Manager::recibeCGPSINF_0()
{
char buf[16];
envia("AT+CGPSINF=0");
char *res = recibe();
if (!strstr(res, "+CGPSINF:"))
{
return false;
}
int i = 0;
StringSplit sp(res, ",");
sp.get();//cabecera
sp.get();//longitud
sp.get();//latidud
//altura
char* res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
return false;
dataGPS.altitude = atof(res2);
sp.get();//tiempo
sp.get();//TTF
//numero de satelites
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
return false;
dataGPS.nSatelites = atoi(res2);
return true;
}
bool Sim808Manager::recibeGPGSA()
{
envia("AT+CGPSINF=8");
char *res = recibe();
if (!strstr(res, "+CGPSINF:"))
{
return false;
}
int i = 0;
StringSplit sp(res, ",");
//pasa datos hasta
for (i = 0; i < 15; i++)
sp.get();//cabecera
//precision posicion
char* res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
return false;
dataGPS.pdop = atof(res2);
//precision horizontal
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
return false;
dataGPS.hdop = atof(res2);
//precision vertical
res2 = sp.get();
i = 0;
if (!res2 || strlen(res2) < 1)
return false;
dataGPS.vdop = atof(res2);
return true;
}
bool Sim808Manager::checkeaConfig(int baud)
{
if (Sim808Manager::configBaud(baud))
return true;
Utiles::printCOM("reinicia modulo sim");
gpsIniciada = false;
simIniciada = false;
enciende();
return Sim808Manager::configBaud(baud);
}
bool Sim808Manager::checkea()
{
if (!CheckAt())
{
Utiles::printCOM("reinicia modulo sim");
gpsIniciada = false;
simIniciada = false;
enciende();
}
else
return true;
return CheckAt();
}
bool Sim808Manager::configBaud(int baud)
{
const uint32_t baudSIM808[] = {
300,
600,
1200,
2400,
4800,
9600,
19200,
38400,
57600,
74880,
115200
};
Utiles::printCOM("configBaud");
pSeria->begin(baud);
Utiles::printCOM("configurado p serial");
//envia("AT+GMR");
//reciveOK();
if (CheckAt())
return true;
Utiles::printCOM("se intenta configurar baud");
char auxbuf[24];
for (int i = 0; i < 11; i++)
{
uint32_t baudTest = baudSIM808[i];
sprintf(auxbuf, "prueba: %u", baudTest );
Utiles::printCOM(auxbuf);
pSeria->begin(baudTest);
if (CheckAt())
{
Utiles::printCOM("Conseguido");
sprintf(auxbuf, "AT+IPR=%u", baud );
envia(auxbuf);
if (reciveOK())
break;
}
Utiles::printCOM("fail");
}
pSeria->begin(baud);
return CheckAt();
}
char* Sim808Manager::EnviaComando(char* at_command)
{
envia(at_command);
return recibe();
}
bool Sim808Manager::IniciaNetwork(const char* apn = 0, const char* userName = 0, const char* passWord = 0)
{
if(!iniciaSIM())
return false;
char* res;
envia("AT+CGATT?");
if (!reciveOK())
return false;
envia("AT+CGATT=1");
if (!reciveOK())
return false;
if(apn)
{
strcpy(buffer, "AT+SAPBR=3,1,\"APN\",\"");
enviaSolo(buffer, strlen(buffer));
enviaSolo(apn, strlen(apn));
envia("\"");
}
else
envia("AT+SAPBR=3,1,\"APN\",\"\"");
if (!reciveOK())
return false;
if(userName)
{
strcpy(buffer, "AT+SAPBR=3,1,\"USER\",\"");
enviaSolo(buffer, strlen(buffer));
enviaSolo(userName, strlen(userName));
envia("\"");
}
else
envia("AT+SAPBR=3,1,\"USER\",\"\"");
if (!reciveOK())
return false;
if(passWord)
{
strcpy(buffer, "AT+SAPBR=3,1,\"PWD\",\"");
enviaSolo(buffer, strlen(buffer));
enviaSolo(passWord, strlen(passWord));
envia("\"");
}
else
envia("AT+SAPBR=3,1,\"PWD\",\"\"");
if (!reciveOK())
return false;
envia("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
if (!reciveOK())
return false;
envia("AT+SAPBR=1,1");
reciveOK();
for(int i=0; i<10; i++)
{
envia("AT+SAPBR=2,1");
res=recibe();
if(res && !strstr(res,"0.0.0.0") && strstr(res,"OK"))
{
//envia("AT+CIPMUX=0");
return true;
}
delay(1000);
}
return false;
}
uint32_t Sim808Manager::str_to_ip(const char* str)
{
uint32_t ip = 0;
char* p = (char*)str;
for (int i = 0; i < 4; i++) {
ip |= atoi(p);
p = strchr(p, '.');
if (p == NULL) {
break;
}
ip <<= 8;
p++;
}
return ip;
}
bool Sim808Manager::connect(ProtocolSimManager ptl, const char* host, int port)
{
//char cmd[64];
char num[4];
char *res;
//sim808_clean_buffer(cmd,64);
if (ptl == SIM808_TCP)
strcpy(buffer, "AT+CIPSTART=\"TCP\",\"");
else if (ptl == SIM808_UDP)
strcpy(buffer, "AT+CIPSTART=\"UDP\",\"");
else
return false;
enviaSolo(buffer, strlen(buffer));
enviaSolo(host, strlen(host));
enviaSolo("\",",2);
itoa(port, num, 10);
envia(num);
for (int i = 0; i < 70; i++)
{
res = recibe();
if (strstr(res, "ERROR"))
{
Utiles::printCOM(res);
buffer[0] = (char)0x1B; //enviamos Esc
buffer[1] = 0;
enviaSolo(buffer, 1);
recibe();
return false;
}
if (strstr(res, "CONNECT"))
return true;
delay(1000);
}
return false;
}
/*
* Serial.println(sim808.EnviaComando("AT+HTTPINIT"));
Serial.println(sim808.EnviaComando("AT+HTTPPARA=\"CID\",1"));
Serial.println(sim808.EnviaComando("AT+HTTPPARA=\"URL\",\"desa.narvaling.com:6265/setcoor/holaArdu\""));
Serial.println(sim808.EnviaComando("AT+HTTPACTION=0"));
Serial.println(sim808.EnviaComando("AT+HTTPREAD"));
*/
bool Sim808Manager::httpGet(char* uri)
{
envia("AT+HTTPINIT");
if (!reciveOK())
{
envia("AT+HTTPTERM");
reciveOK();
return false;
}
envia("AT+HTTPPARA=\"CID\",1");
if (!reciveOK())
{
envia("AT+HTTPTERM");
reciveOK();
return false;
}
strcpy(buffer, "AT+HTTPPARA=\"URL\",\"");
enviaSolo(buffer, strlen(buffer));
enviaSolo(uri, strlen(uri));
envia("\"");
if (!reciveOK())
{
envia("AT+HTTPTERM");
reciveOK();
return false;
}
envia("AT+HTTPACTION=0");
bool reciv = 0;
for (int i = 0; i < 1200 && !reciv; i++)
{
char* res = recibe();
if (res)
{
if (strstr(res, "ERROR"))
{
Utiles::printCOM("error");
Utiles::printCOM(res);
buffer[0] = (char)0x1B; //enviamos Esc
buffer[1] = 0;
enviaSolo(buffer, 1);
recibe();
envia("AT+HTTPTERM");
reciveOK();
return false;
}
else if (strstr(res, "+HTTPACTION:"))
{
reciv = 1;
}
}
if(!reciv)
delay(100);
}
if (!reciv)
{
envia("AT+HTTPTERM");
reciveOK();
return false;
}
envia("AT+HTTPREAD");
if (!reciveOK())
{
envia("AT+HTTPTERM");
reciveOK();
return false;
}
envia("AT+HTTPTERM");
if (!reciveOK())
return false;
return true;
}
bool Sim808Manager::send(char* strbuf, int len)
{
Utiles::printCOM(strbuf);
envia("AT+CIPQSEND=0");
if(!reciveOK())
return false;
if (len <= 0)
return false;
strcpy(buffer, "AT+CIPSEND=");
enviaSolo(buffer, strlen(buffer));
itoa(len, buffer, 12);
envia(buffer);
char* res = recibe();
if (!res || !strstr(res, ">")) {
return false;
}
enviaSolo(strbuf, len);
buffer[0] = (char)26; //0x1A;//(ctrl-z)
buffer[1] = 0;
enviaSolo(buffer, strlen(buffer));
for (int i = 0; i < 70; i++)
{
res = recibe();
if(res)
{
if (strstr(res, "ERROR"))
{
Utiles::printCOM("error");
Utiles::printCOM(res);
buffer[0] = (char)0x1B; //enviamos Esc
buffer[1] = 0;
enviaSolo(buffer, 1);
recibe();
return false;
}
else if (strstr(res, "OK"))
{
return true;
}
}
delay(10000);
}
Utiles::printCOM("Error al enviar datos, envio sale por tiempo");
return false;
}
bool Sim808Manager::ISConectado(void)
{
char resp[96];
envia("AT+CIPSTATUS");
char* res = recibe();
if (res && strstr(res, "CONNECT OK")) {
//+CIPSTATUS: 1,0,"TCP","216.52.233.120","80","CONNECTED"
return true;
}
else {
return false;
}
}
bool Sim808Manager::Cierra()
{
// if not connected, return
if (!ISConectado()) {
return true;
}
envia("AT+CIPCLOSE");
char* res = recibe();
if (!res && NULL != strstr(res, "CLOSE OK")) {
//+CIPSTATUS: 1,0,"TCP","216.52.233.120","80","CONNECTED"
return true;
}
else {
return false;
}
}
void Sim808Manager::Desconecta()
{
Cierra();
envia("AT+CIPSHUT");
recibe();
}