/*
* 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;
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);
/* 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;
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 */
/* 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;
}
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,