| /* |
| * |
| * |
| * Author : lb |
| * Date : 2021/11/5 10:53:49 |
| * |
| */ |
| #include "telutl.h" |
| #include "mbtk_at.h" |
| #include <dlfcn.h> |
| #include <include/log.h> |
| #include <stdarg.h> |
| #include <errno.h> |
| |
| // See utlAtParameterOp_T |
| static char *at_op_list[] = {"UNKNOWN", "EXEC", "GET", "SET", "ACTION", "TEST", NULL}; |
| |
| |
| //void* mbtk_cmd_line_ex = NULL; |
| #ifdef MBTK_DATA_MODE_SUPPORT |
| static mbtk_data_mode_callback_func data_mode_cb = NULL; |
| static TelAtParserID mbtk_atp_index = TEL_AT_CMD_ATP_0; |
| static char datamode_buff[4096]; |
| static int datamode_buff_len = 0; |
| #endif |
| |
| #if 0 |
| mbtk_audio_exec_f mbtk_at_play = NULL; |
| mbtk_audio_exec_f mbtk_at_rec = NULL; |
| #endif |
| |
| typedef struct { |
| /*mbtk_at_func_type_enum type;*/ |
| char lib_name[50]; |
| void *handle; |
| } mbtk_at_lib_info_t; |
| |
| mbtk_at_func_t *func_list = NULL; |
| static mbtk_at_lib_info_t lib_list[] = { |
| {"/lib/libmbtk_lib.so", NULL}, /* MBTK_AT_FUNC_TYPE_BASIC */ |
| //{"/lib/libmbtk_factory.so", NULL}, /* MBTK_AT_FUNC_TYPE_FACTORY */ |
| //{"/lib/libmbtk_audio.so", NULL}, /* MBTK_AT_FUNC_TYPE_AUDIO */ |
| //{"/lib/libmbtk_gnss.so", NULL}, /* MBTK_AT_FUNC_TYPE_GNSS */ |
| //{"/lib/libmbtk_ecall.so", NULL}, /* MBTK_AT_FUNC_TYPE_ECALL */ |
| //{"/lib/libmbtk_socket.so", NULL}, /* MBTK_AT_FUNC_TYPE_SOCKET */ |
| //{"/lib/libmbtk_tcpip.so", NULL}, /* MBTK_AT_FUNC_TYPE_TCPIP */ |
| //{"/lib/libmbtk_http.so", NULL}, /* MBTK_AT_FUNC_TYPE_HTTP */ |
| //{"/lib/libmbtk_ftp.so", NULL} /* MBTK_AT_FUNC_TYPE_FTP */ |
| }; |
| |
| BOOL getExtValue( const utlAtParameterValue_P2c param_value_p, |
| int index, |
| int *value_p, |
| int minValue, |
| int maxValue, |
| int DefaultValue); |
| |
| BOOL getExtUValue(const utlAtParameterValue_P2c param_value_p, |
| int index, |
| unsigned int *value_p, |
| unsigned int minValue, |
| unsigned int maxValue, |
| unsigned int DefaultValue); |
| |
| BOOL getExtString( const utlAtParameterValue_P2c param_value_p, |
| int index, |
| CHAR *outString, |
| INT16 maxStringLength, |
| INT16 *outStringLength, |
| CHAR *defaultString); |
| |
| void mbtk_log(int level, const char *format, ...) |
| { |
| char *timestr; |
| char buf[1024]; |
| va_list ap; |
| struct timeval log_time; |
| int length = 0; |
| |
| va_start(ap, format); |
| length = vsnprintf(buf,1024,format,ap); |
| if(length > 0) { |
| __android_log_printf(LOG_ID_RADIO, level, "%s", buf); |
| } |
| |
| va_end(ap); |
| } |
| |
| char *op2str(utlAtParameterOp_T op) |
| { |
| return at_op_list[op]; |
| } |
| |
| static bool str_empty(const void *str) |
| { |
| if (str && strlen((char*)str) > 0) |
| return false; |
| |
| return true; |
| } |
| |
| void func_add(mbtk_at_func_type_enum type, char *name) |
| { |
| if(!str_empty(name)) { |
| mbtk_at_func_t *func_ptr = (mbtk_at_func_t*)malloc(sizeof(mbtk_at_func_t)); |
| if(func_ptr) { |
| memset(func_ptr, 0x0, sizeof(mbtk_at_func_t)); |
| func_ptr->type = type; |
| memcpy(func_ptr->name, name, strlen(name)); |
| |
| func_ptr->next = func_list; |
| func_list = func_ptr; |
| } |
| } |
| } |
| |
| mbtk_at_func_t *func_get(char *name) |
| { |
| mbtk_at_func_t *func_ptr = func_list; |
| while(func_ptr) { |
| if(!strcmp(func_ptr->name, name)) { |
| return func_ptr; |
| } |
| func_ptr = func_ptr->next; |
| } |
| |
| return func_ptr; |
| } |
| |
| void mbtk_at_proc_null() |
| { |
| LOG("MBTK_AT function not found in so."); |
| } |
| |
| int mbtk_lib_init() |
| { |
| #define MBTK_FUNC_INIT |
| #include "mbtk_at_func.h" |
| #undef MBTK_FUNC_INIT |
| |
| set_service_log_tag("MBTK_AT"); |
| mbtk_at_func_t *func_ptr = func_list; |
| while(func_ptr) { |
| if(lib_list[func_ptr->type].handle == NULL) { |
| lib_list[func_ptr->type].handle = dlopen(lib_list[func_ptr->type].lib_name , RTLD_LAZY); |
| } |
| |
| if(lib_list[func_ptr->type].handle) { |
| func_ptr->func = dlsym(lib_list[func_ptr->type].handle, func_ptr->name); |
| if(func_ptr->func == NULL) { |
| LOG("%s() dlsym from %s fail.", func_ptr->name, lib_list[func_ptr->type].lib_name); |
| //return -1; |
| func_ptr->func = mbtk_at_proc_null; |
| } else { |
| LOG("%s function : %s", lib_list[func_ptr->type].lib_name, func_ptr->name); |
| } |
| } else { |
| LOG("dlopen() %s fail : %d", lib_list[func_ptr->type].lib_name, errno); |
| //return -1; |
| func_ptr->func = mbtk_at_proc_null; |
| } |
| |
| func_ptr = func_ptr->next; |
| } |
| return 0; |
| } |
| |
| #ifdef MBTK_DATA_MODE_SUPPORT |
| static utlReturnCode_T mbtk_utlAtTxLineDataFunction_P(const unsigned char *octets_p, const size_t n, void *arg_p) |
| { |
| if(n > 0) { |
| LOG("DATA[%d]:%s", n, octets_p); |
| LOG("ARG:%s", arg_p); |
| if(datamode_buff_len + n > 4096) { |
| utlAtParserOp(aParser_p[mbtk_atp_index], utlAT_PARSER_OP_DISABLE_BYPASS_MODE); |
| ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL); |
| return utlSUCCESS; |
| } |
| |
| memcpy(datamode_buff + datamode_buff_len, octets_p, n); |
| datamode_buff_len += n; |
| |
| // control-z(0x1a) |
| if(datamode_buff[datamode_buff_len - 1] == 0x1a) { |
| utlAtParserOp(aParser_p[mbtk_atp_index], utlAT_PARSER_OP_DISABLE_BYPASS_MODE); |
| datamode_buff[datamode_buff_len - 1] = '\0'; |
| datamode_buff_len--; |
| |
| ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_OK, 0, datamode_buff); |
| //ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_OK, 0, "OK"); |
| |
| if(data_mode_cb) { |
| data_mode_cb(datamode_buff, datamode_buff_len); |
| data_mode_cb = NULL; |
| } |
| } |
| } |
| |
| return utlSUCCESS; |
| } |
| |
| utlReturnCode_T mbtk_data_mode_enter(TelAtParserID atp_index, mbtk_data_mode_callback_func cb) |
| { |
| data_mode_cb = cb; |
| utlReturnCode_T result = utlAtParserOp(aParser_p[atp_index], utlAT_PARSER_OP_ENABLE_BYPASS_MODE); |
| if (result != utlSUCCESS) |
| { |
| LOG("(utlAT_PARSER_OP_ENABLE_BYPASS_MODE)Enter data mode fail[%d].", result); |
| result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL); |
| } else { |
| result = utlAtParserOp(aParser_p[atp_index], utlAT_PARSER_OP_SET_TX_LINE_DATA_HANDLER, mbtk_utlAtTxLineDataFunction_P); |
| if (result == utlSUCCESS) |
| { |
| // ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, "\r\n>>\r\n"); |
| LOG("Enter data mode success."); |
| mbtk_atp_index = atp_index; |
| memset(datamode_buff, 0x0, 4096); |
| datamode_buff_len = 0; |
| |
| result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_OK, 0, ">>"); |
| } else { |
| LOG("(utlAT_PARSER_OP_SET_TX_LINE_DATA_HANDLER)Enter data mode fail[%d].", result); |
| result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL); |
| } |
| } |
| |
| return result; |
| } |
| #endif |