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