a library to use GPRS like ethernet or wifi, which makes it possible to connect to the internet with your GPRS module

Dependencies:   BufferedSerial

Dependents:   ThinkSpeak_Test roam_v1 roam_v2 finalv3

Fork of GPRSInterface by wei zou

Revision:
13:379ce1d51b88
Parent:
11:0184e407128e
Child:
14:3c6454f033ac
diff -r 47488369a980 -r 379ce1d51b88 GPRS/GPRS.cpp
--- a/GPRS/GPRS.cpp	Tue Mar 10 03:11:38 2015 +0000
+++ b/GPRS/GPRS.cpp	Fri Apr 03 15:44:04 2015 +0800
@@ -21,73 +21,67 @@
 */
 
 #include "mbed.h"
-#include "GPRS.h"
+#include "GPRS.h"
+
+#define DEBUG
+
+#ifdef DEBUG
+#include "USBSerial.h"
+extern USBSerial pc;
+#define LOG(args...)        pc.printf(args)
+#else
+#define LOG(args...)
+#endif
+
 
 GPRS* GPRS::inst;
 
-GPRS::GPRS(PinName tx, PinName rx, int baudRate, const char* apn, const char* userName, const char* passWord) : Modem(tx,rx,baudRate)
+GPRS::GPRS(PinName tx, PinName rx, const char* apn, const char* userName, const char* passWord) : Modem(tx,rx)
 {
     inst = this;
     _apn = apn;
     _userName = userName;
     _passWord = passWord;
-    socketID = -1;
-}
-
-bool GPRS::preInit()
-{
-    for(int i = 0; i < 2; i++) {
-        sendCmd("AT\r\n");
-        wait(1);
-    }
-    return checkSIMStatus();
+    socketID = -1;
+    
+    connected = false;
+    recv_bytes = 0;
 }
 
-bool GPRS::checkSIMStatus(void)
-{
-    char gprsBuffer[32];
-    int count = 0;
-    cleanBuffer(gprsBuffer,32);
-    while(count < 3) {
-        sendCmd("AT+CPIN?\r\n");
-        readBuffer(gprsBuffer,32,DEFAULT_TIMEOUT);
-        if((NULL != strstr(gprsBuffer,"+CPIN: READY"))) {
-            break;
-        }
-        count++;
-        wait(1);
-    }
-    if(count == 3) {
-        return false;
-    }
-    return true;
-}
+
 
 bool GPRS::join()
 {
-    char cmd[64];
-    char ipAddr[32];
+    char ip_addr_buf[32];
+    
     //Select multiple connection
-    sendCmdAndWaitForResp("AT+CIPMUX=1\r\n","OK",DEFAULT_TIMEOUT,CMD);
+    command("AT+CIPMUX=1\r\n");
+    
+    // Set APN
+    command("AT+CSTT=\"%s\",\"%s\",\"%s\"\r\n",_apn,_userName,_passWord);
 
-    //set APN
-    snprintf(cmd,sizeof(cmd),"AT+CSTT=\"%s\",\"%s\",\"%s\"\r\n",_apn,_userName,_passWord);
-    sendCmdAndWaitForResp(cmd, "OK", DEFAULT_TIMEOUT,CMD);
-
-    //Brings up wireless connection
-    sendCmdAndWaitForResp("AT+CIICR\r\n","OK",DEFAULT_TIMEOUT,CMD);
+    // Brings up wireless connection
+    command("AT+CIICR\r\n");
 
-    //Get local IP address
-    sendCmd("AT+CIFSR\r\n");
-    readBuffer(ipAddr,32,2);
+    // Get local IP address
+    printf("AT+CIFSR\r\n");
+    
+    readline(ip_addr_buf, sizeof(ip_addr_buf));   // read echo
+
+    if (readline(ip_addr_buf, sizeof(ip_addr_buf)) <= 0) {
+        LOG("failed to join network\r\n");
+        return false;
+    }
+    
+    int a, b, c, d;
+    if (sscanf(ip_addr_buf, "%d.%d.%d.%d", &a, &b, &c, &d) != 4) {
+        LOG("failed to get ip, r(%s)\r\n", ip_addr_buf);
+        return false;
+    }
+    
+    _ip = (a << 24) + (b << 16) + (c << 8) + d;
 
-    if(NULL != strstr(ipAddr,"AT+CIFSR")) {
-        _ip = str_to_ip(ipAddr+12);
-        if(_ip != 0) {
-            return true;
-        }
-    }
-    return false;
+    return true;
 }
 
 bool GPRS::setProtocol(int socket, Protocol p)
@@ -99,65 +93,59 @@
     return true;
 }
 
