bbb4c9ac3690db984281a8ad4d0216233a785056
[platform/framework/web/wrt-plugins-tizen.git] / src / NetworkBearerSelection / NetworkBearerSelection.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include <Commons/Exception.h>
19 #include <CommonsJavaScript/Converter.h>
20 #include <CommonsJavaScript/PrivateObject.h>
21 #include "OnNetworkBearerSelectionStateChanged.h"
22 #include "NetworkBearerSelection.h"
23 #include <netdb.h>
24 #include <arpa/inet.h>
25 #include <Logger.h>
26
27 using namespace WrtDeviceApis::CommonsJavaScript;
28 using namespace WrtDeviceApis::Commons;
29
30
31 namespace DeviceAPI {
32 namespace NetworkBearerSelection {
33     
34 static void connection_state_changed_callback(connection_profile_state_e state, void* user_data)
35 {
36     LoggerD("enter");
37     if(user_data != NULL) {
38         LoggerD("Callback registration Succeeded");
39         if (state == CONNECTION_PROFILE_STATE_ASSOCIATION) {
40             LoggerD("association state");
41             return;
42         }
43
44         NewtorkBearerSelectionPendingEvent *pendingEvent = (NewtorkBearerSelectionPendingEvent *)user_data;
45         NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
46         EventNetworkBearerSelectionPtr event = pendingEvent->getEvent();
47
48         if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) {
49             networkBearerSelection->makeRequestCallback(event, CONNECTION_STATE_DISCONNECTED);
50             delete pendingEvent;
51             pendingEvent = NULL;
52             user_data = NULL;
53         } else if (state == CONNECTION_PROFILE_STATE_CONNECTED) {
54             networkBearerSelection->makeRequestCallback(event, CONNECTION_STATE_CONNECTED);
55         }
56     
57         user_data = NULL;
58     }
59 }
60
61 static void connection_opened_callback(connection_error_e result, void* user_data)
62 {
63     LoggerD("enter");
64         if (result ==  CONNECTION_ERROR_NONE) {
65         LoggerD("Connection open Succeeded");
66         if(user_data != NULL) {
67             NewtorkBearerSelectionPendingEvent *pendingEvent = (NewtorkBearerSelectionPendingEvent *)user_data;
68             NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
69             EventNetworkBearerSelectionPtr event = pendingEvent->getEvent();
70
71             networkBearerSelection->registStateChangeListener(event);
72
73             delete pendingEvent;
74             pendingEvent = NULL;
75             user_data = NULL;
76         }
77     }
78 }
79
80 static void connection_closed_callback(connection_error_e result, void* user_data)
81 {
82     LoggerD("result : " << result);
83         if (result ==  CONNECTION_ERROR_NONE) {
84                 LoggerD("Connection close Succeeded");
85         if (user_data != NULL) {
86             NewtorkBearerReleasePendingEvent *pendingEvent = (NewtorkBearerReleasePendingEvent *)user_data;
87             NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
88             EventNetworkBearerReleasePtr event = pendingEvent->getEvent();
89
90             networkBearerSelection->deregistStateChangeListener(event);
91
92             delete pendingEvent;
93             pendingEvent = NULL;
94             user_data = NULL;
95         }
96     } else if (result == CONNECTION_ERROR_OPERATION_FAILED) {
97                 LoggerD("Connection close Failed");
98         if (user_data != NULL) {
99             NewtorkBearerReleasePendingEvent *pendingEvent = (NewtorkBearerReleasePendingEvent *)user_data;
100             NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
101             EventNetworkBearerReleasePtr event = pendingEvent->getEvent();
102
103             networkBearerSelection->makeReleaseCallback(event);
104
105             delete pendingEvent;
106             pendingEvent = NULL;
107             user_data = NULL;
108         }
109     }
110 }
111
112 static void connection_closed_callback2(connection_error_e result, void* user_data)
113 {
114     LoggerD("enter");
115         if (result ==  CONNECTION_ERROR_NONE) {
116                 LoggerD("Connection close Succeeded");
117     }
118 }
119
120
121 static void connection_removed_callback(connection_error_e result, void* user_data)
122 {
123     LoggerD("enter");
124     if (user_data != NULL) {
125         if (result ==  CONNECTION_ERROR_NONE) {
126             LoggerD("Connection close Succeeded");
127             NewtorkBearerSelectionPendingEvent *pendingEvent = (NewtorkBearerSelectionPendingEvent *)user_data;
128             NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
129             EventNetworkBearerSelectionPtr event = pendingEvent->getEvent();            
130
131             networkBearerSelection->removeStateChangeListener(event);
132
133             delete pendingEvent;
134             pendingEvent = NULL;
135         }
136
137         user_data = NULL;
138     }
139 }
140
141 NetworkBearerSelection::NetworkBearerSelection() : m_connectionHandle(NULL),
142                                                    m_profileHandle(NULL),
143                                                    m_connectionState(NETWORK_UNKNOWN)
144 {
145     int ret = connection_create(&m_connectionHandle);
146
147         if (CONNECTION_ERROR_NONE == ret) {
148                 LoggerD("Client registration success");
149         } else {
150                 LoggerD("Client registration failed");
151         m_connectionHandle = NULL;
152         }    
153 }
154
155 NetworkBearerSelection::~NetworkBearerSelection()
156 {
157     if(m_connectionHandle != NULL) {
158         LoggerD("Client deregistration success");
159         connection_destroy(m_connectionHandle);
160     } else {
161         LoggerD("Client deregistration failed");
162     }
163 }
164
165 void NetworkBearerSelection::requestRouteToHost(const EventNetworkBearerSelectionPtr &event)
166 {
167     EventRequestReceiver<EventNetworkBearerSelection>::PostRequest(event);
168 }
169
170 void NetworkBearerSelection::releaseRouteToHost(const EventNetworkBearerReleasePtr &event)
171 {
172     EventRequestReceiver<EventNetworkBearerRelease>::PostRequest(event);
173 }
174
175 void NetworkBearerSelection::OnRequestReceived(const EventNetworkBearerSelectionPtr &event)
176 {
177     LoggerD("m_connectionState : " << m_connectionState);
178
179     if (m_connectionState == NETWORK_CONNECTED) {
180         reLaunchConnection(event);
181         return;
182     }
183
184     connection_profile_iterator_h profileIter;
185
186     int ret = connection_get_profile_iterator(m_connectionHandle, CONNECTION_ITERATOR_TYPE_REGISTERED, &profileIter);
187         if (ret != CONNECTION_ERROR_NONE) {
188         LoggerD("Fail to get profile iterator");
189         makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
190         return;
191     }
192     while (connection_profile_iterator_has_next(profileIter)) {
193         if (connection_profile_iterator_next(profileIter, &m_profileHandle) != CONNECTION_ERROR_NONE) {
194             LoggerD("Fail to get profile handle");
195             makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
196             return;
197         }
198     }
199
200     NewtorkBearerSelectionPendingEvent *pendingEvent = new NewtorkBearerSelectionPendingEvent((void *)this, event);
201
202     if (connection_open_profile(m_connectionHandle, m_profileHandle, connection_opened_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
203         LoggerD("Connection open Failed");
204         makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
205         delete pendingEvent;
206         pendingEvent = NULL;
207     }
208 }
209
210 void NetworkBearerSelection::OnRequestReceived(const EventNetworkBearerReleasePtr &event)
211 {
212     LoggerD("enter");
213     if (event->getDomainName().compare(m_domainName) == 0) {
214         if (!m_profileHandle) {
215             event->setExceptionCode(ExceptionCodes::AlreadyInUseException);
216             return;
217         }
218         
219         event->switchToManualAnswer();
220
221         if (connection_profile_unset_state_changed_cb(m_profileHandle) != CONNECTION_ERROR_NONE) {
222             LoggerD("unset callback is failed");
223             return;
224         }        
225         
226         NewtorkBearerReleasePendingEvent *pendingEvent = new NewtorkBearerReleasePendingEvent((void *)this, event);
227
228         if (connection_close_profile(m_connectionHandle, m_profileHandle, connection_closed_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
229             LoggerD("connection close failed");
230             delete pendingEvent;
231             pendingEvent = NULL;
232             EventRequestReceiver<EventNetworkBearerRelease>::ManualAnswer(event);
233             return;
234         }
235     } else {
236         event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
237     }
238 }
239
240 void NetworkBearerSelection::reLaunchConnection(const EventNetworkBearerSelectionPtr &event)
241 {
242     LoggerD("enter");
243
244     if (connection_profile_unset_state_changed_cb(m_profileHandle) != CONNECTION_ERROR_NONE) {
245         LoggerD("unset callback is failed");
246         makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
247         return;
248     }
249
250     NewtorkBearerSelectionPendingEvent *pendingEvent = new NewtorkBearerSelectionPendingEvent((void *)this, event);
251
252     if (connection_close_profile(m_connectionHandle, m_profileHandle, connection_removed_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
253         LoggerD("connection close failed");
254         makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
255         delete pendingEvent;
256         pendingEvent = NULL;
257     }
258 }
259
260 void NetworkBearerSelection::removeStateChangeListener(const EventNetworkBearerSelectionPtr &event)
261 {
262     LoggerD("enter");
263
264     m_profileHandle = NULL;
265     connection_profile_iterator_h profileIter;
266
267     int ret = connection_get_profile_iterator(m_connectionHandle, CONNECTION_ITERATOR_TYPE_REGISTERED, &profileIter);
268     if (ret != CONNECTION_ERROR_NONE) {
269         LoggerD("Fail to get profile iterator");
270         makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
271         return;
272     }
273     while (connection_profile_iterator_has_next(profileIter)) {
274         if (connection_profile_iterator_next(profileIter, &m_profileHandle) != CONNECTION_ERROR_NONE) {
275             LoggerD("Fail to get profile handle");
276             makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
277             return;
278         }
279     }
280
281     NewtorkBearerSelectionPendingEvent *pendingEvent = new NewtorkBearerSelectionPendingEvent((void *)this, event);
282
283     if (connection_open_profile(m_connectionHandle, m_profileHandle, connection_opened_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
284         LoggerD("Connection open Failed");
285         makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
286         delete pendingEvent;
287         pendingEvent = NULL;
288     }
289 }
290
291 void NetworkBearerSelection::registStateChangeListener(const EventNetworkBearerSelectionPtr &event)
292 {
293     LoggerD("enter");
294     char *interfaceName = NULL;
295     char *hostAddr = NULL;
296     struct hostent *host_entry;
297
298         if (connection_profile_get_network_interface_name(m_profileHandle, &interfaceName) != CONNECTION_ERROR_NONE) {
299         LoggerD("Fail to get interface name!");
300         makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
301     }
302         else {
303         LoggerD("Interface name : " << interfaceName);
304         }
305
306     host_entry = gethostbyname(event->getDomainName().c_str());
307
308     if(!host_entry) {
309         LoggerD("gethostbyname is failed");
310         makeRequestCallback(event, CONNECTION_STATE_INVALID_VALUES_ERROR);
311
312         if (connection_close_profile(m_connectionHandle, m_profileHandle, connection_closed_callback2, NULL) != CONNECTION_ERROR_NONE) {
313             LoggerD("connection close failed");
314             makeRequestCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
315         }
316         m_profileHandle = NULL;
317         return;
318     }
319
320     hostAddr = inet_ntoa( *(struct in_addr*)host_entry->h_addr_list[0]);
321     LoggerD("hostAddr : " << hostAddr);
322
323     NewtorkBearerSelectionPendingEvent *pendingEvent = new NewtorkBearerSelectionPendingEvent((void *)this, event);
324     if (connection_profile_set_state_changed_cb(m_profileHandle, connection_state_changed_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
325         LoggerE("Callback register is failed.");
326         delete pendingEvent;
327         pendingEvent = NULL;        
328     } else {
329     connection_add_route(m_connectionHandle, interfaceName, hostAddr);
330 }
331 }
332
333 void NetworkBearerSelection::deregistStateChangeListener(const EventNetworkBearerReleasePtr &event)
334 {
335     LoggerD("enter");
336     m_profileHandle = NULL;
337     m_connectionState = NETWORK_DISCONNECTED;
338         EventRequestReceiver<EventNetworkBearerRelease>::ManualAnswer(event);         
339 }
340
341 void NetworkBearerSelection::makeRequestCallback(const EventNetworkBearerSelectionPtr &event, connectionStateType state)
342 {
343     LoggerD("state : " << state);
344     OnNetworkBearerSelectionStateChangedEmitterPtr emitter = event->getEmitter();
345         OnNetworkBearerSelectionStateChangedPtr listener(new OnNetworkBearerSelectionStateChanged());    
346
347     m_domainName = event->getDomainName();    
348     listener->setConnectionStateType(state);
349
350     if (state == CONNECTION_STATE_INVALID_VALUES_ERROR) {
351         m_connectionState = NETWORK_CONNECTION_FAILED;
352         listener->setExceptionCode(ExceptionCodes::InvalidArgumentException);
353     } else if (state == CONNECTION_STATE_PLATFORM_ERROR) {
354         m_connectionState = NETWORK_CONNECTION_FAILED;
355         listener->setExceptionCode(ExceptionCodes::PlatformException);
356     } else if (state == CONNECTION_STATE_DISCONNECTED) {
357         m_connectionState = NETWORK_DISCONNECTED;
358         if (connection_profile_unset_state_changed_cb(m_profileHandle) != CONNECTION_ERROR_NONE) {
359             LoggerD("unset callback is failed");
360         }
361         m_profileHandle = NULL;
362     } else if (state == CONNECTION_STATE_CONNECTED) {
363         m_connectionState = NETWORK_CONNECTED;
364     }
365     emitter->emit(listener);
366 }
367
368 void NetworkBearerSelection::makeReleaseCallback(const EventNetworkBearerReleasePtr &event)
369 {
370     event->setExceptionCode(ExceptionCodes::AlreadyInUseException);
371 }
372
373 bool NetworkBearerSelection::checkProfileHandle()
374 {
375     if(m_profileHandle == NULL) {
376         return true;
377     }
378     return false;
379 }
380
381 bool NetworkBearerSelection::checkCellularNetworkEnable()
382 {
383         connection_cellular_state_e cellularState;
384
385     if (connection_get_cellular_state(m_connectionHandle, &cellularState) != CONNECTION_ERROR_NONE) {
386                 LoggerD("Fail to get Cellular state");
387         return false;
388     }
389
390     LoggerD("celluar network state is " << cellularState);
391
392     if (cellularState == CONNECTION_CELLULAR_STATE_AVAILABLE || cellularState == CONNECTION_CELLULAR_STATE_CONNECTED) {
393         return true;
394     }
395     return false;
396 }
397
398 }
399 }