Initial refactoring merge
[platform/core/telephony/tel-plugin-vmodem.git] / src / desc-vmodem.c
index 168a9ef..35a2c96 100644 (file)
@@ -1,9 +1,7 @@
 /*
  * tel-plugin-vmodem
  *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Junhwan An <jh48.an@samsung.com>
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
 #include <unistd.h>
-#include <stdlib.h>
 #include <time.h>
 #include <fcntl.h>
 
 #include <glib.h>
 
 #include <tcore.h>
-#include <plugin.h>
 #include <server.h>
-#include <user_request.h>
+#include <plugin.h>
 #include <hal.h>
-#include <core_object.h>
 
+#include "config.h"
 #include "vdpram.h"
+#include "vdpram_dump.h"
 
-#define SERVER_INIT_WAIT_TIMEOUT               500
+#define VMODEM_HAL_NAME                "vmodem"
 
-#define DEVICE_NAME_LEN_MAX                            16
-#define DEVICE_NAME_PREFIX                             "pdp"
+#define DEVICE_NAME_LEN_MAX            16
+#define DEVICE_NAME_PREFIX             "pdp"
 
-#define BUF_LEN_MAX                                            512
+#define BUF_LEN_MAX                    512
 
-#define CORE_OBJECT_NAME_MAX                   16
-
-#define MODEM_PLUGIN_NAME                              "atmodem-plugin.so"
-
-struct custom_data {
-       int vdpram_fd;
-       guint watch_id_vdpram;
-};
-
-struct v_modules {
-       unsigned int co_type;
-       char co_name[CORE_OBJECT_NAME_MAX];
-};
+#define AT_CP_POWER_ON_TIMEOUT 500
 
-/* Supported Modules */
-static struct v_modules supported_modules[] = {
-       {CORE_OBJECT_TYPE_MODEM,        "Modem"},
-       {CORE_OBJECT_TYPE_CALL,         "Call"},
-       {CORE_OBJECT_TYPE_SS,           "SS"},
-       {CORE_OBJECT_TYPE_NETWORK,      "Network"},
-       {CORE_OBJECT_TYPE_PS,           "PS"},
-       {CORE_OBJECT_TYPE_SIM,          "SIM"},
-       {CORE_OBJECT_TYPE_SMS,          "SMS"},
-       {0,                                                     ""}
-};
-
-static void _assign_objects_to_hal(TcoreHal *hal)
-{
-       TcorePlugin *plugin;
-       int i;
-       gboolean ret;
-
-       plugin = tcore_hal_ref_plugin(hal);
-
-       /* Add Core Object type for specific 'hal' */
-       for (i = 0 ; supported_modules[i].co_type != 0 ; i++) {
-               ret = tcore_server_add_cp_mapping_tbl_entry(plugin,
-                                                                       supported_modules[i].co_type, hal);
-               if (ret == TRUE) {
-                       dbg("[VMODEM] Core Object: [%s] - [Success]",
-                                                                       supported_modules[i].co_name);
-               } else {
-                       err("[VMODEM] Core Object: [%s] - [Fail]",
-                                                                       supported_modules[i].co_name);
-               }
-       }
-}
-
-static void _deassign_objects_from_hal(TcoreHal *hal)
-{
-       TcorePlugin *plugin;
-
-       plugin = tcore_hal_ref_plugin(hal);
-
-       /* Remove mapping table entry */
-       tcore_server_remove_cp_mapping_tbl_entry(plugin, hal);
-}
-
-static guint _register_gio_watch(TcoreHal *h, int fd, void *callback)
+static guint __register_gio_watch(TcoreHal *h, int fd, void *callback)
 {
        GIOChannel *channel = NULL;
        guint source;
 
-       dbg("[VMODEM] Register to Watch list - fd: [%d]", fd);
+       dbg("Register to Watch list - fd: [%d]", fd);
 
        if ((fd < 0) || (callback == NULL))
                return 0;
@@ -120,104 +62,69 @@ static guint _register_gio_watch(TcoreHal *h, int fd, void *callback)
        return source;
 }
 
