[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/lib/libatutils/at_utils.c b/ap/lib/libatutils/at_utils.c
new file mode 100755
index 0000000..2d2b366
--- /dev/null
+++ b/ap/lib/libatutils/at_utils.c
@@ -0,0 +1,1060 @@
+/***************************************************************/
+//
+//À©Õ¹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;
+}
+