A library for the SIM900 module to enable calling, answering, sending and receiving SMS messages
Dependents: Seeed_GPRS_Shield_GSM BluetoothNONIN HealthCare_Graduation
Fork of GSM by
gprs.cpp
- Committer:
- lawliet
- Date:
- 2013-11-18
- Revision:
- 2:16985da3a446
- Parent:
- 1:642a8dbe076c
- Child:
- 3:48ee24a4b0f3
File content as of revision 2:16985da3a446:
/* gprs.cpp 2013 Copyright (c) Seeed Technology Inc. All right reserved. Author:lawliet.zou@gmail.com 2013-11-14 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdio.h> #include "mbed.h" #include "gprs.h" #define TRUE 1 #define FALSE 0 #define UART_DEBUG #ifdef UART_DEBUG #define ERROR(x) printf("ERROR:%s\r\n",x) #define DEBUG(x) printf("DEBUG:%s\r\n",x); #else #define ERROR(x) #define DEBUG(x) #endif #define DEFALUT_TIMEOUT 5 int GPRS::init(void) { wait(0.5); if(0 != checkSIMStatus()) { //check SIM card status ERROR("checkSIMStatus"); return -1; } if(checkSignalStrength()<1) { //check Signal Strength ERROR("Signal too weak"); return -1; } if(0 != networkInit()) { ERROR("Network Init error"); return -1; } return 0; } int GPRS::readBuffer(char *buffer,int count) { int i = 0; timeCnt.start(); // start timer while(1) { while (gprsSerial.readable()) { char c = gprsSerial.getc(); if (c == '\r' || c == '\n') c = '$'; buffer[i++] = c; if(i > count)break; } if(i > count)break; if(timeCnt.read() > DEFALUT_TIMEOUT) { timeCnt.stop(); timeCnt.reset(); break; } } wait(0.5); while(gprsSerial.readable()) { // display the other thing.. char c = gprsSerial.getc(); } return 0; } void cleanBuffer(char *buffer, int count) { for(int i=0; i < count; i++) { buffer[i] = '\0'; } } void GPRS::sendCmd(char *cmd) { gprsSerial.puts(cmd); } int GPRS::waitForResp(char *resp, int timeout) { int len = strlen(resp); int sum=0; timeCnt.start(); while(1) { if(gprsSerial.readable()) { char c = gprsSerial.getc(); sum = (c==resp[sum]) ? sum+1 : 0; if(sum == len)break; } if(timeCnt.read() > timeout) { // time out timeCnt.stop(); timeCnt.reset(); ERROR("time out"); return -1; } } timeCnt.stop(); // stop timer timeCnt.reset(); // clear timer while(gprsSerial.readable()) { // display the other thing.. char c = gprsSerial.getc(); } return 0; } int GPRS::sendCmdAndWaitForResp(char *cmd, char *resp, int timeout) { sendCmd(cmd); return waitForResp(resp,timeout); } int GPRS::checkSIMStatus(void) { char gprsBuffer[30]; int count = 0; cleanBuffer(gprsBuffer,30); while(count < 3) { sendCmd("AT+CPIN?\r\n"); readBuffer(gprsBuffer,30); //DEBUG(gprsBuffer); if((NULL != strstr(gprsBuffer,"+CPIN: READY"))) { break; } count++; wait(1); } if(count == 3) { ERROR("Bad SIM Status"); return -1; } return 0; } int GPRS::checkSignalStrength(void) { char gprsBuffer[100]; int index,count = 0; cleanBuffer(gprsBuffer,100); while(count < 3) { sendCmd("AT+CSQ\r\n"); readBuffer(gprsBuffer,25); //DEBUG(gprsBuffer); if(sscanf(gprsBuffer, "AT+CSQ$$$$+CSQ: %d", &index)>0) { break; } ERROR("checking signal strenght error, try again..."); count++; wait(1); } if(count == 3) { ERROR("AT+CSQ"); return -1; } return index; } int GPRS::networkInit(void) { //for GPRS if(0 != sendCmdAndWaitForResp("AT+CGREG?\r\n","+CGREG: 0,1",DEFALUT_TIMEOUT)) { //Open GPRS ERROR("CGREG"); return -1; } wait(1); if(0 != sendCmdAndWaitForResp("AT+CGATT?\r\n","+CGATT: 1",DEFALUT_TIMEOUT)) { //Set GPRS ERROR("CGATT"); return -1; } return 0; } int GPRS::sendSMS(char *number, char *data) { char cmd[64]; if(0 != sendCmdAndWaitForResp("AT+CMGF=1\r\n", "OK", DEFALUT_TIMEOUT)) { // Set message mode to ASCII ERROR("CMGF"); return -1; } wait(0.5); // Set the phone number snprintf(cmd, sizeof(cmd),"AT+CMGS=\"%s\"\r\n", number); if(0 != sendCmdAndWaitForResp(cmd,">",DEFALUT_TIMEOUT)) { ERROR("CMGS"); return -1; } wait(1); gprsSerial.puts(data);// Send Message wait(0.5); gprsSerial.putc(0x1A);//end mark return 0; } int GPRS::readSMS(char *buffer, char *message, bool check) { int index,i = 0; char gprsBuffer[100]; char *p,*s; if(sscanf(buffer, "$$+CMTI: \"SM\",%d", &index)>0) { DEBUG("Opening message..."); gprsSerial.printf("AT+CMGR=%d\r\n", index); } else { ERROR("get Message"); } cleanBuffer(gprsBuffer,100); readBuffer(gprsBuffer,100); //pc.printf(gprsBuffer); //AT+CMGR=17$$$$+CMGR: "REC UNREAD","+8613925257382","","13/11/11,10:36:13+32"$$Hello$$$$OK$$ DEBUG(gprsBuffer); if(NULL == ( s = strstr(gprsBuffer,"+CMGR: \"REC UNREAD\""))) { ERROR("get CMGR error"); return -1; } //check phone number if(check) { char number[20]; snprintf(number,sizeof(number),"\"+86%s\"",phoneNumber); //for China p = s + 20; if(0 != (strncmp(number,p,14))) { ERROR("Phone Number error"); return -1; } } p = s + 64; while(*p != '$') { message[i++] = *(p++); } message[i] = '\0'; DEBUG(message); return 0; } int GPRS::deleteSMS(int index) { char cmd[64]; snprintf(cmd,sizeof(cmd),"AT+CMGD=%d\r\n",index); sendCmd(cmd); return 0; } int GPRS::callUp(char *number) { if(0 != sendCmdAndWaitForResp("AT+COLP=1\r\n","OK",5)) { ERROR("COLP"); return -1; } wait(1); gprsSerial.printf("\r\nATD%s;\r\n",NULL==number?phoneNumber:number); return 0; } int GPRS::answer(void) { gprsSerial.printf("ATA\r\n"); return 0; } int GPRS::loop(bool check) { char gprsBuffer[100]; int i = 0; cleanBuffer(gprsBuffer,100); while(1) { if(gprsSerial.readable()) { break; } wait(1); } timeCnt.start(); // start timer while(1) { while (gprsSerial.readable()) { char c = gprsSerial.getc(); if (c == '\r' || c == '\n') c = '$'; gprsBuffer[i] = c; i++; if(i > 100) { i = 0; break; } } if(timeCnt.read() > 5) { // time out timeCnt.stop(); timeCnt.reset(); break; } } if(NULL != strstr(gprsBuffer,"RING")) { if(0 != answer()) { ERROR("answer"); } } else if(NULL != strstr(gprsBuffer,"$$+CMTI: \"SM\"")) { //SMS: $$+CMTI: "SM",24$$ char message[64]; if(0 != readSMS(gprsBuffer, message, check)) { ERROR("readSMS"); } } return 0; } /****************************************GPRS TCP CONNECT************************************/ int GPRS::connectTCP(char *ip, char *port) { char cipstart[50]; //char ipaddr[20]; #if 0 wait(1); if(0 != sendCmdAndWaitForResp("AT+CSTT\r\n","OK",20)) { //Set GPRS ERROR("CSTT"); return -1; } wait(1); if(0 != sendCmdAndWaitForResp("AT+CIICR\r\n","OK",10)) { //Set APN ERROR("CIICR"); return -1; } wait(2); sendCmd("AT+CIFSR\r\n"); readBuffer(ipaddr,20); DEBUG("ipaddr="); DEBUG(ipaddr); wait(1); #endif #if 1 sprintf(cipstart, "AT+CIPSTART=\"TCP\",\"%s\",\"%s\"\r\n", ip, port); DEBUG(cipstart); if(0 != sendCmdAndWaitForResp(cipstart, "CONNECT OK", 10)) { // connect tcp ERROR("CIPSTART"); return -1; } #endif return 0; } int GPRS::sendTCPData(char *data) { char cmd[64]; int len = strlen(data); snprintf(cmd,sizeof(cmd),"AT+CIPSEND=%d\r\n",len); DEBUG(cmd); if(0 != sendCmdAndWaitForResp(cmd,">",DEFALUT_TIMEOUT)) { ERROR("CIPSEND"); return -1; } if(0 != sendCmdAndWaitForResp(data,"SEND OK",DEFALUT_TIMEOUT)) { ERROR("SendTCPData"); return -1; } return 0; } int GPRS::closeTCP(void) { sendCmd("AT+CIPCLOSE\r\n"); return 0; } int GPRS::shutTCP(void) { sendCmd("AT+CIPSHUT\r\n"); return 0; } /****************************************GPRS DEBUG******************************************/ void GPRS::serialDebug(PinName tx, PinName rx) { char buffer[64]; int count = 0; Serial pc(tx,rx); while(1) { if(gprsSerial.readable()) { while(gprsSerial.readable()) { char c = gprsSerial.getc(); buffer[count++] = c; if(count == 64) break; } pc.puts(buffer); for(int i = 0; i < count; i++) { buffer[i] = NULL; } count = 0; } if(pc.readable()) { gprsSerial.putc(pc.getc()); } } }