bool GPRS::getLocation(const __FlashStringHelper *apn, float *longitude, float *latitude) { int i = 0; char gprsBuffer[80]; char buffer[20]; char *s; if (openBearer(apn) == false) return false; //AT+CIPGSMLOC=1,1 sim900_flush_serial(); sim900_send_cmd(F("AT+CIPGSMLOC=1,1\r")); sim900_clean_buffer(gprsBuffer,sizeof(gprsBuffer)); sim900_read_buffer(gprsBuffer,sizeof(gprsBuffer),2*DEFAULT_TIMEOUT,6*DEFAULT_INTERCHAR_TIMEOUT); //Serial.println(gprsBuffer); if(NULL != ( s = strstr(gprsBuffer,"+CIPGSMLOC:"))) { s = strstr((char *)s, ","); s = s+1; //Serial.println(*s); i=0; while(*(++s) != ',') buffer[i++]=*s; buffer[i] = 0; *longitude = atof(buffer); i=0; while(*(++s) != ',') buffer[i++]=*s; buffer[i] = 0; *latitude = atof(buffer); return true; } return false; }
int GPRS::readSMS(int messageIndex, char *message,int length) { int i = 0; char gprsBuffer[100]; char cmd[16]; char *p,*s; sim900_check_with_cmd("AT+CMGF=1\r\n","OK",DEFAULT_TIMEOUT,CMD); suli_delay_ms(1000); sprintf(cmd,"AT+CMGR=%d\r\n",messageIndex); sim900_send_cmd(cmd); sim900_clean_buffer(gprsBuffer,sizeof(gprsBuffer)); sim900_read_buffer(gprsBuffer,sizeof(gprsBuffer),DEFAULT_TIMEOUT); if(NULL != ( s = strstr(gprsBuffer,"+CMGR:"))){ if(NULL != ( s = strstr(s,"\r\n"))){ p = s + 2; while((*p != '\r')&&(i < length-1)) { message[i++] = *(p++); } message[i] = '\0'; } } return 0; }
int GPRS::recv(char* buf, int len) { sim900_clean_buffer(buf,len); sim900_read_buffer(buf,len); //Ya he llamado a la funcion con la longitud del buffer - 1 y luego le estoy añadiendo el 0 return strlen(buf); }
bool GPRS::isCallActive(char *number) { char gprsBuffer[46]; //46 is enough to see +CPAS: and CLCC: char *p, *s; int i = 0; sim900_send_cmd("AT+CPAS\r\n"); /*Result code: 0: ready 2: unknown 3: ringing 4: call in progress AT+CPAS --> 7 + 2 = 9 chars --> 2 char +CPAS: 3 --> 8 + 2 = 10 chars --> 2 char OK --> 2 + 2 = 4 chars AT+CPAS +CPAS: 0 OK */ sim900_clean_buffer(gprsBuffer,29); sim900_read_buffer(gprsBuffer,27); //HACERR cuando haga lo de esperar a OK no me haría falta esto //We are going to flush serial data until OK is recieved sim900_wait_for_resp("OK\r\n", CMD); //Serial.print("Buffer isCallActive 1: ");Serial.println(gprsBuffer); if(NULL != ( s = strstr(gprsBuffer,"+CPAS:"******"running" (but number 2 that is unknow) if (*s != '2') { //3 or 4, let's go to check for the number sim900_send_cmd("AT+CLCC\r\n"); /* AT+CLCC --> 9 +CLCC: 1,1,4,0,0,"656783741",161,"" OK Without ringing: AT+CLCC OK */ sim900_clean_buffer(gprsBuffer,46); sim900_read_buffer(gprsBuffer,45); //Serial.print("Buffer isCallActive 2: ");Serial.println(gprsBuffer); if(NULL != ( s = strstr(gprsBuffer,"+CLCC:"))) { //There is at least one CALL ACTIVE, get number s = strstr((char *)(s),"\""); s = s + 1; //We are in the first phone number character p = strstr((char *)(s),"\""); //p is last character """ if (NULL != s) { i = 0; while (s < p) { number[i++] = *(s++); } number[i] = '\0'; } //I need to read more buffer //We are going to flush serial data until OK is recieved return sim900_wait_for_resp("OK\r\n", CMD); } } } } return false; }
bool GPRS::readSMS(int messageIndex, char *message, int length, char *phone, char *datetime) { /* Response is like: AT+CMGR=2 +CMGR: "REC READ","XXXXXXXXXXX","","14/10/09,17:30:17+08" SMS text here So we need (more or lees), 80 chars plus expected message length in buffer. CAUTION FREE MEMORY */ int i = 0; char gprsBuffer[80 + length]; //char cmd[16]; char num[4]; char *p,*p2,*s; sim900_check_with_cmd("AT+CMGF=1\r\n","OK\r\n",CMD); delay(1000); //sprintf(cmd,"AT+CMGR=%d\r\n",messageIndex); //sim900_send_cmd(cmd); sim900_send_cmd("AT+CMGR="); itoa(messageIndex, num, 10); sim900_send_cmd(num); sim900_send_cmd("\r\n"); sim900_clean_buffer(gprsBuffer,sizeof(gprsBuffer)); sim900_read_buffer(gprsBuffer,sizeof(gprsBuffer)); if(NULL != ( s = strstr(gprsBuffer,"+CMGR:"))){ // Extract phone number string p = strstr(s,","); p2 = p + 2; //We are in the first phone number character p = strstr((char *)(p2), "\""); if (NULL != p) { i = 0; while (p2 < p) { phone[i++] = *(p2++); } phone[i] = '\0'; } // Extract date time string p = strstr((char *)(p2),","); p2 = p + 1; p = strstr((char *)(p2), ","); p2 = p + 2; //We are in the first date time character p = strstr((char *)(p2), "\""); if (NULL != p) { i = 0; while (p2 < p) { datetime[i++] = *(p2++); } datetime[i] = '\0'; } if(NULL != ( s = strstr(s,"\r\n"))){ i = 0; p = s + 2; while((*p != '\r')&&(i < length-1)) { message[i++] = *(p++); } message[i] = '\0'; } return true; } return false; }
char GPRS::isSMSunread() { char gprsBuffer[48]; //48 is enough to see +CMGL: char *s; //List of all UNREAD SMS and DON'T change the SMS UNREAD STATUS sim900_send_cmd(F("AT+CMGL=\"REC UNREAD\",1\r\n")); /*If you want to change SMS status to READ you will need to send: AT+CMGL=\"REC UNREAD\"\r\n This command will list all UNREAD SMS and change all of them to READ If there is not SMS, response is (30 chars) AT+CMGL="REC UNREAD",1 --> 22 + 2 --> 2 OK --> 2 + 2 If there is SMS, response is like (>64 chars) AT+CMGL="REC UNREAD",1 +CMGL: 9,"REC UNREAD","XXXXXXXXX","","14/10/16,21:40:08+08" Here SMS text. OK or AT+CMGL="REC UNREAD",1 +CMGL: 9,"REC UNREAD","XXXXXXXXX","","14/10/16,21:40:08+08" Here SMS text. +CMGL: 10,"REC UNREAD","YYYYYYYYY","","14/10/16,21:40:08+08" Here second SMS OK */ sim900_clean_buffer(gprsBuffer,31); sim900_read_buffer(gprsBuffer,30,DEFAULT_TIMEOUT); //Serial.print("Buffer isSMSunread: ");Serial.println(gprsBuffer); if(NULL != ( s = strstr(gprsBuffer,"OK"))) { //In 30 bytes "doesn't" fit whole +CMGL: response, if recieve only "OK" // means you don't have any UNREAD SMS delay(50); return 0; } else { //More buffer to read //We are going to flush serial data until OK is recieved sim900_wait_for_resp("OK\r\n", CMD); //sim900_flush_serial(); //We have to call command again sim900_send_cmd("AT+CMGL=\"REC UNREAD\",1\r\n"); sim900_clean_buffer(gprsBuffer,48); sim900_read_buffer(gprsBuffer,47,DEFAULT_TIMEOUT); //Serial.print("Buffer isSMSunread 2: ");Serial.println(gprsBuffer); if(NULL != ( s = strstr(gprsBuffer,"+CMGL:"))) { //There is at least one UNREAD SMS, get index/position s = strstr(gprsBuffer,":"); if (s != NULL) { //We are going to flush serial data until OK is recieved sim900_wait_for_resp("OK\r\n", CMD); return atoi(s+1); } } else { return -1; } } return -1; }
//Here is where we ask for APN configuration, with F() so we can save MEMORY //bool GPRS::join(const __FlashStringHelper *apn, const __FlashStringHelper *userName, const __FlashStringHelper *passWord) bool GPRS::join(char* apn, char* userName, char* passWord, int timeout) { byte i; char *p, *s; char ipAddr[32]; /* if(!sim900_check_with_cmd("AT+CIPSHUT\r\n","SHUT OK\r\n", CMD)) { Serial.write("Error = 1\r\n"); return false; } delay(1000); */ sim900_send_cmd("AT+CIPSHUT\r\n"); delay(500); //Select multiple connection //sim900_check_with_cmd("AT+CIPMUX=1\r\n","OK",DEFAULT_TIMEOUT,CMD); //set APN. OLD VERSION //snprintf(cmd,sizeof(cmd),"AT+CSTT=\"%s\",\"%s\",\"%s\"\r\n",_apn,_userName,_passWord); //sim900_check_with_cmd(cmd, "OK\r\n", DEFAULT_TIMEOUT,CMD); sim900_send_cmd("AT+CSTT=\""); sim900_send_cmd(apn); sim900_send_cmd("\",\""); sim900_send_cmd(userName); sim900_send_cmd("\",\""); sim900_send_cmd(passWord); sim900_send_cmd("\"\r\n"); delay(500); //Brings up wireless connection sim900_send_cmd("AT+CIICR\r\n"); delay(4000); sim900_wait_for_resp("OK\r\n", CMD); delay(500); // sim900_check_with_cmd("AT+CIICR\r\n","OK\r\n", CMD); //Get local IP address sim900_send_cmd("AT+CIFSR\r\n"); delay(500); sim900_clean_buffer(ipAddr,32); sim900_read_buffer(ipAddr,32,DEFAULT_TIMEOUT); //Response: //AT+CIFSR\r\n --> 8 + 2 //\r\n --> 0 + 2 //10.160.57.120\r\n --> 15 + 2 (max) : TOTAL: 29 //Response error: //AT+CIFSR\r\n //\r\n //ERROR\r\n if (NULL != strstr(ipAddr,"ERROR")) { Serial.write("Error = 2\r\n"); return false; } s = ipAddr + 12; p = strstr((char *)(s),"\r\n"); //p is last character \r\n if (NULL != s) { i = 0; while (s < p) { ip_string[i++] = *(s++); } ip_string[i] = '\0'; } _ip = str_to_ip(ip_string); if(_ip != 0) { return true; } Serial.write("Error = 3\r\n"); return false; }
void GPRS::readSMS(char *message, char *phone, char *datetime) { /* Response is like: +CMT: "+79772941911","","15/12/15,01:51:24+12" +CMGR: "REC READ","XXXXXXXXXXX","","14/10/09,17:30:17+08" SMS text here */ int i = 0; int j = 0; char gprsBuffer[80 + 160]; sim900_clean_buffer(gprsBuffer,sizeof(gprsBuffer)); sim900_read_buffer(gprsBuffer,sizeof(gprsBuffer)); int len = strlen(gprsBuffer); if(gprsBuffer[i]=='\"') { i++; j = 0; while(gprsBuffer[i]!='\"') { phone[j++] = gprsBuffer[i++]; } phone[j] = '\0'; i++; } if(gprsBuffer[i]==',') i++; if(gprsBuffer[i]=='\"') { i++; while(gprsBuffer[i]!='\"') { i++; } i++; } if(gprsBuffer[i]==',') i++; if(gprsBuffer[i]=='\"') { i++; j = 0; while(gprsBuffer[i]!='\"') { datetime[j++] = gprsBuffer[i++]; } datetime[j] = '\0'; i++; } if(gprsBuffer[i]=='\r') i++; if(gprsBuffer[i]=='\n') i++; j = 0; while(i < len - 2) message[j++] = gprsBuffer[i++]; message[j] = '\0'; }
int GPRS::recv(char* buf, int len) { sim900_clean_buffer(buf,len); sim900_read_buffer(buf,len,DEFAULT_TIMEOUT); return strlen(buf); }
//Here is where we ask for APN configuration, with F() so we can save MEMORY bool GPRS::join(const __FlashStringHelper *apn, const __FlashStringHelper *userName, const __FlashStringHelper *passWord) { byte i; char *p, *s; char ipAddr[32]; //Select multiple connection //sim900_check_with_cmd("AT+CIPMUX=1\r\n","OK",DEFAULT_TIMEOUT,CMD); //set APN. OLD VERSION //snprintf(cmd,sizeof(cmd),"AT+CSTT=\"%s\",\"%s\",\"%s\"\r\n",_apn,_userName,_passWord); //sim900_check_with_cmd(cmd, "OK\r\n", DEFAULT_TIMEOUT,CMD); //It is the user who need to call gprs.close and gprs.disconnect //sim900_check_with_cmd("AT+CIPSHUT\r\n", "SHUT OK\r\n", CMD, 2000, 1000); /**Reset the IP session if any**/ sim900_send_cmd(F("AT+CSTT=\"")); if (apn) { sim900_send_cmd(apn); } sim900_send_cmd(F("\",\"")); if (userName) { sim900_send_cmd(userName); } sim900_send_cmd(F("\",\"")); if (passWord) { sim900_send_cmd(passWord); } if (!sim900_check_with_cmd(F("\"\r\n"), "OK\r\n", CMD)) { return false; } //Brings up wireless connection if (!sim900_check_with_cmd(F("AT+CIICR\r\n"),"OK\r\n", CMD)) { return false; } //Get local IP address sim900_send_cmd(F("AT+CIFSR\r\n")); sim900_clean_buffer(ipAddr,32); sim900_read_buffer(ipAddr,32); //Response: //AT+CIFSR\r\n --> 8 + 2 //\r\n --> 0 + 2 //10.160.57.120\r\n --> 15 + 2 (max) : TOTAL: 29 //Response error: //AT+CIFSR\r\n //\r\n //ERROR\r\n if (NULL != strstr(ipAddr,"ERROR")) { return false; } s = ipAddr + 11; p = strstr((char *)(s),"\r\n"); //p is last character \r\n if (NULL != s) { i = 0; while (s < p) { ip_string[i++] = *(s++); } ip_string[i] = '\0'; } _ip = str_to_ip(ip_string); if(_ip != 0) { return true; } return false; }
bool GPRS::getBookEntry(int index, char* number, int *type, char *name) { //AT+GPBR=? => +CPBR:(1-250),40,17 +CPBR: (range phone book),number length, name length static const int numMax = 40; static const int nameMax = 17; char gprsBuffer[100]; char tmp[4]; sim900_send_cmd(F("AT+CPBR=")); itoa(index, tmp, 10); sim900_send_cmd(tmp); sim900_send_cmd(F("\r\n")); sim900_clean_buffer(gprsBuffer,sizeof(gprsBuffer)); sim900_read_buffer(gprsBuffer,sizeof(gprsBuffer),DEFAULT_TIMEOUT); //+CPBR: <index>,<number>,<type>,<text> char *beg, *end, *idx, *num, *typ; if(NULL == (beg = strstr(gprsBuffer, "+CPBR: "))) { return false; } if(NULL == (end = strstr(beg, "\r\n"))) { return false; } if(NULL == (idx = strchr(beg, ','))) { return false; } strncpy(tmp, beg+7, (idx-(beg+7)) <= 3 ? (idx-(beg+7)) : 3); tmp[(idx-(beg+7)) <= 3 ? (idx-(beg+7)) : 3] = '\0'; if(strtol(tmp, NULL, 10) != index) { return false; } if(NULL == (num = strchr(idx+1, ','))) { return false; } strncpy(number, idx+2, (num-(idx+3)) <= numMax ? (num-(idx+3)) : numMax); // We also remove " from the number so we increment idx number[(num-(idx+3)) <= numMax ? (num-(idx+3)) : numMax] = '\0'; if(NULL == (typ = strchr(num+1, ','))) { return false; } strncpy(tmp, num+1, (typ-(num+1)) <= 3 ? (typ-(num+1)) : 3); tmp[(typ-(num+1)) <= 3 ? (typ-(num+1)) : 3] = '\0'; if(strtol(tmp, NULL, 10) == 0) { return false; } else { *type = strtol(tmp, NULL, 10); } strncpy(name, typ+2, (end-(typ+3)) <= nameMax ? (end-(typ+3)) : nameMax); // We also remove " from the name so we increment typ name[(end-(typ+3)) <= nameMax ? (end-(typ+3)) : nameMax] = '\0'; return true; }
int16_t GPRS::httpSendGetRequest(const __FlashStringHelper * url, const char * pathPart1, const __FlashStringHelper * pathPart2, uint8_t queryParametersCount, const __FlashStringHelper * const queryParameterKeys[], const char * const queryParamValues[], uint16_t port) { char receiveBuffer[32]; char httpStatusCode[4]; char * commaPtr = NULL; const __FlashStringHelper * tempParamKey; // 1 AT+HTTPPARA=\"CID\",1 if (sim900_check_with_cmd(F("AT+HTTPPARA=\"CID\",1\r\n"), "OK", CMD) == false){ return -1; } // 2 AT+HTTPPARA=\"URL\",\"<url>\" sim900_send_cmd(F("AT+HTTPPARA=\"URL\",\"")); sim900_send_cmd(url); if (port != HTTP_DEFAULT_PORT){ char strPort[6] = {'\0'}; ltoa(port, strPort, 10); sim900_send_cmd(F(":")); sim900_send_cmd(strPort); } sim900_send_cmd(pathPart1); sim900_send_cmd(pathPart2); for (int i = 0; i < queryParametersCount; i++) { // first parameter if (i == 0) sim900_send_cmd("?"); else sim900_send_cmd("&"); // copies the pointers to the strings from progmem to RAM // got this progmem magic from http://www.gammon.com.au/progmem tempParamKey = (const __FlashStringHelper *)pgm_read_word(&queryParameterKeys[i]); sim900_send_cmd(tempParamKey); sim900_send_cmd("="); sim900_send_cmd(queryParamValues[i]); } if (sim900_check_with_cmd(F("\"\r\n"), "OK", CMD) == false) return -1; // 3 AT+HTTPACTION=0 if (sim900_check_with_cmd(F("AT+HTTPACTION=0\r\n"), "OK", DATA) == false) return -1; // fetch additional data which looks like +HTTPACTION: <Method>,<StatusCode>,<DataLen> // where "Method" is always 0 (GET request) sim900_clean_buffer(receiveBuffer, sizeof(receiveBuffer)); if (sim900_read_string_until(receiveBuffer, sizeof(receiveBuffer), "+HTTPACTION: 0,", 15, 15000) == NULL) return -1; sim900_clean_buffer(receiveBuffer, sizeof(receiveBuffer)); // let's not waste time: request should be finished after 1000ms sim900_read_buffer(receiveBuffer, sizeof(receiveBuffer), 1, 1000); sim900_clean_buffer(httpStatusCode, sizeof(httpStatusCode)); //status codes are always 3 chars strncpy(httpStatusCode, receiveBuffer, 3); if (strcmp(httpStatusCode, "200") != 0) return -1; // search for additional comma, DataLen comes after that commaPtr = strrchr(receiveBuffer, ','); if (commaPtr == NULL) return -1; // step over comma commaPtr++; return atol(commaPtr); }