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 Components

Revision:
0:a5ae94727346
Child:
1:642a8dbe076c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gprs.cpp	Thu Nov 14 09:39:58 2013 +0000
@@ -0,0 +1,472 @@
+/*
+  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 ERROR(x)						pc.printf("ERROR:%s\r\n",x)
+#define DEBUG(x)						pc.printf("DEBUG:%s\r\n",x);
+
+#define DEFALUT_TIMEOUT   	5
+#define PHONE_NUMBER 				"13925257382"
+
+Serial 	pc(USBTX,USBRX);
+Serial gprsSerial(p9,p10); //software uart
+Timer timeCnt;
+
+int gprs::init(void)
+{
+	pc.baud(19200);
+	gprsSerial.baud(19200);
+	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;
+			pc.putc(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();
+			pc.putc(c);
+	}
+	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)
+{
+	#if 1
+	int len = strlen(resp);
+	int sum=0;
+	timeCnt.start();  
+	#if 0
+	while(1){
+		if(gprsSerial.readable()){
+			break;
+		}
+		wait(0.5);
+	}
+	#endif
+	while(1){
+		if(gprsSerial.readable()){
+			char c = gprsSerial.getc();
+			pc.putc(c);
+			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();
+			pc.putc(c);
+	}
+	#endif
+	return 0;
+} 
+
+
+
+int gprs::sendCmdAndWaitForResp(char *cmd, char *resp, int timeout)
+{
+	#if 0
+		char gprsBuffer[32];
+		cleanBuffer(gprsBuffer,32);
+    sendCmd(cmd);
+		readBuffer(gprsBuffer,4);
+		if(0 == strncmp(resp,gprsBuffer,4)){
+			return 0;
+		}else{
+			return -1;
+		}
+	#endif
+		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);
+	pc.printf(cmd);
+	if(0 != sendCmdAndWaitForResp(cmd,">",DEFALUT_TIMEOUT)){
+		ERROR("CMGS");
+		return -1;
+	}
+	wait(0.5);
+	gprsSerial.puts(data);// Send Message
+	wait(0.5);
+	gprsSerial.putc(0x1A);//end mark
+	
+	return 0;
+}
+
+int gprs::sendSMS()
+{
+	if(0 != sendCmdAndWaitForResp("AT+CMGF=1\r\n","OK",DEFALUT_TIMEOUT)){
+			ERROR("CMGF");
+			return -1;
+	}
+	wait(1);
+	if(0 != sendCmdAndWaitForResp("AT+CMGS=\"13925257382\"\r\n",">",DEFALUT_TIMEOUT)){
+			ERROR("CMGS");
+			return -1;
+	}
+	wait(1);
+	gprsSerial.puts("lawiet test\n");
+	wait(1);
+	gprsSerial.putc(0x1A);
+	
+	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\"",PHONE_NUMBER); //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?PHONE_NUMBER:number);
+	return 0;
+}
+
+int gprs::answerWithCheck(char *gprsBuffer, bool check)
+{
+	if(check){
+		if(NULL == strstr(gprsBuffer,PHONE_NUMBER)){
+			ERROR("phone number dismatch");
+			return -1;
+		}
+	}
+	
+	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;
+			pc.putc(c);
+			i++;
+			if(i > 100){
+				i = 0;	
+				break;
+			}
+		}
+		if(timeCnt.read() > DEFALUT_TIMEOUT){           // time out
+		
+			timeCnt.stop();
+			timeCnt.reset();
+			break;
+		}
+	}	
+	
+	pc.printf("\r\nDebug message is %s\r\n",gprsBuffer);
+	
+	if(NULL != strstr(gprsBuffer,"$$RING$$$$+CLIP:")){ //it is Ringing
+		if(0 != answerWithCheck(gprsBuffer, TRUE)){
+			ERROR("answer");
+		}
+	}else if(NULL != strstr(gprsBuffer,"$$+CMTI: \"SM\"")){  //SMS: $$+CMTI: "SM",24$$
+		char message[64];
+		if(0 != readSMS(gprsBuffer, message, TRUE)){
+			ERROR("readSMS");
+		}
+		pc.puts(message);
+	}
+	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(void)
+{	
+	char buffer[64];
+	int count = 0;
+	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());
+		}
+	}	
+}
+