blob: c240d9f2f71674ea3791e3e1a8c409a3dc7a9c62 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001#include <string.h> //strstr
2#include <dirent.h>
3#include <sys/stat.h> //mkdir
4#include <stdio.h>
5#include <stdlib.h>
6#include <errno.h>
7#include <sys/time.h>
8#include <time.h>
9#include <stddef.h> // offsetof
10#include <stdarg.h>
11#include <unistd.h> // usleep
12#include <sys/socket.h>
13#include <fcntl.h>
14#include <arpa/inet.h> // inet_addr
15#include <sys/un.h> // struct sockaddr_un
16#include <pthread.h>
17#include <sys/epoll.h>
18#include <signal.h>
19#include <semaphore.h>
20#include <signal.h> //struct sigevent
21#include <string.h> //memset, strncpy
22#include <netdb.h> //struct addrinfo
23#include <sys/types.h> //gettid
24#include <netinet/in.h> //struct sockaddr_in
25#include <netinet/tcp.h> //TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT
26#include <netinet/ip.h> //IPTOS_LOWDELAY
27#include <sys/epoll.h> //epoll_create
28#include <semaphore.h> //sem_t
29#include <inttypes.h> //PRId64
30#include <stdbool.h>
31#include "geofence.h"
32//------------------MTK LBS Utility---------------------------------------------------
33#ifndef LOGD
34#define LOGD(...) { printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
35#define LOGW(...) { printf("\E[1;35;40m"); printf(__VA_ARGS__); printf("\E[0m"); printf("\n"); fflush(stdout); }
36#define LOGE(...) { printf("\E[1;31;40m"); printf(__VA_ARGS__); printf("\E[0m"); printf("\n"); fflush(stdout); }
37#define LOGI(...) { printf("\E[1;35;40m"); printf(__VA_ARGS__); printf("\E[0m"); printf("\n"); fflush(stdout); }
38#endif
39
40#define GEOFENCEADP_MNL_TCP_DATA "mtk_geofenceadp_mnl_data"
41#define GEOFENCEADP_MNL_TCP_CONTROL "mtk_geofenceadp_mnl_control"
42
43//#define AT_COMMAND_PRINT
44
45#define MTK_ADD_GEOFENCE_SUCCESS 0
46#define MTK_ADD_GEOFENCE_ERROR -1
47#define MTK_ADD_GEOFENCE_INSUFFICIENT_MEM -2
48#define MTK_ADD_GEOFENCE_TOO_MANY -3
49
50#define MNLD_STRNCPY(dst,src,size) do{\
51 strncpy((char *)(dst), (src), (size - 1));\
52 (dst)[size - 1] = '\0';\
53 }while(0)
54
55#define GEOFENCE_BUFF_SIZE (1 * 1024)
56#define GEOFENCE_DATAPATH_SIZE (10*1024)
57
58typedef struct {
59 int type; //MTK_GFC_COMMAND_T
60 unsigned int length;
61} mtk_geofence_msg;
62
63typedef struct {
64 bool geofence_support;
65 int server_data_fd;
66}mtk_geofence_server_init_msg;
67
68typedef enum {
69 GEOFENCE_SERVER_CAP,//geofence server capability
70 EXCUTE_RESULT,
71 GEOFENCE_NUM,
72 GEOFENCE_RESPONSE_INFO,
73 GEOFENCE_ALERT_INFO,
74 GNSS_TRACKING_STATUS,
75} mtk_geofence_ret_command;
76
77typedef struct mtk_geofence_create_status {
78 int createstat;// success : 0, error : -1, insufficient_memory : -2, too many fences : -3
79 int id;
80}mtk_geofence_create_status;
81
82typedef struct {
83 int cmdtype;//mtk_geofence_command
84 int result;
85} mtk_geofence_result;
86
87typedef struct cyclical_buffer{
88 char *next_write;
89 char *next_read;
90 char *start_buffer;
91 char *end_buffer;
92 int buffer_size;
93} cyclical_buffer_t;
94
95static char geofence_raw_data[GEOFENCE_DATAPATH_SIZE] = {0};
96static cyclical_buffer_t g_cyclical_buffer; // io - cyclic buffer
97int server_data_fd = -1;
98
99//-1 means fail or serverfd is returned
100static int geofenceinf_socket_tcp_client_connect_local(bool abstract, const char* name) {
101 int fd;
102 int size;
103 struct sockaddr_un addr;
104
105 memset(&addr, 0, sizeof(addr));
106 addr.sun_family = AF_UNIX;
107 size = strlen(name) + offsetof(struct sockaddr_un, sun_path) + 1;
108 if(abstract) {
109 addr.sun_path[0] = 0;
110 memcpy(addr.sun_path + 1, name, strlen(name));
111 } else {
112 strncpy(addr.sun_path, name, sizeof(addr.sun_path));
113 if(unlink(addr.sun_path) == -1) {
114 LOGW("geofenceinf_socket_tcp_client_connect_local() unlink() failed, reason=[%s]%d",
115 strerror(errno), errno);
116 }
117 }
118 fd = socket(AF_UNIX, SOCK_STREAM, 0);
119 if(fd == -1) {
120 LOGE("geofenceinf_socket_tcp_client_connect_local() socket() failed, reason=[%s]%d",
121 strerror(errno), errno);
122 return -1;
123 }
124 if(connect(fd, (struct sockaddr*)&addr, size) == -1) {
125 LOGE("geofenceinf_socket_tcp_client_connect_local() connect() failed, abstruct=%d name=[%s] reason=[%s]%d",
126 abstract, name, strerror(errno), errno);
127 close(fd);
128 return -1;
129 }
130
131 return fd;
132}
133
134void geofenceinf_buffer_initialize
135 ( cyclical_buffer_t *buffer, // buffer to initialize
136 unsigned int buffer_size ) // size of buffer to create
137{
138 // Set up buffer manipulation pointers
139 // end_buffer points to the next byte after the buffer
140 buffer->end_buffer = buffer->start_buffer + buffer_size;
141 buffer->next_read = buffer->start_buffer;
142 buffer->next_write = buffer->start_buffer;
143 buffer->buffer_size = buffer_size;
144 return;
145}
146
147int geofenceinf_check_fence_vadility(mtk_geofence_property *fence) {
148 if ((fence->latest_state != GEOFENCE_ENTERED)
149 && (fence->latest_state != GEOFENCE_EXITED)
150 && (fence->latest_state != GEOFENCE_UNKNOWN)){
151 LOGE("geofenceinf_check_fence_vadility latest_state:%d fail", fence->latest_state);
152 return MTK_GFC_ERROR;
153 }
154
155 if (!(fence->monitor_transition & MTK_GEOFENCE_ENTER) && !(fence->monitor_transition & MTK_GEOFENCE_EXIT)){
156 LOGE("geofenceinf_check_fence_vadility monitor_transition:%d fail", fence->monitor_transition);
157 return MTK_GFC_ERROR;
158 }
159
160 return MTK_GFC_SUCCESS;
161}
162
163int geofenceinf_socket_set_blocking(int fd, int blocking) {
164 if (fd < 0) {
165 LOGE("geofenceinf_socket_set_blocking() invalid fd=%d", fd);
166 return -1;
167 }
168
169 int flags = fcntl(fd, F_GETFL, 0);
170 if (flags == -1) {
171 LOGE("geofenceinf_socket_set_blocking() fcntl() failed invalid flags=%d reason=[%s]%d",
172 flags, strerror(errno), errno);
173 return -1;
174 }
175
176 flags = blocking ? (flags&~O_NONBLOCK) : (flags|O_NONBLOCK);
177 return (fcntl(fd, F_SETFL, flags) == 0) ? 0 : -1;
178}
179
180int geofenceinf_epoll_add_fd2(int epfd, int fd, uint32_t events) {
181 struct epoll_event ev;
182 memset(&ev, 0, sizeof(ev));
183 ev.data.fd = fd;
184 ev.events = events;
185 // don't set the fd to edge trigger
186 // the some event like accept may be lost if two or more clients are connecting to server at the same time
187 // level trigger is preferred to avoid event lost
188 // do not set EPOLLOUT due to it will always trigger when write is available
189 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
190 LOGE("epoll_add_fd2() epoll_ctl() failed reason=[%s]%d epfd=%d fd=%d",
191 strerror(errno), errno, epfd, fd);
192 return -1;
193 }
194 return 0;
195}
196
197int geofenceinf_socket_bind_udp(const char* path) {
198 int fd;
199 struct sockaddr_un addr;
200
201 fd = socket(PF_LOCAL, SOCK_DGRAM, 0);
202 if (fd < 0) {
203 LOGE("socket_bind_udp() socket() failed reason=[%s]%d",
204 strerror(errno), errno);
205 return -1;
206 }
207 LOGD("fd=%d,path=%s", fd, path);
208
209 memset(&addr, 0, sizeof(addr));
210 addr.sun_path[0] = 0;
211 MNLD_STRNCPY(addr.sun_path + 1, path,sizeof(addr.sun_path) - 1);
212 addr.sun_family = AF_UNIX;
213 unlink(addr.sun_path);
214 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
215 LOGE("socket_bind_udp() bind() failed path=[%s] reason=[%s]%d",
216 path, strerror(errno), errno);
217 close(fd);
218 return -1;
219 }
220 return fd;
221}
222
223
224// -1 means failure
225int geofenceinf_safe_sendto(const char* path, const char* buff, int len) {
226 int ret = 0;
227 struct sockaddr_un addr;
228 int retry = 10;
229 int fd = socket(PF_LOCAL, SOCK_DGRAM, 0);
230 if (fd < 0) {
231 LOGE("safe_sendto() socket() failed reason=[%s]%d",
232 strerror(errno), errno);
233 return -1;
234 }
235
236 int flags = fcntl(fd, F_GETFL, 0);
237 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1){
238 LOGE("fcntl failed reason=[%s]%d",
239 strerror(errno), errno);
240
241 close(fd);
242 return -1;
243 }
244
245 memset(&addr, 0, sizeof(addr));
246 addr.sun_path[0] = 0;
247 MNLD_STRNCPY(addr.sun_path + 1, path,sizeof(addr.sun_path) - 1);
248 addr.sun_family = AF_UNIX;
249
250 while ((ret = sendto(fd, buff, len, 0,
251 (const struct sockaddr *)&addr, sizeof(addr))) == -1) {
252 if (errno == EINTR) continue;
253 if (errno == EAGAIN) {
254 if (retry-- > 0) {
255 usleep(100 * 1000);
256 continue;
257 }
258 }
259 LOGE("safe_sendto() sendto() failed path=[%s] ret=%d reason=[%s]%d",
260 path, ret, strerror(errno), errno);
261 break;
262 }
263
264 close(fd);
265 return ret;
266}
267void geofenceinf_client_init(void)
268{
269 g_cyclical_buffer.start_buffer = &geofence_raw_data[0];
270 geofenceinf_buffer_initialize(&g_cyclical_buffer, GEOFENCE_DATAPATH_SIZE);
271}
272
273int geofenceinf_get_server_init_msg(int fd, mtk_geofence_callback *callback)
274{
275 int ret;
276 int recv_len = 0;
277 unsigned int read_count = 0, msg_len = 0;
278 char buffer[GEOFENCE_BUFF_SIZE] = {0};
279 char data[GEOFENCE_BUFF_SIZE] = {0};
280 mtk_geofence_msg *prmsg = NULL;
281 mtk_geofence_server_init_msg server_init_msg;
282 mtk_geofence_server_capability cap;
283
284 memset(&server_init_msg, 0, sizeof(mtk_geofence_server_init_msg));
285 //receive geofence server ack capability & server data fd
286 do {
287 ret = read(fd, buffer, GEOFENCE_BUFF_SIZE);
288 if(ret == -1) {
289 LOGW("geofenceinf_get_server_init_msg() read() fd=[%d] failed, reason=[%s]%d", fd, strerror(errno), errno);
290 return ret;
291 } else if(ret == 0) {
292 LOGW("geofenceinf_get_server_init_msg() read() fd=[%d] find the remote side has closed the session", fd);
293 return ret;
294 } else {
295 memcpy((char *)(data + recv_len), buffer, ret);
296 recv_len += ret;
297 read_count++;
298 if ((recv_len >= sizeof(mtk_geofence_msg)) && (msg_len == 0)){
299 prmsg = (mtk_geofence_msg *)&buffer[0];
300 msg_len = prmsg->length;
301 }
302 if (read_count >= 10){
303 LOGW("geofenceinf_get_server_init_msg() read() fd:%d too much counts:%d", fd, read_count);
304 return MTK_GFC_ERROR;
305 }
306 }
307 memset(buffer, 0, GEOFENCE_BUFF_SIZE);
308 } while((recv_len < msg_len) || (msg_len == 0));
309
310 msg_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_server_init_msg);
311 prmsg = (mtk_geofence_msg *)&data[0];
312 if (prmsg->length == msg_len){
313 memcpy(&server_init_msg, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_server_init_msg));
314 } else if (prmsg->length > msg_len) {
315 memcpy(&server_init_msg, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_server_init_msg));
316 LOGD("mnl msg len:%d > struct len:%d", prmsg->length, msg_len);
317 } else {
318 memset(buffer, 0, GEOFENCE_BUFF_SIZE);
319 memcpy(buffer, (char*)prmsg, prmsg->length);
320 memset((char *)(buffer + prmsg->length), 0, (msg_len - prmsg->length));
321 memcpy(&server_init_msg, (((char*)buffer)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_server_init_msg));
322 LOGD("mnl msg len:%d < struct len:%d", prmsg->length, msg_len);
323 }
324
325 if (server_init_msg.server_data_fd >= 0){
326 server_data_fd = server_init_msg.server_data_fd;
327 LOGD("geofenceinf_get_server_init_msg:server data fd:%d", server_data_fd);
328 }
329
330 if (callback->geofence_capability_update != NULL){
331 memset(&cap, 0, sizeof(mtk_geofence_server_capability));
332 cap.geofence_support = server_init_msg.geofence_support;
333 callback->geofence_capability_update(&cap);
334 }
335 return MTK_GFC_SUCCESS;
336}
337
338int geofenceinf_client_register(const char* name, mtk_geofence_callback *callback)
339{
340 int fd;
341
342 if ( (fd = geofenceinf_socket_tcp_client_connect_local(true, GEOFENCEADP_MNL_TCP_DATA)) < 0){
343 LOGE("Geofence connect server failed:%d", fd);
344 } else {
345 LOGD("Geofence new client [%s], fd:%d", name, fd);
346 geofenceinf_client_init();
347 if (geofenceinf_get_server_init_msg(fd, callback) < 0){
348 close(fd);
349 return MTK_GFC_ERROR;
350 }
351 geofenceinf_socket_set_blocking(fd, 0);
352 }
353
354 return fd;
355}
356
357int geofenceinf_send2mnl(int fd, const char* buff, int len) {
358 int ret = write(fd, buff, len);
359 LOGD("geofence_send2mnl() write():length:%d", len);
360 if(ret == -1) {
361 LOGE("geofence_send2mnl() write() failed, reason=[%s]%d", strerror(errno), errno);
362 }
363 return ret;
364}
365
366int geofenceinf_safe_recv(int fd, char* buff, int len) {
367 int ret = 0;
368 int retry = 10;
369
370 while ((ret = read(fd, buff, len)) == -1) {
371 LOGW("geofenceinf_safe_recv() ret=%d len=%d", ret, len);
372 if (errno == EINTR) continue;
373 if (errno == EAGAIN) {
374 if (retry-- > 0) {
375 usleep(100 * 1000);
376 continue;
377 }
378 }
379 LOGE("geofenceinf_safe_recv() recvfrom() failed reason=[%s]%d",
380 strerror(errno), errno);
381 break;
382 }
383 return ret;
384}
385
386int geofenceinf_control_path_safe_recv(int fd, char* buff, int len, int expect_len) {
387 int ret = 0, ret1 = 0;
388 int retry = 10;
389 char data[GEOFENCE_BUFF_SIZE] = {0};
390
391 ret = read(fd, buff, len);
392 if(ret == -1) {
393 LOGW("geofenceinf_control_path_safe_recv() read() fd=[%d] failed, reason=[%s]%d",
394 fd, strerror(errno), errno);
395 return ret;
396 } else if(ret == 0) {
397 LOGW("geofenceinf_control_path_safe_recv() read() fd=[%d] find the remote side has closed the session", fd);
398 return ret;
399 }
400
401 if (ret < expect_len){
402 //set fd non-blocking, try it again.
403 geofenceinf_socket_set_blocking(fd, 0);
404 while ((ret1 = read(fd, data, GEOFENCE_BUFF_SIZE)) == -1) {
405 LOGW("geofenceinf_control_path_safe_recv() ret=%d", ret1);
406 if (errno == EINTR) continue;
407 if (errno == EAGAIN) {
408 if (retry-- > 0) {
409 usleep(100 * 1000);
410 continue;
411 }
412 }
413 LOGE("geofenceinf_safe_recv() recvfrom() failed reason=[%s]%d",
414 strerror(errno), errno);
415 break;
416 }
417 if ((ret1 > 0) && ((ret + ret1) < len)){
418 memcpy((char *)(buff + ret), data, ret1);
419 ret = ret + ret1;
420 }
421 }
422
423 return ret;
424}
425
426int geofenceinf_geofence_add_result(mtk_geofence_msg *prmsg, mtk_geofence_create_status *fence_ret) {
427 unsigned int msg_len;
428 #ifdef AT_COMMAND_PRINT
429 char data[GEOFENCE_BUFF_SIZE] = {0};
430 #endif
431
432 msg_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_create_status);
433 if (prmsg->length == msg_len){
434 memcpy(fence_ret, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_create_status));
435 } else {
436 //LOGE("geofenceinf_geofence_add_result:message len error %d %d",prmsg->length, msg_len);
437 return MTK_GFC_ERROR;
438 }
439
440 #ifdef AT_COMMAND_PRINT
441 /*Construct AT command */
442 if (fence_ret->createstat == MTK_ADD_GEOFENCE_SUCCESS){
443 sprintf(data, "+EGEOADDCIRCLE:%d,%d/r/n", fence_ret->createstat, fence_ret->id);
444 //Send AT command
445
446 } else {
447 sprintf(data, "+EGEOADDCIRCLE:%d/r/n", fence_ret->createstat);
448 //Send AT command
449 }
450 LOGD("AT command:%s",data);
451 #endif
452
453 return MTK_GFC_SUCCESS;
454}
455
456int geofenceinf_geofence_remove_result(mtk_geofence_msg *prmsg, mtk_geofence_result *remove_result) {
457 unsigned int msg_len;
458 #ifdef AT_COMMAND_PRINT
459 char data[GEOFENCE_BUFF_SIZE] = {0};
460 #endif
461
462 msg_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_result);
463 if (prmsg->length == msg_len){
464 memcpy(remove_result, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_result));
465 } else {
466 //LOGE("geofenceinf_get_remove_result:message len error %d %d",prmsg->length, msg_len);
467 return MTK_GFC_ERROR;
468 }
469
470 #ifdef AT_COMMAND_PRINT
471 /*Construct AT command */
472 if (remove_result->result == 0){
473 sprintf(data, "OK/r/n");
474 } else {
475 sprintf(data, "FAIL/r/n");
476 }
477 LOGD("AT command:%s",data);
478 #endif
479
480 return MTK_GFC_SUCCESS;
481}
482
483int geofenceinf_geofence_clear_result(mtk_geofence_msg *prmsg, mtk_geofence_result *clear_result) {
484 unsigned int msg_len;
485 #ifdef AT_COMMAND_PRINT
486 char data[GEOFENCE_BUFF_SIZE] = {0};
487 #endif
488
489 msg_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_result);
490 if (prmsg->length == msg_len){
491 memcpy(clear_result, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_result));
492 } else {
493 //LOGE("geofenceinf_geofence_clear_result:message len error %d %d",prmsg->length, msg_len);
494 return MTK_GFC_ERROR;
495 }
496
497 #ifdef AT_COMMAND_PRINT
498 /*Construct AT command */
499 if (clear_result->result == 0){
500 sprintf(data, "OK/r/n");
501 } else {
502 sprintf(data, "FAIL/r/n");
503 }
504 LOGD("AT command:%s",data);
505 #endif
506
507 return MTK_GFC_SUCCESS;
508}
509
510int geofenceinf_geofence_get_geofences_num(mtk_geofence_msg *prmsg, int *fence_nums) {
511 unsigned int msg_len;
512 #ifdef AT_COMMAND_PRINT
513 char data[GEOFENCE_BUFF_SIZE] = {0};
514 #endif
515
516 msg_len = sizeof(mtk_geofence_msg) + sizeof(int);
517 if (prmsg->length == msg_len){
518 memcpy(fence_nums, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(int));
519 } else {
520 //LOGE("geofenceinf_geofence_get_geofences_numgeofenceinf_geofence_get_geofences_numgeofenceinf_geofence_get_geofences_num:message len error %d %d",prmsg->length, msg_len);
521 return MTK_GFC_ERROR;
522 }
523
524 #ifdef AT_COMMAND_PRINT
525 /*Construct AT command */
526 sprintf(data, "+EGEOMAX: :%d/r/n", *fence_nums);
527 LOGD("AT command:%s",data);
528 #endif
529
530 return MTK_GFC_SUCCESS;
531}
532
533// GNSS Adaptor --> MNLD Message
534int geofenceinf_add_geofence(mtk_geofence_property *fence) {
535 int ret;
536 mtk_geofence_msg *geo_header = NULL;
537 unsigned int msg_len;
538 int recv_len, expect_len;
539 char buffer[GEOFENCE_BUFF_SIZE] = {0};
540 char geo_data[GEOFENCE_BUFF_SIZE] = {0};
541 mtk_geofence_create_status fence_status;
542 int fd = -1, temp_server_data_fd = -1;
543 mtk_geofence_msg *prmsg = NULL;
544
545 LOGD("geofence_add_geofences");
546 if (server_data_fd < 0){
547 LOGE("geofenceinf_add_geofence:wait server data fd");
548 return -1;
549 } else {
550 temp_server_data_fd = server_data_fd;
551 }
552 /* For geofence recover mechanism */
553 ret = geofenceinf_check_fence_vadility(fence);
554 if(ret < 0) {
555 LOGE("geofenceinf_check_fence_vadility fail");
556 return -1;
557 }
558
559 //construct add fence cmd
560 msg_len = sizeof(mtk_geofence_msg) + sizeof(int) + sizeof(mtk_geofence_property);
561 geo_header = (mtk_geofence_msg *)&geo_data[0];
562 if (msg_len > GEOFENCE_BUFF_SIZE){
563 LOGE("geofenceinf message length too long:%d", msg_len);
564 return MTK_GFC_ERROR;
565 }
566 //construct total message
567 //construct header
568 geo_header->type = ADD_GEOFENCE_AREA;
569 geo_header->length = msg_len;
570 //input server data fd
571 memcpy( ((char*)geo_header) + sizeof(mtk_geofence_msg), &temp_server_data_fd, sizeof(int));
572 //input geofence property payload
573 memcpy( ((char*)geo_header) + sizeof(mtk_geofence_msg) + sizeof(int), fence, sizeof(mtk_geofence_property));
574
575 //Create TCP client fd, and connect tcp server
576 if ( (fd = geofenceinf_socket_tcp_client_connect_local(true, GEOFENCEADP_MNL_TCP_CONTROL)) < 0){
577 LOGE("geofenceinf_add_geofence:create client fd failed:%d", fd);
578 return -1;
579 }
580
581 ret = geofenceinf_send2mnl(fd, (char *)geo_header, msg_len);
582 if(ret < 0) {
583 LOGE("geofenceinf_add_geofence:send message to mnl failed");
584 close(fd);
585 return -1;
586 }
587
588 //wait ack
589 expect_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_create_status);
590 if ( (recv_len = geofenceinf_control_path_safe_recv(fd, buffer, GEOFENCE_BUFF_SIZE, expect_len)) <= 0){
591 LOGE("geofenceinf_add_geofence:don't recv any data");
592 close(fd);
593 return -1;
594 } else {
595 prmsg = (mtk_geofence_msg *)&buffer[0];
596 ret = geofenceinf_geofence_add_result(prmsg, &fence_status);
597 if (ret == MTK_GFC_ERROR){
598 LOGE("geofenceinf_add_geofence:message data don't match struct %d %d", recv_len, expect_len);
599 close(fd);
600 return -1;
601 }
602 }
603
604 if (fence_status.createstat == 0){
605 close(fd);
606 return fence_status.id;
607 } else {
608 close(fd);
609 return fence_status.createstat;
610 }
611}
612
613int geofenceinf_remove_geofence(const int geofence_id) {
614 int ret;
615 mtk_geofence_msg *geo_header=NULL;
616 unsigned int msg_len;
617 int recv_len;
618 int expect_len;
619 char buffer[GEOFENCE_BUFF_SIZE] = {0};
620 char geo_data[GEOFENCE_BUFF_SIZE] = {0};
621 int fd = -1, temp_server_data_fd = -1;
622 mtk_geofence_msg *prmsg = NULL;
623 mtk_geofence_result remove_result;
624
625 LOGD("geofence_remove_geofences,fence id:%d", geofence_id);
626 if (server_data_fd < 0){
627 LOGE("geofenceinf_remove_geofence:wait server data fd");
628 return MTK_GFC_ERROR;
629 } else {
630 temp_server_data_fd = server_data_fd;
631 }
632
633 //construct remove fence cmd
634 msg_len = sizeof(mtk_geofence_msg) + sizeof(int) + sizeof(int);
635 geo_header = (mtk_geofence_msg *)&geo_data[0];
636 if (msg_len > GEOFENCE_BUFF_SIZE){
637 LOGE("geofenceinf message length too long:%d", msg_len);
638 return MTK_GFC_ERROR;
639 }
640
641 //construct total message
642 //construct header
643 geo_header->type = REMOVE_GEOFENCE;
644 geo_header->length = msg_len;
645 //input server data fd
646 memcpy( ((char*)geo_header) + sizeof(mtk_geofence_msg), &temp_server_data_fd, sizeof(int));
647 //input geofence property payload
648 memcpy( ((char*)geo_header) + sizeof(mtk_geofence_msg) + sizeof(int), &geofence_id, sizeof(int));
649
650 //Create TCP client fd, and connect tcp server
651 if ( (fd = geofenceinf_socket_tcp_client_connect_local(true, GEOFENCEADP_MNL_TCP_CONTROL)) < 0){
652 LOGE("geofenceinf_remove_geofence:create client fd failed:%d", fd);
653 return MTK_GFC_ERROR;
654 }
655
656 ret = geofenceinf_send2mnl(fd, (char *)geo_header, msg_len);
657 if(ret < 0) {
658 LOGE("geofenceinf_remove_geofence:send message to mnl failed");
659 close(fd);
660 return MTK_GFC_ERROR;
661 }
662
663 //wait ack
664 expect_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_result);
665 if ( (recv_len = geofenceinf_control_path_safe_recv(fd, buffer, GEOFENCE_BUFF_SIZE, expect_len)) <= 0){
666 LOGE("geofenceinf_remove_geofence:don't recv any data");
667 close(fd);
668 return MTK_GFC_ERROR;
669 } else {
670 prmsg = (mtk_geofence_msg *)&buffer[0];
671 ret = geofenceinf_geofence_remove_result(prmsg, &remove_result);
672 if (ret == MTK_GFC_ERROR){
673 LOGE("geofenceinf_remove_geofence:message data don't match struct %d %d", recv_len, expect_len);
674 close(fd);
675 return MTK_GFC_ERROR;
676 }
677 }
678
679 if (remove_result.result == 0){
680 close(fd);
681 return MTK_GFC_SUCCESS;
682 } else {
683 close(fd);
684 return MTK_GFC_ERROR;
685 }
686}
687
688int geofenceinf_clear_geofences(void) {
689 int ret;
690 mtk_geofence_msg *geo_header=NULL;
691 unsigned int msg_len;
692 int recv_len;
693 int expect_len;
694 char buffer[GEOFENCE_BUFF_SIZE] = {0};
695 char geo_data[GEOFENCE_BUFF_SIZE] = {0};
696 int fd = -1, temp_server_data_fd = -1;
697 mtk_geofence_msg *prmsg = NULL;
698 mtk_geofence_result clear_result;
699
700 LOGD("geofence_clear_geofences");
701 if (server_data_fd < 0){
702 LOGE("geofenceinf_clear_geofences:wait server data fd");
703 return MTK_GFC_ERROR;
704 } else {
705 temp_server_data_fd = server_data_fd;
706 }
707
708 //construct remove fence cmd
709 msg_len = sizeof(mtk_geofence_msg) + sizeof(int);
710 geo_header = (mtk_geofence_msg *)&geo_data[0];
711 if (msg_len > GEOFENCE_BUFF_SIZE){
712 LOGE("geofenceinf message length too long:%d", msg_len);
713 return MTK_GFC_ERROR;
714 }
715
716 //construct total message
717 //construct header
718 geo_header->type = CLEAR_GEOFENCE;
719 geo_header->length = msg_len;
720 //input server data fd
721 memcpy( ((char*)geo_header) + sizeof(mtk_geofence_msg), &temp_server_data_fd, sizeof(int));
722
723 //Create TCP client fd, and connect tcp server
724 if ( (fd = geofenceinf_socket_tcp_client_connect_local(true, GEOFENCEADP_MNL_TCP_CONTROL)) < 0){
725 LOGE("geofenceinf_clear_geofences:create client fd failed:%d", fd);
726 return MTK_GFC_ERROR;
727 }
728
729 ret = geofenceinf_send2mnl(fd, (char *)geo_header, msg_len);
730 if(ret < 0) {
731 LOGE("geofenceinf_clear_geofences:send message to mnl failed");
732 close(fd);
733 return MTK_GFC_ERROR;
734 }
735
736 //wait ack
737 expect_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_result);
738 if ( (recv_len = geofenceinf_control_path_safe_recv(fd, buffer, GEOFENCE_BUFF_SIZE, expect_len)) <= 0){
739 LOGE("geofenceinf_clear_geofences:don't recv any data");
740 close(fd);
741 return MTK_GFC_ERROR;
742 } else {
743 prmsg = (mtk_geofence_msg *)&buffer[0];
744 ret = geofenceinf_geofence_clear_result(prmsg, &clear_result);
745 if (ret == MTK_GFC_ERROR){
746 LOGE("geofenceinf_clear_geofences:message data don't match struct %d %d", recv_len, expect_len);
747 close(fd);
748 return MTK_GFC_ERROR;
749 }
750 }
751
752 if (clear_result.result == 0){
753 close(fd);
754 return MTK_GFC_SUCCESS;
755 } else {
756 close(fd);
757 return MTK_GFC_ERROR;
758 }
759}
760
761int geofenceinf_query_geofences_num(void) {
762 int ret;
763 mtk_geofence_msg *geo_header=NULL;
764 unsigned int msg_len;
765 int recv_len;
766 int expect_len;
767 char buffer[GEOFENCE_BUFF_SIZE] = {0};
768 char geo_data[GEOFENCE_BUFF_SIZE] = {0};
769 int fence_nums;
770 int fd = -1, temp_server_data_fd = -1;
771 mtk_geofence_msg *prmsg = NULL;
772
773 LOGD("geofence_query_geofences_num");
774 if (server_data_fd < 0){
775 LOGE("geofence_query_geofences_num:wait server data fd");
776 return -1;
777 } else {
778 temp_server_data_fd = server_data_fd;
779 }
780
781 //construct remove fence cmd
782 msg_len = sizeof(mtk_geofence_msg) + sizeof(int);
783 geo_header = (mtk_geofence_msg *)&geo_data[0];
784 if (msg_len > GEOFENCE_BUFF_SIZE){
785 LOGE("geofenceinf message length too long:%d", msg_len);
786 return MTK_GFC_ERROR;
787 }
788
789 //construct total message
790 //construct header
791 geo_header->type = QUERY_GEOFENCE_NUM;
792 geo_header->length = msg_len;
793 //input server data fd
794 memcpy( ((char*)geo_header) + sizeof(mtk_geofence_msg), &temp_server_data_fd, sizeof(int));
795
796 //Create TCP client fd, and connect tcp server
797 if ( (fd = geofenceinf_socket_tcp_client_connect_local(true, GEOFENCEADP_MNL_TCP_CONTROL)) < 0){
798 LOGE("geofence_query_geofences_num:create client fd failed:%d", fd);
799 return -1;
800 }
801
802 ret = geofenceinf_send2mnl(fd, (char *)geo_header, msg_len);
803 if(ret < 0) {
804 LOGE("geofence_query_geofences_num:send message to mnl failed");
805 close(fd);
806 return MTK_GFC_ERROR;
807 }
808
809 //wait ack
810 expect_len = sizeof(mtk_geofence_msg) + sizeof(fence_nums);
811 if ( (recv_len = geofenceinf_control_path_safe_recv(fd, buffer, GEOFENCE_BUFF_SIZE, expect_len)) <= 0){
812 LOGE("geofence_query_geofences_num:don't recv any data");
813 close(fd);
814 return MTK_GFC_ERROR;
815 } else {
816 prmsg = (mtk_geofence_msg *)&buffer[0];
817 ret = geofenceinf_geofence_get_geofences_num(prmsg, &fence_nums);
818 if (ret == MTK_GFC_ERROR){
819 LOGE("geofence_query_geofences_num:message data don't match struct %d %d", recv_len, expect_len);
820 close(fd);
821 return MTK_GFC_ERROR;
822 }
823 }
824
825 if (fence_nums > 0){
826 close(fd);
827 return fence_nums;
828 } else {
829 close(fd);
830 return MTK_GFC_ERROR;
831 }
832}
833
834// GNSS Adaptor --> MNLD Message
835int geofenceinf_client_capability_config(mtk_geofence_client_capability *cap) {
836 int ret;
837 mtk_geofence_msg *geo_header=NULL;
838 char geo_data[GEOFENCE_BUFF_SIZE] = {0};
839 unsigned int msg_len;
840 int fd = -1, temp_server_data_fd = -1;
841
842 LOGD("geofenceinf_client_capability_config");
843 if (server_data_fd < 0){
844 LOGE("geofenceinf_client_capability_config:wait server data fd");
845 return -1;
846 } else {
847 temp_server_data_fd = server_data_fd;
848 }
849
850 //construct remove fence cmd
851 msg_len = sizeof(mtk_geofence_msg) + sizeof(int) + sizeof(mtk_geofence_client_capability);
852 geo_header = (mtk_geofence_msg *)&geo_data[0];
853 if (msg_len > GEOFENCE_BUFF_SIZE){
854 LOGE("geofenceinf message length too long:%d", msg_len);
855 return MTK_GFC_ERROR;
856 }
857
858 //construct total message
859 //construct header
860 geo_header->type = GEOFENCE_CLIENT_CAP;
861 geo_header->length = msg_len;
862 //input server data fd
863 memcpy( ((char*)geo_header) + sizeof(mtk_geofence_msg), &temp_server_data_fd, sizeof(int));
864 memcpy( ((char*)geo_header) + sizeof(mtk_geofence_msg) + sizeof(int), cap, sizeof(mtk_geofence_client_capability));
865
866 //Create TCP client fd, and connect tcp server
867 if ( (fd = geofenceinf_socket_tcp_client_connect_local(true, GEOFENCEADP_MNL_TCP_CONTROL)) < 0){
868 LOGE("geofenceinf_client_capability_config:create client fd failed:%d", fd);
869 return -1;
870 }
871
872 ret = geofenceinf_send2mnl(fd, (char *)geo_header, msg_len);
873 if(ret < 0) {
874 LOGE("geofenceinf_client_capability_config:send message to mnl failed");
875 close(fd);
876 return MTK_GFC_ERROR;
877 }
878 return MTK_GFC_SUCCESS;
879}
880
881void geofenceinf_server_capability_sync(mtk_geofence_msg *prmsg, mtk_geofence_callback *at_callback) {
882 mtk_geofence_server_capability cap;
883 unsigned int msg_len;
884 char data[GEOFENCE_BUFF_SIZE] = {0};
885
886 msg_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_server_capability);
887 if (prmsg->length == msg_len){
888 memcpy(&cap, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_server_capability));
889 } else if (prmsg->length > msg_len) {
890 memcpy(&cap, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_server_capability));
891 LOGD("mnl msg len:%d > struct len:%d", prmsg->length, msg_len);
892 } else {
893 memcpy(data, (char*)prmsg, prmsg->length);
894 memset((char *)(data + prmsg->length), 0, (msg_len - prmsg->length));
895 memcpy(&cap, (((char*)data)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_server_capability));
896 LOGD("mnl msg len:%d < struct len:%d", prmsg->length, msg_len);
897 }
898
899 if (at_callback->geofence_capability_update != NULL){
900 at_callback->geofence_capability_update(&cap);
901 }
902
903 return;
904}
905
906void geofenceinf_get_server_data_fd(mtk_geofence_msg *prmsg) {
907 int data_fd;
908 unsigned int msg_len;
909 char data[GEOFENCE_BUFF_SIZE] = {0};
910
911 msg_len = sizeof(mtk_geofence_msg) + sizeof(int);
912 if (prmsg->length == msg_len){
913 memcpy(&data_fd, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(int));
914 } else if (prmsg->length > msg_len) {
915 memcpy(&data_fd, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(int));
916 LOGD("mnl msg len:%d > struct len:%d", prmsg->length, msg_len);
917 } else {
918 memcpy(data, (char*)prmsg, prmsg->length);
919 memset((char *)(data + prmsg->length), 0, (msg_len - prmsg->length));
920 memcpy(&data_fd, (((char*)data)+sizeof(mtk_geofence_msg)), sizeof(int));
921 LOGD("mnl msg len:%d < struct len:%d", prmsg->length, msg_len);
922 }
923
924 if (data_fd < 0){
925 LOGD("geofenceinf_get_server_data_fd error");
926 } else {
927 server_data_fd = data_fd;
928 LOGD("geofenceinf_get_server_data_fd:%d", server_data_fd);
929 }
930
931 return;
932}
933
934void geofenceinf_geofence_alert(mtk_geofence_msg *prmsg, mtk_geofence_callback *at_callback) {
935 mtk_geofence_alert fence_alert;
936 unsigned int msg_len;
937 char data[GEOFENCE_BUFF_SIZE] = {0};
938
939 msg_len = sizeof(mtk_geofence_msg) + sizeof(mtk_geofence_alert);
940 if (prmsg->length == msg_len){
941 memcpy(&fence_alert, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_alert));
942 } else if (prmsg->length > msg_len) {
943 memcpy(&fence_alert, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_alert));
944 LOGD("mnl msg len:%d > struct len:%d", prmsg->length, msg_len);
945 } else {
946 memcpy(data, (char*)prmsg, prmsg->length);
947 memset((char *)(data + prmsg->length), 0, (msg_len - prmsg->length));
948 memcpy(&fence_alert, (((char*)data)+sizeof(mtk_geofence_msg)), sizeof(mtk_geofence_alert));
949 LOGD("mnl msg len:%d < struct len:%d", prmsg->length, msg_len);
950 }
951
952 #ifdef AT_COMMAND_PRINT
953 /*Construct AT command */
954 sprintf(data, "+EGEORESP:%d,%d,%.6f,%.6f,%.2f,%.2f,%.2f,%d,%d,%d,%d,%d,%.2f,%.2f,%.2f/r/n",
955 fence_alert.id,
956 fence_alert.alert_state,
957 fence_alert.latitude,
958 fence_alert.longitude,
959 fence_alert.altitude,
960 fence_alert.speed,
961 fence_alert.heading,
962 fence_alert.h_acc,
963 fence_alert.h_err_majoraxis,
964 fence_alert.h_err_minoraxis,
965 fence_alert.h_err_angle,
966 fence_alert.hor_conf,
967 fence_alert.pdop,
968 fence_alert.hdop,
969 fence_alert.vdop);
970 LOGD("AT command:%s",data);
971 #endif
972 //Send AT command
973 if (at_callback->geofence_fence_alert_callback != NULL){
974 at_callback->geofence_fence_alert_callback(&fence_alert);
975 }
976
977 return;
978}
979
980void geofenceinf_gnss_tracking_status(mtk_geofence_msg *prmsg, mtk_geofence_callback *at_callback) {
981 mtk_gnss_tracking_status tracking_Status;
982 unsigned int msg_len;
983 char data[GEOFENCE_BUFF_SIZE] = {0};
984
985 msg_len = sizeof(mtk_geofence_msg) + sizeof(mtk_gnss_tracking_status);
986 if (prmsg->length == msg_len){
987 memcpy(&tracking_Status, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_gnss_tracking_status));
988 } else if (prmsg->length > msg_len) {
989 memcpy(&tracking_Status, (((char*)prmsg)+sizeof(mtk_geofence_msg)), sizeof(mtk_gnss_tracking_status));
990 LOGD("mnl msg len:%d > struct len:%d", prmsg->length, msg_len);
991 } else {
992 memcpy(data, (char*)prmsg, prmsg->length);
993 memset((char *)(data + prmsg->length), 0, (msg_len - prmsg->length));
994 memcpy(&tracking_Status, (((char*)data)+sizeof(mtk_geofence_msg)), sizeof(mtk_gnss_tracking_status));
995 LOGD("mnl msg len:%d < struct len:%d", prmsg->length, msg_len);
996 }
997
998 #ifdef AT_COMMAND_PRINT
999 /*Construct AT command */
1000 sprintf(data, "+EGEOTRACK:%d,\"%d/%d/%d,%d:%d:%d\"",
1001 tracking_Status.status,
1002 tracking_Status.year,
1003 tracking_Status.month,
1004 tracking_Status.day,
1005 tracking_Status.hour,
1006 tracking_Status.minute,
1007 tracking_Status.second
1008 );
1009 LOGD("AT command:%s",data);
1010 #endif
1011 //Send AT command
1012 if (at_callback->geofence_tracking_status_callback != NULL){
1013 at_callback->geofence_tracking_status_callback(&tracking_Status);
1014 }
1015
1016 return;
1017}
1018
1019int geofenceinf_add_rawdata_to_buffer(char *data, int length)
1020{
1021 int i;
1022 LOGD("geofenceadp rev raw data:%d", length);
1023 for (i = 0; i < length; i++)
1024 {
1025 *(g_cyclical_buffer.next_write++) = data[i];
1026 if (g_cyclical_buffer.next_write == g_cyclical_buffer.end_buffer){
1027 g_cyclical_buffer.next_write = g_cyclical_buffer.start_buffer;
1028 }
1029
1030 if (g_cyclical_buffer.next_write == g_cyclical_buffer.next_read){
1031 LOGE("geofence ring_buffer overflow\r\n");
1032 return -1;
1033 }
1034 }
1035
1036 return 0;
1037}
1038
1039int geofenceinf_get_one_message(char *data, unsigned int len)
1040{
1041 char *next_write, *next_read;
1042 unsigned int data_size, i, header_len;
1043 char buffer[GEOFENCE_BUFF_SIZE] = {0};
1044 unsigned int return_len = 0;
1045 mtk_geofence_msg geo_header;
1046
1047 next_write = g_cyclical_buffer.next_write;
1048 next_read = g_cyclical_buffer.next_read;
1049
1050 if (g_cyclical_buffer.next_read == next_write)
1051 {
1052 //buffer empty
1053 return -1;
1054 }
1055
1056 header_len = sizeof(mtk_geofence_msg);
1057 /*Compute data length*/
1058 if (g_cyclical_buffer.next_read < next_write)
1059 {
1060 data_size = (unsigned long)next_write - (unsigned long)g_cyclical_buffer.next_read;
1061 }
1062 else
1063 {
1064 data_size = (unsigned long)g_cyclical_buffer.end_buffer - (unsigned long)g_cyclical_buffer.next_read +
1065 (unsigned long)next_write - (unsigned long)g_cyclical_buffer.start_buffer;
1066 }
1067
1068 /*Copy data header to buffer*/
1069 if (data_size >= header_len)
1070 {
1071 for (i = 0; i < header_len; i++)
1072 {
1073 buffer[i] = *(next_read++);
1074 if (next_read == g_cyclical_buffer.end_buffer){
1075 next_read = g_cyclical_buffer.start_buffer;
1076 }
1077 }
1078
1079 memset(&geo_header, 0, sizeof(mtk_geofence_msg));
1080 memcpy(&geo_header, buffer, sizeof(mtk_geofence_msg));
1081 if (geo_header.length <= data_size){
1082 for (i = 0; (i < geo_header.length)&&(i < len); i++)
1083 {
1084 data[i] = *(g_cyclical_buffer.next_read++);
1085 return_len++;
1086 if (g_cyclical_buffer.next_read == g_cyclical_buffer.end_buffer){
1087 g_cyclical_buffer.next_read = g_cyclical_buffer.start_buffer;
1088 }
1089 }
1090 }
1091 else {
1092 //no enough data
1093 return -2;
1094 }
1095 }
1096 else
1097 {
1098 //no enough data
1099 return -2;
1100 }
1101
1102 return return_len;
1103}
1104
1105int mnl2geofence_hdlr (int fd, mtk_geofence_callback *callback) {
1106 char data[GEOFENCE_BUFF_SIZE] = {0};
1107 char buff[GEOFENCE_BUFF_SIZE] = {0};
1108 int len;
1109 int read_len;
1110 int msg_len;
1111 mtk_geofence_ret_command cmd;
1112 mtk_geofence_msg *prmsg = NULL;
1113
1114 read_len = geofenceinf_safe_recv(fd, buff, sizeof(buff));
1115 if (read_len <= 0) {
1116 close(fd);
1117 server_data_fd = -1;
1118 if(callback->geofence_connection_broken) {
1119 LOGW("Connection broken...");
1120 callback->geofence_connection_broken();
1121 }
1122 LOGE("mnl2geofence_hdlr() geofenceinf_safe_recv() failed read_len=%d, %s", read_len, strerror(errno));
1123 return MTK_GFC_ERROR;
1124 }
1125
1126 if (geofenceinf_add_rawdata_to_buffer(buff, read_len) < 0){
1127 //error handle
1128 LOGE("geofenceinf_add_rawdata_to_buffer() overflow\r\n");
1129 }
1130
1131 while ((len = geofenceinf_get_one_message(data, GEOFENCE_BUFF_SIZE)) > 0)
1132 {
1133 if((len > 0) && (len <= GEOFENCE_BUFF_SIZE)) {
1134 prmsg = (mtk_geofence_msg *)&data[0];
1135 } else {
1136 LOGE("len err:%d",len);
1137 return MTK_GFC_ERROR;
1138 }
1139
1140 cmd = prmsg->type;
1141 msg_len = prmsg->length;
1142 if (msg_len < 0){
1143 LOGE("mnl2geofence_hdlr() message length error:%d", msg_len);
1144 return MTK_GFC_ERROR;
1145 }
1146 //LOGD("command %d, len %d", cmd, msg_len);
1147 switch (cmd) {
1148 case GEOFENCE_ALERT_INFO:
1149 geofenceinf_geofence_alert(prmsg, callback);
1150 break;
1151 case GNSS_TRACKING_STATUS:
1152 geofenceinf_gnss_tracking_status(prmsg, callback);
1153 break;
1154 case GEOFENCE_SERVER_CAP:
1155 geofenceinf_server_capability_sync(prmsg, callback);
1156 break;
1157 default:
1158 LOGE("invalid geofence cmd:%d",cmd);
1159 break;
1160 }
1161
1162 memset(data, 0, GEOFENCE_BUFF_SIZE);
1163 len = 0;
1164 }
1165 return MTK_GFC_SUCCESS;
1166}