-static void _deregister_gio_watch(guint watch_id)
+static void __deregister_gio_watch(guint watch_id)
 {
-       dbg("[VMODEM] Deregister Watch ID: [%d]", watch_id);
+       dbg("Deregister Watch ID: [%d]", watch_id);
 
        /* Remove source */
        g_source_remove(watch_id);
 }
 
-static gboolean _load_modem_plugin(gpointer data)
+static TcoreHookReturn __on_hal_send(TcoreHal *hal,
+               guint data_len, void *data, void *user_data)
 {
-       TcoreHal *hal;
-       TcorePlugin *plugin;
-       struct custom_data *user_data;
-
-       dbg("[VMMODEM] Entry");
-
-       if (data == NULL) {
-               err("[VMMODEM] data is NULL");
-               return FALSE;
-       }
-
-       hal = data;
-       plugin = tcore_hal_ref_plugin(hal);
-
-       /* Load Modem Plug-in */
-       if (tcore_server_load_modem_plugin(tcore_plugin_ref_server(plugin),
-                                       plugin, MODEM_PLUGIN_NAME) == TCORE_RETURN_FAILURE) {
-               err("[VMMODEM] Load Modem Plug-in - [FAIL]");
-
-               /* Clean-up */
-               _deassign_objects_from_hal(hal);
-
-               goto EXIT;
-       } else {
-               dbg("[VMMODEM] Load Modem Plug-in - [SUCCESS]");
-       }
-
-       /* To stop the cycle need to return FALSE */
-       return FALSE;
+       /* Dumping Send (Write) data */
+       vdpram_hex_dump(TRUE, data_len, data);
 
-EXIT:
-       user_data = tcore_hal_ref_user_data(hal);
-       if (user_data == NULL)
-               return FALSE;
-
-       /* Deregister from Watch list */
-       _deregister_gio_watch(user_data->watch_id_vdpram);
-
-       /* Free HAL */
-       tcore_hal_free(hal);
-
-       /* Close VDPRAM device */
-       vdpram_close(user_data->vdpram_fd);
-
-       /* Free custom data */
-       g_free(user_data);
+       return TCORE_HOOK_RETURN_CONTINUE;
+}
 
-       return FALSE;
+static void __on_hal_recv(TcoreHal *hal,
+       guint data_len, const void *data, void *user_data)
+{
+       /* Dumping Receive (Read) data */
+       vdpram_hex_dump(FALSE, data_len, (void *)data);
 }
 
