rhr
Diff: gprs.cpp
- Revision:
- 0:a5ae94727346
- Child:
- 1:642a8dbe076c
diff -r 000000000000 -r a5ae94727346 gprs.cpp --- /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()); + } + } +} +