blob: fa34eda6c93ab409c91162553da46c9a1c470cdb [file] [log] [blame]
b.liu68a94c92025-05-24 12:53:41 +08001#include <sys/types.h>
2#include <sys/socket.h>
3#include <sys/un.h>
4#include <unistd.h>
5#include <arpa/inet.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <signal.h>
9#include <string.h>
10#include <pthread.h>
11#include <fcntl.h>
12#include <errno.h>
13#include <stdint.h>
14#include <dlfcn.h>
15#include <stdbool.h>
16#include "gsw_at.h"
17
18#ifndef LOG_ERR_LEVEL
19#define LOG_ERR_LEVEL 3 /* error conditions */
20#endif
21#ifndef LOG_WARN_LEVEL
22#define LOG_WARN_LEVEL 4 /* warning conditions */
23#endif
24#ifndef LOG_INFO_LEVEL
25#define LOG_INFO_LEVEL 6 /* informational */
26#endif
27#ifndef LOG_DEBUG_LEVEL
28#define LOG_DEBUG_LEVEL 7 /* debug-level messages */
29#endif
30#ifndef LOG_VERBOSE_LEVEL
31#define LOG_VERBOSE_LEVEL 8
32#endif
33
34#define LOGV(fmt, args ...) \
35 do{ \
36 char *file_ptr_1001 = __FILE__; \
37 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
38 char line_1001[10] = {0}; \
39 sprintf(line_1001, "%d", __LINE__); \
40 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
41 if(*ptr_1001 == '/') \
42 break; \
43 ptr_1001--; \
44 } \
45 fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: " fmt, ptr_1001 + 1, line_1001, ##args); \
46 } while(0)
47
48#define LOGI(fmt, args...) \
49 do{ \
50 char *file_ptr_1001 = __FILE__; \
51 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
52 char line_1001[10] = {0}; \
53 sprintf(line_1001, "%d", __LINE__); \
54 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
55 if(*ptr_1001 == '/') \
56 break; \
57 ptr_1001--; \
58 } \
59 fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: " fmt, ptr_1001 + 1, line_1001, ##args); \
60 } while(0)
61
62#define LOGD(fmt, args...) \
63 do{ \
64 char *file_ptr_1001 = __FILE__; \
65 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
66 char line_1001[10] = {0}; \
67 sprintf(line_1001, "%d", __LINE__); \
68 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
69 if(*ptr_1001 == '/') \
70 break; \
71 ptr_1001--; \
72 } \
73 fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: " fmt, ptr_1001 + 1, line_1001, ##args); \
74 } while(0)
75
76#define LOGW(fmt, args...) \
77 do{ \
78 char *file_ptr_1001 = __FILE__; \
79 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
80 char line_1001[10] = {0}; \
81 sprintf(line_1001, "%d", __LINE__); \
82 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
83 if(*ptr_1001 == '/') \
84 break; \
85 ptr_1001--; \
86 } \
87 fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: " fmt, ptr_1001 + 1, line_1001, ##args); \
88 } while(0)
89
90#define LOGE(fmt, args...) \
91 do{ \
92 char *file_ptr_1001 = __FILE__; \
93 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
94 char line_1001[10] = {0}; \
95 sprintf(line_1001, "%d", __LINE__); \
96 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
97 if(*ptr_1001 == '/') \
98 break; \
99 ptr_1001--; \
100 } \
101 fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: " fmt, ptr_1001 + 1, line_1001, ##args); \
102 } while(0)
103
104
105#define GSW_HAL_SUCCESS 0
106#define GSW_HAL_FAIL -1 //表示失败(通用性)
107#define GSW_HAL_MEM_INVAILD -2 //表示入参地址为NULL
108
109#define OUT_MAX_SIZE 1024
110#define LINE __LINE__
111#define FUNC __FUNCTION__
112#define AT_EXTERSION_SOCKET_NAME "/tmp/atcmdext"
113#define SOCKET_ZERO 0
114#define SOCKET_SUCC 1
115#define SOCKET_FAIL -1
116
117typedef void (*mbtk_log)(int level, const char *format,...);
118typedef enum
119{
120 A_SUCCESS = 0,
121 A_ERROR = -1
122}LYNQ_AT_E;
123
124static mbtk_log fun_ptr_log = NULL;
125void *dlHandle_at = NULL;
126char *lynqLib_at = "/lib/libmbtk_lib.so";
127char *output = NULL;
128int sockfd = 0;
129int result = A_SUCCESS;
130char buffer_at[OUT_MAX_SIZE] = {0};
131struct sockaddr_in addr_serv;
132struct sockaddr_un addr_server;
133AT_CALLBACK tmp = NULL;
134static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
135socklen_t len;
136bool connect_state = false;
137
138
139int socket_local_client (char* name) {
140 LOGD("[%d][%s] enter",LINE,FUNC);
141 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
142 if (sockfd < 0)
143 {
144 LOGD("Can't open stream socket (%s)", name);
145 return -1;
146 }
147 addr_server.sun_family = AF_UNIX;
148 memset(addr_server.sun_path, '\0', sizeof(addr_server.sun_path));
149 strncpy(addr_server.sun_path, name, sizeof(addr_server.sun_path) - 1);
150 if (connect(sockfd, (struct sockaddr *) &addr_server, sizeof(struct sockaddr_un)) < 0)
151 {
152 close(sockfd);
153 LOGD("Can't connect to server side, path: %s, %s", name, strerror(errno));
154 return -1;
155 }
156 LOGD("[%d][%s] connect %s success",LINE,FUNC,name);
157 return sockfd;
158}
159bool send_msg_to_service(int fd,char *msg,int size)
160{
161 LOGD("[%d][%s] enter",LINE,FUNC);
162 if (fd < 0)
163 {
164 LOGD("fd invalid when send to atci service. errno = %d", errno);
165 return false;
166 }
167 if(NULL == msg)
168 {
169 LOGD("atcmd is null.");
170 return false;
171 }
172 int sendLen = send(fd, msg, size, 0);
173 if (sendLen != size)
174 {
175 LOGD("lose data when send to atci service. errno = %d", errno);
176 return false;
177 }
178 LOGD("client send to app demo: %s", msg);
179 return true;
180}
181
182int atsvc_cmd_recv(int fd, char *buf, int len)
183{
184 int ret = 0;
185 ret = recv(fd, buf, len, 0);
186 LOGD("[%d][%s] recv after",LINE,FUNC);
187 if (ret < 0)
188 {
189 LOGD("acti_cmd_recv client select error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
190 return SOCKET_FAIL;
191 }
192 else if(ret == 0)
193 {
194 LOGD("acti_cmd_recv client recv error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
195 return SOCKET_ZERO;
196 }
197 return SOCKET_SUCC;
198}
199/**
200 * @brief send third cmd to service and receive input,then send output to service
201 *
202 * @param parm
203 * @return void*
204 */
205void *thread_recv(void *parm)
206{
207 LOGD("[%d][%s] enter",LINE,FUNC);
208 char at_cmd[100] = {0};
209 int fd = -1;
210 int ret = 0;
211 fd = socket_local_client(AT_EXTERSION_SOCKET_NAME);
212 if(fd <= 0)
213 {
214 LOGE("socket_local_client fail\n");
215 connect_state = false;
216 pthread_mutex_unlock(&s_startupMutex);
217 return NULL;
218 }
219 int len_buf = strlen(buffer_at);
220 if(!send_msg_to_service(fd,buffer_at,len_buf))
221 {
222 LOGE("send_msg_to_service fail\n");
223 connect_state = false;
224 pthread_mutex_unlock(&s_startupMutex);
225 return NULL;
226 }
227 connect_state = true;
228 pthread_mutex_unlock(&s_startupMutex);
229 char *input = NULL;
230 output = (char *)malloc(sizeof(char)*OUT_MAX_SIZE);
231 if(NULL == output)
232 {
233 LOGE("thread_recv malloc fail\n");
234 return NULL;
235 }
236 TryNewLink:
237 if(connect_state == false)
238 {
239 if (connect(fd, (struct sockaddr *) &addr_server, sizeof(struct sockaddr_un)) < 0)
240 {
241 close(fd);
242 LOGE("Can't connect to server side, path: %s, errno:%d", AT_EXTERSION_SOCKET_NAME, errno);
243 return NULL;
244 }
245 connect_state = true;
246 }
247 while (1)
248 {
249 /*receive at cmd*/
250 memset(at_cmd, 0, sizeof(at_cmd));
251 ret = atsvc_cmd_recv(fd, at_cmd,sizeof(at_cmd));
252 if (ret < 0)
253 {
254 LOGE("[%d][%s]receive CMD error",LINE,FUNC);
255 continue;
256 }
257 else if(ret == SOCKET_ZERO)
258 {
259 LOGE("maybe client socket closed 1. retry new link!");
260 connect_state = false;
261 goto TryNewLink;
262 }
263 input = at_cmd;
264 int len = strlen(input);
265 while (len > 0 && (input[len - 1] == '\r' || input[len - 1] == '\n'))
266 {
267 input[--len] = '\0';
268 }
269 //begin deal with callback
270 tmp(input, output, OUT_MAX_SIZE);
271 LOGD("lynq_reg_third_at send output to service\n");
272 if(!send_msg_to_service(fd,output, strlen(output)))
273 {
274 LOGE("thread_recv send fail\n");
275 continue;
276 }
277 }
278 free(output);
279 output = NULL;
280 if(fd != 0)
281 {
282 close(fd);
283 }
284 return NULL;
285}
286
287/**
288 * @brief Threads are created to communicate with the server
289 *
290 * @return int
291 */
292int lynq_connect_service_start(void)
293{
294 LOGD("[%d][%s] enter",LINE,FUNC);
295 pthread_t lynq_at_tid;
296 int rt = pthread_create(&lynq_at_tid, NULL, thread_recv, NULL);
297 pthread_mutex_lock(&s_startupMutex);
298 LOGD("[%d][%s] pthread mutex unlock",LINE,FUNC);
299 if((connect_state != true) && rt < 0)
300 {
301 LOGE("connect fail,rt:%d,connect state:%d\n",rt,connect_state);
302 return -1;
303 }
304 return 0;
305}
306
307/**
308 * @brief Type:[IN] send third at cmd to service
309 * @param ext_at Type:[IN] input at cmd
310 * @param callback Type:[IN]
311 * @return int
312 */
313int32_t gsw_reg_atcmd(const char *atcmd,AT_CALLBACK func)
314{
315 if(NULL == atcmd || NULL == func)
316 {
317 return GSW_HAL_FAIL;
318 }
319 dlHandle_at = dlopen(lynqLib_at, RTLD_NOW);
320 fun_ptr_log = (mbtk_log)dlsym(dlHandle_at, "mbtk_log");
321 if(fun_ptr_log == NULL || dlHandle_at == NULL)
322 {
323 return GSW_HAL_FAIL;
324 }
325 memcpy(buffer_at, atcmd, strlen(atcmd));
326 tmp = func;
327 LOGD("lynq_reg_third_at start\n");
328 int ret = lynq_connect_service_start();
329
330 if(ret != 0)
331 {
332 LOGE("lynq_connect_service_start start failed\n");
333 return GSW_HAL_FAIL;
334 }
335 LOGD("lynq_connect_service_start success ret:%d\n",ret);
336 return GSW_HAL_SUCCESS;
337}
338
339int32_t gsw_sdk_at_init(void)
340{
341 return GSW_HAL_SUCCESS;
342}