blob: 2d2b366d2449978a75df19fa2e4dd51ebe811b12 [file] [log] [blame]
/***************************************************************/
//
//À©Õ¹atÃüÁ¾ß¼¯£¬ÓÃÓÚÉú³ÉºÍ½âÎöÀ©Õ¹atÃüÁî
//¶¯×÷ÇëÇó£ºat+xx=yy,zz\r\n
//²éѯÇëÇó: at+xx? \r\n
//Ö÷¶¯Éϱ¨: \r\n+xx:yy,zz\r\n
//½á¹ûÂ룺\r\nok:2\r\n
// \r\nerror:ww\r\n
//±¸×¢£ºÆäÖУ¬xxΪATÃüÁîÃû£»yyΪ²ÎÊý1µÄÖµ£¬zzΪ²ÎÊý2µÄÖµ£»wwΪ¾ßÌåµÄ´íÎóÂëÖµ£¬Èç¹ûûÓдíÎóÂ룬ĬÈÏΪ0.
//
/***************************************************************/
#include "at_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zxic_errno.h"
#include "at_msg.h"
#include "softap_log.h"
#include <ctype.h>
#include <sys/time.h>
#include <termios.h>
#define DIFF_VALUE ('a'-'A')
#define AT_PARAM_MAX_NUM (50)
/***************************************************************/
//
//Éú³Éat¶¯×÷ÇëÇóÃüÁî,Ò»°ãÔÚapp_clt_ops_tÖе÷Ó㬸ù¾ÝÏûÏ¢ÄÚÈÝ£¬Éú³É×îÖÕµÄatÇëÇóÃüÁî
//Éú³ÉatÇëÇóÃüÁîʱ£¬±ØÐëͨ¹ýmallocÉêÇëʹÓõÄÄڴ棬²¢·µ»Ø¸ÃÖ¸Õë¸øÍâ²ãµ÷Óú¯ÊýʹÓã¬
//×îÖÕÓÉÍâ²ãµ÷Óú¯ÊýÊͷŸÃÄÚ´æ
//input: cmd "xx"
// param "yy,zz"
//output: at+xx=yy,zz\r\n
/***************************************************************/
char* at_act_build(char* cmd, char* param)
{
char * at_str;
if(param)
{
at_str = malloc(32 + strlen(cmd) + strlen(param));
}
else
{
at_str = malloc(32 + strlen(cmd));
}
assert(at_str);
//if(!at_str)
//return NULL;
if(param)
sprintf(at_str,"at+%s=%s\r\n",cmd,param);
else
sprintf(at_str,"at+%s\r\n",cmd);
return at_str;
}
/***************************************************************/
//Éú³Éat²éѯÇëÇóÃüÁһ°ãÔÚapp_clt_ops_tÖе÷Ó㬸ù¾ÝÏûÏ¢ÄÚÈÝ£¬Éú³É×îÖÕµÄatÇëÇóÃüÁî
//Éú³Éat²éѯÃüÁîʱ£¬Í¨¹ýmallocÉêÇëʹÓõÄÄڴ棬²¢·µ»Ø¸ÃÖ¸Õë¸øÍâ²ãµ÷Óú¯ÊýʹÓã¬
//×îÖÕÓÉÍâ²ãµ÷Óú¯ÊýÊͷŸÃÄÚ´æ
//input: cmd "xx"
//output: at+xx? \r\n
/***************************************************************/
char* at_query_build(char* cmd)
{
char * at_str;
at_str = malloc(32 + strlen(cmd)); //ÓÉat_ctl¸ºÔðÊÍ·Å
assert(at_str);
//if(!at_str)
//return NULL;
sprintf(at_str,"at+%s?\r\n",cmd);
return at_str;
}
/***************************************************************/
//Éú³Éat²éѯÇëÇóÃüÁîµÄÏìÓ¦ÃüÁµ±ÓÐÖмä½á¹ûÉϱ¨Ê±£¬ÔÚser_ops_t2µÄrsp_actµ÷Óã¬
//¸Ãº¯ÊýÖн«ÖмäÉϱ¨½á¹ûºÍokatÃüÁî×é×°ÔÚÒ»Æð£¬Í¨¹ýmallocÉêÇëʹÓõÄÄڴ棬²¢·µ»Ø
//¸ÃÖ¸Õë¸øÍâ²ãµ÷Óú¯ÊýʹÓã¬×îÖÕÓÉÍâ²ãµ÷Óú¯ÊýÊͷŸÃÄÚ´æ
//input: cmd "xx"
// param "yy,zz"
//output: \r\n+xx:yy,zz\r\n
/***************************************************************/
char* at_query_result_build(char* cmd, char* param)
{
char * at_str;
if(param)
{
at_str = malloc(32 + strlen(cmd) + strlen(param));
}
else
{
at_str = malloc(32 + strlen(cmd));
}
assert(at_str);
//if(!at_str)
//return NULL;
if(!param)
sprintf(at_str,"\r\n+%s\r\n\r\nOK\r\n",cmd);
else
sprintf(at_str,"\r\n+%s: %s\r\n\r\nOK\r\n",cmd,param);
return at_str;
}
/***************************************************************/
//Éú³ÉatµÄokÏìÓ¦ÃüÁ¸ù¾Ý²ÎÊýÐÅÏ¢Éú³É²»Í¬µÄokÏìÓ¦ÃüÁî
//ͨ¹ýmallocÉêÇëʹÓõÄÄڴ棬²¢·µ»Ø¸ÃÖ¸Õë¸øÍâ²ãµ÷Óú¯ÊýʹÓã¬×îÖÕÓÉÍâ²ãµ÷Óú¯ÊýÊͷŸÃÄÚ´æ
//input: param "xx"
//output: \r\nok:xx
/***************************************************************/
char* at_ok_build()
{
char * at_str;
at_str = malloc(32); //ÓÉat_ctl¸ºÔðÊÍ·Å
assert(at_str);
sprintf(at_str,"\r\nOK\r\n");
return at_str;
}
/***************************************************************/
//Éú³ÉatµÄerrÏìÓ¦ÃüÁ¸ù¾Ý²ÎÊýÐÅÏ¢Éú³É²»Í¬µÄerrÏìÓ¦ÃüÁî
//ͨ¹ýmallocÉêÇëʹÓõÄÄڴ棬²¢·µ»Ø¸ÃÖ¸Õë¸øÍâ²ãµ÷Óú¯ÊýʹÓã¬×îÖÕÓÉÍâ²ãµ÷Óú¯ÊýÊͷŸÃÄÚ´æ
//input: param xx
//output: \r\nerr:xx
/***************************************************************/
char* at_err_build(int param)
{
char *at_str = NULL;
at_str = malloc(32);
assert(at_str);
if(param == 0)
sprintf(at_str,"\r\nERROR\r\n");
else
sprintf(at_str,"\r\n+CME ERROR: %d\r\n",param);
return at_str;
}
static int is_digit_str(const char *str)
{
unsigned int digit_len = 0;
while(*str == ' '){
str++;
}
if(*str == '-' || *str == '+'){
str++;
}
while(isdigit(*str)){
str++;
digit_len++;
}
while(*str == ' '){
str++;
}
return *str == '\0' && digit_len > 0;
}
/*¸Ãº¯ÊýÓÃÓÚ°´ÕÕ¸ø¶¨µÄ¸ñʽ½âÎö²ÎÊý£¬¸ñʽ½öÖ§³Ö%dºÍ%s,ͬʱ¿ÉÒÔÔÚÿ¸ö¸ñʽǰ¼ÓÉÏÊý×ÖÒÔÖ¸¶¨
±äÁ¿¿ÉÒÔ¸³ÖµµÄ¿Õ¼ä´óС£¬µ¥Î»Îª×Ö½Ú£¬ÀýÈç%2d±íʾ½ÓÊÜ´æ´¢¿Õ¼äΪ2×Ö½Ú£»%5s±íʾËãÉÏ'\0'£¬×î¶à¿ÉÒÔ
½ÓÊÜ5¸ö×Ö·û¡£µ±%d²»Ö¸¶¨Êý×Öʱ£¬°´ÕÕ4×Ö½Ú½øÐи³Öµ£¬%sÔò°´ÕÕʵ¼Ê½âÎöµÄ×Ö·û´®³¤¶ÈÍêÈ«¸³Öµ£¬ÓпÉÄÜ
»áÓÐÔ½½ç¡£´ËÍâÓû§Ê¹ÓÃʱ£¬Èô²»ÏëÓɸýӿÚÄÚ²¿½øÐвÎÊýµÄ¸ñʽ»¯½âÎö£¬¿ÉÒÔ½«fmt¸³ÖµÎª"%s"£¬
pval¸³ÖµÎªchar **p˫ָÕ룬ÕâÑù²ÎÊý½«×÷ΪÕûÌå×Ö·û´®·µ»Ø¸øµ÷ÓÃÕß*/
int parse_param2(char *fmt, char *buf, void **pval)
{
char *p;
char *sepp;
char *tmp;
char sepc;
char *pstr[AT_PARAM_MAX_NUM] = { 0 };
int len, flag;
int n = 0;
int nparam = 0;
if (buf == NULL) {
printf("buf NULL\n");
return -1;
}
len = strlen(buf) + 1;
tmp = p = (char*)malloc(len);
if (p == NULL) {
//assert(0);
printf("fail to malloc\n");
return -1;
}
memset(p, 0, len);
memcpy(p, buf, strlen(buf));
/* remove \r or \n at th end */
for(len--; len > 0; len--){
if(p[len - 1] == '\r' || p[len - 1] == '\n'){
p[len - 1] = '\0';
} else {
break;
}
}
/* divise the at-string to some string param */
do {
flag = 0;
if (*p == '"') {
int i, j;
for (i = j = 0, ++p; p[j] != '\0'; i++, j++) {
if (p[j] == '"') {
++j;
break;
}
}
if (j == 1) flag = 1;
p[j - 1] = '\0';
sepp = p + j;
} else {
sepp = p + strcspn(p, ",");
if (p == sepp) flag = 1;
}
nparam++;
sepc = sepp[0];
sepp[0] = '\0';
if (flag == 1)
pstr[n++] = NULL;
else
pstr[n++] = p;
p = sepp + 1;
} while ((n < AT_PARAM_MAX_NUM) && (sepc == ','));
/* convert the string params to the types that fmt Appointed */
int param_count = 0; /* count the param that being get */
int param_str_index = 0; /* the index of string params */
int param_val_index = 0; /* the index of param values */
for (; fmt != NULL && param_str_index < nparam; param_str_index++) {
char type;
int size;
char str_param_size[6] = { 0 };
int param_size_index = 0;
while(*fmt == ' ') fmt++;
if(*fmt == ','){
fmt++;
continue; /* igmore the param that is without type */
}
if(*fmt++ != '%'){
break;
}
for (; param_size_index < sizeof(str_param_size) - 1; fmt++, param_size_index++){
if(!isdigit(*fmt)){
break;
}
str_param_size[param_size_index] = *fmt;
}
type = *(fmt++);
char *stop;
errno = 0;
size = (int)strtol(str_param_size, &stop, 10);
if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
{
printf("strtol errno %d: %s\n", errno, strerror(errno));
}
//size = atoi(str_param_size);
if(size < 0)
break;
while(*fmt == ' ') fmt++; /* igmore the blanks */
fmt = (*fmt == ',' ? fmt + 1 : NULL);
if (type == 'd') {
if(size == 0 || size == 4) {
if(pstr[param_str_index] != NULL) {
if(!is_digit_str(pstr[param_str_index])){
break;
}
*((int *)pval[param_val_index]) = (int)atoi(pstr[param_str_index]);
param_count++;
}
} else if(size == 1) {
if(pstr[param_str_index] != NULL) {
if(!is_digit_str(pstr[param_str_index])){
break;
}
*((char *)pval[param_val_index]) = (char)atoi(pstr[param_str_index]);
param_count++;
}
} else if(size == 2) {
if(pstr[param_str_index] != NULL) {
if(!is_digit_str(pstr[param_str_index])){
break;
}
*((short *)pval[param_val_index]) = (short)atoi(pstr[param_str_index]);
param_count++;
}
}else {
break;
}
} else if (type == 's') {
if (size == 0) {
if(pstr[param_str_index] != NULL) {
strcpy((char *)pval[param_val_index], pstr[param_str_index]);
param_count++;
}
} else if (size < 0xffff) {//klocwork
if(pstr[param_str_index] != NULL) {
//strncpy((char *)pval[param_val_index], pstr[param_str_index], size - 1);
snprintf((char *)pval[param_val_index],size,"%s",pstr[param_str_index]);
param_count++;
}
} else {
break;
}
} else {
break;
}
param_val_index++;
}
free(tmp);
return param_count;
}
static int is_print_str(const char *str){
while(isprint(*str)){
str++;
}
return *str == '\0';
}
static int get_fmt_param_count(const char *str){
int fmt_param_count = 0;
for(; *str != '\0'; str++){
if(*str == ','){
fmt_param_count++;
}
}
return fmt_param_count + 1;
}
/*return 0±íʾ½âÎö²ÎÊýÕý³££¬ÄÚ²¿½øÐÐÑϸñµÄ²ÎÊý¼ì²é£¬°üÀ¨²ÎÊý¸öÊýÒ»ÖÂÐÔ¼ì²é£¬¶ÔÓÚ¿ÉÑ¡²ÎÊý£¬ÐèÒªµ÷ÓÃÕß×ÔÐп¼ÂÇ*/
int parse_param_safe(char *fmt, char *buf, void **pval)
{
char *p;
char *sepp;
char *tmp;
char sepc;
char *pstr[AT_PARAM_MAX_NUM] = {0};
int len, flag;
int n = 0;
int nparam = 0;//buf×Ö·û´®Êµ¼ÊµÄ²ÎÊý¸öÊý
int fmt_param_num = 0;//fmt¸ñʽ»¯ÖÐÒªÇóµÄ²ÎÊý×ܸöÊý£¬Óë%¸öÊýÒ»ÖÂ
int ret = AT_PARSE_OK;
int mark_flag = 0;//ÓÃÓÚ±êÊ¶ÌØÊâ·ûºÅµÄÅä¶ÔÇé¿ö£¬Ä¿Ç°ÓÃÓÚË«ÒýºÅ
if (buf == NULL) {
return ATERR_PROC_FAILED;
}
while(*buf == ' ') buf++;
len = strlen(buf) + 1;
tmp = p = (char*)malloc(len);
if (p == NULL) {
return ATERR_NO_PRINT;
}
//fmt_param_num = find_char_num(fmt,"%");
memset(p, 0, len);
//ÉêÇëÐÂÄÚ´æ´æ·ÅÈë²ÎµÄATÃüÁÒÔ±ã½øÐÐÕûÐζ¨ÖÆ
memcpy(p, buf, strlen(buf));
/*È¥³ýβ²¿µÄ\r\n£¬Ä¿Ç°½öÔÚ7100ÉÏÓдËÎÊÌâ */
for(len--; len > 0; len--){
if(p[len - 1] == '\r' || p[len - 1] == '\n'){
p[len - 1] = '\0';
} else {
break;
}
}
if(!is_print_str(p)){/* ÈçATÃüÁîÖаüº¬²»¿É¼û×Ö·ûÖ±½Ó·µ»Ø´íÎó */
free(tmp);
return ATERR_NO_PRINT;
}
/*°´¶ººÅ½øÐÐÿ¸ö²ÎÊýµÄ·Ö¸îÕûÐÎ,Ë«ÒýºÅÀïµÄ¶ººÅÌø¹ý*/
do {
flag = 0;
mark_flag = 0;
if (*p == '"') {
int i, j;
for (i = j = 0, ++p; p[j] != '\0'; i++, j++) {
if (p[j] == '"') {
++j;
mark_flag = 1;
break;
}
}
if(mark_flag == 0){/* δƥÅ䵽˫ÒýºÅÖ±½Ó·µ»Ø´íÎó */
free(tmp);
return ATERR_DROP_MARK;
}
if (j == 1) flag = 1;
p[j - 1] = '\0';
sepp = p + j;
} else {
sepp = p + strcspn(p, ",");
if (p == sepp) flag = 1;
}
nparam++;
sepc = sepp[0];
sepp[0] = '\0';
if (flag == 1)
pstr[n++] = NULL;
else
pstr[n++] = p;
p = sepp + 1;
} while ((n < AT_PARAM_MAX_NUM) && (sepc == ','));
if(nparam < get_fmt_param_count(fmt)){
ret = ATWARN_DROP_RN;
}else if(nparam > get_fmt_param_count(fmt)){
ret = ATWARN_LACK_PARAM;
}
/* convert the string params to the types that fmt Appointed */
int param_count = 0; /*ÊäÈëµÄ×Ö·û´®ÖÐÓÐЧ²ÎÊý¸öÊý*/
int param_str_index = 0; /* the index of string params */
int param_val_index = 0; /* the index of param values */
//°´ÕÕÈë²Î¸ñʽ½øÐÐÿ¸ö²ÎÊýÖµµÄ·µ»Ø¸³Öµ
for (; fmt != NULL && param_str_index < nparam; param_str_index++) {
char type;
int size;
char str_param_size[10] = { 0 };
int param_size_index = 0;
while(*fmt == ' ') fmt++;
if(*fmt == ','){
fmt++;
continue; /* igmore the param that is without type */
}
if(*fmt++ != '%'){
ret = ATERR_NO_PRINT;
break;
}
for (; param_size_index < sizeof(str_param_size) - 1; fmt++, param_size_index++){
if(!isdigit(*fmt)){
break;
}
str_param_size[param_size_index] = *fmt;
}
type = *(fmt++);
char *stop;
errno = 0;
size = (int)strtol(str_param_size, &stop, 10);
if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
{
printf("strtol errno %d: %s\n", errno, strerror(errno));
}
//size = atoi(str_param_size);
if(size < 0){
ret = ATERR_STR_TOO_LONG;
break;
}
while(*fmt == ' ') fmt++; /* igmore the blanks */
fmt = (*fmt == ',' ? fmt + 1 : NULL);
if (type == 'd') {
if(size == 0 || size == 4) {
if(pstr[param_str_index] != NULL) {
*((int *)pval[param_val_index]) = (int)atoi(pstr[param_str_index]);
param_count++;
}
} else if(size == 1) {
if(pstr[param_str_index] != NULL) {
*((char *)pval[param_val_index]) = (char)atoi(pstr[param_str_index]);
param_count++;
}
} else if(size == 2) {
if(pstr[param_str_index] != NULL) {
*((short *)pval[param_val_index]) = (short)atoi(pstr[param_str_index]);
param_count++;
}
}else {
assert(0);
break;
}
} else if (type == 's') {
if (size == 0) {
if(pstr[param_str_index] != NULL) {
strcpy((char *)pval[param_val_index], pstr[param_str_index]);
param_count++;
}
} else {
if(pstr[param_str_index] != NULL && size < strlen(pstr[param_str_index])){
ret = ATERR_STR_TOO_LONG;
break;
}
if(pstr[param_str_index] != NULL) {
//strncpy((char *)pval[param_val_index], pstr[param_str_index], size - 1);
if(size < 0xffff)//klocwork
snprintf((char *)pval[param_val_index],size,"%s",pstr[param_str_index]);
param_count++;
}
}
} else {
assert(0);
break;
}
param_val_index++;
}
free(tmp);
return ret;
}
/*return 0±íʾ½âÎö²ÎÊýÕý³££¬²»½øÐвÎÊý¸öÊýµÄÓÐЧÐÔ¼ì²é£¬¾ßÌå·µ»ØÖµ²Î¿´AT_PARSE_OKµÈºêÖµ*/
int parse_param(char *fmt, char *buf, void **pval)
{
int ret = parse_param_safe(fmt,buf,pval);
if(ret==ATWARN_LACK_PARAM||ret==ATWARN_DROP_RN)
return AT_PARSE_OK;
return ret;
}
/**
* @brief ¿É´òÓ¡×Ö·û´®×ª»»Îª×Ö½ÚÊý¾Ý £¬È磺
"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}
* @param pSrc Ô´×Ö·û´®Ö¸Õë
* @param pDst Ä¿±êÊý¾ÝÖ¸Õë
* @param nSrcLength Ô´×Ö·û´®³¤¶È
* @return Ä¿±êÊý¾Ý³¤¶È
* @note
* @warning
*/
int string2bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
int i=0;
//УÑé²ÎÊý
if(pSrc == NULL || pDst == NULL || nSrcLength < 0)
{
return -1;
}
for(i = 0; i < nSrcLength; i += 2)
{
// Êä³ö¸ß4λ
if(*pSrc >= '0' && *pSrc <= '9')
{
*pDst = (*pSrc - '0') << 4;
}
else
{
*pDst = ((toupper(*pSrc) - 'A') + 10) << 4;
}
pSrc++;
// Êä³öµÍ4λ
if(*pSrc >= '0' && *pSrc <= '9')
{
*pDst |= *pSrc - '0';
}
else
{
*pDst |= (toupper(*pSrc) - 'A') + 10;
}
pSrc++;
pDst++;
}
// ·µ»ØÄ¿±êÊý¾Ý³¤¶È
return nSrcLength / 2;
}
/**
* @brief ×Ö½ÚÊý¾Ýת»»Îª¿É´òÓ¡×Ö·û´® £¬È磺
{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01"
* @param pSrc Ô´Êý¾ÝÖ¸Õë
* @param pDst Ä¿±ê×Ö·û´®Ö¸Õë
* @param nSrcLength Ô´Êý¾Ý³¤¶È
* @return Ä¿±êÊý¾Ý³¤¶È£»
* @note
* @warning
*/
int bytes2string(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
const char tab[]="0123456789ABCDEF"; // 0x0-0xfµÄ×Ö·û²éÕÒ±í
int i = 0;
//УÑé²ÎÊý
if(pSrc == NULL || pDst == NULL || nSrcLength < 0)
{
return -1;
}
for(i=0; i<nSrcLength; i++)
{
*pDst++ = tab[*pSrc >> 4]; // Êä³öµÍ4λ
*pDst++ = tab[*pSrc & 0x0f]; // Êä³ö¸ß4λ
pSrc++;
}
// ·µ»ØÄ¿±ê×Ö·û´®³¤¶È
return nSrcLength * 2;
}
/**************************************************************************
* º¯ÊýÃû³Æ£º void zxic_err_track(int err)
* ¹¦ÄÜÃèÊö£º ½«Ó¦ÓôíÎóºÅÌí¼Óµ½nvÖÐ
* ÊäÈë²ÎÊý£º err: ´íÎóºÅ
* ·µ »Ø Öµ£ºÄ¿±êÊý¾Ý³¤¶È£»
**************************************************************************/
void zxic_err_track(int err)
{
ERR_TRACK errTrack = {0};
char nvErrTrack[2 * sizeof(ERR_TRACK)] = {0};
char assert_errno[10] = {0};
int recordLen = 0, curErrno = 0, prenum = 0, i = 0;
struct timeval curTime = {0};
unsigned long curErrTime = 0; //ºÁÃë
int index;
gettimeofday(&curTime, NULL);
curErrTime = curTime.tv_sec * 1000 + curTime.tv_usec / 1000;
curErrno = err;
//at_print(AT_DEBUG,"[ERR]curErrno = %d\r\n", curErrno);
//·¢ËÍÐèÒª¶ÏÑÔµÄerrno£¬Ö±½Ó¶ÏÑÔ
sc_cfg_get("assert_errno", assert_errno, sizeof(assert_errno));
if (curErrno == atoi(assert_errno)) {
assert(0);
}
//´ÓNV¶ÁÈ¡´íÎó¿ìÕÕÐÅÏ¢
recordLen = 2 * sizeof(ERR_TRACK);
memset(nvErrTrack, 0x00, recordLen);
sc_cfg_get("err_track", nvErrTrack, recordLen);
string2bytes(nvErrTrack, (unsigned char*)&errTrack, strlen(nvErrTrack));
//´òÓ¡¿ìÕÕÐÅÏ¢
#if 0
at_print(AT_DEBUG, "[ERR]num = %d\r\n", errTrack.num);
for (i = 0; i < 5; i++) {
at_print(AT_DEBUG, "[ERR]errTrack.errInfo[%d].errno = %d\r\n", i, errTrack.errInfo[i].err_no);
at_print(AT_DEBUG, "[ERR]errTrack.errInfo[%d].errtime = %ld\r\n", i, errTrack.errInfo[i].err_time);
}
#endif
index = errTrack.num % ERR_TRACK_MAX_NUM;
//Ñ­»·¼Ç¼´íÎóÐÅÏ¢
if (index == 0 && errTrack.num != 0)
prenum = ERR_TRACK_MAX_NUM - 1;
else if (index == 0)
prenum = 0;
else
prenum = index - 1;
//Á½´ÎerrnoÏàͬ£¬½ö¸üÐÂʱ¼ä
if (curErrno == errTrack.errInfo[prenum].err_no) {
errTrack.errInfo[prenum].err_time = curErrTime;
}
//Á½´Îerrno²»Ïàͬ£¬¼Ç¼ÏÂеÄerrnoºÍerrtime
else {
errTrack.errInfo[index].err_no = curErrno;
errTrack.errInfo[index].err_time = curErrTime;
errTrack.num++;
}
//±£´æ´íÎó¿ìÕÕÐÅÏ¢µ½NV
memset(nvErrTrack, 0x00, recordLen);
bytes2string((unsigned char*)&errTrack, nvErrTrack, sizeof(ERR_TRACK));
sc_cfg_set("err_track", nvErrTrack);
}
void get_at_req_prefix(char *at_str, char** at_prefix)
{
char *prefix = NULL;
char *pszAtHead = NULL;
char *ptemstr = NULL;
if((*at_str == 'A'||*at_str == 'a')&&(*(at_str+1) == 'T'||*(at_str+1) == 't'))
{
if(isalpha(*(at_str+2)))
{
*at_prefix = NULL;
}
else
{
prefix = (char*)malloc(50);
if(prefix == NULL) {
softap_assert("malloc fail!");
return;
}
memset(prefix, 0x00, 50);
pszAtHead = at_str;
//ÕÒµ½Ê׸ö·Ç×Öĸ»òÕßÊý×ֵIJÎÊý£¬ÀýÈç+
for(; *at_str != '\0'; at_str++)
{
if(!(isalnum(*at_str) || *at_str == '\r' || *at_str == '\n'))
{
pszAtHead = at_str;
pszAtHead++;
break;
}
}
for(ptemstr = pszAtHead; *ptemstr != '\0'; ptemstr++)
{
if(*ptemstr == '=' || *ptemstr == '?' || *ptemstr == '\r')
{
memcpy(prefix, pszAtHead, ptemstr-pszAtHead);
*at_prefix = prefix;
return;
}
}
}
}
else
{
softap_assert("req_at cmd is invalid!");
}
if(prefix)
free(prefix);
}
//¸øat_client·¢ËÍÇëÇóÏûÏ¢£¬Ð¯´øatÃüÁî×Ö·û´®ºÍ³¬Ê±Ê±³¤
void send_app_req(int module_id, char *req_at, int len, int timeout,int direct)
{
struct app_send_req_at appreq;
memset(&appreq, 0x00, sizeof(struct app_send_req_at));
memcpy(appreq.atstr, req_at, len);
appreq.str_len = len;
appreq.timeout = timeout;
if(direct == NEAR_PS)
ipc_send_message(module_id, MODULE_ID_AT_CTL, MSG_CMD_SEND_AT_TO_PS,sizeof(struct app_send_req_at), &appreq, 0);
else
ipc_send_message(module_id, MODULE_ID_AT_CTL, MSG_CMD_SEND_REQAT_TO_FARPS,sizeof(struct app_send_req_at), &appreq, 0);
printf("send_app_req\n");
}
/**
* @brief Ó¦Ó÷¢ËͶ¯×÷ÀàATÇëÇ󣬲¢×èÈûµÈ´ý¶¯×÷½á¹û£»×¢Ò⣺¸Ã½Ó¿ÚÖ»ÄÜÓÃÓÚ²éѯºÍÉèÖúÍÖ´ÐÐÇëÇó£¬Í¨¹ýÈë²Î½øÐÐÖмä½á¹ûµÄÄÚ²¿½âÎö´¦Àí£¬²¢ÇÒ
ÓÐÖмä½á¹ûÉϱ¨Ê±£¬Ö»Ö§³ÖÒ»ÌõÖмä½á¹ûµÄÉϱ¨½âÎö£»
* @param req_at ÇëÇóATÃüÁî
* @param info_fmt ATÏìÓ¦µÄ¸ñʽ»¯·½Ê½
* @param pval ¸ñʽ»¯ºóµÄATÏìÓ¦
* @param safe_parm_check ָʾÊÇ·ñ¶Ô²ÎÊý¸öÊý½øÐÐÒ»ÖÂÐÔ¼ì²é£¬0±íʾº¬¿ÉÑ¡²ÎÊý£¬²»¶Ô²ÎÊý¸öÊý½øÐмì²é;1±íʾ¶Ô²ÎÊý¸öÊý½øÐÐÑϸñ¼ì²é
* @return 0±íʾ·µ»Ø³É¹¦£¬ÆäËûÖµ±íʾʧ°Ü´íÎóÂë
* @note 1. Óû§Ê¹ÓÃʱ£¬Èô²»ÏëÓɸýӿÚÄÚ²¿½øÐвÎÊýµÄ¸ñʽ»¯½âÎö£¬¿ÉÒÔ½«info_fmt¸³ÖµÎª"%s"£¬pval¸³ÖµÎªchar **p˫ָÕ룬ÕâÑù²ÎÊý½«×÷ΪÕûÌå×Ö·û´®·µ»Ø¸øµ÷ÓÃÕß
2. ¶ÔÓÚZMGL,CPBR, COPS=?µÈÒ»ÌõÇëÇó»áÓжàÌõÖмä½á¹ûÇé¿ö£¬»¹ÐèʹÓÃregister_inform_func×¢²áÖмä½á¹ûµÄ´¦Àíº¯Êý
* @warning
*/
int send_req_and_wait(char *req_at,int len,char *info_fmt,void **pval, int safe_parm_check,int timeout,int direct)
{
int my_handle = 0;
char *prefix = NULL;
MSG_BUF rsp_msg = {0};
LONG msgSize = sizeof(MSG_BUF)-sizeof(LONG);
int iRet = 0;
int module_id = MODULE_ID_ATDYNAMIC_BASE;//ÄÚ²¿¶¯Ì¬»ñȡԴģ¿éID£¬³õʼֵΪMODULE_ID_ATDYNAMIC_BASE
int err = 0;
int at_send_cnt = 0;
if(len >= MSG_DATA_MAX_LEN-12)
softap_assert("send_req_and_wait req at is too long!!!!!");
assert((info_fmt==NULL&&pval==NULL)||(info_fmt!=NULL&&pval!=NULL));
//¶¯Ì¬´´½¨ÁÙʱµÄÏûÏ¢¶ÓÁйܵÀ
//msggetʹÓòÎÊýIPC_CREAT | IPC_EXCL| 0600£¬Åжϵ±Ç°module_idµÄÏûÏ¢¶ÓÁÐÊÇ·ñ
//´æÔÚ£¬Èç¹û²»´æÔÚ£¬Ö±½Ó´´½¨ÐµÄÏûÏ¢¶ÓÁУ»Èç¹û´æÔÚ£¬·µ»ØÖµÎ´-1£¬È»ºómodule_id
//Öµ¼Ó1£¬²»¶ÏÑ­»·Ö±µ½ÕÒµ½Ã»ÓÐʹÓõÄmodule_idÖµ
while((my_handle = msgget(module_id,IPC_CREAT | IPC_EXCL| 0600)) == -1)
{
module_id++;
if (module_id > MODULE_ID_ATDYNAMIC_END)
//µ±module_id´óÓÚMODULE_ID_ATDYNAMIC_ENDֵʱ£¬Ö÷¶¯¶ÏÑÔ
softap_assert("at dynamic msg pipi not free timely!!!!!!!!!!!");
}
//¸ù¾ÝÇëÇóATÃüÁîºÍ²éѯÓï·¨£¬ÕÒµ½¶ÔÓ¦µÄ²éѯǰ׺£¬¶¯Ì¬¸³Öµ¸ø³ö²Î£¬Íⲿ½øÐÐÄÚ´æµÄÊÍ·Å
get_at_req_prefix(req_at,&prefix);
RESEND:
//¸øat_ctl·¢ËÍÏûÏ¢£¬·¢Ë͵ÄÏûÏ¢ÄÚÈÝÊÇatÃüÁî×Ö·û´®
at_send_cnt++;
assert(at_send_cnt<=3);
//ÓÉatctlÖ÷¿ØÄÚ²¿ÉèÖó¬Ê±µÈ´ý£¬ÖØ·¢ºó»áÓÉÖØ¹¹ÖØÉè¸Ã¶¨Ê±Æ÷
send_app_req(module_id,req_at,len,timeout,direct);
slog(NET_PRINT, SLOG_ERR, "prefix:%s\n",prefix);
while(1)
{
iRet = 0;
memset(&rsp_msg, 0x00, sizeof(MSG_BUF));
iRet = msgrcv(my_handle, &rsp_msg, msgSize, 0, 0);
if (iRet < 0)
{
continue;
}
//ËÀµÈÓ¦´ðÏûÏ¢
if(rsp_msg.usMsgCmd == MSG_CMD_SEND_AT_MSG_RSP)//Æ¥Åäµ½ÊÇMSG_CMD_SEND_AT_MSG_RSPʱ²Å´¦Àí
{
char *buf = rsp_msg.aucDataBuf;
char *at_paras = NULL;
char *rsp_head = NULL;
char *rsp_tail = NULL;
rsp_head = buf;
slog(NET_PRINT, SLOG_ERR, "recv MSG_CMD_SEND_AT_MSG_RSP, buf:%s\n",buf);
//¶ÔÓÚ²éѯÇëÇ󣬲¢ÌṩÁ˲ÎÊýÄÚ´æ¿Õ¼ä£¬Ôò½øÐвÎÊýµÄ½âÎö
if(prefix!=NULL && info_fmt!=NULL && pval!=NULL && ((rsp_head=at_strstr(buf,prefix))!=NULL))
{
//Ìø¹ýÖмä½á¹ûµÄÍ·²¿£¬ÕÒµ½²ÎÊýµÄÊ×µØÖ·
rsp_head = rsp_head+strlen(prefix)+2;
if((rsp_tail = strstr(rsp_head,"\r\n")) == NULL)//µ±Éϱ¨µÄÖмä½á¹ûÖÐûÓÐ\r\nʱ£¬ËµÃ÷½á¹ûÓÐÎÊÌ⣬ֱ½Ó¶ÏÑÔ
softap_assert("rsp result is wrong and please contact with yangyun!");
if(strcmp(info_fmt,"%s") == 0)
//Èç¹û²»ÏëÓÉÄÚ²¿½øÐвÎÊýµÄ¸ñʽ»¯½âÎöʱ£¬Ö±½Ó½«È«²¿²ÎÊýÄÚÈÝÈ¡³öÀ´¸³Öµµ½pval[0]ÖУ¬²»×öÈκνâÎö
//strncpy((char *)*pval, rsp_head, (int)(rsp_tail-rsp_head));
//·ÀÖ¹Èë²Î·ÇÈ«0£¬ÔÚĩβ¼Ó×Ö·û´®½áÊø·û
snprintf((char *)*pval, (rsp_tail-rsp_head)+1, "%s", rsp_head);
else//ÐèÒª²ÎÊý½âÎöʱ£¬½«Öмä½á¹û´ÓÉϱ¨½á¹ûÖгé³öÀ´£¨Éϱ¨µÄ½á¹ûÖпÉÄÜÓÐOK´æÔÚ£©
{
char *at_paras = malloc(strlen(rsp_head)+1);
if(at_paras == NULL) {
softap_assert("malloc fail!");
break;
}
memset(at_paras, 0, strlen(rsp_head)+1);
memcpy(at_paras, rsp_head, (int)(rsp_tail-rsp_head));
if(safe_parm_check)
err = parse_param_safe(info_fmt, at_paras, pval);//°´ÕÕ¸ñʽ½âÎö²ÎÊý
else
err = parse_param(info_fmt, at_paras, pval);//°´ÕÕ¸ñʽ½âÎö²ÎÊý
slog(NET_PRINT, SLOG_ERR, "rsp parse_param_safe return ERR=%d!!!!!!\n",err);
//if(at_paras != NULL)
free(at_paras);
//²ÎÊý²»ºÏ·¨£¬ÇÒÊÇÓëÍⲿMCU½øÐн»»¥Ê±£¬Á¢¼´ÖØÐ·¢ËÍÇëÇó
if(direct==FAR_PS && err != AT_PARSE_OK)
goto RESEND;
//²ÎÊý²»ºÏ·¨£¬ZXICÄÚ²¿½»»¥Ê±£¬Á¢¼´·µ»Ø²ÎÊý´íÎóÂë
else if(err != AT_PARSE_OK)
break;
}
}
//¶ÔÓÚ²éѯÀ࣬²»Ó¦¸Ã·µ»Ø´íÎó£¬ÕÒЭÒéÕ»
if((rsp_head = strstr(buf,"ERROR")) != NULL)
{
err = USER_EXTAND_ERR_BASE;
sscanf(rsp_head+strlen("ERROR")+2, "%d", &err);
slog(NET_PRINT, SLOG_ERR, "server return ERR=%d, at_send_cnt=%d!!!!!!!\n",err,at_send_cnt);
//ÎÞÐè³¬Ê±ÖØ·¢»òÕß·µ»ØµÄ´íÎóÂëΪÓû§À©Õ¹´íÎ󣬲»½øÐÐÖØ·¢
if(direct==FAR_PS&&err<9000)
goto RESEND;
char needInit[20] = {0};
//¶ÔÓÚͨ¹ý7100ÉÏÍøÄ£Ê½£¬×öÌØÊâ¶¨ÖÆ£¬»Ø¸´errorºó±ØÐëÖØ´«
sc_cfg_get("customer_type",needInit,sizeof(needInit));
if(0 == strcmp(needInit, "7100modem") && err<9000)
goto RESEND;
break;
}
//¶ÔÓÚÉèÖÃÀàÃüÁîºÍһЩִÐÐÀàÃüÁֻÓÐOKÉϱ¨Ã»ÓÐÖмä½á¹ûÉϱ¨
else if((rsp_head = strstr(buf,"OK")) != NULL)
{
break;
}
}
}
if(prefix!=NULL)
free(prefix);
//²éѯÃüÁî½á¹û·µ»Øºó£¬Ïú»Ù֮ǰ´´½¨µÄÏûÏ¢¶ÓÁÐ
if(msgctl(my_handle,IPC_RMID,0) < 0)
slog(NET_PRINT, SLOG_ERR, "%d:%s",errno,strerror(errno));
return err;
}
int get_modem_info(char *req_at,char *info_fmt,void **pval)
{
return send_req_and_wait(req_at,strlen(req_at),info_fmt,pval,0,0,NEAR_PS);
}
int get_modem_info2(char *req_at,char *info_fmt,void **pval, int safe_parm_check, int timeout)
{
return send_req_and_wait(req_at,strlen(req_at),info_fmt,pval,safe_parm_check,timeout,NEAR_PS);
}
int send_reqat_to_farps(char *req_at,int len,char *info_fmt,void **pval, int safe_parm_check, int timeout)
{
return send_req_and_wait(req_at,len,info_fmt,pval,safe_parm_check,timeout,FAR_PS);
}
/*ÔÚºöÂÔ´óСдµÄǰÌáÏÂ,±È½ÏÁ½×Ö·û´®ÊÇ·ñÍêȫƥÅ䣬Èç¹ûÆ¥Åä·µ»Ø0£¬Èç¹ûµÚÒ»¸öÈë²Î´óÓÚµÚ¶þ¸öÈë²Î£¬
·µ»ØÕýÖµ£¬·ñÔò·µ»Ø¸ºÖµ£»
¿ÉÓÃÓڱȽÏATÃüÁîǰ׺ÊÇ·ñÆ¥Å䣬ÀýÈçat+cops?ºÍAT+COPS?µÄ±È½Ï*/
int at_strcmp(const char *dest, const char *source)
{
//int DIFF_VALUE = 'a'-'A';
int ch1 = 0;
int ch2 = 0;
if(NULL == dest || NULL == source)
{
return -1;
}
//½«Á½×Ö·û´®ÖеĴóС×ÖĸÏÈת»¯³É¶ÔÓ¦µÄСд×Öĸºó±È½Ï
do
{
if((ch1 = *(unsigned char *)dest) >= 'A' && (ch1 <= 'Z'))
{
ch1 += DIFF_VALUE;
}
if((ch2 = *(unsigned char *)source) >= 'A' && (ch2 <= 'Z'))
{
ch2 += DIFF_VALUE;
}
dest++;
source++;
}while((ch1 == ch2) && ch1 && ch2);
if(ch1 == ch2)
return 0;
else
return *(--dest) - *(--source);
}
/*ÔÚºöÂÔ´óСдµÄǰÌáÏÂ,±È½ÏÁ½×Ö·û´®Ç°size×Ö·ûÊÇ·ñÆ¥Å䣬Èç¹ûÆ¥Åä·µ»Ø0£¬
Èç¹ûµÚÒ»¸öÈë²Î´óÓÚµÚ¶þ¸öÈë²Î£¬·µ»ØÕýÖµ£¬·ñÔò·µ»Ø¸ºÖµ£»
¿ÉÓÃÓڱȽÏATÃüÁîÇëÇóǰ׺ºÍÆäÖмä½á¹ûµÄǰ׺ÊÇ·ñÆ¥Å䣬ÀýÈçcops?ºÍCOPSÔÚǰ4¸ö×Ö·ûµÄ±È½Ï*/
int at_strncmp(const char *dest, const char *source, int size)
{
//int DIFF_VALUE = 'a'-'A';
int ch1 = 0;
int ch2 = 0;
if(NULL == dest || NULL == source || size < 0)
{
return -1;
}
if(0 == size)
{
return 0;
}
//½«Á½×Ö·û´®ÖеĴóС×ÖĸÏÈת»¯³É¶ÔÓ¦µÄСд×Öĸºó±È½Ïǰsize×Ö·û
do
{
if((ch1 = *(unsigned char *)dest) >= 'A' && (ch1 <= 'Z'))
{
ch1 += DIFF_VALUE;
}
if((ch2 = *(unsigned char *)source) >= 'A' && (ch2 <= 'Z'))
{
ch2 += DIFF_VALUE;
}
dest++;
source++;
}while(--size && (ch1 == ch2) && ch1 && ch2);
if(ch1 == ch2)
return 0;
else
return *(--dest) - *(--source);
}
/*ÔÚºöÂÔ´óСдµÄǰÌáÏÂ, ÔÚsourceÖÐѰÕÒsubstr×Ó´®£¬Èç¹ûÕÒµ½£¬Ö±½Ó·µ»ØÔÚsourceÖеÚÒ»´Î³öÏÖµÄλÖã¬
Èç¹ûûÓÐÕÒµ½£¬·µ»ØNULL*/
char * at_strstr(const char * source, const char * substr)
{
//int DIFF_VALUE = 'a'-'A';
int ch1 = 0;
int ch2 = 0;
if(substr == NULL || source == NULL)
return NULL;
//½«Á½×Ö·û´®ÖеĴóС×ÖĸÏÈת»¯³É¶ÔÓ¦µÄСд×ÖĸºóÔÙ²éÕÒ
while(*source != '\0')
{
char *p = (char *)source;
char *q = (char *)substr;
char *res = NULL;
res = p;
do
{
if((ch1 = *(unsigned char *)p) >= 'A' && (ch1 <= 'Z'))
{
ch1 += DIFF_VALUE;
}
if((ch2 = *(unsigned char *)q) >= 'A' && (ch2 <= 'Z'))
{
ch2 += DIFF_VALUE;
}
p++;
q++;
}while(ch1 && ch2 && (ch1 == ch2));
if(ch2 == '\0')
return res;
source++;
}
return NULL;
}
//·þÎñ¶ËÓ¦ÓóÌÐò£¬·¢ËÍÖмä½á¹ûºÍÏìÓ¦µ½ÍⲿMCU
int send_rsp_str_to_farps(int module_id, char *rsp_cmd,int rsp_len)
{
return ipc_send_message(module_id, MODULE_ID_AT_CTL, MSG_CMD_SEND_RSP_TO_OUTSIDE, rsp_len, rsp_cmd, 0);
}
unsigned short get_chksum(const unsigned char *ptr, unsigned short len)
{
unsigned int sum = 0;
unsigned int tmp;
const unsigned char *end;
end = ptr + len - 1;
while (ptr < end) {
tmp = (ptr[0] << 8) + ptr[1];
sum += tmp;
if (sum < tmp) {
sum++;
}
ptr += 2;
}
if (ptr == end) {
tmp = ptr[0] << 8;
sum += tmp;
if (sum < tmp) {
sum++;
}
}
return sum;
}