blob: 503073422d13087e93d6424f0e67c77ae3d935cf [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2*(C) Copyright 2021 ASR MicroElectronics Ltd.
3* All Rights Reserved
4******************************************************************************/
5/*--------------------------------------------------------------------------------------------------------------------
6 * -------------------------------------------------------------------------------------------------------------------
7 *
8 * Filename: ecall_daemon_main.c
9 *
10 * Authors: xz
11 *
12 * Description: Entry Point of ecall daemon
13 *
14 * History:
15 * July 20, 2021 - Initial Version
16 *
17 * Notes:
18 *
19 ******************************************************************************/
20
21#ifndef NO_AUDIO
22
23//#include <stdio.h>
24#include <string.h>
25#include <unistd.h>
26
27#include "ecall_daemon.h"
28#include "ril.h"
29#include <cutils/properties.h>
30
31struct ubus_context *ecall_ctx = NULL;
32struct ubus_subscriber ecall_subscriber;
33static struct blob_buf ecall_daemon_blob;
34
35#define ECALL_DAEMON_VERSION "1803L_ecall_daemon_version_2.4_20250225"
36
37const struct blobmsg_policy ecall_daemon_set_mode_policy[] ={
38 [0] = {
39 .name = "ecallMode",
40 .type = BLOBMSG_TYPE_STRING,
41 },
42};
43
44const struct blobmsg_policy ecall_daemon_set_smsNum_policy[] ={
45 [0] = {
46 .name = "smsNum",
47 .type = BLOBMSG_TYPE_STRING,
48 },
49};
50
51const struct blobmsg_policy ecall_daemon_send_msdSms_policy[] ={
52 [0] = {
53 .name = "smsFlag",
54 .type = BLOBMSG_TYPE_INT32,
55 },
56};
57
58const struct blobmsg_policy ecall_daemon_set_ecallTimer_policy[] ={
59 [0] = {
60 .name = "timerName",
61 .type = BLOBMSG_TYPE_STRING,
62 },
63 [1] = {
64 .name = "timerValue",
65 .type = BLOBMSG_TYPE_INT32,
66 },
67};
68
69const struct blobmsg_policy ecall_daemon_get_ecallTimer_policy[] ={
70 [0] = {
71 .name = "timerName",
72 .type = BLOBMSG_TYPE_STRING,
73 },
74};
75
76const struct blobmsg_policy ecall_daemon_set_ecallTestNum_policy[] ={
77 [0] = {
78 .name = "testNumber",
79 .type = BLOBMSG_TYPE_STRING,
80 },
81 [1] = {
82 .name = "reconfigNumber",
83 .type = BLOBMSG_TYPE_STRING,
84 },
85};
86
87const struct blobmsg_policy ecall_daemon_set_ecallMsd_policy[] ={
88 [0] = {
89 .name = "msd",
90 .type = BLOBMSG_TYPE_STRING,
91 },
92};
93
94int ecall_daemon_invoke_noreply(const char *service, const char *method, struct blob_attr *msg)
95{
96 int rc;
97 uint32_t id;
98 struct ubus_request req;
99
100 /* Look up the target object id by the object path */
101 if (ubus_lookup_id(ecall_ctx, service, &id))
102 return -1;
103
104 rc = ubus_invoke_async(ecall_ctx, id, method, msg, &req);
105 if (rc != 0)
106 return -2;
107
108 /* cancel req (on client side) because noreply is needed */
109 ubus_abort_request(ecall_ctx, &req);
110 return 0;
111}
112
113int ecall_daemon_ubus_send_ecallCmd(unsigned int op_id, unsigned int param1)
114{
115 unsigned int length;
116 struct blob_buf outBlob;
117 int ret = 0;
118
119 memset(&outBlob, 0, sizeof(outBlob));
120
121 blob_buf_init(&outBlob, 0);
122 length = sizeof(op_id) + sizeof(param1);
123 blobmsg_add_u32(&outBlob, "length", (unsigned int)length);
124 blobmsg_add_u32(&outBlob, "op", (unsigned int)op_id);
125 blobmsg_add_u32(&outBlob, "param1", (unsigned int)param1);
126 if (ecall_daemon_invoke_noreply("audio_if", "ecall_data_set", outBlob.head) == 0)
127 {
128 ret = 0;
129 ECALL_Log("%s: succeed in sending AUDIO_IF_UBUS_ECALL_DATA_SET\n", __FUNCTION__);
130 }
131 else
132 {
133 ret = -1;
134 ECALL_Log("%s: fail to send AUDIO_IF_UBUS_ECALL_DATA_SET\n", __FUNCTION__);
135 }
136
137 blob_buf_free(&outBlob);
138
139 return ret;
140}
141
142static int ecall_daemon_mode_string_reply(struct ubus_context *ctx, struct ubus_request_data *req, char *str)
143{
144 blob_buf_init(&ecall_daemon_blob, 0);
145 blobmsg_add_string(&ecall_daemon_blob, "ecallMode", str);
146 ubus_send_reply(ctx, req, ecall_daemon_blob.head);
147 return 0;
148}
149
150static int ecall_daemon_smsNum_string_reply(struct ubus_context *ctx, struct ubus_request_data *req, char *str)
151{
152 blob_buf_init(&ecall_daemon_blob, 0);
153 blobmsg_add_string(&ecall_daemon_blob, "smsNum", str);
154 ubus_send_reply(ctx, req, ecall_daemon_blob.head);
155 return 0;
156}
157
158static int ecall_daemon_timerVal_string_reply(struct ubus_context *ctx, struct ubus_request_data *req, char *str)
159{
160 blob_buf_init(&ecall_daemon_blob, 0);
161 blobmsg_add_string(&ecall_daemon_blob, "timerVal", str);
162 ubus_send_reply(ctx, req, ecall_daemon_blob.head);
163 return 0;
164}
165
166static int ecall_daemon_ubus_set_ecallMode(struct ubus_context *ctx, struct ubus_object *obj,
167 struct ubus_request_data *req, const char *method,
168 struct blob_attr *msg)
169{
170 UNUSED(ctx);
171 UNUSED(obj);
172 UNUSED(req);
173 UNUSED(method);
174 struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_mode_policy)];
175 struct blob_attr *cur;
176 char *ecallMode = NULL;
177 int err = 0;
178
179 err = blobmsg_parse(ecall_daemon_set_mode_policy, ARRAY_SIZE(ecall_daemon_set_mode_policy), tb, blob_data(msg), blob_len(msg));
180 if (err < 0)
181 {
182 ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
183 return -1;
184 }
185
186 cur = tb[0];
187 if (cur)
188 ecallMode = blobmsg_get_string(cur);
189 else
190 ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
191
192 ECALL_Log("%s: ecallMode=%s\n", __FUNCTION__, ecallMode);
193
194 if (ecallMode != NULL)
195 {
196 err = ecall_daemon_handle_setMode(ecallMode);
197 ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
198 }
199
200 return 0;
201}
202
203static int ecall_daemon_ubus_get_ecallMode(struct ubus_context *ctx, struct ubus_object *obj,
204 struct ubus_request_data *req, const char *method,
205 struct blob_attr *msg)
206{
207 UNUSED(obj);
208 UNUSED(req);
209 UNUSED(method);
210 UNUSED(msg);
211
212 char respBuff[16] = {0};
213
214 if (ecall_daemon_get_mode() == 0)
215 {
216 snprintf(respBuff, sizeof(respBuff), "EU");
217 }
218 else if (ecall_daemon_get_mode() == 1)
219 {
220 snprintf(respBuff, sizeof(respBuff), "ERA");;
221 }
222 else
223 {
224 snprintf(respBuff, sizeof(respBuff), "NULL");;
225 }
226
227 ECALL_Log("%s: respBuff=%s\n", __FUNCTION__, respBuff);
228
229 ecall_daemon_mode_string_reply(ctx, req, respBuff);
230
231 return 0;
232}
233
234static int ecall_daemon_ubus_set_smsNum(struct ubus_context *ctx, struct ubus_object *obj,
235 struct ubus_request_data *req, const char *method,
236 struct blob_attr *msg)
237{
238 UNUSED(ctx);
239 UNUSED(obj);
240 UNUSED(req);
241 UNUSED(method);
242
243 struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_smsNum_policy)];
244 struct blob_attr *cur;
245 char *smsNum = NULL;
246 int err = 0;
247
248 err = blobmsg_parse(ecall_daemon_set_smsNum_policy, ARRAY_SIZE(ecall_daemon_set_smsNum_policy), tb, blob_data(msg), blob_len(msg));
249 if (err < 0)
250 {
251 ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
252 return -1;
253 }
254
255 cur = tb[0];
256 if (cur)
257 smsNum = blobmsg_get_string(cur);
258 else
259 ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
260
261 ECALL_Log("%s: smsNum=%s\n", __FUNCTION__, smsNum);
262
263 if (smsNum != NULL)
264 {
265 err = ecall_daemon_set_ecallSmsNum(smsNum);
266 ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
267 }
268
269 return 0;
270}
271
272static int ecall_daemon_ubus_get_smsNum(struct ubus_context *ctx, struct ubus_object *obj,
273 struct ubus_request_data *req, const char *method,
274 struct blob_attr *msg)
275{
276 UNUSED(obj);
277 UNUSED(req);
278 UNUSED(method);
279 UNUSED(msg);
280
281 char respBuff[64] = {0};
282 char *smsNumber = NULL;
283
284 smsNumber = ecall_daemon_get_ecallSmsNum();
285 if ((smsNumber != NULL) && (strlen(smsNumber) > 0))
286 {
287 snprintf(respBuff, sizeof(respBuff), "%s", smsNumber);
288 }
289
290 ECALL_Log("%s: respBuff=%s\n", __FUNCTION__, respBuff);
291
292 ecall_daemon_smsNum_string_reply(ctx, req, respBuff);
293
294 return 0;
295}
296
297static int ecall_daemon_ubus_send_msdSms(struct ubus_context *ctx, struct ubus_object *obj,
298 struct ubus_request_data *req, const char *method,
299 struct blob_attr *msg)
300{
301 UNUSED(ctx);
302 UNUSED(obj);
303 UNUSED(req);
304 UNUSED(method);
305
306 struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_send_msdSms_policy)];
307 struct blob_attr *cur;
308 int smsFlag = 0;
309 int err = 0;
310
311 err = blobmsg_parse(ecall_daemon_send_msdSms_policy, ARRAY_SIZE(ecall_daemon_send_msdSms_policy), tb, blob_data(msg), blob_len(msg));
312 if (err < 0)
313 {
314 ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
315 return -1;
316 }
317
318 cur = tb[0];
319 if (cur)
320 smsFlag = blobmsg_get_u32(cur);
321 else
322 ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
323
324 ECALL_Log("%s: smsFlag=%d\n", __FUNCTION__, smsFlag);
325
326 err = ecall_daemon_send_msdSms(smsFlag);
327 ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
328
329 return 0;
330}
331
332static int ecall_daemon_ubus_set_ecallTimer(struct ubus_context *ctx, struct ubus_object *obj,
333 struct ubus_request_data *req, const char *method,
334 struct blob_attr *msg)
335{
336 UNUSED(ctx);
337 UNUSED(obj);
338 UNUSED(req);
339 UNUSED(method);
340
341 struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_ecallTimer_policy)];
342 struct blob_attr *cur;
343 char *timerName = NULL;
344 int timerValue = 0;
345 int err = 0;
346
347 err = blobmsg_parse(ecall_daemon_set_ecallTimer_policy, ARRAY_SIZE(ecall_daemon_set_ecallTimer_policy), tb, blob_data(msg), blob_len(msg));
348 if (err < 0)
349 {
350 ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
351 return -1;
352 }
353
354 cur = tb[0];
355 if (cur)
356 timerName = blobmsg_get_string(cur);
357 else
358 ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
359
360 cur = tb[1];
361 if (cur)
362 timerValue = blobmsg_get_u32(cur);
363 else
364 ECALL_Log("%s: missing parameter2\n", __FUNCTION__);
365
366 ECALL_Log("%s: timerName=%s, timerValue=%d\n", __FUNCTION__, timerName, timerValue);
367
368 if (timerName != NULL && timerValue >= 0)
369 {
370 err = ecall_daemon_set_ecallTimer(timerName, timerValue);
371 ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
372 }
373
374 return 0;
375}
376
377static int ecall_daemon_ubus_get_ecallTimer(struct ubus_context *ctx, struct ubus_object *obj,
378 struct ubus_request_data *req, const char *method,
379 struct blob_attr *msg)
380{
381 UNUSED(obj);
382 UNUSED(method);
383 struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_get_ecallTimer_policy)];
384 struct blob_attr *cur;
385 char *timerName = NULL;
386 int timerValue = 0;
387 int err = 0;
388 char respBuff[256] = {0};
389
390 err = blobmsg_parse(ecall_daemon_get_ecallTimer_policy, ARRAY_SIZE(ecall_daemon_get_ecallTimer_policy), tb, blob_data(msg), blob_len(msg));
391 if (err < 0)
392 {
393 ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
394 return -1;
395 }
396
397 cur = tb[0];
398 if (cur)
399 timerName = blobmsg_get_string(cur);
400 else
401 ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
402
403 if (timerName != NULL)
404 {
405 if (0 == strncmp(timerName, "ecallParams", strlen("ecallParams")))
406 {
407 ecall_daemon_get_ecallParams(respBuff, sizeof(respBuff));
408 }
409 else
410 {
411 timerValue = ecall_daemon_get_ecallTimerValue(timerName);
412 memset(respBuff, '\0', sizeof(respBuff));
413 snprintf(respBuff, sizeof(respBuff), "\"%s\"=%d\r\n", timerName, timerValue);
414 }
415 }
416 ECALL_Log("%s: respBuff=%s\n", __FUNCTION__, respBuff);
417
418 ecall_daemon_timerVal_string_reply(ctx, req, respBuff);
419
420 return 0;
421}
422
423static int ecall_daemon_ubus_set_ecallTestNum(struct ubus_context *ctx, struct ubus_object *obj,
424 struct ubus_request_data *req, const char *method,
425 struct blob_attr *msg)
426{
427 UNUSED(ctx);
428 UNUSED(obj);
429 UNUSED(req);
430 UNUSED(method);
431
432 struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_ecallTestNum_policy)];
433 struct blob_attr *cur;
434 char *ecallTestNumber = NULL;
435 char *ecallReconfigNumber = NULL;
436 int err = 0;
437
438 err = blobmsg_parse(ecall_daemon_set_ecallTestNum_policy, ARRAY_SIZE(ecall_daemon_set_ecallTestNum_policy), tb, blob_data(msg), blob_len(msg));
439 if (err < 0)
440 {
441 ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
442 return -1;
443 }
444
445 cur = tb[0];
446 if (cur)
447 ecallTestNumber = blobmsg_get_string(cur);
448 else
449 ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
450
451 cur = tb[1];
452 if (cur)
453 ecallReconfigNumber = blobmsg_get_string(cur);
454 else
455 ECALL_Log("%s: missing parameter2\n", __FUNCTION__);
456
457 ECALL_Log("%s: ecallTestNumber=%s, ecallReconfigNumber=%s\n", __FUNCTION__, ecallTestNumber, ecallReconfigNumber);
458
459 err = ecall_daemon_set_ecallTestNum(ecallTestNumber, ecallReconfigNumber);
460
461 ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
462
463 return 0;
464}
465
466static int ecall_daemon_ubus_set_ecallMsd(struct ubus_context *ctx, struct ubus_object *obj,
467 struct ubus_request_data *req, const char *method,
468 struct blob_attr *msg)
469{
470 UNUSED(ctx);
471 UNUSED(obj);
472 UNUSED(req);
473 UNUSED(method);
474
475 struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_ecallMsd_policy)];
476 struct blob_attr *cur;
477 char *ecallMsd = NULL;
478 int err = 0;
479
480 err = blobmsg_parse(ecall_daemon_set_ecallMsd_policy, ARRAY_SIZE(ecall_daemon_set_ecallMsd_policy), tb, blob_data(msg), blob_len(msg));
481 if (err < 0)
482 {
483 ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
484 return -1;
485 }
486
487 cur = tb[0];
488 if (cur)
489 ecallMsd = blobmsg_get_string(cur);
490 else
491 ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
492
493 ECALL_Log("%s: ecallMsd=%s\n", __FUNCTION__, ecallMsd);
494
495 if (ecallMsd != NULL)
496 {
497 err = ecall_daemon_set_ecallMsd(ecallMsd);
498 ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
499 }
500
501 return 0;
502}
503
504static int ecall_daemon_ubus_set_ecallPush(struct ubus_context *ctx, struct ubus_object *obj,
505 struct ubus_request_data *req, const char *method,
506 struct blob_attr *msg)
507{
508 UNUSED(ctx);
509 UNUSED(obj);
510 UNUSED(req);
511 UNUSED(method);
512 UNUSED(msg);
513
514 int err = 0;
515
516 err = ecall_daemon_set_ecallPush(1);
517
518 ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
519
520 return 0;
521}
522
523static const struct ubus_method ecall_methods[] = {
524 UBUS_METHOD("ecall_daemon_ubus_set_ecallMode", ecall_daemon_ubus_set_ecallMode, ecall_daemon_set_mode_policy),
525 UBUS_METHOD_NOARG("ecall_daemon_ubus_get_ecallMode", ecall_daemon_ubus_get_ecallMode),
526 UBUS_METHOD("ecall_daemon_ubus_set_smsNum", ecall_daemon_ubus_set_smsNum, ecall_daemon_set_smsNum_policy),
527 UBUS_METHOD_NOARG("ecall_daemon_ubus_get_smsNum", ecall_daemon_ubus_get_smsNum),
528 UBUS_METHOD("ecall_daemon_ubus_send_msdSms", ecall_daemon_ubus_send_msdSms, ecall_daemon_send_msdSms_policy),
529 UBUS_METHOD("ecall_daemon_ubus_set_ecallTimer", ecall_daemon_ubus_set_ecallTimer, ecall_daemon_set_ecallTimer_policy),
530 UBUS_METHOD("ecall_daemon_ubus_get_ecallTimer", ecall_daemon_ubus_get_ecallTimer, ecall_daemon_get_ecallTimer_policy),
531 UBUS_METHOD("ecall_daemon_ubus_set_ecallTestNum", ecall_daemon_ubus_set_ecallTestNum, ecall_daemon_set_ecallTestNum_policy),
532 UBUS_METHOD("ecall_daemon_ubus_set_ecallMsd", ecall_daemon_ubus_set_ecallMsd, ecall_daemon_set_ecallMsd_policy),
533 UBUS_METHOD_NOARG("ecall_daemon_ubus_set_ecallPush", ecall_daemon_ubus_set_ecallPush),
534};
535
536static struct ubus_object_type ecall_object_type = UBUS_OBJECT_TYPE("ecall_daemon", ecall_methods);
537static struct ubus_object ecall_object = {
538 .name = "ecall_daemon",
539 .type = &ecall_object_type,
540 .methods = ecall_methods,
541 .n_methods = ARRAY_SIZE(ecall_methods),
542};
543
544int main()
545{
546
547 uint32_t id;
548 int ret, retries = 0;
549
550 //set tag name
551 set_service_log_tag("ecall_daemon");
552
553 //ECALL_Log(ecall_daemon_main_0, "ecall_daemon: start\n");s
554 ECALL_Log("ecall_daemon_version: %s\n", ECALL_DAEMON_VERSION);
555
556 uloop_init();
557 while(1)
558 {
559 ecall_ctx = ubus_connect(NULL);
560 if (!ecall_ctx)
561 usleep(200000); //200ms
562 else
563 break;
564 }
565
566 ubus_add_uloop(ecall_ctx);
567
568 ret = ubus_add_object(ecall_ctx, &ecall_object);
569 if (ret) {
570 ECALL_Log("ecall_daemon: Failed to add object: %s\n", ubus_strerror(ret));
571 goto fail1;
572 }
573
574 ret = ubus_register_subscriber(ecall_ctx, &ecall_subscriber);
575 if (ret) {
576 ECALL_Log("ecall_daemon: Failed to add ecall_subscriber: %s\n", ubus_strerror(ret));
577 goto fail2;
578 }
579
580 ecall_subscriber.cb = ecall_subscriber_cb;
581 ecall_subscriber.remove_cb = ecall_subscriber_remove_cb;
582 do {
583 if (RildReady())
584 break;
585 sleep(1);
586 } while (retries++ < 20); //RIL_MAX_RETRIES 20
587
588 if (retries >= 20) {
589 ECALL_Log("ecall_daemon main: Failed to look up RIL object\n");
590 goto fail1;
591 }
592 ECALL_Log("ecall_daemon main: RIL is ready\n");
593
594 //register for PS ind
595 if (ubus_lookup_id(ecall_ctx, "ril.unsol.ps", &id)) {
596 ECALL_Log("ecall_daemon: Failed to look up ril.unsol.ps object\n");
597 goto fail2;
598 }
599
600 ubus_subscribe(ecall_ctx, &ecall_subscriber, id);
601 ECALL_Log("ecall_daemon: subscribe ril.unsol.ps object ok");
602
603 //register for CC ind
604 if (ubus_lookup_id(ecall_ctx, "ril.unsol.cc", &id)) {
605 ECALL_Log("ecall_daemon: Failed to look up ril.unsol.cc object\n");
606 goto fail2;
607 }
608
609 ubus_subscribe(ecall_ctx, &ecall_subscriber, id);
610 ECALL_Log("ecall_daemon: subscribe ril.unsol.cc object ok");
611
612 //register for MM ind
613 if (ubus_lookup_id(ecall_ctx, "ril.unsol.mm", &id)) {
614 ECALL_Log("ecall_daemon: Failed to look up ril.unsol.mm object\n");
615 goto fail2;
616 }
617
618 ubus_subscribe(ecall_ctx, &ecall_subscriber, id);
619 ECALL_Log("ecall_daemon: subscribe ril.unsol.mm object ok");
620
621 //register for msg ind
622 if (ubus_lookup_id(ecall_ctx, "ril.unsol.msg", &id)) {
623 ECALL_Log("ecall_daemon: Failed to look up ril.unsol.msg object\n");
624 goto fail2;
625 }
626
627 ubus_subscribe(ecall_ctx, &ecall_subscriber, id);
628 ECALL_Log("ecall_daemon: subscribe ril.unsol.msg object ok");
629
630 ecall_set_ecall_status(DAEMON_ECALL_IDLE);
631
632 ecall_timer_init();
633
634 ecall_stop_auto_answer();
635
636 uloop_run();
637
638fail2:
639 ubus_remove_object(ecall_ctx, &ecall_object);
640fail1:
641 ubus_free(ecall_ctx);
642 uloop_done();
643 ECALL_Log("ecall_daemon main: exit\n");
644
645 return 0;
646}
647
648#endif