4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Junhwan An <jh48.an@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
34 #include <user_request.h>
36 #include <core_object.h>
40 #define SERVER_INIT_WAIT_TIMEOUT 500
42 #define DEVICE_NAME_LEN_MAX 16
43 #define DEVICE_NAME_PREFIX "pdp"
45 #define BUF_LEN_MAX 512
47 #define CORE_OBJECT_NAME_MAX 16
49 #define MODEM_PLUGIN_NAME "atmodem-plugin.so"
53 guint watch_id_vdpram;
58 char co_name[CORE_OBJECT_NAME_MAX];
61 /* Supported Modules */
62 static struct v_modules supported_modules[] = {
63 {CORE_OBJECT_TYPE_MODEM, "Modem"},
64 {CORE_OBJECT_TYPE_CALL, "Call"},
65 {CORE_OBJECT_TYPE_SS, "SS"},
66 {CORE_OBJECT_TYPE_NETWORK, "Network"},
67 {CORE_OBJECT_TYPE_PS, "PS"},
68 {CORE_OBJECT_TYPE_SIM, "SIM"},
69 {CORE_OBJECT_TYPE_SMS, "SMS"},
73 static void _assign_objects_to_hal(TcoreHal *hal)
79 plugin = tcore_hal_ref_plugin(hal);
81 /* Add Core Object type for specific 'hal' */
82 for (i = 0 ; supported_modules[i].co_type != 0 ; i++) {
83 ret = tcore_server_add_cp_mapping_tbl_entry(plugin,
84 supported_modules[i].co_type, hal);
86 dbg("[VMODEM] Core Object: [%s] - [Success]",
87 supported_modules[i].co_name);
89 err("[VMODEM] Core Object: [%s] - [Fail]",
90 supported_modules[i].co_name);
95 static void _deassign_objects_from_hal(TcoreHal *hal)
99 plugin = tcore_hal_ref_plugin(hal);
101 /* Remove mapping table entry */
102 tcore_server_remove_cp_mapping_tbl_entry(plugin, hal);
105 static guint _register_gio_watch(TcoreHal *h, int fd, void *callback)
107 GIOChannel *channel = NULL;
110 dbg("[VMODEM] Register to Watch list - fd: [%d]", fd);
112 if ((fd < 0) || (callback == NULL))
115 channel = g_io_channel_unix_new(fd);
116 source = g_io_add_watch(channel, G_IO_IN, (GIOFunc) callback, h);
117 g_io_channel_unref(channel);
123 static void _deregister_gio_watch(guint watch_id)
125 dbg("[VMODEM] Deregister Watch ID: [%d]", watch_id);
128 g_source_remove(watch_id);
131 static gboolean _load_modem_plugin(gpointer data)
135 struct custom_data *user_data;
137 dbg("[VMMODEM] Entry");
140 err("[VMMODEM] data is NULL");
145 plugin = tcore_hal_ref_plugin(hal);
147 /* Load Modem Plug-in */
148 if (tcore_server_load_modem_plugin(tcore_plugin_ref_server(plugin),
149 plugin, MODEM_PLUGIN_NAME) == TCORE_RETURN_FAILURE) {
150 err("[VMMODEM] Load Modem Plug-in - [FAIL]");
153 _deassign_objects_from_hal(hal);
157 dbg("[VMMODEM] Load Modem Plug-in - [SUCCESS]");
160 /* To stop the cycle need to return FALSE */
164 user_data = tcore_hal_ref_user_data(hal);
165 if (user_data == NULL)
168 /* Deregister from Watch list */
169 _deregister_gio_watch(user_data->watch_id_vdpram);
174 /* Close VDPRAM device */
175 vdpram_close(user_data->vdpram_fd);
177 /* Free custom data */
183 static TReturn _modem_power(TcoreHal *hal, gboolean enable)
185 struct custom_data *user_data;
187 user_data = tcore_hal_ref_user_data(hal);
188 if (user_data == NULL) {
189 err("[VMODEM] User data is NULL");
190 return TCORE_RETURN_FAILURE;
193 if (enable == TRUE) { /* POWER ON */
194 if (FALSE == vdpram_poweron(user_data->vdpram_fd)) {
195 err("[VMODEM] Power ON - [FAIL]");
196 return TCORE_RETURN_FAILURE;
199 /* Set Power State - ON */
200 tcore_hal_set_power_state(hal, TRUE);
201 } else { /* POWER OFF */
202 if (vdpram_poweroff(user_data->vdpram_fd) == FALSE) {
203 err("[VMODEM] Power OFF - [FAIL]");
204 return TCORE_RETURN_FAILURE;
207 /* Set Power state - OFF */
208 tcore_hal_set_power_state(hal, FALSE);
211 return TCORE_RETURN_SUCCESS;
214 static gboolean on_recv_vdpram_message(GIOChannel *channel,
215 GIOCondition condition, gpointer data)
217 TcoreHal *hal = data;
218 struct custom_data *custom;
219 char buf[BUF_LEN_MAX];
222 custom = tcore_hal_ref_user_data(hal);
223 memset(buf, 0x0, BUF_LEN_MAX);
225 /* Read from Device */
226 n = vdpram_tty_read(custom->vdpram_fd, buf, BUF_LEN_MAX);
228 err("[VMODEM] Read error - Data received: [%d]", n);
231 dbg("[VMODEM] DPRAM Receive - Data length: [%d]", n);
233 /* Emit receive callback */
234 tcore_hal_emit_recv_callback(hal, n, buf);
239 static TReturn hal_power(TcoreHal *hal, gboolean flag)
241 return _modem_power(hal, flag);
244 static TReturn hal_send(TcoreHal *hal, unsigned int data_len, void *data)
247 struct custom_data *user_data;
249 if (tcore_hal_get_power_state(hal) == FALSE) {
250 err("[VMODEM] HAL Power state - OFF");
251 return TCORE_RETURN_FAILURE;
254 user_data = tcore_hal_ref_user_data(hal);
255 if (user_data == NULL) {
256 err("[VMODEM] User data is NULL");
257 return TCORE_RETURN_FAILURE;
260 ret = vdpram_tty_write(user_data->vdpram_fd, data, data_len);
262 err("[VMODEM] Write failed");
263 return TCORE_RETURN_FAILURE;
266 dbg("vdpram_tty_write success ret=%d (fd=%d, len=%d)", ret, user_data->vdpram_fd, data_len);
267 return TCORE_RETURN_SUCCESS;
271 static TReturn hal_setup_netif(CoreObject *co,
272 TcoreHalSetupNetifCallback func,
273 void *user_data, unsigned int cid,
276 char ifname[DEVICE_NAME_LEN_MAX];
280 char *control = NULL;
283 err("[VMODEM] Context ID: [%d]", cid);
284 return TCORE_RETURN_EINVAL;
287 if (enable == TRUE) {
288 dbg("[VMODEM] ACTIVATE - Context ID: [%d]", cid);
289 control = "/sys/class/net/svnet0/pdp/activate";
291 dbg("[VMODEM] DEACTIVATE - Context ID: [%d]", cid);
292 control = "/sys/class/net/svnet0/pdp/deactivate";
295 fd = open(control, O_WRONLY);
297 err("[VMODEM] Failed to Open interface: [%s]", control);
299 /* Invoke callback function */
301 func(co, -1, NULL, user_data);
303 return TCORE_RETURN_FAILURE;
306 /* Context ID needs to be written to the Device */
307 snprintf(buf, sizeof(buf), "%d", cid);
308 size = write(fd, buf, strlen(buf));
314 snprintf(ifname, DEVICE_NAME_LEN_MAX, "%s%d", DEVICE_NAME_PREFIX, (cid - 1));
315 dbg("[VMODEM] Interface Name: [%s]", ifname);
317 /* Invoke callback function */
319 func(co, 0, ifname, user_data);
321 return TCORE_RETURN_SUCCESS;
325 static struct tcore_hal_operations hal_ops = {
328 .setup_netif = hal_setup_netif,
331 static gboolean on_load()
333 dbg("[VMODEM] Load!!!");
338 static gboolean on_init(TcorePlugin *plugin)
341 struct custom_data *data;
343 dbg("[VMODEM] Init!!!");
345 if (plugin == NULL) {
346 err("[VMODEM] PLug-in is NULL");
350 /* Register Modem Interface Plug-in */
351 if (tcore_server_register_modem(tcore_plugin_ref_server(plugin), plugin)
353 err("[VMODEM] Registration Failed");
356 dbg("[VMODEM] Registered from Server");
358 data = g_try_new0(struct custom_data, 1);
360 err("[VMODEM] Failed to allocate memory for Custom data");
362 /* Unregister from Server */
363 tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
370 data->vdpram_fd = vdpram_open();
373 * Create and initialize HAL
375 hal = tcore_hal_new(plugin, "vmodem", &hal_ops, TCORE_HAL_MODE_CUSTOM);
377 /* Close VDPRAM device */
378 vdpram_close(data->vdpram_fd);
380 /* Fre custom data */
383 /* Unregister from Server */
384 tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
389 /* Set HAL as Modem Interface Plug-in's User data */
390 tcore_plugin_link_user_data(plugin, hal);
392 /* Link custom data to HAL user data */
393 tcore_hal_link_user_data(hal, data);
395 /* Register to Watch llist */
396 data->watch_id_vdpram = _register_gio_watch(hal,
397 data->vdpram_fd, on_recv_vdpram_message);
398 dbg("[VMODEM] fd: [%d] Watch ID: [%d]",
399 data->vdpram_fd, data->watch_id_vdpram);
401 /* Power ON VDPRAM device */
402 if (_modem_power(hal, TRUE) == TCORE_RETURN_SUCCESS) {
403 dbg("[VMODEM] Power ON - [SUCCESS]");
405 err("[VMODEM] Power ON - [FAIL]");
409 /* Add Core Objects list to HAL */
410 _assign_objects_to_hal(hal);
412 /* Check CP Power ON */
413 g_timeout_add_full(G_PRIORITY_HIGH, SERVER_INIT_WAIT_TIMEOUT, _load_modem_plugin, hal, 0);
415 dbg("[VMMODEM] Exit");
419 /* Deregister from Watch list */
420 _deregister_gio_watch(data->watch_id_vdpram);
425 /* Close VDPRAM device */
426 vdpram_close(data->vdpram_fd);
428 /* Free custom data */
431 /* Unregister from Server */
432 tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
437 static void on_unload(TcorePlugin *plugin)
440 struct custom_data *user_data;
442 dbg("[VMODEM] Unload!!!");
447 hal = tcore_plugin_ref_user_data(plugin);
451 /* Unload Modem Plug-in */
452 #if 0 /* TODO - Open the code below */
453 tcore_server_unload_modem_plugin(tcore_plugin_ref_server(plugin), plugin);
455 user_data = tcore_hal_ref_user_data(hal);
456 if (user_data == NULL)
459 /* Deregister from Watch list */
460 _deregister_gio_watch(user_data->watch_id_vdpram);
461 dbg("[VMODEM] Deregistered Watch ID");
465 dbg("[VMODEM] Freed HAL");
467 /* Close VDPRAM device */
468 vdpram_close(user_data->vdpram_fd);
469 dbg("[VMODEM] Closed VDPRAM device");
471 /* Free custom data */
474 tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
475 dbg("[VMODEM] Unregistered from Server");
477 dbg("[VMODEM] Unloaded MODEM");
480 /* VMODEM Descriptor Structure */
481 struct tcore_plugin_define_desc plugin_define_desc = {
483 .priority = TCORE_PLUGIN_PRIORITY_HIGH,