-bool GPRS::connect(int socket, Protocol ptl,const char * host, int port, int timeout)
-{
-    char cmd[64];
-    char resp[96];
+bool GPRS::connect(int socket, Protocol ptl, const char * host, int port, int timeout)
+{
+    const char *protocol;
     if (socket < 0 || socket > MAX_SOCK_NUM-1) {
         return false;
     }
     if(ptl == TCP) {
-        sprintf(cmd, "AT+CIPSTART=%d,\"TCP\",\"%s\",%d\r\n",socket, host, port);
+        protocol = "TCP";
     } else if(ptl == UDP) {
-        sprintf(cmd, "AT+CIPSTART=%d,\"UDP\",\"%s\",%d\r\n",socket, host, port);
+        protocol = "UDP";
     } else {
         return false;
+    }
+    
+    command("AT+CIPSTART=%d,\"%s\",\"%s\",%d\r\n", socket, protocol, host, port);
+    
+    char response[64] = {0,};
+    if (readline(response, sizeof(response)) < 0) {
+        LOG("wait for connection - timeout\r\n");
+        return false;
+    }
+    
+    if (strstr(response, "CONNECT OK") || strstr(response, "ALREADY CONNECT")) {
+        connected = true;
+        return true;
+    } else {
+        LOG("failed to connect (r:%s)\r\n", response);
+        return false;
     }
-    sendCmd(cmd);
-    readBuffer(resp,96,2*DEFAULT_TIMEOUT);
-    if(NULL != strstr(resp,"CONNECT")) { //ALREADY CONNECT or CONNECT OK
-        return true;
-    }
-    return false;//ERROR
 }
 
 bool GPRS::gethostbyname(const char* host, uint32_t* ip)
-{
-    uint32_t addr = str_to_ip(host);
-    char buf[17];
-    snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, addr&0xff);
-    if (strcmp(buf, host) == 0) {
-        *ip = addr;
-        return true;
-    }
+{
+    int a, b, c, d;
+    if (sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) {
+        *ip = (a << 24) + (b << 16) + (c << 8) + d;
+        
+        return true;
+    }
+    
     return false;
 }
 
 bool GPRS::disconnect()
 {
-    sendCmd("AT+CIPSHUT\r\n");
+    puts("AT+CIPSHUT\r\n");
+    connected = false;
     return true;
 }
 
 bool GPRS::is_connected(int socket)
 {
-    char cmd[16];
-    char resp[96];
-    snprintf(cmd,16,"AT+CIPSTATUS=%d\r\n",socket);
-    for (int i = 0; i < 3; i++) {
-        sendCmd(cmd);
-        readBuffer(resp,sizeof(resp),DEFAULT_TIMEOUT);
-        if(NULL != strstr(resp,"CONN")) {
-            //+CIPSTATUS: 1,0,"TCP","216.52.233.120","80","CONNECTED"
-            return true;
-        } else if (NULL != strstr(resp,"CLOSE")) {
-            //+CIPSTATUS: 1,0,"TCP","216.52.233.120","80","CLOSED"
-            //+CIPSTATUS: 0,,"","","","INITIAL"
-            return false;
-        }
-    }
-    
-    return false;
+    return connected;
 }
 
 void GPRS::reset()
@@ -167,121 +155,117 @@
 
 bool GPRS::close(int socket)
 {
-    char cmd[16];
-    char resp[16];
-
-    if (socket < 0 || socket > MAX_SOCK_NUM-1) {
+    if (socket < 0 || socket > (MAX_SOCK_NUM - 1)) {
         return false;
-    }
-    // if not connected, return
-    if (is_connected(socket) == false) {
-        return true;
-    }
-    snprintf(cmd, sizeof(cmd),"AT+CIPCLOSE=%d\r\n",socket);
-    snprintf(resp,sizeof(resp),"%d, CLOSE OK",socket);
-    if(0 != sendCmdAndWaitForResp(cmd, resp, DEFAULT_TIMEOUT,CMD)) {
-        return false;
-    }
+    }
+    
+    printf("AT+CIPCLOSE=%d\r\n", socket);
+    connected = false;
     return true;
-}
-
-bool GPRS::readable(void)
-{
-    return readable();
-}
-
-int GPRS::wait_readable(int socket, int wait_time)
-{
-    if (socket < 0 || socket > MAX_SOCK_NUM-1) {
-        return -1;
-    }
-    char resp[16];
-    snprintf(resp,sizeof(resp),"\r\n\r\n+RECEIVE,%d",socket);//"+RECEIVE:<socketID>,<length>"
-    int len = strlen(resp);
-
-    if(false == respCmp(resp,len,wait_time)) {
-        return -1;
-    }
-    char c = readByte();//','
-    char dataLen[4];
-    int i = 0;
-    c = readByte();
-    while((c >= '0') && (c <= '9')) {
-        dataLen[i++] = c;
-        c = readByte();
-    }
-    c = readByte();//'\n'
-    len = atoi(dataLen);
-    return len;
-}
-
-int GPRS::wait_writeable(int socket, int req_size)
-{
-    if (socket < 0 || socket > MAX_SOCK_NUM-1) {
-        return -1;
-    }
-    return req_size>256?256:req_size+1;
+}
+
+int GPRS::sock_send(int socket, const char * data, int len)
+{
+    if (socket < 0 || socket > MAX_SOCK_NUM-1 || len <= 0) {
+        return -1;
+    }
+
+    char response[64];
+
+    flush();
+    printf("AT+CIPSEND=%d,%d\r\n", socket, len);
+    readline(response, sizeof(response));       // echo, ignore
+    if (match("> ")) {
+        connected = false;
+        return -1;
+    }
+    
+    write(data, len);
+    
+    // read echo data
+    for (int i = 0; i < len; i++) {
+        while (!readable()) {
+        }
+        char ch = getc();
+    }
+    
+    readline(response, sizeof(response));
+    
+    // data received
+    int sock;
+    int bytes = 0;
+    if (sscanf(response, "+RECEIVE,%d,%d:", &sock, &bytes) == 2) {
+        while (bytes > 0) {
+            if (readable()) {
+                recv_buf[recv_bytes] = getc();
+                recv_bytes++;
+                bytes--;
+            }
+        }
+        
+        readline(response, sizeof(response));
+    }
+    
+    if (strstr(response, "SEND OK")) {      // 0, SEND OK
+        return len;
+    }
+    
+    if (strstr(response, "CLOSED")) {
+        connected = false;
+    }
+    return -1;
+}
+
+int GPRS::sock_recv(int socket, char* buf, int len)
+{
+    if (recv_bytes > 0) {
+        if (len >= recv_bytes) {
+            len = recv_bytes;
+            memcpy(buf, recv_buf, recv_bytes);
+            recv_bytes = 0;
+        } else {
+            memcpy(buf, recv_buf, len);
+            recv_bytes -= len;
+            memcpy(recv_buf, recv_buf + len, recv_bytes);
+        }
+        
+        return len;
+    }
+    
+    char response[32];
+    if (readline(response, sizeof(response)) <= 0) {
+        return -1;
+    }
+    
+    if (strstr(response, "CLOSED")) {
+        LOG("socket is closed, r(%s)\r\n", response);
+        connected = false;
+        
+        return -1;
+    }
+    
+    int sock;
+    int bytes = 0;
+    if (sscanf(response, "+RECEIVE,%d,%d:", &sock, &bytes) != 2) {
+        LOG("socket is closed, r(%s)\r\n", response);
+        
+        connected = false;
+        return -1;
+    }
+    
+    int bytes_read = 0;
+    while (bytes_read < bytes) {
+        if (readable()) {
+            buf[bytes_read] = getc();
+            bytes_read++;
+        }
+    }
+    
+    return bytes;  
+}
+
+int GPRS::new_socket()
+{
+    socketID = 0; //we only support one socket.
+    return socketID; 
 }
-
-int GPRS::send(int socket, const char * data, int len)
-{
-    if (socket < 0 || socket > MAX_SOCK_NUM-1) {
-        return -1;
-    }
-
-    char cmd[32];
-    char resp[16];
-    wait(1);
-    if(len > 0){
-        snprintf(cmd,sizeof(cmd),"AT+CIPSEND=%d,%d\r\n",socket,len);
-        if(0 != sendCmdAndWaitForResp(cmd,">",DEFAULT_TIMEOUT,CMD)) {
-            return false;
-        }
-        sendData(data, len);
-        snprintf(resp,sizeof(resp),"%d, SEND OK",socket);
-        if(0 != waitForResp(resp,DEFAULT_TIMEOUT,DATA)) {
-            return -1;
-        }
-    }
-    return len;
-}
-
-int GPRS::recv(int socket, char* buf, int len)
-{
-    if (socket < 0 || socket > MAX_SOCK_NUM-1) {
-        return -1;
-    }
-    cleanBuffer(buf,len);
-    readBuffer(buf,len,DEFAULT_TIMEOUT/2);
-    return len;
-    //return strlen(buf);
-}
-
-int GPRS::new_socket()
-{
-    socketID = 0; //we only support one socket.
-    return socketID; 
-}
-
-uint16_t GPRS::new_port()
-{
-    uint16_t port = rand();
-    port |= 49152;
-    return port;
-}
-
-uint32_t GPRS::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;
-}