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
Diff: GPRS/GPRS.cpp
- 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; -}