b.liu | d440f9f | 2025-04-18 10:44:31 +0800 | [diff] [blame^] | 1 | /* |
| 2 | * |
| 3 | * |
| 4 | * Author : lb |
| 5 | * Date : 2021/11/5 10:53:49 |
| 6 | * |
| 7 | */ |
| 8 | #include "telutl.h" |
| 9 | #include "mbtk_at.h" |
| 10 | #include <dlfcn.h> |
| 11 | #include <include/log.h> |
| 12 | #include <stdarg.h> |
| 13 | #include <errno.h> |
| 14 | |
| 15 | // See utlAtParameterOp_T |
| 16 | static char *at_op_list[] = {"UNKNOWN", "EXEC", "GET", "SET", "ACTION", "TEST", NULL}; |
| 17 | |
| 18 | |
| 19 | //void* mbtk_cmd_line_ex = NULL; |
| 20 | #ifdef MBTK_DATA_MODE_SUPPORT |
| 21 | static mbtk_data_mode_callback_func data_mode_cb = NULL; |
| 22 | static TelAtParserID mbtk_atp_index = TEL_AT_CMD_ATP_0; |
| 23 | static char datamode_buff[4096]; |
| 24 | static int datamode_buff_len = 0; |
| 25 | #endif |
| 26 | |
| 27 | #if 0 |
| 28 | mbtk_audio_exec_f mbtk_at_play = NULL; |
| 29 | mbtk_audio_exec_f mbtk_at_rec = NULL; |
| 30 | #endif |
| 31 | |
| 32 | typedef struct { |
| 33 | /*mbtk_at_func_type_enum type;*/ |
| 34 | char lib_name[50]; |
| 35 | void *handle; |
| 36 | } mbtk_at_lib_info_t; |
| 37 | |
| 38 | mbtk_at_func_t *func_list = NULL; |
| 39 | static mbtk_at_lib_info_t lib_list[] = { |
| 40 | {"/lib/libmbtk_lib.so", NULL}, /* MBTK_AT_FUNC_TYPE_BASIC */ |
| 41 | //{"/lib/libmbtk_factory.so", NULL}, /* MBTK_AT_FUNC_TYPE_FACTORY */ |
| 42 | //{"/lib/libmbtk_audio.so", NULL}, /* MBTK_AT_FUNC_TYPE_AUDIO */ |
| 43 | //{"/lib/libmbtk_gnss.so", NULL}, /* MBTK_AT_FUNC_TYPE_GNSS */ |
| 44 | //{"/lib/libmbtk_ecall.so", NULL}, /* MBTK_AT_FUNC_TYPE_ECALL */ |
| 45 | //{"/lib/libmbtk_socket.so", NULL}, /* MBTK_AT_FUNC_TYPE_SOCKET */ |
| 46 | //{"/lib/libmbtk_tcpip.so", NULL}, /* MBTK_AT_FUNC_TYPE_TCPIP */ |
| 47 | //{"/lib/libmbtk_http.so", NULL}, /* MBTK_AT_FUNC_TYPE_HTTP */ |
| 48 | //{"/lib/libmbtk_ftp.so", NULL} /* MBTK_AT_FUNC_TYPE_FTP */ |
| 49 | }; |
| 50 | |
| 51 | BOOL getExtValue( const utlAtParameterValue_P2c param_value_p, |
| 52 | int index, |
| 53 | int *value_p, |
| 54 | int minValue, |
| 55 | int maxValue, |
| 56 | int DefaultValue); |
| 57 | |
| 58 | BOOL getExtUValue(const utlAtParameterValue_P2c param_value_p, |
| 59 | int index, |
| 60 | unsigned int *value_p, |
| 61 | unsigned int minValue, |
| 62 | unsigned int maxValue, |
| 63 | unsigned int DefaultValue); |
| 64 | |
| 65 | BOOL getExtString( const utlAtParameterValue_P2c param_value_p, |
| 66 | int index, |
| 67 | CHAR *outString, |
| 68 | INT16 maxStringLength, |
| 69 | INT16 *outStringLength, |
| 70 | CHAR *defaultString); |
| 71 | |
| 72 | void mbtk_log(int level, const char *format, ...) |
| 73 | { |
| 74 | char *timestr; |
| 75 | char buf[1024]; |
| 76 | va_list ap; |
| 77 | struct timeval log_time; |
| 78 | int length = 0; |
| 79 | |
| 80 | va_start(ap, format); |
| 81 | length = vsnprintf(buf,1024,format,ap); |
| 82 | if(length > 0) { |
| 83 | __android_log_printf(LOG_ID_RADIO, level, "%s", buf); |
| 84 | } |
| 85 | |
| 86 | va_end(ap); |
| 87 | } |
| 88 | |
| 89 | char *op2str(utlAtParameterOp_T op) |
| 90 | { |
| 91 | return at_op_list[op]; |
| 92 | } |
| 93 | |
| 94 | static bool str_empty(const void *str) |
| 95 | { |
| 96 | if (str && strlen((char*)str) > 0) |
| 97 | return false; |
| 98 | |
| 99 | return true; |
| 100 | } |
| 101 | |
| 102 | void func_add(mbtk_at_func_type_enum type, char *name) |
| 103 | { |
| 104 | if(!str_empty(name)) { |
| 105 | mbtk_at_func_t *func_ptr = (mbtk_at_func_t*)malloc(sizeof(mbtk_at_func_t)); |
| 106 | if(func_ptr) { |
| 107 | memset(func_ptr, 0x0, sizeof(mbtk_at_func_t)); |
| 108 | func_ptr->type = type; |
| 109 | memcpy(func_ptr->name, name, strlen(name)); |
| 110 | |
| 111 | func_ptr->next = func_list; |
| 112 | func_list = func_ptr; |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | mbtk_at_func_t *func_get(char *name) |
| 118 | { |
| 119 | mbtk_at_func_t *func_ptr = func_list; |
| 120 | while(func_ptr) { |
| 121 | if(!strcmp(func_ptr->name, name)) { |
| 122 | return func_ptr; |
| 123 | } |
| 124 | func_ptr = func_ptr->next; |
| 125 | } |
| 126 | |
| 127 | return func_ptr; |
| 128 | } |
| 129 | |
| 130 | void mbtk_at_proc_null() |
| 131 | { |
| 132 | LOG("MBTK_AT function not found in so."); |
| 133 | } |
| 134 | |
| 135 | int mbtk_lib_init() |
| 136 | { |
| 137 | #define MBTK_FUNC_INIT |
| 138 | #include "mbtk_at_func.h" |
| 139 | #undef MBTK_FUNC_INIT |
| 140 | |
| 141 | set_service_log_tag("MBTK_AT"); |
| 142 | mbtk_at_func_t *func_ptr = func_list; |
| 143 | while(func_ptr) { |
| 144 | if(lib_list[func_ptr->type].handle == NULL) { |
| 145 | lib_list[func_ptr->type].handle = dlopen(lib_list[func_ptr->type].lib_name , RTLD_LAZY); |
| 146 | } |
| 147 | |
| 148 | if(lib_list[func_ptr->type].handle) { |
| 149 | func_ptr->func = dlsym(lib_list[func_ptr->type].handle, func_ptr->name); |
| 150 | if(func_ptr->func == NULL) { |
| 151 | LOG("%s() dlsym from %s fail.", func_ptr->name, lib_list[func_ptr->type].lib_name); |
| 152 | //return -1; |
| 153 | func_ptr->func = mbtk_at_proc_null; |
| 154 | } else { |
| 155 | LOG("%s function : %s", lib_list[func_ptr->type].lib_name, func_ptr->name); |
| 156 | } |
| 157 | } else { |
| 158 | LOG("dlopen() %s fail : %d", lib_list[func_ptr->type].lib_name, errno); |
| 159 | //return -1; |
| 160 | func_ptr->func = mbtk_at_proc_null; |
| 161 | } |
| 162 | |
| 163 | func_ptr = func_ptr->next; |
| 164 | } |
| 165 | return 0; |
| 166 | } |
| 167 | |
| 168 | #ifdef MBTK_DATA_MODE_SUPPORT |
| 169 | static utlReturnCode_T mbtk_utlAtTxLineDataFunction_P(const unsigned char *octets_p, const size_t n, void *arg_p) |
| 170 | { |
| 171 | if(n > 0) { |
| 172 | LOG("DATA[%d]:%s", n, octets_p); |
| 173 | LOG("ARG:%s", arg_p); |
| 174 | if(datamode_buff_len + n > 4096) { |
| 175 | utlAtParserOp(aParser_p[mbtk_atp_index], utlAT_PARSER_OP_DISABLE_BYPASS_MODE); |
| 176 | ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL); |
| 177 | return utlSUCCESS; |
| 178 | } |
| 179 | |
| 180 | memcpy(datamode_buff + datamode_buff_len, octets_p, n); |
| 181 | datamode_buff_len += n; |
| 182 | |
| 183 | // control-z(0x1a) |
| 184 | if(datamode_buff[datamode_buff_len - 1] == 0x1a) { |
| 185 | utlAtParserOp(aParser_p[mbtk_atp_index], utlAT_PARSER_OP_DISABLE_BYPASS_MODE); |
| 186 | datamode_buff[datamode_buff_len - 1] = '\0'; |
| 187 | datamode_buff_len--; |
| 188 | |
| 189 | ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_OK, 0, datamode_buff); |
| 190 | //ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_OK, 0, "OK"); |
| 191 | |
| 192 | if(data_mode_cb) { |
| 193 | data_mode_cb(datamode_buff, datamode_buff_len); |
| 194 | data_mode_cb = NULL; |
| 195 | } |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | return utlSUCCESS; |
| 200 | } |
| 201 | |
| 202 | utlReturnCode_T mbtk_data_mode_enter(TelAtParserID atp_index, mbtk_data_mode_callback_func cb) |
| 203 | { |
| 204 | data_mode_cb = cb; |
| 205 | utlReturnCode_T result = utlAtParserOp(aParser_p[atp_index], utlAT_PARSER_OP_ENABLE_BYPASS_MODE); |
| 206 | if (result != utlSUCCESS) |
| 207 | { |
| 208 | LOG("(utlAT_PARSER_OP_ENABLE_BYPASS_MODE)Enter data mode fail[%d].", result); |
| 209 | result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL); |
| 210 | } else { |
| 211 | result = utlAtParserOp(aParser_p[atp_index], utlAT_PARSER_OP_SET_TX_LINE_DATA_HANDLER, mbtk_utlAtTxLineDataFunction_P); |
| 212 | if (result == utlSUCCESS) |
| 213 | { |
| 214 | // ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, "\r\n>>\r\n"); |
| 215 | LOG("Enter data mode success."); |
| 216 | mbtk_atp_index = atp_index; |
| 217 | memset(datamode_buff, 0x0, 4096); |
| 218 | datamode_buff_len = 0; |
| 219 | |
| 220 | result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_OK, 0, ">>"); |
| 221 | } else { |
| 222 | LOG("(utlAT_PARSER_OP_SET_TX_LINE_DATA_HANDLER)Enter data mode fail[%d].", result); |
| 223 | result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL); |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | return result; |
| 228 | } |
| 229 | #endif |