-static TReturn _modem_power(TcoreHal *hal, gboolean enable)
+static gboolean __modem_power(TcoreHal *hal, gboolean enable)
 {
-       struct custom_data *user_data;
+       CustomData *user_data;
 
        user_data = tcore_hal_ref_user_data(hal);
        if (user_data == NULL) {
-               err("[VMODEM] User data is NULL");
-               return TCORE_RETURN_FAILURE;
+               err("User data is NULL");
+               return FALSE;
        }
 
-       if (enable == TRUE) {                                                   /* POWER ON */
+       if (enable == TRUE) {           /* POWER ON */
                if (FALSE == vdpram_poweron(user_data->vdpram_fd)) {
-                       err("[VMODEM] Power ON - [FAIL]");
-                       return TCORE_RETURN_FAILURE;
+                       err("Power ON - [FAIL]");
+                       return FALSE;
                }
 
                /* Set Power State - ON */
                tcore_hal_set_power_state(hal, TRUE);
-       } else {                                                                                /* POWER OFF */
+       } else {                                /* POWER OFF */
                if (vdpram_poweroff(user_data->vdpram_fd) == FALSE) {
-                       err("[VMODEM] Power OFF - [FAIL]");
-                       return TCORE_RETURN_FAILURE;
+                       err("Power OFF - [FAIL]");
+                       return FALSE;
                }
 
                /* Set Power state - OFF */
                tcore_hal_set_power_state(hal, FALSE);
        }
 
-       return TCORE_RETURN_SUCCESS;
+       return TRUE;
 }
 
-static gboolean on_recv_vdpram_message(GIOChannel *channel,
-                                                                       GIOCondition condition, gpointer data)
+static gboolean __on_recv_vdpram_message(GIOChannel *channel,
+       GIOCondition condition, gpointer data)
 {
        TcoreHal *hal = data;
-       struct custom_data *custom;
-       char buf[BUF_LEN_MAX];
+       CustomData *custom;
+       char buf[BUF_LEN_MAX] = {0, };
        int n = 0;
+       TelReturn ret;
 
        custom = tcore_hal_ref_user_data(hal);
        memset(buf, 0x0, BUF_LEN_MAX);
@@ -225,53 +132,117 @@ static gboolean on_recv_vdpram_message(GIOChannel *channel,
        /* Read from Device */
        n = vdpram_tty_read(custom->vdpram_fd, buf, BUF_LEN_MAX);
        if (n < 0) {
-               err("[VMODEM] Read error - Data received: [%d]", n);
+               err("Read error - Data received: [%d]", n);
                return TRUE;
        }
-       dbg("[VMODEM] DPRAM Receive - Data length: [%d]", n);
+       dbg("DPRAM Receive - Data length: [%d]", n);
 
        /* Emit receive callback */
+
+
+       msg("\n---------- [RECV] Length of received data: [%d] ----------\n", n);
+
+       /* Emit response callback */
        tcore_hal_emit_recv_callback(hal, n, buf);
 
+       /* Dispatch received data to response handler */
+       ret = tcore_hal_dispatch_response_data(hal, 0, n, buf);
+       msg("\n---------- [RECV FINISH] Receive processing: [%d] ----------\n", ret);
+
        return TRUE;
 }
 
-static TReturn hal_power(TcoreHal *hal, gboolean flag)
+static gboolean __power_on(gpointer data)
 {
-       return _modem_power(hal, flag);
+       CustomData *user_data;
+       TcoreHal *hal = (TcoreHal*)data;
+
+       dbg("Entry");
+
+       user_data = tcore_hal_ref_user_data(hal);
+       tcore_check_return_value_assert(user_data != NULL, TRUE);
+
+       /*
+        * Open DPRAM device: Create and Open interface to CP
+        */
+       user_data->vdpram_fd = vdpram_open();
+       if (user_data->vdpram_fd < 1) {
+               TcorePlugin *plugin = tcore_hal_ref_plugin(hal);
+               Server *server = tcore_plugin_ref_server(plugin);
+
+               err("Failed to Create/Open CP interface");
+
+               /* Notify server a modem error occured */
+               tcore_server_send_server_notification(server,
+                       TCORE_SERVER_NOTIFICATION_MODEM_ERR, 0, NULL);
+
+               goto EXIT;
+       }
+       dbg("Created AP-CP interface");
+
+       /* Register to Watch llist */
+       user_data->vdpram_watch_id = __register_gio_watch(hal,
+                               user_data->vdpram_fd, __on_recv_vdpram_message);
+       dbg("fd: [%d] Watch ID: [%d]", user_data->vdpram_fd, user_data->vdpram_watch_id);
+
+       /* Power ON VDPRAM device */
+       if (__modem_power(hal, TRUE)) {
+               dbg("Power ON - [SUCCESS]");
+       } else {
+               err("Power ON - [FAIL]");
+               goto EXIT;
+       }
+
+       /* CP is ONLINE, send AT+CPAS */
+       vmodem_config_check_cp_power(hal);
+
+       /* To stop the cycle need to return FALSE */
+       return FALSE;
+
+EXIT:
+       /* TODO: Handle Deregister */
+
+       /* To stop the cycle need to return FALSE */
+       return FALSE;
 }
 
-static TReturn hal_send(TcoreHal *hal, unsigned int data_len, void *data)
+/* HAL Operations */
+static TelReturn _hal_power(TcoreHal *hal, gboolean flag)
 {
-       int ret;
-       struct custom_data *user_data;
+       return __modem_power(hal, flag);
+}
+
+static TelReturn _hal_send(TcoreHal *hal,
+       guint data_len, void *data)
+{
+       CustomData *user_data;
+       gint ret;
 
        if (tcore_hal_get_power_state(hal) == FALSE) {
-               err("[VMODEM] HAL Power state - OFF");
-               return TCORE_RETURN_FAILURE;
+               err("HAL Power state - OFF");
+               return TEL_RETURN_FAILURE;
        }
 
        user_data = tcore_hal_ref_user_data(hal);
        if (user_data == NULL) {
-               err("[VMODEM] User data is NULL");
-               return TCORE_RETURN_FAILURE;
+               err("User data is NULL");
+               return TEL_RETURN_FAILURE;
        }
 
        ret = vdpram_tty_write(user_data->vdpram_fd, data, data_len);
-       if(ret < 0)     {
-               err("[VMODEM] Write failed");
-               return TCORE_RETURN_FAILURE;
-       }
-       else {
-               dbg("vdpram_tty_write success ret=%d (fd=%d, len=%d)", ret, user_data->vdpram_fd, data_len);
-               return TCORE_RETURN_SUCCESS;
+       if(ret < 0) {
+               err("Write failed");
+               return TEL_RETURN_FAILURE;
        }
+       dbg("vdpram_tty_write success ret=%d (fd=%d, len=%d)",
+               ret, user_data->vdpram_fd, data_len);
+
+       return TEL_RETURN_SUCCESS;
 }
 
-static TReturn hal_setup_netif(CoreObject *co,
-                               TcoreHalSetupNetifCallback func,
-                               void *user_data, unsigned int cid,
-                               gboolean enable)
+static TelReturn _hal_setup_netif(CoreObject *co,
+       TcoreHalSetupNetifCallback func, void *user_data,
+       guint cid, gboolean enable)
 {
        char ifname[DEVICE_NAME_LEN_MAX];
        int size = 0;
@@ -280,27 +251,27 @@ static TReturn hal_setup_netif(CoreObject *co,
        char *control = NULL;
 
        if (cid > 3) {
-               err("[VMODEM] Context ID: [%d]", cid);
-               return TCORE_RETURN_EINVAL;
+               err("Context ID: [%d]", cid);
+               return TEL_RETURN_INVALID_PARAMETER;
        }
 
        if (enable == TRUE) {
-               dbg("[VMODEM] ACTIVATE - Context ID: [%d]", cid);
+               dbg("ACTIVATE - Context ID: [%d]", cid);
                control = "/sys/class/net/svnet0/pdp/activate";
        } else {
-               dbg("[VMODEM] DEACTIVATE - Context ID: [%d]", cid);
+               dbg("DEACTIVATE - Context ID: [%d]", cid);
                control = "/sys/class/net/svnet0/pdp/deactivate";
        }
 
        fd = open(control, O_WRONLY);
        if (fd < 0) {
-               err("[VMODEM] Failed to Open interface: [%s]", control);
+               err("Failed to Open interface: [%s]", control);
 
                /* Invoke callback function */
                if (func)
                        func(co, -1, NULL, user_data);
 
-               return TCORE_RETURN_FAILURE;
+               return TEL_RETURN_FAILURE;
        }
 
        /* Context ID needs to be written to the Device */
@@ -312,25 +283,25 @@ static TReturn hal_setup_netif(CoreObject *co,
 
        /* Device name */
        snprintf(ifname, DEVICE_NAME_LEN_MAX, "%s%d", DEVICE_NAME_PREFIX, (cid - 1));
-       dbg("[VMODEM] Interface Name: [%s]", ifname);
+       dbg("Interface Name: [%s]", ifname);
 
        /* Invoke callback function */
        if (func)
                func(co, 0, ifname, user_data);
 
-       return TCORE_RETURN_SUCCESS;
+       return TEL_RETURN_SUCCESS;
 }
 
 /* HAL Operations */
-static struct tcore_hal_operations hal_ops = {
-       .power = hal_power,
-       .send = hal_send,
-       .setup_netif = hal_setup_netif,
+static TcoreHalOperations hal_ops = {
+       .power = _hal_power,
+       .send = _hal_send,
+       .setup_netif = _hal_setup_netif,
 };
 
 static gboolean on_load()
 {
-       dbg("[VMODEM] Load!!!");
+       dbg("Load!!!");
 
        return TRUE;
 }
@@ -338,148 +309,105 @@ static gboolean on_load()
 static gboolean on_init(TcorePlugin *plugin)
 {
        TcoreHal *hal;
-       struct custom_data *data;
+       CustomData *data;
+       dbg("Init!!!");
 
-       dbg("[VMODEM] Init!!!");
+       tcore_check_return_value_assert(plugin != NULL, FALSE);
 
-       if (plugin == NULL) {
-               err("[VMODEM] PLug-in is NULL");
-               return FALSE;
-       }
-
-       /* Register Modem Interface Plug-in */
-       if (tcore_server_register_modem(tcore_plugin_ref_server(plugin), plugin)
-                                                               == FALSE) {
-               err("[VMODEM] Registration Failed");
-               return FALSE;
-       }
-       dbg("[VMODEM] Registered from Server");
-
-       data = g_try_new0(struct custom_data, 1);
-       if (data == NULL) {
-               err("[VMODEM] Failed to allocate memory for Custom data");
-
-               /* Unregister from Server */
-               tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
-               return FALSE;
-       }
+       /* Custom data for Modem Interface Plug-in */
+       data = tcore_malloc0(sizeof(CustomData));
+       dbg("Created custom data memory");
 
-       /*
-        * Open DPRAM device
-        */
-       data->vdpram_fd = vdpram_open();
-
-       /*
-        * Create and initialize HAL
-        */
-       hal = tcore_hal_new(plugin, "vmodem", &hal_ops, TCORE_HAL_MODE_CUSTOM);
+       /* Create Physical HAL */
+       hal = tcore_hal_new(plugin, VMODEM_HAL_NAME,
+                       &hal_ops, TCORE_HAL_MODE_AT);
        if (hal == NULL) {
-               /* Close VDPRAM device */
-               vdpram_close(data->vdpram_fd);
-
-               /* Fre custom data */
-               g_free(data);
-
-               /* Unregister from Server */
-               tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
-
+               err("Failed to Create Physical HAL");
+               tcore_free(data);
                return FALSE;
        }
+       dbg("HAL [0x%x] created", hal);
 
        /* Set HAL as Modem Interface Plug-in's User data */
        tcore_plugin_link_user_data(plugin, hal);
 
-       /* Link custom data to HAL user data */
+       /* Link Custom data to HAL's 'user_data' */
        tcore_hal_link_user_data(hal, data);
 
-       /* Register to Watch llist */
-       data->watch_id_vdpram = _register_gio_watch(hal,
-                                                               data->vdpram_fd, on_recv_vdpram_message);
-       dbg("[VMODEM] fd: [%d] Watch ID: [%d]",
-                                                               data->vdpram_fd, data->watch_id_vdpram);
+       /* Add callbacks for Send/Receive Hooks */
+       tcore_hal_add_send_hook(hal, __on_hal_send, NULL);
+       tcore_hal_add_recv_callback(hal, __on_hal_recv, NULL);
+       dbg("Added Send hook and Receive callback");
 
-       /* Power ON VDPRAM device */
-       if (_modem_power(hal, TRUE) == TCORE_RETURN_SUCCESS) {
-               dbg("[VMODEM] Power ON - [SUCCESS]");
-       } else {
-               err("[VMODEM] Power ON - [FAIL]");
-               goto EXIT;
-       }
+       /* Set HAL state to Power OFF (FALSE) */
+       (void)tcore_hal_set_power_state(hal, FALSE);
+       dbg("HAL Power State: Power OFF");
 
-       /* Add Core Objects list to HAL */
-       _assign_objects_to_hal(hal);
+       /* Resgister to Server */
+       if (tcore_server_register_modem(tcore_plugin_ref_server(plugin),
+               plugin) == FALSE) {
+               err("Registration Failed");
+
+               tcore_hal_free(hal);
+               tcore_free(data);
+               return FALSE;
+       }
+       dbg("Registered from Server");
 
        /* Check CP Power ON */
-       g_timeout_add_full(G_PRIORITY_HIGH, SERVER_INIT_WAIT_TIMEOUT, _load_modem_plugin, hal, 0);
+       g_timeout_add_full(G_PRIORITY_HIGH,
+               AT_CP_POWER_ON_TIMEOUT, __power_on, hal, NULL);
 
-       dbg("[VMMODEM] Exit");
        return TRUE;
-
-EXIT:
-       /* Deregister from Watch list */
-       _deregister_gio_watch(data->watch_id_vdpram);
-
-       /* Free HAL */
-       tcore_hal_free(hal);
-
-       /* Close VDPRAM device */
-       vdpram_close(data->vdpram_fd);
-
-       /* Free custom data */
-       g_free(data);
-
-       /* Unregister from Server */
-       tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
-
-       return FALSE;
 }
 
 static void on_unload(TcorePlugin *plugin)
 {
        TcoreHal *hal;
-       struct custom_data *user_data;
+       CustomData *user_data;
+       dbg("Unload!!!");
 
-       dbg("[VMODEM] Unload!!!");
+       tcore_check_return_assert(plugin != NULL);
 
-       if (plugin == NULL)
-               return;
+       /* Unload Modem Plug-in */
+       tcore_server_unload_modem_plugin(tcore_plugin_ref_server(plugin), plugin);
+
+       /* Unregister Modem Interface Plug-in from Server */
+       tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
+       dbg("Unregistered from Server");
 
+       /* HAL cleanup */
        hal = tcore_plugin_ref_user_data(plugin);
-       if (hal == NULL)
+       if (hal == NULL) {
+               err("HAL is NULL");
                return;
+       }
 
-       /* Unload Modem Plug-in */
-#if 0  /* TODO - Open the code below */
-       tcore_server_unload_modem_plugin(tcore_plugin_ref_server(plugin), plugin);
-#endif
        user_data = tcore_hal_ref_user_data(hal);
        if (user_data == NULL)
                return;
 
        /* Deregister from Watch list */
-       _deregister_gio_watch(user_data->watch_id_vdpram);
-       dbg("[VMODEM] Deregistered Watch ID");
-
-       /* Free HAL */
-       tcore_hal_free(hal);
-       dbg("[VMODEM] Freed HAL");
+       __deregister_gio_watch(user_data->vdpram_watch_id);
+       dbg("Deregistered Watch ID");
 
        /* Close VDPRAM device */
-       vdpram_close(user_data->vdpram_fd);
-       dbg("[VMODEM] Closed VDPRAM device");
+       (void)vdpram_close(user_data->vdpram_fd);
+       dbg("Closed VDPRAM device");
 
        /* Free custom data */
        g_free(user_data);
 
-       tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
-       dbg("[VMODEM] Unregistered from Server");
+       /* Free HAL */
+       tcore_hal_free(hal);
+       dbg("Freed HAL");
 
-       dbg("[VMODEM] Unloaded MODEM");
+       dbg("Unloaded MODEM Interface Plug-in");
 }
 
-/* VMODEM Descriptor Structure */
-struct tcore_plugin_define_desc plugin_define_desc = {
-       .name = "VMODEM",
+/* VMODEM (Modem Interface Plug-in) descriptor */
+EXPORT_API struct tcore_plugin_define_desc plugin_define_desc = {
+       .name = "vmodem",
        .priority = TCORE_PLUGIN_PRIORITY_HIGH,
        .version = 1,
        .load = on_load,