Initial refactoring merge
[platform/core/telephony/tel-plugin-vmodem.git] / src / config.c
1 /*
2  * tel-plugin-vmodem
3  *
4  * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <pthread.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <time.h>
26
27 #include <glib.h>
28
29 #include <tcore.h>
30 #include <server.h>
31 #include <plugin.h>
32 #include <storage.h>
33 #include <core_object.h>
34 #include <hal.h>
35 #include <at.h>
36
37 #include "config.h"
38
39 #define AT_MODEM_PLUGIN_NAME            "atmodem-plugin.so"
40
41 /* Maximum Core objects per Logical HAL (indirectly per Channel) */
42 #define MAX_CO_PER_CHANNEL              2
43
44 /* CP States */
45 #define AT_CPAS_RESULT_READY            0
46 #define AT_CPAS_RESULT_UNAVAIL          1
47 #define AT_CPAS_RESULT_UNKNOWN          2
48 #define AT_CPAS_RESULT_RINGING          3
49 #define AT_CPAS_RESULT_CALL_PROGRESS    4
50 #define AT_CPAS_RESULT_ASLEEP           5
51
52 typedef struct {
53         guint type;
54         gchar *name;
55 } VmodemSupportedCo;
56
57 /*
58  * List of supported Core Object types
59  */
60 static VmodemSupportedCo supported_modules[] = {
61         {CORE_OBJECT_TYPE_MODEM, "Modem"},
62         {CORE_OBJECT_TYPE_NETWORK, "Network"},
63         {CORE_OBJECT_TYPE_CALL, "Call"},
64         {CORE_OBJECT_TYPE_SIM, "Sim"},
65         {CORE_OBJECT_TYPE_SMS, "Sms"},
66         {CORE_OBJECT_TYPE_SS, "SS"},
67         {CORE_OBJECT_TYPE_PS, "PS"},
68         {0, ""},
69 };
70
71 static gboolean __check_cp_poweron(TcoreHal *hal);
72
73 static void __assign_objects_to_hal(TcoreHal *hal)
74 {
75         TcorePlugin *plugin;
76         gboolean ret;
77         guint i = 0;
78
79         plugin = tcore_hal_ref_plugin(hal);
80
81         while (supported_modules[i].type != 0) {
82                 /* Add Core Object type for specific 'hal' */
83                 ret = tcore_server_add_cp_mapping_tbl_entry(plugin,
84                                 supported_modules[i].type, hal);
85                 if (ret == TRUE) {
86                         dbg("Core Object Type: [0x%x] - Success",
87                                 supported_modules[i].name);
88                 } else {
89                         err("Core Object Type: [0x%x] - Fail",
90                                 supported_modules[i].name);
91                 }
92
93                 i++;
94         };
95 }
96
97 static void __deassign_objects_from_hal(TcoreHal *hal)
98 {
99         TcorePlugin *plugin;
100
101         plugin = tcore_hal_ref_plugin(hal);
102
103         /* Remove mapping table entry */
104         tcore_server_remove_cp_mapping_tbl_entry(plugin, hal);
105 }
106
107 static gboolean __load_modem_plugin(gpointer data)
108 {
109         TcoreHal *hal = (TcoreHal *)data;
110         TcorePlugin *plugin;
111
112         dbg("Entry");
113
114         if (hal == NULL) {
115                 err("hal is NULL");
116                 return FALSE;
117         }
118
119         plugin = tcore_hal_ref_plugin(hal);
120
121         /* Load Modem Plug-in */
122         if (tcore_server_load_modem_plugin(tcore_plugin_ref_server(plugin),
123                         plugin, AT_MODEM_PLUGIN_NAME) != TEL_RETURN_SUCCESS) {
124                 err("Load Modem Plug-in - [FAIL]");
125
126                 /* Clean-up */
127                 __deassign_objects_from_hal(hal);
128
129                 goto EXIT;
130         } else {
131                 dbg("Load Modem Plug-in - [SUCCESS]");
132         }
133
134         return TRUE;
135
136 EXIT:
137         /* TODO: Handle Deregister */
138
139         return FALSE;
140 }
141
142 static void __on_confirmation_send_message(TcorePending *p,
143         TelReturn send_status, void *user_data)
144 {
145         dbg("Message send confirmation - [%s]",
146                 ((send_status != TEL_RETURN_SUCCESS) ? "FAIL" : "OK"));
147 }
148
149 static void __on_timeout_check_cp_poweron(TcorePending *p, void *user_data)
150 {
151         TcoreHal *hal = user_data;
152         guint data_len = 0;
153         char *data = "AT+CPAS";
154
155         data_len = sizeof(data);
156
157         dbg("Resending Command: [%s] Command Length: [%d]", data, data_len);
158
159         /*
160          * Retransmit 1st AT command (AT+CPAS) directly via HAL without disturbing
161          * pending queue.
162          * HAL was passed as user_data, re-using it
163          */
164         tcore_hal_send_data(hal, data_len, (void *)data);
165 }
166
167 static void __on_response_check_cp_poweron(TcorePending *pending,
168         guint data_len, const void *data, void *user_data)
169 {
170         const TcoreAtResponse *resp = data;
171         TcoreHal *hal = user_data;
172
173         GSList *tokens = NULL;
174         const char *line;
175         gboolean bpoweron = FALSE;
176         int response = 0;
177
178         if (resp && resp->success) {
179                 dbg("Check CP POWER - [OK]");
180
181                 /* Parse AT Response */
182                 if (resp->lines) {
183                         dbg("Check CP POWER - [OK]");
184                         line = (const char *) resp->lines->data;
185                         dbg("line: %s", line);
186                         tokens = tcore_at_tok_new(line);
187                         dbg("tokens: %p", tokens);
188                         if (g_slist_length(tokens) != 1) {
189                                 err("Invalid message");
190                                 goto ERROR;
191                         }
192
193                         dbg("Check CP POWER - [OK]");
194
195                         response = atoi(g_slist_nth_data(tokens, 0));
196                         dbg("CPAS State: [%d]", response);
197
198                         switch (response) {
199                         case AT_CPAS_RESULT_READY:
200                         case AT_CPAS_RESULT_RINGING:
201                         case AT_CPAS_RESULT_CALL_PROGRESS:
202                         case AT_CPAS_RESULT_ASLEEP:
203                                 dbg("CP Power ON!!!");
204                                 bpoweron = TRUE;
205                         break;
206
207                         case AT_CPAS_RESULT_UNAVAIL:
208                         case AT_CPAS_RESULT_UNKNOWN:
209                         default:
210                                 err("Value is Unvailable/Unknown - but CP responded - proceed with Power ON!!!");
211                                 bpoweron = TRUE;
212                         break;
213                         }
214                 }
215                 else {
216                         err("Check CP POWER - [NOK] - lines NULL");
217                 }
218         } else {
219                 err("Check CP POWER - [NOK]");
220         }
221
222 ERROR:
223         /* Free tokens */
224         tcore_at_tok_free(tokens);
225
226         if (bpoweron == TRUE) {
227                 dbg("CP Power ON received");
228
229                 /* Load Modem Plug-in */
230                 if(__load_modem_plugin(hal) == FALSE) {
231                         /* TODO: Handle Deregistration */
232                 }
233                 else {
234                         dbg("Modem Plug-in loaded successfully");
235                 }
236         } else {
237                 err("CP is not ready, send CPAS again");
238                 __check_cp_poweron(hal);
239         }
240 }
241
242 static gboolean __check_cp_poweron(TcoreHal *hal)
243 {
244         TcoreAtRequest *at_req;
245         TcorePending *pending = NULL;
246
247         /* Create Pending request */
248         pending = tcore_pending_new(NULL, 0);
249
250         /* Create AT Request */
251         at_req = tcore_at_request_new("AT+CPAS",
252                 "+CPAS:", TCORE_AT_COMMAND_TYPE_SINGLELINE);
253
254         dbg("AT-Command: [%s] Prefix(if any): [%s] Command length: [%d]",
255                 at_req->cmd, at_req->prefix, strlen(at_req->cmd));
256
257         tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
258
259         /* Set timeout value and timeout callback */
260         tcore_pending_set_timeout(pending, 10);
261         tcore_pending_set_timeout_callback(pending,
262                 __on_timeout_check_cp_poweron, hal);
263
264         /* Set request data and register Response and Send callbacks */
265         tcore_pending_set_request_data(pending, 0, at_req);
266         tcore_pending_set_response_callback(pending,
267                 __on_response_check_cp_poweron, hal);
268         tcore_pending_set_send_callback(pending,
269                 __on_confirmation_send_message, NULL);
270
271         /* Send command to CP */
272         if (tcore_hal_send_request(hal, pending) != TEL_RETURN_SUCCESS) {
273                 err("Failed to send CPAS");
274
275                 /* Free resource */
276                 tcore_at_request_free(at_req);
277                 tcore_pending_free(pending);
278
279                 return FALSE;
280         }
281
282         dbg("Successfully sent CPAS");
283         return TRUE;
284 }
285
286 void vmodem_config_check_cp_power(TcoreHal *hal)
287 {
288         gboolean ret;
289         dbg("Entry");
290
291         tcore_check_return(hal != NULL);
292
293         ret = __check_cp_poweron(hal);
294         if (ret == TRUE) {
295                 dbg("Successfully sent check CP Power ON command");
296
297                 /* Add Core Objects list to HAL */
298                 __assign_objects_to_hal(hal);
299         } else {
300                 err("Failed to send check CP Power ON command");
301                 /* TODO: Handle Deregister */
302         }
303 }