
aaaa
Dependencies: SeeedStudioTFTv2 TFT_fonts mbed
Fork of Seeed_TFT_Touch_Shield by
Diff: Modem.cpp
- Revision:
- 5:c1af1f8fa026
- Child:
- 7:5cf5aeae1954
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modem.cpp Sat Oct 25 20:21:17 2014 +0000 @@ -0,0 +1,401 @@ +#include "Modem.h" + +Modem::Modem(PinName tx, PinName rx, int baudRate,char *default_number):serial_modem(tx,rx) +{ + this->default_number = default_number; +// serial_modem.baud(baudRate); + buffer_p = 0; + read_trail = false; + read_buffer[BUF_SIZE]='\0'; +} + + +/*********************************************** +Utility/debug Functions +***********************************************/ +void cleanBuffer(char *buffer, int count) +{ + for(int i=0; i < count; i++) { + buffer[i] = '\0'; + } +} + +int Modem::loopHandle(void) +{ + char gprsBuffer[100]; + int i; + char *s = NULL; + while(serial_modem.readable()) { + char c = serial_modem.getc(); + } + wait(0.5); +START: + cleanBuffer(gprsBuffer,100); + i = 0; + while(1) { + if(serial_modem.readable()) { + timeCnt.start(); // start timer + while(1) { + while (serial_modem.readable()) { + char c = serial_modem.getc(); + if (c == '\r' || c == '\n') c = '$'; + gprsBuffer[i] = c; + i++; + if(i > 100) { + i = 0; + break; + } + } + if(timeCnt.read() > 2) { // time out + timeCnt.stop(); + timeCnt.reset(); + break; + } + } + break; + } + } + if(NULL != strstr(gprsBuffer,"RING")) { + return MESSAGE_RING; + } else if(NULL != (s = strstr(gprsBuffer,"+CMT"))) { //SMS: $$+CMTI: "SM",24$$ + if(NULL != (s = strstr(gprsBuffer,"+32"))) { + s += 6; + int i = 0; + cleanBuffer(messageBuffer,SMS_MAX_LENGTH); + while((*s != '$')&&(i < SMS_MAX_LENGTH-1)) { + messageBuffer[i++] = *(s++); + } + messageBuffer[i] = '\0'; + return MESSAGE_SMS; + } else { + goto START; + } + } else { + goto START; + } +} + + +void Modem::clean_buffer() +{ + int i = 0; + for(i = 0 ; i < BUF_SIZE ; i ++) { + read_buffer[i] = '\0'; + } +} + +void Modem::reset_buffer() +{ + buffer_p = 0; + clean_buffer(); +} + +void Modem::debug_cmd_buffer() +{ +// TFT.printf("[DEBUG] "); + int i = 0 ; + for(i = 0 ; i < BUF_SIZE ; i ++) { +// TFT.putc(read_buffer[i]); + } +// TFT.printf("\r\n"); +} + +int Modem::find_pattern_end(char *pattern, char *buffer, int size) +{ + int i = 0; + int final_state = strlen(pattern); + int state = 0; + for (i = 0; i < size; i++) { + char current = buffer[i]; + if (pattern[state] == current) { + state += 1; + continue; + } + if (state == final_state) { + return i; + } + state = 0; + } + + return -1; +} + +/******************************************************* +Control/Init/Setup Functions for SeedsStudto GPRS modem +********************************************************/ + +int Modem::init() +{ + int i = 0; + int ret = 0 ; + for(i = 0 ; i < 10 ; i++) { + ret = check_AT(); + wait(1); + } + + if(ret) { + ret = check_PIN(); + } + if(ret) { + ret = setup_SMS(); + } + return ret; +}; + +int Modem::check_AT() +{ + int ret = sendCmdWaitResp("AT\r\n","OK", 5); + if(ret == 0) { + return -1 ; + } + + return 1; +} + +int Modem::check_PIN() +{ + int ret = sendCmdWaitResp("AT+CPIN?\r\n","+CPIN: READY", 5); + + //debug code + debug_cmd_buffer(); + + if(ret == 0) { + return -1 ; + } + + return 1; +} + +int Modem::setup_SMS() +{ +// sendCmdWaitResp("AT+CPMS=\"SM\",\"BM\"\r\n", "OK", 5); +// int ret = sendCmdWaitResp("AT+CNMI=2,2\r\n", "OK", 5); + int ret = 1 ; + if(ret) { + ret = sendCmdWaitResp("AT+CMGF=1\r\n","OK", 5); + } + //debug code + debug_cmd_buffer(); + if(ret == 0) { + return -1 ; + } + + return 1; +} + +/*********************************************** +Start of Primary Interface Functions +***********************************************/ + +int Modem::call_phone(char* number) +{ + //enable optional caller presentation + sendCmdWaitResp("AT+COLP=1\r\n","OK", 5); + //send actual call + wait(1); + debug_cmd_buffer(); + int ret = 0 ; + char temp[30]; + + if(number == NULL) { + snprintf(temp, 30, "\r\nATD%s;\r\n",default_number); + } else { + snprintf(temp, 30, "\r\nATD%s;\r\n",number); + } + ret = sendCmdWaitResp(temp,"OK", 5); +// ret = sendCmdWaitResp("\r\nATD+13174806512;\r\n","OK", 5); + //debug code + debug_cmd_buffer(); + + if(ret == 0) { + return -1 ; + } + return ret ; +}; + +void Modem::hangup_phone() +{ + int ret = sendCmdWaitResp("ATH\r\n","OK", 5); + wait(1); +} + +void Modem::recv_phone() +{ + int ret = sendCmdWaitResp("ATA\r\n","OK", 5); +} + +void Modem::get_clck(char* msg, int size) +{ + int ret = sendCmdWaitResp("AT+CCLK?\r\n","OK", 5); + //if returned OK + debug_cmd_buffer(); + if(ret == 1) { + char *pattern = "+CCLK:"; + int index = find_pattern_end(pattern, read_buffer, BUF_SIZE); + int state = 0; + int curr = index + 2; + int end = curr + 17 ; + while(curr < end) { + msg[state]=read_buffer[curr]; + state++; + curr++; + } + msg[state] = '\0'; + } +} + +int Modem::send_sms(char* number, char* msg) +{ + char temp[60]; + while(read_device_ready()) { + char c = read_device(); + } + + if(number == NULL) { + snprintf(temp, 60, "AT+CMGS=\"%s\"\r\n",default_number); + } else { + snprintf(temp, 60, "AT+CMGS=\"%s\"\r\n",number); + } + + sendCmdWaitResp(temp, ">", 5); + debug_cmd_buffer(); + wait(3); + //now write the actual message + write_device_str(msg); + //final ctrl+z character in ascii + write_device((char)0x1a); + + return 1 ; +} + +void Modem::recv_sms(char* msg, int msg_size ,int index) +{ + char temp[30]; + snprintf(temp, 30, "AT+CMGR=%d\r\n",index); + read_trail = true; + int ret = sendCmdWaitResp("AT+CMGL=\"ALL\"\r\n","OK", 30); + read_trail = false; + wait(3); + + debug_cmd_buffer(); + //if returned OK +// if(ret == 1) { + char *pattern = "+CMT:"; + int in = find_pattern_end(pattern, read_buffer, BUF_SIZE); + int state = 0; + int curr = in ; + int end = BUF_SIZE ; + while(curr < end) { + msg[state]=read_buffer[curr]; + state++; + curr++; + } + msg[state] = '\0'; + +// } + wait(1); +// ret = sendCmdWaitResp("AT+CMGD=1,4\r\n","OK", 5); +} + +/*********************************************** +Start of Low Level Functions +***********************************************/ + +bool Modem::read_device_ready() +{ + return serial_modem.readable(); +} + +void Modem::cls() +{ +// TFT.locate(0,0); +// TFT.cls(); + +} + +char Modem::read_device() +{ + return serial_modem.getc(); +} + +int Modem::write_device(char c) +{ + int ret = 0; + while(!serial_modem.writeable()) { + //wait until writeable + } + ret = serial_modem.putc(c); + if(ret != -1) + return 0; + return ret; +}; + + +int Modem::write_device_str(char* str) +{ + int ret = 0; + while(!serial_modem.writeable()) { + //wait until writeable + } + + ret = serial_modem.puts(str); + if(ret != -1) + return 0; + + return ret; +} + +int Modem::sendCmdWaitResp(char* cmd, char* response, int timeout) +{ + //reset buffer pointer + reset_buffer(); + //send command and wait until respose + write_device_str(cmd); + + //wait + Timer my_timer; + my_timer.start(); + float start = my_timer.read(); + float elapsed = 0 ; + + int expected_resp_len = strlen(response); + int curr_len = 0 ; + while(1) { + //ok start waiting game ;) + if(read_device_ready()) { + char rec_char = read_device(); +// pc.putc(rec_char); + curr_len++; + if(rec_char != response[curr_len - 1]) { + //we haven't recieved expected response + //reset + curr_len = 0 ; + } + //update characters read so far in to the buffer (circular) + read_buffer[buffer_p] = rec_char; + buffer_p = (buffer_p + 1) % BUF_SIZE; + + if(!read_trail && curr_len == expected_resp_len) { + //at this point response is matched and we have waited for the length of response + return 1 ; + } + } + + elapsed = my_timer.read() - start; + if(elapsed > timeout) { + //we have waited long enough to succeed, but failed + break; + } + } + + + while(serial_modem.readable()) { // display the other thing.. + char c = serial_modem.getc(); + //if we enabled reading trailing characters -> read them onto buffer + if(read_trail) { + read_buffer[buffer_p] = c; + buffer_p = (buffer_p + 1) % BUF_SIZE; + } + } + return 0 ; +} \ No newline at end of file