/********************************************************************************* * Copyright: (C) guowenxue * All rights reserved. * * Filename: cp_atcmd.c * Description: This is file is used to send AT command to GPRS module. * * Version: 1.0.0(02/02/2012~) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "02/02/2012 10:28:44 AM" * ********************************************************************************/ #include "cp_atcmd.h" #include "cp_string.h" #include "cp_logger.h" #include "cp_time.h" #ifndef ATCMD_REPLY_LEN #define ATCMD_REPLY_LEN 512 #endif /* * Description: Send the AT command which modem will only reply "OK" or "ERROR", * such as AT,ATE0,AT+CNMP=2 etc. * * Return Value: 0: OK -X: ERROR */ int send_atcmd_check_ok(comport_t *comport, char *atcmd, unsigned long timeout) { int retval; retval = send_atcmd(comport, atcmd, "OK\r\n", "ERROR\r\n", timeout, NULL, 0); return 0==retval ? 0 : -2; } /* * Description: Send the AT command which will reply the value directly in a * single line, such as AT+CGMM, AT+CGSN * * Output Value: Buf: The AT command query value * Return Value: 0: OK -X: ERROR * */ int send_atcmd_check_value(comport_t *comport, char *atcmd, unsigned long timeout, char *buf, int buf_len) { int i = 0; int retval=0; char tmp[ATCMD_REPLY_LEN]; char *start; if(NULL==buf) { log_err("Function call arguments error!\n"); return -1; } memset(tmp, 0, sizeof(tmp)); retval = send_atcmd(comport, atcmd, "OK\r\n", "ERROR\r\n", timeout, tmp, sizeof(tmp)); if( 0 != retval) { return -2; /* AT command can not get reply */ } /* Parser the receive string to get the expect value*/ if(NULL != (start=strchr(tmp, '\n')) ) { start ++; /* Skip '\n' character */ while(*start!='\r' && ilongitude, loc->latitude, loc->date, loc->time); if(status) /* Get LOC failure */ { memset(loc->longitude, 0, sizeof(loc->longitude)); memset(loc->latitude, 0, sizeof(loc->latitude)); memset(loc->date, 0, sizeof(loc->date)); memset(loc->time, 0, sizeof(loc->time)); log_warn("AT+QGSMLOC=1 Check GPRS Location failure: %s\n", recv_buf); return -1; } log_nrml("GPRS location result=%d latitude,longitude: [%s,%s]\n", status, loc->latitude, loc->longitude); log_nrml("GPRS Date and time: %s,%s\n", loc->date, loc->time); return retval; } int atcmd_set_network_mode(comport_t *comport, int mode) { int retval; char atcmd[64]={0}; sprintf (atcmd, "AT+CNMP=%d\r", mode); if(0 != (retval=send_atcmd_check_ok(comport, atcmd, 3000)) ) { log_warn("AT+CNMP Set Network Mode as %d: [FAILED]\n", mode); return retval; } log_nrml("AT+CNMP=%d Set Network Mode: [OK]\n", mode); /* AT+CNAOP=?: 0->Automatic, 1->GSM,WCDMA, 2->WCDMA,GSM */ strncpy (atcmd, "AT+CNAOP=2\r", sizeof(atcmd)); if(0 != (retval=send_atcmd_check_ok(comport, atcmd, 3000)) ) { log_warn("AT+CNAOP=2 Set Acquisitions order preference to WCDMA,GSM [FAILED]\n"); return retval; } log_nrml("AT+CNAOP=2 Set Network Preference [OK]\n"); return 0; } int atcmd_check_gprs_name(comport_t *comport, char *name) { int retval; char recv_buf[ATCMD_REPLY_LEN]; if(name == NULL) { return -1; } retval = send_atcmd_check_value(comport, "AT+CGMM\r", 5000, recv_buf, sizeof(recv_buf)); if(retval) { log_warn("AT+CGMM Check GPRS Module Name: [FAILED]\n"); return retval; } strcpy(name, recv_buf); log_nrml("AT+CGMM Check GPRS Module Name: [%s]\n", name); return 0; } int atcmd_check_gprs_version(comport_t *comport, char *version) { int retval; char recv_buf[ATCMD_REPLY_LEN]; if(version == NULL) { return -1; } retval = send_atcmd_check_request(comport, "AT+CGMR\r", 5000, recv_buf, sizeof(recv_buf)); if(retval) { log_warn("AT+CGMR Check GPRS Module Version: [FAILED]\n"); return retval; } strcpy(version, recv_buf); log_nrml("AT+CGMR Check GPRS Module Version: [%s]\n", version); return 0; } int atcmd_check_gprs_iemi(comport_t *comport, char *iemi) { int retval; char recv_buf[ATCMD_REPLY_LEN]; if(iemi == NULL) { return -1; } retval = send_atcmd_check_value(comport, "AT+CGSN\r", 5000, recv_buf, sizeof(recv_buf)); if(retval) { log_warn("AT+CGSN Check GPRS Module IEMI: [FAILED]\n"); return retval; } strcpy(iemi, recv_buf); log_nrml("AT+CGSN Check GPRS Module IEMI: [%s]\n", iemi); return 0; } int atcmd_check_gprs_network(comport_t *comport, int *network) { int retval; char recv_buf[ATCMD_REPLY_LEN]; if(network == NULL) { return -1; } retval = send_atcmd_check_request(comport, "AT+CNSMOD?\r", 5000, recv_buf, sizeof(recv_buf)); if(retval) { log_warn("AT+CNSMOD Check Network Mode: [FAILED]\n"); return retval; } split_string_to_value(recv_buf, "%d,%d", NULL, network); log_nrml("AT+CNSMOD? Check Network Mode: [%d]\n", *network); return 0; } int atcmd_set_apn(comport_t *comport, char *apn) { char atcmd[64]={0}; int retval; sprintf (atcmd, "AT+CGDCONT=1,\"IP\",\"%s\"\r", apn); if(0 != (retval=send_atcmd_check_ok(comport, atcmd, 2000)) ) { log_err("AT+CGDCONT Set APN as \"%s\" [FAILED]\n", apn); return retval; } log_nrml("AT+CGDCONT Set APN as \"%s\" [OK]\n"); return retval; } unsigned char at_match (char *p_pcStr, char *p_pcMatch) { char acBuf [256], *pcStart = NULL, *pcTab = NULL; pcStart = p_pcMatch; while (0 != pcStart) { memset (acBuf, 0x00, sizeof (acBuf)); pcTab = strchr (pcStart, 9); // Find for TAB if (0 != pcTab) { if (pcTab != pcStart) { strncpy (acBuf, pcStart, pcTab - pcStart); } pcStart = (0 != *(++pcTab)) ? pcTab : 0; } else { strcpy (acBuf, pcStart); pcStart = NULL; } if (0 != acBuf [0] && 0 != strstr (p_pcStr, acBuf)) { return 0x00; } } return 0x01; } /*========================================================================================================= * Parameter Description: * comport_t *comport: The GPRS module data port(/dev/ttyS2); * char *atCmd: The AT command which will be sent to GPRS module * char *expect: The EXPECT reply string by GPRS module for the AT command, such as "OK" * char *error: The ERROR reply string by GPRS module for the AT command, such as "ERROR" * unsigned long timeout: Read from data port timeout value * char reply: The AT command reply output buffer * int reply_len: The AT command reply output buffer length * * Return Value: * int retval: 0->command send OK and "expect" string mached. !0->failure * char *content: The AT command reply string by modem. * *=========================================================================================================*/ int send_atcmd(comport_t *comport, char *atCmd, char *expect, char *error, unsigned long timeout, char *reply, int reply_len) { int retval = -1; unsigned long delay = 200; unsigned long gap = 300; unsigned long ulStartTime; int iCmdLen = 0, iRecvLen = 0, iRecvSize = 0, iSize = 0; char acRecv[1024]; char *pcRecvPtr = NULL; if(comport->is_connted != 0x01) /* Comport not opened */ { log_dbg("Comport not opened.\n"); return -1; } #if 0 /*========================================= *= Pause a while before send AT command = *=========================================*/ if(0 != delay) { ulStartTime = time_now(); while (time_elapsed(ulStartTime) < delay) { micro_second_sleep(1); } } #endif /*==================== *= Throw Rubbish = *====================*/ ulStartTime = time_now(); memset(&acRecv, 0, sizeof(acRecv)); while (time_elapsed(ulStartTime) < delay) { iSize = comport_recv(comport, acRecv, 1, 50); if(iSize <= 0) { break; } micro_second_sleep(1); } /*==================== *= Send AT command = *====================*/ iCmdLen = strlen(atCmd); retval = comport_send (comport, atCmd, iCmdLen); if (0 != retval) { retval = 0x02; goto CleanUp; } /*=================================================== *= Pause a while before read command response. *===================================================*/ if(0 != gap) { ulStartTime = time_now(); while (time_elapsed(ulStartTime) < gap) { micro_second_sleep(1); } } memset (acRecv, 0, sizeof (acRecv)); pcRecvPtr = acRecv; iRecvLen = 0; iRecvSize = sizeof (acRecv); retval = -1; ulStartTime = time_now(); while (time_elapsed(ulStartTime) < timeout) { if ( iRecvLen < (iRecvSize-1) ) { iSize = comport_recv (comport, pcRecvPtr, 1, 50); if (iSize >0) { iRecvLen += iSize; pcRecvPtr += iSize; acRecv [iRecvSize-1] = 0; /*======================================== * Match the received with expect String = *========================================*/ if(NULL != expect) { if (0x00 == at_match(acRecv, expect)) { retval = 0; goto CleanUp; } } /*======================================== * Match the received with error String = *========================================*/ if(NULL != error) { if (0x00 == at_match(acRecv, error)) { retval = -3; goto CleanUp; } } } /*End of (iSize > 0) */ } /* End of (iRecvLen < (iRecvSize-1)) */ micro_second_sleep(1); } /* End of time_elapsed(ulStartTime) < timeout */ if(NULL==expect) retval = 0x00; else retval = -4; CleanUp: //printf("acRecv:\n %s\n", acRecv); if( NULL != reply) { strncpy(reply, acRecv, reply_len); } #if 1 /* Log the command result to log system */ { char log[512] = {0}; snprintf(log, 512, "Send AT command: \"%s\" get reply \"%s\"", atCmd, acRecv); int i = 0; for (i=0; i<512; i++) { if('\r'==log[i] || '\n'==log[i] || '\t'==log[i]) { log[i]=' '; } else if (0 == log[i]) { break; } } log_info("%s\n", log); } #endif return retval; }