blob: 503073422d13087e93d6424f0e67c77ae3d935cf [file] [log] [blame]
/******************************************************************************
*(C) Copyright 2021 ASR MicroElectronics Ltd.
* All Rights Reserved
******************************************************************************/
/*--------------------------------------------------------------------------------------------------------------------
* -------------------------------------------------------------------------------------------------------------------
*
* Filename: ecall_daemon_main.c
*
* Authors: xz
*
* Description: Entry Point of ecall daemon
*
* History:
* July 20, 2021 - Initial Version
*
* Notes:
*
******************************************************************************/
#ifndef NO_AUDIO
//#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ecall_daemon.h"
#include "ril.h"
#include <cutils/properties.h>
struct ubus_context *ecall_ctx = NULL;
struct ubus_subscriber ecall_subscriber;
static struct blob_buf ecall_daemon_blob;
#define ECALL_DAEMON_VERSION "1803L_ecall_daemon_version_2.4_20250225"
const struct blobmsg_policy ecall_daemon_set_mode_policy[] ={
[0] = {
.name = "ecallMode",
.type = BLOBMSG_TYPE_STRING,
},
};
const struct blobmsg_policy ecall_daemon_set_smsNum_policy[] ={
[0] = {
.name = "smsNum",
.type = BLOBMSG_TYPE_STRING,
},
};
const struct blobmsg_policy ecall_daemon_send_msdSms_policy[] ={
[0] = {
.name = "smsFlag",
.type = BLOBMSG_TYPE_INT32,
},
};
const struct blobmsg_policy ecall_daemon_set_ecallTimer_policy[] ={
[0] = {
.name = "timerName",
.type = BLOBMSG_TYPE_STRING,
},
[1] = {
.name = "timerValue",
.type = BLOBMSG_TYPE_INT32,
},
};
const struct blobmsg_policy ecall_daemon_get_ecallTimer_policy[] ={
[0] = {
.name = "timerName",
.type = BLOBMSG_TYPE_STRING,
},
};
const struct blobmsg_policy ecall_daemon_set_ecallTestNum_policy[] ={
[0] = {
.name = "testNumber",
.type = BLOBMSG_TYPE_STRING,
},
[1] = {
.name = "reconfigNumber",
.type = BLOBMSG_TYPE_STRING,
},
};
const struct blobmsg_policy ecall_daemon_set_ecallMsd_policy[] ={
[0] = {
.name = "msd",
.type = BLOBMSG_TYPE_STRING,
},
};
int ecall_daemon_invoke_noreply(const char *service, const char *method, struct blob_attr *msg)
{
int rc;
uint32_t id;
struct ubus_request req;
/* Look up the target object id by the object path */
if (ubus_lookup_id(ecall_ctx, service, &id))
return -1;
rc = ubus_invoke_async(ecall_ctx, id, method, msg, &req);
if (rc != 0)
return -2;
/* cancel req (on client side) because noreply is needed */
ubus_abort_request(ecall_ctx, &req);
return 0;
}
int ecall_daemon_ubus_send_ecallCmd(unsigned int op_id, unsigned int param1)
{
unsigned int length;
struct blob_buf outBlob;
int ret = 0;
memset(&outBlob, 0, sizeof(outBlob));
blob_buf_init(&outBlob, 0);
length = sizeof(op_id) + sizeof(param1);
blobmsg_add_u32(&outBlob, "length", (unsigned int)length);
blobmsg_add_u32(&outBlob, "op", (unsigned int)op_id);
blobmsg_add_u32(&outBlob, "param1", (unsigned int)param1);
if (ecall_daemon_invoke_noreply("audio_if", "ecall_data_set", outBlob.head) == 0)
{
ret = 0;
ECALL_Log("%s: succeed in sending AUDIO_IF_UBUS_ECALL_DATA_SET\n", __FUNCTION__);
}
else
{
ret = -1;
ECALL_Log("%s: fail to send AUDIO_IF_UBUS_ECALL_DATA_SET\n", __FUNCTION__);
}
blob_buf_free(&outBlob);
return ret;
}
static int ecall_daemon_mode_string_reply(struct ubus_context *ctx, struct ubus_request_data *req, char *str)
{
blob_buf_init(&ecall_daemon_blob, 0);
blobmsg_add_string(&ecall_daemon_blob, "ecallMode", str);
ubus_send_reply(ctx, req, ecall_daemon_blob.head);
return 0;
}
static int ecall_daemon_smsNum_string_reply(struct ubus_context *ctx, struct ubus_request_data *req, char *str)
{
blob_buf_init(&ecall_daemon_blob, 0);
blobmsg_add_string(&ecall_daemon_blob, "smsNum", str);
ubus_send_reply(ctx, req, ecall_daemon_blob.head);
return 0;
}
static int ecall_daemon_timerVal_string_reply(struct ubus_context *ctx, struct ubus_request_data *req, char *str)
{
blob_buf_init(&ecall_daemon_blob, 0);
blobmsg_add_string(&ecall_daemon_blob, "timerVal", str);
ubus_send_reply(ctx, req, ecall_daemon_blob.head);
return 0;
}
static int ecall_daemon_ubus_set_ecallMode(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(ctx);
UNUSED(obj);
UNUSED(req);
UNUSED(method);
struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_mode_policy)];
struct blob_attr *cur;
char *ecallMode = NULL;
int err = 0;
err = blobmsg_parse(ecall_daemon_set_mode_policy, ARRAY_SIZE(ecall_daemon_set_mode_policy), tb, blob_data(msg), blob_len(msg));
if (err < 0)
{
ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
return -1;
}
cur = tb[0];
if (cur)
ecallMode = blobmsg_get_string(cur);
else
ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
ECALL_Log("%s: ecallMode=%s\n", __FUNCTION__, ecallMode);
if (ecallMode != NULL)
{
err = ecall_daemon_handle_setMode(ecallMode);
ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
}
return 0;
}
static int ecall_daemon_ubus_get_ecallMode(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(obj);
UNUSED(req);
UNUSED(method);
UNUSED(msg);
char respBuff[16] = {0};
if (ecall_daemon_get_mode() == 0)
{
snprintf(respBuff, sizeof(respBuff), "EU");
}
else if (ecall_daemon_get_mode() == 1)
{
snprintf(respBuff, sizeof(respBuff), "ERA");;
}
else
{
snprintf(respBuff, sizeof(respBuff), "NULL");;
}
ECALL_Log("%s: respBuff=%s\n", __FUNCTION__, respBuff);
ecall_daemon_mode_string_reply(ctx, req, respBuff);
return 0;
}
static int ecall_daemon_ubus_set_smsNum(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(ctx);
UNUSED(obj);
UNUSED(req);
UNUSED(method);
struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_smsNum_policy)];
struct blob_attr *cur;
char *smsNum = NULL;
int err = 0;
err = blobmsg_parse(ecall_daemon_set_smsNum_policy, ARRAY_SIZE(ecall_daemon_set_smsNum_policy), tb, blob_data(msg), blob_len(msg));
if (err < 0)
{
ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
return -1;
}
cur = tb[0];
if (cur)
smsNum = blobmsg_get_string(cur);
else
ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
ECALL_Log("%s: smsNum=%s\n", __FUNCTION__, smsNum);
if (smsNum != NULL)
{
err = ecall_daemon_set_ecallSmsNum(smsNum);
ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
}
return 0;
}
static int ecall_daemon_ubus_get_smsNum(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(obj);
UNUSED(req);
UNUSED(method);
UNUSED(msg);
char respBuff[64] = {0};
char *smsNumber = NULL;
smsNumber = ecall_daemon_get_ecallSmsNum();
if ((smsNumber != NULL) && (strlen(smsNumber) > 0))
{
snprintf(respBuff, sizeof(respBuff), "%s", smsNumber);
}
ECALL_Log("%s: respBuff=%s\n", __FUNCTION__, respBuff);
ecall_daemon_smsNum_string_reply(ctx, req, respBuff);
return 0;
}
static int ecall_daemon_ubus_send_msdSms(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(ctx);
UNUSED(obj);
UNUSED(req);
UNUSED(method);
struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_send_msdSms_policy)];
struct blob_attr *cur;
int smsFlag = 0;
int err = 0;
err = blobmsg_parse(ecall_daemon_send_msdSms_policy, ARRAY_SIZE(ecall_daemon_send_msdSms_policy), tb, blob_data(msg), blob_len(msg));
if (err < 0)
{
ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
return -1;
}
cur = tb[0];
if (cur)
smsFlag = blobmsg_get_u32(cur);
else
ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
ECALL_Log("%s: smsFlag=%d\n", __FUNCTION__, smsFlag);
err = ecall_daemon_send_msdSms(smsFlag);
ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
return 0;
}
static int ecall_daemon_ubus_set_ecallTimer(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(ctx);
UNUSED(obj);
UNUSED(req);
UNUSED(method);
struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_ecallTimer_policy)];
struct blob_attr *cur;
char *timerName = NULL;
int timerValue = 0;
int err = 0;
err = blobmsg_parse(ecall_daemon_set_ecallTimer_policy, ARRAY_SIZE(ecall_daemon_set_ecallTimer_policy), tb, blob_data(msg), blob_len(msg));
if (err < 0)
{
ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
return -1;
}
cur = tb[0];
if (cur)
timerName = blobmsg_get_string(cur);
else
ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
cur = tb[1];
if (cur)
timerValue = blobmsg_get_u32(cur);
else
ECALL_Log("%s: missing parameter2\n", __FUNCTION__);
ECALL_Log("%s: timerName=%s, timerValue=%d\n", __FUNCTION__, timerName, timerValue);
if (timerName != NULL && timerValue >= 0)
{
err = ecall_daemon_set_ecallTimer(timerName, timerValue);
ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
}
return 0;
}
static int ecall_daemon_ubus_get_ecallTimer(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(obj);
UNUSED(method);
struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_get_ecallTimer_policy)];
struct blob_attr *cur;
char *timerName = NULL;
int timerValue = 0;
int err = 0;
char respBuff[256] = {0};
err = blobmsg_parse(ecall_daemon_get_ecallTimer_policy, ARRAY_SIZE(ecall_daemon_get_ecallTimer_policy), tb, blob_data(msg), blob_len(msg));
if (err < 0)
{
ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
return -1;
}
cur = tb[0];
if (cur)
timerName = blobmsg_get_string(cur);
else
ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
if (timerName != NULL)
{
if (0 == strncmp(timerName, "ecallParams", strlen("ecallParams")))
{
ecall_daemon_get_ecallParams(respBuff, sizeof(respBuff));
}
else
{
timerValue = ecall_daemon_get_ecallTimerValue(timerName);
memset(respBuff, '\0', sizeof(respBuff));
snprintf(respBuff, sizeof(respBuff), "\"%s\"=%d\r\n", timerName, timerValue);
}
}
ECALL_Log("%s: respBuff=%s\n", __FUNCTION__, respBuff);
ecall_daemon_timerVal_string_reply(ctx, req, respBuff);
return 0;
}
static int ecall_daemon_ubus_set_ecallTestNum(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(ctx);
UNUSED(obj);
UNUSED(req);
UNUSED(method);
struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_ecallTestNum_policy)];
struct blob_attr *cur;
char *ecallTestNumber = NULL;
char *ecallReconfigNumber = NULL;
int err = 0;
err = blobmsg_parse(ecall_daemon_set_ecallTestNum_policy, ARRAY_SIZE(ecall_daemon_set_ecallTestNum_policy), tb, blob_data(msg), blob_len(msg));
if (err < 0)
{
ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
return -1;
}
cur = tb[0];
if (cur)
ecallTestNumber = blobmsg_get_string(cur);
else
ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
cur = tb[1];
if (cur)
ecallReconfigNumber = blobmsg_get_string(cur);
else
ECALL_Log("%s: missing parameter2\n", __FUNCTION__);
ECALL_Log("%s: ecallTestNumber=%s, ecallReconfigNumber=%s\n", __FUNCTION__, ecallTestNumber, ecallReconfigNumber);
err = ecall_daemon_set_ecallTestNum(ecallTestNumber, ecallReconfigNumber);
ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
return 0;
}
static int ecall_daemon_ubus_set_ecallMsd(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(ctx);
UNUSED(obj);
UNUSED(req);
UNUSED(method);
struct blob_attr *tb[ARRAY_SIZE(ecall_daemon_set_ecallMsd_policy)];
struct blob_attr *cur;
char *ecallMsd = NULL;
int err = 0;
err = blobmsg_parse(ecall_daemon_set_ecallMsd_policy, ARRAY_SIZE(ecall_daemon_set_ecallMsd_policy), tb, blob_data(msg), blob_len(msg));
if (err < 0)
{
ECALL_Log("%s: blobmsg_parse table fail\n", __FUNCTION__);
return -1;
}
cur = tb[0];
if (cur)
ecallMsd = blobmsg_get_string(cur);
else
ECALL_Log("%s: missing parameter1\n", __FUNCTION__);
ECALL_Log("%s: ecallMsd=%s\n", __FUNCTION__, ecallMsd);
if (ecallMsd != NULL)
{
err = ecall_daemon_set_ecallMsd(ecallMsd);
ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
}
return 0;
}
static int ecall_daemon_ubus_set_ecallPush(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
UNUSED(ctx);
UNUSED(obj);
UNUSED(req);
UNUSED(method);
UNUSED(msg);
int err = 0;
err = ecall_daemon_set_ecallPush(1);
ECALL_Log("%s: err=%d\n", __FUNCTION__, err);
return 0;
}
static const struct ubus_method ecall_methods[] = {
UBUS_METHOD("ecall_daemon_ubus_set_ecallMode", ecall_daemon_ubus_set_ecallMode, ecall_daemon_set_mode_policy),
UBUS_METHOD_NOARG("ecall_daemon_ubus_get_ecallMode", ecall_daemon_ubus_get_ecallMode),
UBUS_METHOD("ecall_daemon_ubus_set_smsNum", ecall_daemon_ubus_set_smsNum, ecall_daemon_set_smsNum_policy),
UBUS_METHOD_NOARG("ecall_daemon_ubus_get_smsNum", ecall_daemon_ubus_get_smsNum),
UBUS_METHOD("ecall_daemon_ubus_send_msdSms", ecall_daemon_ubus_send_msdSms, ecall_daemon_send_msdSms_policy),
UBUS_METHOD("ecall_daemon_ubus_set_ecallTimer", ecall_daemon_ubus_set_ecallTimer, ecall_daemon_set_ecallTimer_policy),
UBUS_METHOD("ecall_daemon_ubus_get_ecallTimer", ecall_daemon_ubus_get_ecallTimer, ecall_daemon_get_ecallTimer_policy),
UBUS_METHOD("ecall_daemon_ubus_set_ecallTestNum", ecall_daemon_ubus_set_ecallTestNum, ecall_daemon_set_ecallTestNum_policy),
UBUS_METHOD("ecall_daemon_ubus_set_ecallMsd", ecall_daemon_ubus_set_ecallMsd, ecall_daemon_set_ecallMsd_policy),
UBUS_METHOD_NOARG("ecall_daemon_ubus_set_ecallPush", ecall_daemon_ubus_set_ecallPush),
};
static struct ubus_object_type ecall_object_type = UBUS_OBJECT_TYPE("ecall_daemon", ecall_methods);
static struct ubus_object ecall_object = {
.name = "ecall_daemon",
.type = &ecall_object_type,
.methods = ecall_methods,
.n_methods = ARRAY_SIZE(ecall_methods),
};
int main()
{
uint32_t id;
int ret, retries = 0;
//set tag name
set_service_log_tag("ecall_daemon");
//ECALL_Log(ecall_daemon_main_0, "ecall_daemon: start\n");s
ECALL_Log("ecall_daemon_version: %s\n", ECALL_DAEMON_VERSION);
uloop_init();
while(1)
{
ecall_ctx = ubus_connect(NULL);
if (!ecall_ctx)
usleep(200000); //200ms
else
break;
}
ubus_add_uloop(ecall_ctx);
ret = ubus_add_object(ecall_ctx, &ecall_object);
if (ret) {
ECALL_Log("ecall_daemon: Failed to add object: %s\n", ubus_strerror(ret));
goto fail1;
}
ret = ubus_register_subscriber(ecall_ctx, &ecall_subscriber);
if (ret) {
ECALL_Log("ecall_daemon: Failed to add ecall_subscriber: %s\n", ubus_strerror(ret));
goto fail2;
}
ecall_subscriber.cb = ecall_subscriber_cb;
ecall_subscriber.remove_cb = ecall_subscriber_remove_cb;
do {
if (RildReady())
break;
sleep(1);
} while (retries++ < 20); //RIL_MAX_RETRIES 20
if (retries >= 20) {
ECALL_Log("ecall_daemon main: Failed to look up RIL object\n");
goto fail1;
}
ECALL_Log("ecall_daemon main: RIL is ready\n");
//register for PS ind
if (ubus_lookup_id(ecall_ctx, "ril.unsol.ps", &id)) {
ECALL_Log("ecall_daemon: Failed to look up ril.unsol.ps object\n");
goto fail2;
}
ubus_subscribe(ecall_ctx, &ecall_subscriber, id);
ECALL_Log("ecall_daemon: subscribe ril.unsol.ps object ok");
//register for CC ind
if (ubus_lookup_id(ecall_ctx, "ril.unsol.cc", &id)) {
ECALL_Log("ecall_daemon: Failed to look up ril.unsol.cc object\n");
goto fail2;
}
ubus_subscribe(ecall_ctx, &ecall_subscriber, id);
ECALL_Log("ecall_daemon: subscribe ril.unsol.cc object ok");
//register for MM ind
if (ubus_lookup_id(ecall_ctx, "ril.unsol.mm", &id)) {
ECALL_Log("ecall_daemon: Failed to look up ril.unsol.mm object\n");
goto fail2;
}
ubus_subscribe(ecall_ctx, &ecall_subscriber, id);
ECALL_Log("ecall_daemon: subscribe ril.unsol.mm object ok");
//register for msg ind
if (ubus_lookup_id(ecall_ctx, "ril.unsol.msg", &id)) {
ECALL_Log("ecall_daemon: Failed to look up ril.unsol.msg object\n");
goto fail2;
}
ubus_subscribe(ecall_ctx, &ecall_subscriber, id);
ECALL_Log("ecall_daemon: subscribe ril.unsol.msg object ok");
ecall_set_ecall_status(DAEMON_ECALL_IDLE);
ecall_timer_init();
ecall_stop_auto_answer();
uloop_run();
fail2:
ubus_remove_object(ecall_ctx, &ecall_object);
fail1:
ubus_free(ecall_ctx);
uloop_done();
ECALL_Log("ecall_daemon main: exit\n");
return 0;
}
#endif