4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
36 #include "vdpram_dump.h"
38 #define VMODEM_HAL_NAME "vmodem"
40 #define DEVICE_NAME_LEN_MAX 16
41 #define DEVICE_NAME_PREFIX "pdp"
43 #define BUF_LEN_MAX 512
45 #define AT_CP_POWER_ON_TIMEOUT 500
47 static guint __register_gio_watch(TcoreHal *h, int fd, void *callback)
49 GIOChannel *channel = NULL;
52 dbg("Register to Watch list - fd: [%d]", fd);
54 if ((fd < 0) || (callback == NULL))
57 channel = g_io_channel_unix_new(fd);
58 source = g_io_add_watch(channel, G_IO_IN, (GIOFunc) callback, h);
59 g_io_channel_unref(channel);
65 static void __deregister_gio_watch(guint watch_id)
67 dbg("Deregister Watch ID: [%d]", watch_id);
70 g_source_remove(watch_id);
73 static TcoreHookReturn __on_hal_send(TcoreHal *hal,
74 guint data_len, void *data, void *user_data)
76 /* Dumping Send (Write) data */
77 vdpram_hex_dump(TRUE, data_len, data);
79 return TCORE_HOOK_RETURN_CONTINUE;
82 static void __on_hal_recv(TcoreHal *hal,
83 guint data_len, const void *data, void *user_data)
85 /* Dumping Receive (Read) data */
86 vdpram_hex_dump(FALSE, data_len, (void *)data);
89 static gboolean __modem_power(TcoreHal *hal, gboolean enable)
91 CustomData *user_data;
93 user_data = tcore_hal_ref_user_data(hal);
94 if (user_data == NULL) {
95 err("User data is NULL");
99 if (enable == TRUE) { /* POWER ON */
100 if (FALSE == vdpram_poweron(user_data->vdpram_fd)) {
101 err("Power ON - [FAIL]");
105 /* Set Power State - ON */
106 tcore_hal_set_power_state(hal, TRUE);
107 } else { /* POWER OFF */
108 if (vdpram_poweroff(user_data->vdpram_fd) == FALSE) {
109 err("Power OFF - [FAIL]");
113 /* Set Power state - OFF */
114 tcore_hal_set_power_state(hal, FALSE);
120 static gboolean __on_recv_vdpram_message(GIOChannel *channel,
121 GIOCondition condition, gpointer data)
123 TcoreHal *hal = data;
125 char buf[BUF_LEN_MAX] = {0, };
129 custom = tcore_hal_ref_user_data(hal);
130 memset(buf, 0x0, BUF_LEN_MAX);
132 /* Read from Device */
133 n = vdpram_tty_read(custom->vdpram_fd, buf, BUF_LEN_MAX);
135 err("Read error - Data received: [%d]", n);
138 dbg("DPRAM Receive - Data length: [%d]", n);
140 /* Emit receive callback */
143 msg("\n---------- [RECV] Length of received data: [%d] ----------\n", n);
145 /* Emit response callback */
146 tcore_hal_emit_recv_callback(hal, n, buf);
148 /* Dispatch received data to response handler */
149 ret = tcore_hal_dispatch_response_data(hal, 0, n, buf);
150 msg("\n---------- [RECV FINISH] Receive processing: [%d] ----------\n", ret);
155 static gboolean __power_on(gpointer data)
157 CustomData *user_data;
158 TcoreHal *hal = (TcoreHal*)data;
162 user_data = tcore_hal_ref_user_data(hal);
163 tcore_check_return_value_assert(user_data != NULL, TRUE);
166 * Open DPRAM device: Create and Open interface to CP
168 user_data->vdpram_fd = vdpram_open();
169 if (user_data->vdpram_fd < 1) {
170 TcorePlugin *plugin = tcore_hal_ref_plugin(hal);
171 Server *server = tcore_plugin_ref_server(plugin);
173 err("Failed to Create/Open CP interface");
175 /* Notify server a modem error occured */
176 tcore_server_send_server_notification(server,
177 TCORE_SERVER_NOTIFICATION_MODEM_ERR, 0, NULL);
181 dbg("Created AP-CP interface");
183 /* Register to Watch llist */
184 user_data->vdpram_watch_id = __register_gio_watch(hal,
185 user_data->vdpram_fd, __on_recv_vdpram_message);
186 dbg("fd: [%d] Watch ID: [%d]", user_data->vdpram_fd, user_data->vdpram_watch_id);
188 /* Power ON VDPRAM device */
189 if (__modem_power(hal, TRUE)) {
190 dbg("Power ON - [SUCCESS]");
192 err("Power ON - [FAIL]");
196 /* CP is ONLINE, send AT+CPAS */
197 vmodem_config_check_cp_power(hal);
199 /* To stop the cycle need to return FALSE */
203 /* TODO: Handle Deregister */
205 /* To stop the cycle need to return FALSE */
210 static TelReturn _hal_power(TcoreHal *hal, gboolean flag)
212 return __modem_power(hal, flag);
215 static TelReturn _hal_send(TcoreHal *hal,
216 guint data_len, void *data)
218 CustomData *user_data;
221 if (tcore_hal_get_power_state(hal) == FALSE) {
222 err("HAL Power state - OFF");
223 return TEL_RETURN_FAILURE;
226 user_data = tcore_hal_ref_user_data(hal);
227 if (user_data == NULL) {
228 err("User data is NULL");
229 return TEL_RETURN_FAILURE;
232 ret = vdpram_tty_write(user_data->vdpram_fd, data, data_len);
235 return TEL_RETURN_FAILURE;
237 dbg("vdpram_tty_write success ret=%d (fd=%d, len=%d)",
238 ret, user_data->vdpram_fd, data_len);
240 return TEL_RETURN_SUCCESS;
243 static TelReturn _hal_setup_netif(CoreObject *co,
244 TcoreHalSetupNetifCallback func, void *user_data,
245 guint cid, gboolean enable)
247 char ifname[DEVICE_NAME_LEN_MAX];
251 char *control = NULL;
254 err("Context ID: [%d]", cid);
255 return TEL_RETURN_INVALID_PARAMETER;
258 if (enable == TRUE) {
259 dbg("ACTIVATE - Context ID: [%d]", cid);
260 control = "/sys/class/net/svnet0/pdp/activate";
262 dbg("DEACTIVATE - Context ID: [%d]", cid);
263 control = "/sys/class/net/svnet0/pdp/deactivate";
266 fd = open(control, O_WRONLY);
268 err("Failed to Open interface: [%s]", control);
270 /* Invoke callback function */
272 func(co, -1, NULL, user_data);
274 return TEL_RETURN_FAILURE;
277 /* Context ID needs to be written to the Device */
278 snprintf(buf, sizeof(buf), "%d", cid);
279 size = write(fd, buf, strlen(buf));
285 snprintf(ifname, DEVICE_NAME_LEN_MAX, "%s%d", DEVICE_NAME_PREFIX, (cid - 1));
286 dbg("Interface Name: [%s]", ifname);
288 /* Invoke callback function */
290 func(co, 0, ifname, user_data);
292 return TEL_RETURN_SUCCESS;
296 static TcoreHalOperations hal_ops = {
299 .setup_netif = _hal_setup_netif,
302 static gboolean on_load()
309 static gboolean on_init(TcorePlugin *plugin)
315 tcore_check_return_value_assert(plugin != NULL, FALSE);
317 /* Custom data for Modem Interface Plug-in */
318 data = tcore_malloc0(sizeof(CustomData));
319 dbg("Created custom data memory");
321 /* Create Physical HAL */
322 hal = tcore_hal_new(plugin, VMODEM_HAL_NAME,
323 &hal_ops, TCORE_HAL_MODE_AT);
325 err("Failed to Create Physical HAL");
329 dbg("HAL [0x%x] created", hal);
331 /* Set HAL as Modem Interface Plug-in's User data */
332 tcore_plugin_link_user_data(plugin, hal);
334 /* Link Custom data to HAL's 'user_data' */
335 tcore_hal_link_user_data(hal, data);
337 /* Add callbacks for Send/Receive Hooks */
338 tcore_hal_add_send_hook(hal, __on_hal_send, NULL);
339 tcore_hal_add_recv_callback(hal, __on_hal_recv, NULL);
340 dbg("Added Send hook and Receive callback");
342 /* Set HAL state to Power OFF (FALSE) */
343 (void)tcore_hal_set_power_state(hal, FALSE);
344 dbg("HAL Power State: Power OFF");
346 /* Resgister to Server */
347 if (tcore_server_register_modem(tcore_plugin_ref_server(plugin),
349 err("Registration Failed");
355 dbg("Registered from Server");
357 /* Check CP Power ON */
358 g_timeout_add_full(G_PRIORITY_HIGH,
359 AT_CP_POWER_ON_TIMEOUT, __power_on, hal, NULL);
364 static void on_unload(TcorePlugin *plugin)
367 CustomData *user_data;
370 tcore_check_return_assert(plugin != NULL);
372 /* Unload Modem Plug-in */
373 tcore_server_unload_modem_plugin(tcore_plugin_ref_server(plugin), plugin);
375 /* Unregister Modem Interface Plug-in from Server */
376 tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
377 dbg("Unregistered from Server");
380 hal = tcore_plugin_ref_user_data(plugin);
386 user_data = tcore_hal_ref_user_data(hal);
387 if (user_data == NULL)
390 /* Deregister from Watch list */
391 __deregister_gio_watch(user_data->vdpram_watch_id);
392 dbg("Deregistered Watch ID");
394 /* Close VDPRAM device */
395 (void)vdpram_close(user_data->vdpram_fd);
396 dbg("Closed VDPRAM device");
398 /* Free custom data */
405 dbg("Unloaded MODEM Interface Plug-in");
408 /* VMODEM (Modem Interface Plug-in) descriptor */
409 EXPORT_API struct tcore_plugin_define_desc plugin_define_desc = {
411 .priority = TCORE_PLUGIN_PRIORITY_HIGH,