tizen beta release
[framework/location/gps-manager.git] / gps-manager / data_connection.c
1 /*
2  * gps-manager
3  *
4  * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.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 <pthread.h>
24 #include <string.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                                 unsigned char *ip =
112                                     (unsigned char *)&prof_info->ProfileInfo.Pdp.net_info.IpAddr.Data.Ipv4.s_addr;
113                                 unsigned char *dns1 = (unsigned char *)&net_info->DnsAddr[0].Data.Ipv4.s_addr;
114                                 unsigned char *dns2 = (unsigned char *)&net_info->DnsAddr[0].Data.Ipv4.s_addr;
115
116                                 strncpy(profile_name, net_info->ProfileName, NET_PROFILE_NAME_LEN_MAX);
117
118                                 LOG_GPS(DBG_LOW, "= IP address %d.%d.%d.%d\n", (int)ip[0], ip[1], ip[2], ip[3]);
119                                 LOG_GPS(DBG_LOW, "= DNS address %d.%d.%d.%d\n", (int)dns1[0], dns1[1], dns1[2], dns1[3]);
120                                 LOG_GPS(DBG_LOW, "= DNS2 address %d.%d.%d.%d\n", (int)dns2[0], dns2[1], dns2[2], dns2[3]);
121                                 LOG_GPS(DBG_LOW, "= Device name %s\n", net_info->DevName);
122                                 LOG_GPS(DBG_LOW, "= Profile name %s\n", profile_name);
123
124                                 set_connection_status(ACTIVATED);
125                                 pdp_proxy_conf();
126                                 noti_resp_noti(pdp_pipe_fds, TRUE);
127                         } else {
128                                 LOG_GPS(DBG_ERR, " PDP Activation Failed - PDP Error[%d]\n", event_cb->Error);
129                                 set_connection_status(DEACTIVATED);
130                                 noti_resp_noti(pdp_pipe_fds, FALSE);
131                         }
132                 }
133                 break;
134
135         case NET_EVENT_CLOSE_RSP:
136                 if (get_connection_status() != ACTIVATED && get_connection_status() != DEACTIVATING) {
137                         LOG_GPS(DBG_ERR, "Not Activated && Deactivating status\n");
138                 } else if (event_cb->Error == NET_ERR_NONE || event_cb->Error == NET_ERR_UNKNOWN) {
139                         LOG_GPS(DBG_LOW, "Successful PDP De-Activation\n");
140                         set_connection_status(DEACTIVATED);
141                         noti_resp_noti(pdp_pipe_fds, TRUE);
142                 } else {
143                         LOG_GPS(DBG_ERR, " PDP DeActivation Failed - PDP Error[%d]\n", event_cb->Error);
144                         noti_resp_noti(pdp_pipe_fds, FALSE);
145                 }
146                 break;
147
148         case NET_EVENT_CLOSE_IND:
149                 if (get_connection_status() != ACTIVATED && get_connection_status() != DEACTIVATING) {
150                         LOG_GPS(DBG_ERR, "Not Activated && Deactivating status\n");
151                 } else if (event_cb->Error == NET_ERR_NONE || event_cb->Error == NET_ERR_UNKNOWN) {
152                         LOG_GPS(DBG_LOW, "Successful PDP De-Activation\n");
153                         set_connection_status(DEACTIVATED);
154                         noti_resp_noti(pdp_pipe_fds, TRUE);
155                 } else {
156                         LOG_GPS(DBG_ERR, " PDP DeActivation Failed - PDP Error[%d]\n", event_cb->Error);
157                         noti_resp_noti(pdp_pipe_fds, FALSE);
158                 }
159                 break;
160         case NET_EVENT_OPEN_IND:
161                 break;
162         default:
163                 break;
164         }
165 }
166
167 unsigned int start_pdp_connection(void)
168 {
169         int err = -1;
170
171         set_connection_status(DEACTIVATED);
172         if (noti_resp_init(pdp_pipe_fds))
173                 LOG_GPS(DBG_LOW, "Success start_pdp_connection\n");
174         else {
175                 LOG_GPS(DBG_ERR, "ERROR in noti_resp_init()\n");
176                 return FALSE;
177         }
178
179         err = net_register_client((net_event_cb_t) pdp_evt_cb, NULL);
180
181         if (err == NET_ERR_NONE || err == NET_ERR_APP_ALREADY_REGISTERED) {
182                 LOG_GPS(DBG_LOW, "Client registration is succeed\n");
183         } else {
184                 LOG_GPS(DBG_WARN, "Error in net_register_client [%d]\n", err);
185                 noti_resp_deinit(pdp_pipe_fds);
186                 return FALSE;
187         }
188
189         set_connection_status(ACTIVATING);
190         err = net_open_connection_with_preference(NET_SERVICE_INTERNET);
191
192         if (err == NET_ERR_NONE) {
193                 LOG_GPS(DBG_LOW, "Sent PDP Activation.\n");
194         } else {
195                 LOG_GPS(DBG_WARN, "Error in net_open_connection_with_preference() [%d]\n", err);
196                 set_connection_status(DEACTIVATED);
197                 err = net_deregister_client();
198                 if (err == NET_ERR_NONE)
199                         LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
200                 else
201                         LOG_GPS(DBG_ERR, "Error deregistering the client\n");
202                 noti_resp_deinit(pdp_pipe_fds);
203                 return FALSE;
204         }
205
206         if (noti_resp_wait(pdp_pipe_fds) > 0) {
207                 if (noti_resp_check(pdp_pipe_fds)) {
208                         LOG_GPS(DBG_LOW, "PDP Activation Successful\n");
209                         noti_resp_deinit(pdp_pipe_fds);
210                         return TRUE;
211                 } else {
212                         LOG_GPS(DBG_ERR, "PDP failed\n");
213                         noti_resp_deinit(pdp_pipe_fds);
214
215                         err = net_deregister_client();
216                         if (err == NET_ERR_NONE) {
217                                 LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
218                         } else {
219                                 LOG_GPS(DBG_ERR, "Error deregistering the client\n");
220                         }
221                         return FALSE;
222                 }
223         } else {
224                 LOG_GPS(DBG_ERR, "NO Pdp Act Response or Some error in select.\n");
225                 noti_resp_deinit(pdp_pipe_fds);
226
227                 err = net_deregister_client();
228                 if (err == NET_ERR_NONE) {
229                         LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
230                 } else {
231                         LOG_GPS(DBG_ERR, "Error deregistering the client\n");
232                 }
233                 return FALSE;
234         }
235 }
236
237 unsigned int stop_pdp_connection(void)
238 {
239         int err;
240         pdp_status pStatus = get_connection_status();
241         if (pStatus == DEACTIVATED || pStatus == DEACTIVATING) {
242                 LOG_GPS(DBG_ERR, "pdp stop progressing already. pStatus[%d] \n", pStatus);
243                 return TRUE;
244         }
245
246         if (noti_resp_init(pdp_pipe_fds))
247                 LOG_GPS(DBG_LOW, "Success stop_pdp_connection\n");
248         else {
249                 LOG_GPS(DBG_ERR, "ERROR in noti_resp_init()\n");
250                 return FALSE;
251         }
252
253         set_connection_status(DEACTIVATING);
254         err = net_close_connection(profile_name);
255         if (err == NET_ERR_NONE) {
256                 LOG_GPS(DBG_LOW, "Success net_close_connection\n");
257         } else {
258                 LOG_GPS(DBG_WARN, "Error in sending net_close_connection error=%d\n", err);
259                 set_connection_status(pStatus);
260                 noti_resp_deinit(pdp_pipe_fds);
261                 return FALSE;
262         }
263         if (noti_resp_wait(pdp_pipe_fds) > 0) {
264                 if (noti_resp_check(pdp_pipe_fds))
265                         LOG_GPS(DBG_LOW, "Close Connection success\n");
266                 else
267                         LOG_GPS(DBG_ERR, "Close connection failed\n");
268         }
269
270         noti_resp_deinit(pdp_pipe_fds);
271
272         set_connection_status(DEACTIVATED);
273
274         err = net_deregister_client();
275         if (err == NET_ERR_NONE) {
276                 LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
277         } else {
278                 LOG_GPS(DBG_WARN, "Error deregistering the client\n");
279                 return FALSE;
280         }
281
282         return TRUE;
283 }
284
285 unsigned int query_dns(char *pdns_lookup_addr, unsigned int *ipaddr, int *port)
286 {
287         FUNC_ENTRANCE_SERVER;
288         //int dns_id;
289         unsigned int ret = 0;
290         char *temp = NULL;
291         struct hostent *he;
292
293         LOG_GPS(DBG_LOW, "query_dns::url:%s\n", pdns_lookup_addr);
294
295         char *colon = strchr(pdns_lookup_addr, ':');
296         char *last = NULL;
297         if (colon != NULL) {
298                 char *ptr = (char *)strtok_r(pdns_lookup_addr, ":", &last);
299                 pdns_lookup_addr = ptr;
300
301                 ptr = (char *)strtok_r(NULL, ":", &last);
302                 *port = atoi(ptr);
303         }
304
305         he = gethostbyname(pdns_lookup_addr);
306
307         if (he != NULL) {
308                 temp = (char *)&g_ipaddr;
309                 temp[0] = he->h_addr_list[0][0];
310                 temp[1] = he->h_addr_list[0][1];
311                 temp[2] = he->h_addr_list[0][2];
312                 temp[3] = he->h_addr_list[0][3];
313
314                 LOG_GPS(DBG_LOW, "-> %u.%u.%u.%u\n", (unsigned char)temp[0], (unsigned char)temp[1], (unsigned char)temp[2],
315                            (unsigned char)temp[3]);
316                 LOG_GPS(DBG_LOW, "g_agps_ipaddr: %u\n", g_ipaddr);
317                 *ipaddr = g_ipaddr;
318
319                 ret = TRUE;
320         } else {
321                 LOG_GPS(DBG_ERR, "//gethostbyname : Error getting host information\n");
322                 ret = FALSE;
323         }
324
325         return ret;
326
327 }
328
329 int noti_resp_init(int *noti_pipe_fds)
330 {
331         if (pipe(noti_pipe_fds) < 0)
332                 return 0;
333         else
334                 return 1;
335 }
336
337 int noti_resp_wait(int *noti_pipe_fds)
338 {
339         fd_set rfds;
340         fd_set wfds;
341         FD_ZERO(&rfds);
342         FD_ZERO(&wfds);
343         FD_SET(*noti_pipe_fds, &rfds);
344         return select(*noti_pipe_fds + 1, &rfds, &wfds, NULL, NULL);
345 }
346
347 int noti_resp_noti(int *noti_pipe_fds, int result)
348 {
349         return write(*(noti_pipe_fds + 1), &result, sizeof(int));
350 }
351
352 int noti_resp_check(int *noti_pipe_fds)
353 {
354         int activation;
355         read(*noti_pipe_fds, &activation, sizeof(int));
356         return activation;
357 }
358
359 int noti_resp_deinit(int *noti_pipe_fds)
360 {
361         int err;
362         err = close(*noti_pipe_fds);
363         if (err != 0)
364                 LOG_GPS(DBG_ERR, "ERROR closing fds1.\n");
365
366         err = close(*(noti_pipe_fds + 1));
367         if (err != 0)
368                 LOG_GPS(DBG_ERR, "ERROR closing fds2.\n");
369
370         return err;
371 }