ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/services/ecall_daemon/src/ecall_daemon_main.c b/marvell/services/ecall_daemon/src/ecall_daemon_main.c
new file mode 100644
index 0000000..5030734
--- /dev/null
+++ b/marvell/services/ecall_daemon/src/ecall_daemon_main.c
@@ -0,0 +1,648 @@
+/******************************************************************************

+*(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