sync with latest 3.0
[platform/core/location/lbs-server.git] / lbs-server / src / data_connection.c
1 /*
2  * lbs-server
3  *
4  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
7  *          Genie Kim <daejins.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <sys/time.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <signal.h>
29 #include <sys/time.h>
30 #include <sys/types.h>
31 #include <sys/ioctl.h>
32 #include <sys/poll.h>
33 #include <fcntl.h>
34 #include <netdb.h>
35 #include <sys/socket.h>
36 #include <sys/un.h>
37 #include <assert.h>
38 #include <setjmp.h>
39
40 #include "data_connection.h"
41 #include <network-cm-intf.h>
42 #include "debug_util.h"
43
44 int noti_resp_init(int *noti_pipe_fds);
45 int noti_resp_wait(int *noti_pipe_fds);
46 int noti_resp_check(int *noti_pipe_fds);
47 int noti_resp_noti(int *noti_pipe_fds, int result);
48 int noti_resp_deinit(int *noti_pipe_fds);
49
50 unsigned int g_ipaddr;
51 static int pdp_pipe_fds[2];
52
53 typedef enum {
54         DEACTIVATED,
55         ACTIVATING,
56         ACTIVATED,
57         DEACTIVATING
58 } pdp_status;
59
60 char profile_name[NET_PROFILE_NAME_LEN_MAX + 1];
61
62 pdp_status act_level;
63
64 char *PdpStat[] = { "Deactivated", "Activating", "Activated", "Deactivating" };
65
66 static void set_connection_status(pdp_status i)
67 {
68         act_level = i;
69         LOG_GPS(DBG_LOW, "==Status: %s\n", PdpStat[i]);
70 }
71
72 static pdp_status get_connection_status()
73 {
74         return act_level;
75 }
76
77 static void pdp_proxy_conf()
78 {
79         net_proxy_t proxy;
80         int ret;
81         ret = net_get_active_proxy(&proxy);
82
83         if (ret == NET_ERR_NONE) {
84                 if (strncmp(proxy.proxy_addr, "0.0.0.0", 7)) {
85                         char buf[100];
86                         snprintf(buf, sizeof(buf), "http://%s/", proxy.proxy_addr);
87                         setenv("http_proxy", buf, 1);
88                 } else {
89                         unsetenv("http_proxy");
90                 }
91         } else {
92                 LOG_GPS(DBG_ERR, "Fail to get proxy\n");
93         }
94 }
95
96 void pdp_evt_cb(net_event_info_t *event_cb, void *user_data)
97 {
98         switch (event_cb->Event) {
99         case NET_EVENT_OPEN_RSP: {
100                 LOG_GPS(DBG_LOW, "event_cb->Error : [%d]\n", event_cb->Error);
101                 if (get_connection_status() != ACTIVATING) {
102                         LOG_GPS(DBG_LOW, "Not Activating status\n");
103                 } else if (event_cb->Error == NET_ERR_NONE || event_cb->Error == NET_ERR_ACTIVE_CONNECTION_EXISTS) {
104                         LOG_GPS(DBG_LOW, "Successful PDP Activation\n");
105                         net_profile_info_t *prof_info = NULL;
106                         net_dev_info_t *net_info = NULL;
107
108                         prof_info = (net_profile_info_t *) event_cb->Data;
109                         net_info = &(prof_info->ProfileInfo.Pdp.net_info);
110
111                         strncpy(profile_name, net_info->ProfileName, NET_PROFILE_NAME_LEN_MAX);
112
113                         set_connection_status(ACTIVATED);
114                         pdp_proxy_conf();
115                         noti_resp_noti(pdp_pipe_fds, TRUE);
116                 } else {
117                         LOG_GPS(DBG_ERR, " PDP Activation Failed - PDP Error[%d]\n", event_cb->Error);
118                         set_connection_status(DEACTIVATED);
119                         noti_resp_noti(pdp_pipe_fds, FALSE);
120                 }
121         }
122         break;
123
124         case NET_EVENT_CLOSE_RSP:
125                 if (get_connection_status() != ACTIVATED && get_connection_status() != DEACTIVATING) {
126                         LOG_GPS(DBG_ERR, "Not Activated && Deactivating status\n");
127                 } else if (event_cb->Error == NET_ERR_NONE || event_cb->Error == NET_ERR_UNKNOWN) {
128                         LOG_GPS(DBG_LOW, "Successful PDP De-Activation\n");
129                         set_connection_status(DEACTIVATED);
130                         noti_resp_noti(pdp_pipe_fds, TRUE);
131                 } else {
132                         LOG_GPS(DBG_ERR, " PDP DeActivation Failed - PDP Error[%d]\n", event_cb->Error);
133                         noti_resp_noti(pdp_pipe_fds, FALSE);
134                 }
135                 break;
136
137         case NET_EVENT_CLOSE_IND:
138                 if (get_connection_status() != ACTIVATED && get_connection_status() != DEACTIVATING) {
139                         LOG_GPS(DBG_ERR, "Not Activated && Deactivating status\n");
140                 } else if (event_cb->Error == NET_ERR_NONE || event_cb->Error == NET_ERR_UNKNOWN) {
141                         LOG_GPS(DBG_LOW, "Successful PDP De-Activation\n");
142                         set_connection_status(DEACTIVATED);
143                         noti_resp_noti(pdp_pipe_fds, TRUE);
144                 } else {
145                         LOG_GPS(DBG_ERR, " PDP DeActivation Failed - PDP Error[%d]\n", event_cb->Error);
146                         noti_resp_noti(pdp_pipe_fds, FALSE);
147                 }
148                 break;
149         case NET_EVENT_OPEN_IND:
150                 break;
151         default:
152                 break;
153         }
154 }
155
156 unsigned int start_pdp_connection(void)
157 {
158         int err = -1;
159
160         set_connection_status(DEACTIVATED);
161         if (noti_resp_init(pdp_pipe_fds)) {
162                 LOG_GPS(DBG_LOW, "Success start_pdp_connection\n");
163         } else {
164                 LOG_GPS(DBG_ERR, "ERROR in noti_resp_init()\n");
165                 return FALSE;
166         }
167
168         err = net_register_client((net_event_cb_t) pdp_evt_cb, NULL);
169
170         if (err == NET_ERR_NONE || err == NET_ERR_APP_ALREADY_REGISTERED) {
171                 LOG_GPS(DBG_LOW, "Client registration is succeed\n");
172         } else {
173                 LOG_GPS(DBG_WARN, "Error in net_register_client [%d]\n", err);
174                 noti_resp_deinit(pdp_pipe_fds);
175                 return FALSE;
176         }
177
178         set_connection_status(ACTIVATING);
179         err = net_open_connection_with_preference(NET_SERVICE_INTERNET);
180
181         if (err == NET_ERR_NONE) {
182                 LOG_GPS(DBG_LOW, "Sent PDP Activation.\n");
183         } else {
184                 LOG_GPS(DBG_WARN, "Error in net_open_connection_with_preference() [%d]\n", err);
185                 set_connection_status(DEACTIVATED);
186                 err = net_deregister_client();
187                 if (err == NET_ERR_NONE)
188                         LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
189                 else
190                         LOG_GPS(DBG_ERR, "Error deregistering the client\n");
191
192                 noti_resp_deinit(pdp_pipe_fds);
193                 return FALSE;
194         }
195
196         if (noti_resp_wait(pdp_pipe_fds) > 0) {
197                 if (noti_resp_check(pdp_pipe_fds)) {
198                         LOG_GPS(DBG_LOW, "PDP Activation Successful\n");
199                         noti_resp_deinit(pdp_pipe_fds);
200                         return TRUE;
201                 } else {
202                         LOG_GPS(DBG_ERR, "PDP failed\n");
203                         noti_resp_deinit(pdp_pipe_fds);
204
205                         err = net_deregister_client();
206                         if (err == NET_ERR_NONE)
207                                 LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
208                         else
209                                 LOG_GPS(DBG_ERR, "Error deregistering the client\n");
210
211                         return FALSE;
212                 }
213         } else {
214                 LOG_GPS(DBG_ERR, "NO Pdp Act Response or Some error in select.\n");
215                 noti_resp_deinit(pdp_pipe_fds);
216
217                 err = net_deregister_client();
218                 if (err == NET_ERR_NONE)
219                         LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
220                 else
221                         LOG_GPS(DBG_ERR, "Error deregistering the client\n");
222
223                 return FALSE;
224         }
225 }
226
227 unsigned int stop_pdp_connection(void)
228 {
229         int err;
230         pdp_status pStatus = get_connection_status();
231         if (pStatus == DEACTIVATED || pStatus == DEACTIVATING) {
232                 LOG_GPS(DBG_ERR, "pdp stop progressing already. pStatus[%d] \n", pStatus);
233                 return TRUE;
234         }
235
236         if (noti_resp_init(pdp_pipe_fds)) {
237                 LOG_GPS(DBG_LOW, "Success stop_pdp_connection\n");
238         } else {
239                 LOG_GPS(DBG_ERR, "ERROR in noti_resp_init()\n");
240                 return FALSE;
241         }
242
243         set_connection_status(DEACTIVATING);
244         err = net_close_connection(profile_name);
245         if (err == NET_ERR_NONE) {
246                 LOG_GPS(DBG_LOW, "Success net_close_connection\n");
247         } else {
248                 LOG_GPS(DBG_WARN, "Error in sending net_close_connection error=%d\n", err);
249                 set_connection_status(pStatus);
250                 noti_resp_deinit(pdp_pipe_fds);
251                 return FALSE;
252         }
253         if (noti_resp_wait(pdp_pipe_fds) > 0) {
254                 if (noti_resp_check(pdp_pipe_fds))
255                         LOG_GPS(DBG_LOW, "Close Connection success\n");
256                 else
257                         LOG_GPS(DBG_ERR, "Close connection failed\n");
258         }
259
260         noti_resp_deinit(pdp_pipe_fds);
261
262         set_connection_status(DEACTIVATED);
263
264         err = net_deregister_client();
265         if (err == NET_ERR_NONE) {
266                 LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
267         } else {
268                 LOG_GPS(DBG_WARN, "Error deregistering the client\n");
269                 return FALSE;
270         }
271
272         return TRUE;
273 }
274
275 unsigned int query_dns(char *pdns_lookup_addr, unsigned int *ipaddr, int *port)
276 {
277         FUNC_ENTRANCE_SERVER;
278
279         if (!pdns_lookup_addr || !ipaddr || !port) return FALSE;
280
281         /*int dns_id; */
282         unsigned int ret = 0;
283         struct hostent hostbuf, *he = NULL;
284         int tmplen = 1024;
285         char *tmpbuf = NULL;
286         int res, herr;
287
288         char *colon = strchr(pdns_lookup_addr, ':');
289         char *last = NULL;
290         if (colon != NULL) {
291                 char *ptr = (char *)strtok_r(pdns_lookup_addr, ":", &last);
292                 pdns_lookup_addr = ptr;
293
294                 ptr = (char *)strtok_r(NULL, ":", &last);
295
296                 if (ptr)
297                         *port = atoi(ptr);
298         }
299
300         tmpbuf = malloc(tmplen);
301         if (!tmpbuf) return FALSE;
302
303         while ((res = gethostbyname_r(pdns_lookup_addr, &hostbuf, tmpbuf, tmplen, &he, &herr)) == ERANGE) {
304                 /* Enlarge the buffer.  */
305                 tmplen *= 2;
306                 void *tmp = realloc(tmpbuf, tmplen);
307                 if (!tmp) {
308                         free(tmpbuf);
309                         LOG_GPS(DBG_ERR, "Failed to reallocate memories.");
310                         return FALSE;
311                 } else {
312                         tmpbuf = tmp;
313                 }
314         }
315         free(tmpbuf);
316
317         if (he != NULL) {
318                 LOG_GPS(DBG_LOW, "g_agps_ipaddr: %u\n", g_ipaddr);
319                 *ipaddr = g_ipaddr;
320
321                 ret = TRUE;
322         } else {
323                 LOG_GPS(DBG_ERR, "//gethostbyname : Error getting host information\n");
324                 ret = FALSE;
325         }
326
327         return ret;
328
329 }
330
331 int noti_resp_init(int *noti_pipe_fds)
332 {
333         if (pipe(noti_pipe_fds) < 0)
334                 return 0;
335         else
336                 return 1;
337 }
338
339 int noti_resp_wait(int *noti_pipe_fds)
340 {
341         fd_set rfds;
342         fd_set wfds;
343         FD_ZERO(&rfds);
344         FD_ZERO(&wfds);
345         FD_SET(*noti_pipe_fds, &rfds);
346         return select(*noti_pipe_fds + 1, &rfds, &wfds, NULL, NULL);
347 }
348
349 int noti_resp_noti(int *noti_pipe_fds, int result)
350 {
351         return write(*(noti_pipe_fds + 1), &result, sizeof(int));
352 }
353
354 int noti_resp_check(int *noti_pipe_fds)
355 {
356         int activation = 0;
357         ssize_t ret_val = 0;
358         ret_val = read(*noti_pipe_fds, &activation, sizeof(int));
359         if (ret_val == 0)
360                 LOG_GPS(DBG_ERR, "No data");
361
362         return activation;
363 }
364
365 int noti_resp_deinit(int *noti_pipe_fds)
366 {
367         int err;
368         err = close(*noti_pipe_fds);
369         if (err != 0)
370                 LOG_GPS(DBG_ERR, "ERROR closing fds1.\n");
371
372         err = close(*(noti_pipe_fds + 1));
373         if (err != 0)
374                 LOG_GPS(DBG_ERR, "ERROR closing fds2.\n");
375
376         return err;
377 }