4 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
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.
30 #include <core_object.h>
34 #include "atd_modem.h"
36 #include "atd_network.h"
39 #define STATUS_INFO_RESP "CPAS"
41 static void __initialize_device_retry(TcorePlugin *plugin);
43 static TReturn __send_at_request_immediately(CoreObject *co,
45 const char *at_cmd_prefix,
46 enum tcore_at_command_type at_cmd_type,
48 TcorePendingResponseCallback resp_cb,
50 TcorePendingSendCallback send_cb,
53 TcorePendingTimeoutCallback timeout_cb,
54 void *timeout_cb_data)
56 TcorePending *pending = NULL;
57 TcoreATRequest *req = NULL;
59 TReturn ret = TCORE_RETURN_FAILURE;
61 hal = tcore_object_get_hal(co);
66 dbg("hal: [0x%x]", hal);
68 /* Create Pending Request */
69 pending = tcore_pending_new(co, 0);
71 dbg("Pending is NULL");
75 /* Create AT-Command Request */
76 req = tcore_at_request_new(at_cmd, at_cmd_prefix, at_cmd_type);
78 dbg("Request is NULL");
79 tcore_pending_free(pending);
82 dbg("AT Command: [%s], Prefix(if any): [%s], AT-Command length: [%d]",
83 req->cmd, req->prefix, strlen(req->cmd));
85 tcore_pending_set_request_data(pending, 0, req);
86 tcore_pending_set_response_callback(pending, resp_cb, resp_cb_data);
87 tcore_pending_set_send_callback(pending, send_cb, send_cb_data);
88 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_HIGH);
89 tcore_pending_set_timeout(pending, timeout);
90 tcore_pending_set_timeout_callback(pending, timeout_cb, timeout_cb_data);
91 tcore_pending_link_user_request(pending, ur);
93 ret = tcore_hal_send_request(hal, pending);
94 dbg("ret: [0x%x]", ret);
98 static void on_response_sync_for_resp(TcorePending *p,
99 int data_len, const void *data, void *user_data)
101 const TcoreATResponse *at_resp = data;
102 gboolean ret = FALSE;
104 if (at_resp && at_resp->success) {
105 dbg("Received - [Success]");
106 /* tty device works successfully. proceed */
108 ret = modem_power_on(user_data);
109 dbg("Modem Power ON: [%s]", (ret == TRUE ? "SUCCESS" : "FAIL"));
111 err("Received - [Fail]");
114 static void __sync_for_resp(TcorePlugin *plugin)
116 CoreObject *co_modem;
119 if (plugin == NULL) {
120 err("Invalid plugin !");
124 /* Modem Core object */
125 co_modem = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
127 /* Some Dongle returns late response
128 * due to its late initialize.
130 * Send 'meaningless' command
131 * and sync sequence AT response for unexpected response */
132 ret = __send_at_request_immediately(co_modem,
136 on_response_sync_for_resp, plugin,
140 dbg("ret: [0x%x]", ret);
143 static void on_timeout_initialize_device(TcorePending *p, void *user_data)
145 dbg("Timeout! pending:[%p]", p);
146 dbg(" Try another command to tty device again..");
148 /* When AT device doesn't responded with 'AT+CPAS' command,
149 * need to send 'AT' command and check its response..
151 __initialize_device_retry(user_data);
154 static void on_response_initialize_device(TcorePending *p,
155 int data_len, const void *data, void *user_data)
157 const TcoreATResponse *at_resp = data;
158 gboolean ret = FALSE;
160 if (at_resp && at_resp->success) {
163 gboolean expected = FALSE;
165 dbg("Initialize for AT device - [Success] / Lines: %d",
166 g_slist_length(at_resp->lines));
168 lines = at_resp->lines;
170 line = (const char *)lines->data;
172 /* Check if response contains 'CPAS' - valid response */
173 if (g_strrstr(line, STATUS_INFO_RESP)) {
178 /* Move to next line */
182 /* Send empty command and wait for valid response */
183 if (expected == FALSE) {
184 TcorePlugin *plugin = tcore_pending_ref_plugin(p);
185 dbg("Response contains unexpected lines.");
186 dbg("Sync AT response");
187 __sync_for_resp(plugin);
189 /* tty device works successfully. proceed */
191 ret = modem_power_on(user_data);
192 dbg("Modem Power ON: [%s]", (ret == TRUE ? "SUCCESS" : "FAIL"));
195 dbg("Initialize for AT device - [Failed]");
199 static void on_response_initialize_device_retry(TcorePending *p,
200 int data_len, const void *data, void *user_data)
202 const TcoreATResponse *at_resp = data;
203 gboolean ret = FALSE;
205 if (at_resp && at_resp->success) {
208 gboolean unexpected = FALSE;
210 dbg("Initialize for AT device - [Success] / Lines: %d",
211 g_slist_length(at_resp->lines));
213 lines = at_resp->lines;
215 line = (const char *)lines->data;
217 /* Check if response contains 'CPAS' - invalid response */
218 if (g_strrstr(line, STATUS_INFO_RESP)) {
223 /* Move to next line */
227 /* Send empty command and wait for valid response */
229 TcorePlugin *plugin = tcore_pending_ref_plugin(p);
230 dbg("Response contains unexpected lines.");
231 dbg("Sync AT response");
232 __sync_for_resp(plugin);
234 /* tty device works successfully. proceed */
236 ret = modem_power_on(user_data);
237 dbg("Modem Power ON: [%s]", (ret == TRUE ? "SUCCESS" : "FAIL"));
240 dbg("Initialize for AT device - [Failed]");
244 static void __initialize_device(TcorePlugin *plugin)
246 CoreObject *co_modem;
249 if (plugin == NULL) {
250 err("Invalid plugin !");
254 /* Modem Core object */
255 co_modem = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
257 /* Send command and set timeout to 5 sec */
258 ret = tcore_prepare_and_send_at_request(co_modem,
262 on_response_initialize_device, plugin,
264 5, on_timeout_initialize_device, plugin);
266 dbg("ret: [0x%x]", ret);
269 static void __initialize_device_retry(TcorePlugin *plugin)
271 CoreObject *co_modem;
274 if (plugin == NULL) {
275 err("Invalid plugin !");
279 /* Modem Core object */
280 co_modem = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
282 /* Send 'AT' command and set timeout to 5 sec */
283 ret = tcore_prepare_and_send_at_request(co_modem,
287 on_response_initialize_device_retry, plugin,
289 5, on_timeout_initialize_device, plugin);
291 dbg("ret: [0x%x]", ret);
294 /**< Initializer Table */
295 struct object_initializer init_table = {
296 .modem_init = atd_modem_init,
297 .sim_init = atd_sim_init,
298 .network_init = atd_network_init,
299 .ps_init = atd_ps_init,
305 .phonebook_init = NULL,
309 /**< Deinitializer Table */
310 struct object_deinitializer deinit_table = {
311 .modem_deinit = atd_modem_exit,
312 .sim_deinit = atd_sim_exit,
313 .ps_deinit = atd_ps_exit,
314 .network_deinit = atd_network_exit,
320 .phonebook_deinit = NULL,
324 static gboolean on_load()
331 static gboolean on_init(TcorePlugin *p)
336 err("invalid plugin!!");
340 /* Initialize Modules (Core Objects) */
341 if (tcore_object_init_objects(p, &init_table)
342 != TCORE_RETURN_SUCCESS) {
343 err("Failed to initialize Core Objects");
347 /* Initialize tty device */
348 __initialize_device(p);
350 dbg("Init - Complete!");
355 static void on_unload(TcorePlugin *p)
359 /* Deinitialize Modules (Core Objects) */
360 tcore_object_deinit_objects(p, &deinit_table);
363 /* AT Dongle - Modem Plug-in Descriptor */
364 struct tcore_plugin_define_desc plugin_define_desc = {
366 .priority = TCORE_PLUGIN_PRIORITY_MID,