Apply tizen coding rule
[platform/framework/web/download-provider.git] / provider / download-provider-network.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "download-provider.h"
18 #include "download-provider-log.h"
19 #include "download-provider-pthread.h"
20 #include "download-provider-network.h"
21 #include "download-provider-client-manager.h"
22
23 #include <net_connection.h>
24
25 #ifdef SUPPORT_WIFI_DIRECT
26 #include <wifi-direct.h>
27 #endif
28
29 pthread_mutex_t g_dp_network_mutex = PTHREAD_MUTEX_INITIALIZER;
30 int g_network_status = DP_NETWORK_OFF;
31 connection_h g_network_connection = 0;
32 int g_network_is_wifi_direct = 0;
33
34 #ifdef SUPPORT_COMPANION_MODE
35 // support B3 companion mode
36 #include "vconf.h"
37 #include "vconf-keys.h"
38 #include "SAPInterface.h"
39 #define VCONFKEY_SAP_CONNECTION_NOTIFICATION VCONFKEY_WMS_WMANAGER_CONNECTED
40 #define VCONFKEY_SAP_CONNECTION_TYPE "memory/private/sap/conn_type"
41 #endif
42
43 static int __dp_network_is_companion_mode()
44 {
45 #ifdef SUPPORT_COMPANION_MODE
46         int wms_connected = 0;
47         int companion_mode = 0;
48         vconf_get_int(VCONFKEY_SAP_CONNECTION_NOTIFICATION, &wms_connected);
49         vconf_get_int(VCONFKEY_SAP_CONNECTION_TYPE, &companion_mode);
50         TRACE_INFO("wms_connected:%d, companion_mode:%d", wms_connected, companion_mode);
51         if (wms_connected == 1 && (companion_mode & SAP_BT))
52                 return 1;
53
54 #endif
55         return 0;
56 }
57
58 #ifdef SUPPORT_WIFI_DIRECT
59
60 static int __dp_network_wifi_direct_status()
61 {
62         int is_connected = 0;
63         wifi_direct_state_e wifi_state = WIFI_DIRECT_STATE_DEACTIVATED;
64         if (wifi_direct_get_state(&wifi_state) == 0) {
65                 if (wifi_state == WIFI_DIRECT_STATE_CONNECTED) {
66                         TRACE_INFO("WIFI_DIRECT_STATE_CONNECTED");
67                         is_connected = 1;
68                 }
69         }
70         return is_connected;
71 }
72
73 // support WIFI-Direct
74 static void __dp_network_wifi_direct_changed_cb(wifi_direct_error_e error_code,
75                 wifi_direct_connection_state_e connection_state, const char *mac_address, void *data)
76 {
77         pthread_mutex_lock(&g_dp_network_mutex);
78         if (connection_state == WIFI_DIRECT_CONNECTION_RSP) {
79                 TRACE_INFO("WIFI_DIRECT_CONNECTION_RSP");
80                 g_network_is_wifi_direct = __dp_network_wifi_direct_status();
81         } else {
82                 TRACE_INFO("WIFI_DIRECT_DISCONNECTION");
83                 g_network_is_wifi_direct = 0;
84         }
85         pthread_mutex_unlock(&g_dp_network_mutex);
86 }
87 #endif
88
89 //////////////////////////////////////////////////////////////////////////
90 /// @brief              check the status in more detail by connection type
91 /// @return     dp_network_type
92 static int __dp_get_network_connection_status(connection_h connection, connection_type_e type)
93 {
94         int network_type = DP_NETWORK_OFF;
95         if (__dp_network_is_companion_mode() == 1) {
96                 network_type = DP_NETWORK_ALL;
97                 TRACE_INFO("COMPANION MODE");
98         } else if (type == CONNECTION_TYPE_WIFI) {
99                 connection_wifi_state_e wifi_state;
100                 wifi_state = CONNECTION_WIFI_STATE_DEACTIVATED;
101                 if (connection_get_wifi_state(connection, &wifi_state) !=
102                                 CONNECTION_ERROR_NONE) {
103                         TRACE_ERROR("Failed connection_get_wifi_state");
104                 } else {
105                         if (wifi_state == CONNECTION_WIFI_STATE_CONNECTED) {
106                                 TRACE_INFO("WIFI CONNECTED");
107                                 network_type = DP_NETWORK_WIFI;
108                         }
109                 }
110         } else if (type == CONNECTION_TYPE_CELLULAR) {
111                 connection_cellular_state_e cellular_state;
112                 cellular_state = CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE;
113                 if (connection_get_cellular_state(connection,
114                                         &cellular_state) != CONNECTION_ERROR_NONE) {
115                         TRACE_ERROR("Failed connection_get_cellular_state");
116                 } else {
117                         if (cellular_state == CONNECTION_CELLULAR_STATE_CONNECTED) {
118                                 TRACE_INFO("DATA NETWORK CONNECTED");
119                                 network_type = DP_NETWORK_DATA_NETWORK;
120                         }
121                 }
122         } else if (type == CONNECTION_TYPE_ETHERNET) {
123                 connection_ethernet_state_e ethernet_state;
124                 ethernet_state = CONNECTION_ETHERNET_STATE_DISCONNECTED;
125                 if (connection_get_ethernet_state(connection,
126                                         &ethernet_state) != CONNECTION_ERROR_NONE) {
127                         TRACE_ERROR("Failed connection_get_ethernet_state");
128                 } else {
129                         if (ethernet_state == CONNECTION_ETHERNET_STATE_CONNECTED) {
130                                 TRACE_INFO("ETHERNET CONNECTED");
131                                 network_type = DP_NETWORK_WIFI;
132                         }
133                 }
134         } else {
135                 TRACE_INFO("DISCONNECTED");
136                 network_type = DP_NETWORK_OFF;
137         }
138         pthread_mutex_lock(&g_dp_network_mutex);
139
140         g_network_status = network_type;
141
142         pthread_mutex_unlock(&g_dp_network_mutex);
143
144         return network_type;
145 }
146
147 //////////////////////////////////////////////////////////////////////////
148 /// @brief              [callback] called whenever changed network status
149 /// @todo               care requests by network status
150 static void __dp_network_connection_type_changed_cb(connection_type_e type, void *data)
151 {
152         pthread_mutex_lock(&g_dp_network_mutex);
153         // this callback guarantee that already connected
154         if (__dp_network_is_companion_mode() == 1) {
155                 TRACE_INFO("COMPANION MODE");
156                 g_network_status = DP_NETWORK_ALL;
157         } else if (type == CONNECTION_TYPE_WIFI) {
158                 TRACE_INFO("WIFI CONNECTED");
159                 g_network_status = DP_NETWORK_WIFI;
160         } else if (type == CONNECTION_TYPE_CELLULAR) {
161                 TRACE_INFO("DATA NETWORK CONNECTED");
162                 g_network_status = DP_NETWORK_DATA_NETWORK;
163         } else if (type == CONNECTION_TYPE_ETHERNET) {
164                 TRACE_INFO("ETHERNET CONNECTED");
165                 g_network_status = DP_NETWORK_WIFI;
166         } else {
167                 TRACE_INFO("DISCONNECTED");
168                 g_network_status = DP_NETWORK_OFF;
169         }
170         pthread_mutex_unlock(&g_dp_network_mutex);
171 }
172
173 //////////////////////////////////////////////////////////////////////////
174 /// @brief              [callback] called when changed network ip
175 /// @todo               auto resume feature
176 static void __dp_network_connection_ip_changed_cb(const char *ip, const char *ipv6, void *data)
177 {
178         if (dp_network_get_status() != DP_NETWORK_OFF) {
179                 TRACE_DEBUG("[CONNECTION] IP CHANGED");
180                 // broadcast to all thread for clients
181                 dp_broadcast_signal();
182         }
183 }
184
185 int dp_network_get_status()
186 {
187         int status = DP_NETWORK_OFF;
188         pthread_mutex_lock(&g_dp_network_mutex);
189         status = g_network_status;
190         pthread_mutex_unlock(&g_dp_network_mutex);
191         return status;
192 }
193
194 int dp_network_is_wifi_direct()
195 {
196         pthread_mutex_lock(&g_dp_network_mutex);
197         int status = g_network_is_wifi_direct;
198         pthread_mutex_unlock(&g_dp_network_mutex);
199         return status;
200 }
201
202 //////////////////////////////////////////////////////////////////////////
203 /// @brief              create connection handle & regist callback
204 /// @return     0 : success -1 : failed
205 int dp_network_connection_init()
206 {
207         int retcode = 0;
208
209 #ifdef SUPPORT_WIFI_DIRECT
210         if (wifi_direct_initialize() == 0) {
211                 wifi_direct_set_connection_state_changed_cb
212                         (__dp_network_wifi_direct_changed_cb, NULL);
213                 g_network_is_wifi_direct = __dp_network_wifi_direct_status();
214         }
215 #endif
216
217         if ((retcode = connection_create(&g_network_connection)) !=
218                         CONNECTION_ERROR_NONE) {
219                 TRACE_ERROR("Failed connection_create [%d]", retcode);
220                 return -1;
221         }
222         if ((retcode = connection_set_type_changed_cb(g_network_connection,
223                                         __dp_network_connection_type_changed_cb, NULL)) !=
224                         CONNECTION_ERROR_NONE) {
225                 TRACE_ERROR("Failed connection_set_type_changed_cb [%d]", retcode);
226                 connection_destroy(g_network_connection);
227                 g_network_connection = 0;
228                 return -1;
229         }
230
231         if ((retcode = connection_set_ip_address_changed_cb
232                                 (g_network_connection, __dp_network_connection_ip_changed_cb,
233                                  NULL)) != CONNECTION_ERROR_NONE) {
234                 TRACE_ERROR("Failed __dp_network_connection_ip_changed_cb [%d]", retcode);
235                 connection_destroy(g_network_connection);
236                 g_network_connection = 0;
237                 return -1;
238         }
239
240         connection_type_e type = CONNECTION_TYPE_DISCONNECTED;
241         if ((retcode = connection_get_type(g_network_connection, &type)) !=
242                         CONNECTION_ERROR_NONE) {
243                 TRACE_ERROR("Failed connection_get_type [%d]", retcode);
244                 connection_destroy(g_network_connection);
245                 g_network_connection = 0;
246                 return -1;
247         }
248         g_network_status =
249                 __dp_get_network_connection_status(g_network_connection, type);
250         return 0;
251 }
252
253 //////////////////////////////////////////////////////////////////////////
254 /// @brief              destroy connection handle
255 void dp_network_connection_destroy()
256 {
257         pthread_mutex_lock(&g_dp_network_mutex);
258 #ifdef SUPPORT_WIFI_DIRECT
259         wifi_direct_unset_connection_state_changed_cb();
260         wifi_direct_deinitialize();
261 #endif
262
263         if (g_network_connection != 0) {
264                 connection_unset_type_changed_cb(g_network_connection);
265                 connection_unset_ip_address_changed_cb(g_network_connection);
266                 connection_destroy(g_network_connection);
267         }
268         g_network_connection = 0;
269         pthread_mutex_unlock(&g_dp_network_mutex);
270 }