merge with master
[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-log.h"
18 #include "download-provider-config.h"
19 #include "download-provider-pthread.h"
20 #include "download-provider-network.h"
21
22 extern pthread_mutex_t g_dp_queue_mutex;
23 extern pthread_cond_t g_dp_queue_cond;
24
25 #if 0
26 typedef enum
27 {
28     CONNECTION_TYPE_DISCONNECTED = 0,  /**< Disconnected */
29     CONNECTION_TYPE_WIFI = 1,  /**< Wi-Fi type */
30     CONNECTION_TYPE_CELLULAR = 2,  /**< Cellular type */
31     CONNECTION_TYPE_ETHERNET = 3,  /**< Ethernet type */
32     CONNECTION_TYPE_BT = 4,  /**< Bluetooth type */
33 } connection_type_e;
34 typedef enum
35 {
36     CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE = 0,  /**< Out of service */
37     CONNECTION_CELLULAR_STATE_FLIGHT_MODE = 1,  /**< Flight mode */
38     CONNECTION_CELLULAR_STATE_ROAMING_OFF = 2,  /**< Roaming is turned off */
39     CONNECTION_CELLULAR_STATE_CALL_ONLY_AVAILABLE = 3,  /**< Call is only available */
40     CONNECTION_CELLULAR_STATE_AVAILABLE = 4,  /**< Available but not connected yet */
41     CONNECTION_CELLULAR_STATE_CONNECTED = 5,  /**< Connected */
42 } connection_cellular_state_e
43 typedef enum
44 {
45     CONNECTION_WIFI_STATE_DEACTIVATED = 0,  /**< Deactivated state */
46     CONNECTION_WIFI_STATE_DISCONNECTED = 1,  /**< disconnected state */
47     CONNECTION_WIFI_STATE_CONNECTED = 2,  /**< Connected state */
48 } connection_wifi_state_e;
49 typedef enum
50 {
51     CONNECTION_ETHERNET_STATE_DEACTIVATED = 0,  /**< Deactivated state */
52     CONNECTION_ETHERNET_STATE_DISCONNECTED = 1,  /**< disconnected state */
53     CONNECTION_ETHERNET_STATE_CONNECTED = 2,  /**< Connected state */
54 } connection_ethernet_state_e;
55 typedef enum
56 {
57     CONNECTION_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
58     CONNECTION_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
59     CONNECTION_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory error */
60     CONNECTION_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid Operation */
61     CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED = TIZEN_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED, /**< Address family not supported */
62     CONNECTION_ERROR_OPERATION_FAILED = TIZEN_ERROR_NETWORK_CLASS|0x0401, /**< Operation failed */
63     CONNECTION_ERROR_ITERATOR_END = TIZEN_ERROR_NETWORK_CLASS|0x0402, /**< End of iteration */
64     CONNECTION_ERROR_NO_CONNECTION = TIZEN_ERROR_NETWORK_CLASS|0x0403, /**< There is no connection */
65     CONNECTION_ERROR_NOW_IN_PROGRESS = TIZEN_ERROR_NOW_IN_PROGRESS, /** Now in progress */
66     CONNECTION_ERROR_ALREADY_EXISTS = TIZEN_ERROR_NETWORK_CLASS|0x0404, /**< Already exists */
67     CONNECTION_ERROR_OPERATION_ABORTED = TIZEN_ERROR_NETWORK_CLASS|0x0405, /**< Operation is aborted */
68     CONNECTION_ERROR_DHCP_FAILED = TIZEN_ERROR_NETWORK_CLASS|0x0406, /**< DHCP failed  */
69     CONNECTION_ERROR_INVALID_KEY = TIZEN_ERROR_NETWORK_CLASS|0x0407, /**< Invalid key  */
70     CONNECTION_ERROR_NO_REPLY = TIZEN_ERROR_NETWORK_CLASS|0x0408, /**< No reply */
71 } connection_error_e;
72
73
74 static void __print_connection_errorcode_to_string(connection_error_e errorcode)
75 {
76         switch(errorcode)
77         {
78                 case CONNECTION_ERROR_INVALID_PARAMETER :
79                         TRACE_INFO("CONNECTION_ERROR_INVALID_PARAMETER");
80                         break;
81                 case CONNECTION_ERROR_OUT_OF_MEMORY :
82                         TRACE_INFO("CONNECTION_ERROR_OUT_OF_MEMORY");
83                         break;
84                 case CONNECTION_ERROR_INVALID_OPERATION :
85                         TRACE_INFO("CONNECTION_ERROR_INVALID_OPERATION");
86                         break;
87                 case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED :
88                         TRACE_INFO("CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED");
89                         break;
90                 case CONNECTION_ERROR_OPERATION_FAILED :
91                         TRACE_INFO("CONNECTION_ERROR_OPERATION_FAILED");
92                         break;
93                 case CONNECTION_ERROR_ITERATOR_END :
94                         TRACE_INFO("CONNECTION_ERROR_ITERATOR_END");
95                         break;
96                 case CONNECTION_ERROR_NO_CONNECTION :
97                         TRACE_INFO("CONNECTION_ERROR_NO_CONNECTION");
98                         break;
99                 case CONNECTION_ERROR_NOW_IN_PROGRESS :
100                         TRACE_INFO("CONNECTION_ERROR_NOW_IN_PROGRESS");
101                         break;
102                 case CONNECTION_ERROR_ALREADY_EXISTS :
103                         TRACE_INFO("CONNECTION_ERROR_ALREADY_EXISTS");
104                         break;
105                 case CONNECTION_ERROR_OPERATION_ABORTED :
106                         TRACE_INFO("CONNECTION_ERROR_OPERATION_ABORTED");
107                         break;
108                 case CONNECTION_ERROR_DHCP_FAILED :
109                         TRACE_INFO("CONNECTION_ERROR_DHCP_FAILED");
110                         break;
111                 case CONNECTION_ERROR_INVALID_KEY :
112                         TRACE_INFO("CONNECTION_ERROR_INVALID_KEY");
113                         break;
114                 case CONNECTION_ERROR_NO_REPLY :
115                         TRACE_INFO("CONNECTION_ERROR_NO_REPLY");
116                         break;
117                 default :
118                         TRACE_INFO("CONNECTION_ERROR_NONE");
119                         break;
120         }
121 }
122 #endif
123
124
125
126
127
128
129
130 //////////////////////////////////////////////////////////////////////////
131 /// @brief              check the status in more detail by connection type
132 /// @return     dp_network_type
133 static dp_network_type __dp_get_network_connection_status(connection_h connection, connection_type_e type)
134 {
135         dp_network_type network_type = DP_NETWORK_TYPE_OFF;
136         if (type == CONNECTION_TYPE_WIFI) {
137                 connection_wifi_state_e wifi_state;
138                 wifi_state = CONNECTION_WIFI_STATE_DEACTIVATED;
139                 if (connection_get_wifi_state
140                         (connection, &wifi_state) != CONNECTION_ERROR_NONE)
141                         TRACE_ERROR("Failed connection_get_wifi_state");
142                 if (wifi_state == CONNECTION_WIFI_STATE_CONNECTED) {
143                         TRACE_INFO("[CONNECTION_WIFI] CONNECTED");
144                         network_type = DP_NETWORK_TYPE_WIFI;
145                 } else {
146                         TRACE_INFO("[CONNECTION_WIFI] [%d]", wifi_state);
147                 }
148         } else if (type == CONNECTION_TYPE_CELLULAR) {
149                 connection_cellular_state_e cellular_state;
150                 cellular_state = CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE;
151                 if (connection_get_cellular_state
152                         (connection, &cellular_state) != CONNECTION_ERROR_NONE)
153                         TRACE_ERROR("Failed connection_get_cellular_state");
154                 if (cellular_state == CONNECTION_CELLULAR_STATE_CONNECTED) {
155                         TRACE_INFO("[CONNECTION_CELLULAR] DATA NETWORK CONNECTED");
156                         network_type = DP_NETWORK_TYPE_DATA_NETWORK;
157                 } else {
158                         TRACE_INFO("[CONNECTION_CELLULAR] [%d]", cellular_state);
159                 }
160         } else if (type == CONNECTION_TYPE_ETHERNET) {
161                 connection_ethernet_state_e ethernet_state;
162                 ethernet_state = CONNECTION_ETHERNET_STATE_DISCONNECTED;
163                 if (connection_get_ethernet_state
164                         (connection, &ethernet_state) != CONNECTION_ERROR_NONE)
165                         TRACE_ERROR("Failed connection_get_ethernet_state");
166                 if (ethernet_state == CONNECTION_ETHERNET_STATE_CONNECTED) {
167                         TRACE_INFO("[CONNECTION_ETHERNET] ETHERNET CONNECTED");
168                         network_type = DP_NETWORK_TYPE_ETHERNET;
169                 } else {
170                         TRACE_INFO("[CONNECTION_ETHERNET] [%d]", ethernet_state);
171                 }
172         } else {
173                 TRACE_INFO("[DISCONNECTED]");
174                 network_type = DP_NETWORK_TYPE_OFF;
175         }
176         return network_type;
177 }
178
179 //////////////////////////////////////////////////////////////////////////
180 /// @brief              [callback] called whenever changed network status
181 /// @todo               care requests by network status
182 static void __dp_network_connection_type_changed_cb(connection_type_e type, void *data)
183 {
184         TRACE_INFO("type[%d]", type);
185         dp_privates *privates = (dp_privates*)data;
186         if (!privates) {
187                 TRACE_ERROR("[CRITICAL] Invalid data");
188                 return ;
189         }
190         CLIENT_MUTEX_LOCK(&(g_dp_queue_mutex));
191         #if 1 // this callback guarantee that already connectdd
192         if (type == CONNECTION_TYPE_WIFI) {
193                 TRACE_INFO("[CONNECTION_WIFI] CONNECTED");
194                 privates->network_status = DP_NETWORK_TYPE_WIFI;
195         } else if (type == CONNECTION_TYPE_CELLULAR) {
196                 TRACE_INFO("[CONNECTION_CELLULAR] DATA NETWORK CONNECTED");
197                 privates->network_status = DP_NETWORK_TYPE_DATA_NETWORK;
198         } else if (type == CONNECTION_TYPE_ETHERNET) {
199                 TRACE_INFO("[CONNECTION_ETHERNET] ETHERNET CONNECTED");
200                 privates->network_status = DP_NETWORK_TYPE_ETHERNET;
201         } else {
202                 TRACE_INFO("[DISCONNECTED]");
203                 privates->network_status = DP_NETWORK_TYPE_OFF;
204         }
205         if (privates->network_status != DP_NETWORK_TYPE_OFF)
206                 pthread_cond_signal(&g_dp_queue_cond);
207         #else
208         privates->network_status =
209                 __dp_get_network_connection_status(privates->connection, type);
210         #endif
211         CLIENT_MUTEX_UNLOCK(&(g_dp_queue_mutex));
212 }
213
214 //////////////////////////////////////////////////////////////////////////
215 /// @brief              create connection handle & regist callback
216 /// @return     0 : success -1 : failed
217 int dp_network_connection_init(dp_privates *privates)
218 {
219         int retcode = 0;
220
221         TRACE_INFO("");
222         if (!privates) {
223                 TRACE_ERROR("[CRITICAL] Invalid data");
224                 return -1;
225         }
226         if ((retcode = connection_create(&privates->connection)) !=
227                         CONNECTION_ERROR_NONE) {
228                 TRACE_ERROR("Failed connection_create [%d]", retcode);
229                 return -1;
230         }
231         if ((retcode = connection_set_type_changed_cb
232                         (privates->connection, __dp_network_connection_type_changed_cb,
233                                 privates)) != CONNECTION_ERROR_NONE) {
234                 TRACE_ERROR("Failed connection_set_type_changed_cb [%d]", retcode);
235                 connection_destroy(privates->connection);
236                 return -1;
237         }
238         connection_type_e type = CONNECTION_TYPE_DISCONNECTED;
239         if ((retcode = connection_get_type(privates->connection, &type)) !=
240                         CONNECTION_ERROR_NONE) {
241                 TRACE_ERROR("Failed connection_get_type [%d]", retcode);
242                 connection_destroy(privates->connection);
243                 return -1;
244         }
245         privates->network_status =
246                 __dp_get_network_connection_status(privates->connection, type);
247         return 0;
248 }
249
250 //////////////////////////////////////////////////////////////////////////
251 /// @brief              destroy connection handle
252 void dp_network_connection_destroy(connection_h connection)
253 {
254         TRACE_INFO("");
255         connection_unset_type_changed_cb (connection);
256         connection_destroy(connection);
257 }
258
259 //////////////////////////////////////////////////////////////////////////
260 /// @brief              check network status using connection API
261 /// @todo               the standard of enabled networking can be changed later
262 /// @return     Network type
263 dp_network_type dp_get_network_connection_instant_status()
264 {
265         int retcode = 0;
266         connection_h network_handle = NULL;
267         dp_network_type network_type = DP_NETWORK_TYPE_OFF;
268         if ((retcode = connection_create(&network_handle)) !=
269                         CONNECTION_ERROR_NONE) {
270                 TRACE_ERROR("Failed connection_create [%d]", retcode);
271                 return DP_NETWORK_TYPE_OFF;
272         }
273
274         connection_type_e type = CONNECTION_TYPE_DISCONNECTED;
275         if ((retcode = connection_get_type(network_handle, &type)) !=
276                         CONNECTION_ERROR_NONE) {
277                 TRACE_ERROR("Failed connection_get_type [%d]", retcode);
278                 connection_destroy(network_handle);
279                 return DP_NETWORK_TYPE_OFF;
280         }
281         network_type =
282                 __dp_get_network_connection_status(network_handle, type);
283
284         if (connection_destroy(network_handle) != CONNECTION_ERROR_NONE)
285                 TRACE_ERROR("Failed connection_destroy");
286
287         return network_type;
288 }