wrt-plugins-tizen_0.4.23
[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 using namespace DPL;
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         NewtorkBearerSelectionPendingEvent *pendingEvent = (NewtorkBearerSelectionPendingEvent *)user_data;
40         NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
41         EventNetworkBearerSelectionPtr event = pendingEvent->getEvent();
42
43         if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) {
44             networkBearerSelection->makeCallback(event, CONNECTION_STATE_DISCONNECTED);
45         } else if (state == CONNECTION_PROFILE_STATE_CONNECTED) {
46             networkBearerSelection->makeCallback(event, CONNECTION_STATE_CONNECTED);
47         }
48     
49         delete pendingEvent;
50         pendingEvent = NULL;
51         user_data = NULL;
52     }
53 }
54
55 static void connection_opened_callback(connection_error_e result, void* user_data)
56 {
57     LoggerD("enter");
58         if (result ==  CONNECTION_ERROR_NONE) {
59         LoggerD("Connection open Succeeded");
60         if(user_data != NULL) {
61             NewtorkBearerSelectionPendingEvent *pendingEvent = (NewtorkBearerSelectionPendingEvent *)user_data;
62             NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
63             EventNetworkBearerSelectionPtr event = pendingEvent->getEvent();
64
65             networkBearerSelection->registStateChangeListener(event);
66
67             delete pendingEvent;
68             pendingEvent = NULL;
69             user_data = NULL;
70         }
71     }
72 }
73
74 static void connection_closed_callback(connection_error_e result, void* user_data)
75 {
76     LoggerD("enter");
77         if (result ==  CONNECTION_ERROR_NONE) {
78                 LoggerD("Connection close Succeeded");
79         if (user_data != NULL) {
80             NewtorkBearerReleasePendingEvent *pendingEvent = (NewtorkBearerReleasePendingEvent *)user_data;
81             NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
82             EventNetworkBearerReleasePtr event = pendingEvent->getEvent();
83
84             networkBearerSelection->deregistStateChangeListener(event);
85
86             delete pendingEvent;
87             pendingEvent = NULL;
88             user_data = NULL;
89         }
90     }
91 }
92
93 static void connection_closed_callback2(connection_error_e result, void* user_data)
94 {
95     LoggerD("enter");
96         if (result ==  CONNECTION_ERROR_NONE) {
97                 LoggerD("Connection close Succeeded");
98     }
99 }
100
101
102 static void connection_removed_callback(connection_error_e result, void* user_data)
103 {
104     LoggerD("enter");
105     if (user_data != NULL) {
106         if (result ==  CONNECTION_ERROR_NONE) {
107             LoggerD("Connection close Succeeded");
108             NewtorkBearerSelectionPendingEvent *pendingEvent = (NewtorkBearerSelectionPendingEvent *)user_data;
109             NetworkBearerSelection *networkBearerSelection = (NetworkBearerSelection *)pendingEvent->getThisObject();
110             EventNetworkBearerSelectionPtr event = pendingEvent->getEvent();            
111
112             networkBearerSelection->removeStateChangeListener(event);
113
114             delete pendingEvent;
115             pendingEvent = NULL;
116         }
117
118         user_data = NULL;
119     }
120 }
121
122 NetworkBearerSelection::NetworkBearerSelection() : m_connectionHandle(NULL),
123                                                    m_profileHandle(NULL),
124                                                    m_connectionState(NETWORK_UNKNOWN)
125 {
126     int ret = connection_create(&m_connectionHandle);
127
128         if (CONNECTION_ERROR_NONE == ret) {
129                 LoggerD("Client registration success");
130         } else {
131                 LoggerD("Client registration failed");
132         m_connectionHandle = NULL;
133         }    
134 }
135
136 NetworkBearerSelection::~NetworkBearerSelection()
137 {
138     if(m_connectionHandle != NULL) {
139         LoggerD("Client deregistration success");
140         connection_destroy(m_connectionHandle);
141     } else {
142         LoggerD("Client deregistration failed");
143     }
144 }
145
146 void NetworkBearerSelection::requestRouteToHost(const EventNetworkBearerSelectionPtr &event)
147 {
148     EventRequestReceiver<EventNetworkBearerSelection>::PostRequest(event);
149 }
150
151 void NetworkBearerSelection::releaseRouteToHost(const EventNetworkBearerReleasePtr &event)
152 {
153     EventRequestReceiver<EventNetworkBearerRelease>::PostRequest(event);
154 }
155
156 void NetworkBearerSelection::OnRequestReceived(const EventNetworkBearerSelectionPtr &event)
157 {
158     LoggerD("m_connectionState : " << m_connectionState);
159
160     if (m_connectionState == NETWORK_CONNECTED) {
161         reLaunchConnection(event);
162         return;
163     }
164
165     connection_profile_iterator_h profileIter;
166
167     int ret = connection_get_profile_iterator(m_connectionHandle, CONNECTION_ITERATOR_TYPE_REGISTERED, &profileIter);
168         if (ret != CONNECTION_ERROR_NONE) {
169         LoggerD("Fail to get profile iterator");
170         makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
171         return;
172     }
173     while (connection_profile_iterator_has_next(profileIter)) {
174         if (connection_profile_iterator_next(profileIter, &m_profileHandle) != CONNECTION_ERROR_NONE) {
175             LoggerD("Fail to get profile handle");
176             makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
177             return;
178         }
179     }
180
181     NewtorkBearerSelectionPendingEvent *pendingEvent = new NewtorkBearerSelectionPendingEvent((void *)this, event);
182
183     if (connection_open_profile(m_connectionHandle, m_profileHandle, connection_opened_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
184         LoggerD("Connection open Failed");
185         makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
186         delete pendingEvent;
187         pendingEvent = NULL;
188     }
189 }
190
191 void NetworkBearerSelection::OnRequestReceived(const EventNetworkBearerReleasePtr &event)
192 {
193     LoggerD("enter");
194     if (event->getDomainName().compare(m_domainName) == 0) {
195         event->switchToManualAnswer();
196
197         if (connection_profile_unset_state_changed_cb(m_profileHandle) != CONNECTION_ERROR_NONE) {
198             LoggerD("unset callback is failed");
199             return;
200         }        
201         
202         NewtorkBearerReleasePendingEvent *pendingEvent = new NewtorkBearerReleasePendingEvent((void *)this, event);
203
204         if (connection_close_profile(m_connectionHandle, m_profileHandle, connection_closed_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
205             LoggerD("connection close failed");
206             delete pendingEvent;
207             pendingEvent = NULL;
208             EventRequestReceiver<EventNetworkBearerRelease>::ManualAnswer(event);
209             return;
210         }
211     } else {
212         event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
213     }
214 }
215
216 void NetworkBearerSelection::reLaunchConnection(const EventNetworkBearerSelectionPtr &event)
217 {
218     LoggerD("enter");
219
220     if (connection_profile_unset_state_changed_cb(m_profileHandle) != CONNECTION_ERROR_NONE) {
221         LoggerD("unset callback is failed");
222         makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
223         return;
224     }
225
226     NewtorkBearerSelectionPendingEvent *pendingEvent = new NewtorkBearerSelectionPendingEvent((void *)this, event);
227
228     if (connection_close_profile(m_connectionHandle, m_profileHandle, connection_removed_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
229         LoggerD("connection close failed");
230         makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
231         delete pendingEvent;
232         pendingEvent = NULL;
233     }
234 }
235
236 void NetworkBearerSelection::removeStateChangeListener(const EventNetworkBearerSelectionPtr &event)
237 {
238     LoggerD("enter");
239
240     m_profileHandle = NULL;
241     connection_profile_iterator_h profileIter;
242
243     int ret = connection_get_profile_iterator(m_connectionHandle, CONNECTION_ITERATOR_TYPE_REGISTERED, &profileIter);
244     if (ret != CONNECTION_ERROR_NONE) {
245         LoggerD("Fail to get profile iterator");
246         makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
247         return;
248     }
249     while (connection_profile_iterator_has_next(profileIter)) {
250         if (connection_profile_iterator_next(profileIter, &m_profileHandle) != CONNECTION_ERROR_NONE) {
251             LoggerD("Fail to get profile handle");
252             makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
253             return;
254         }
255     }
256
257     NewtorkBearerSelectionPendingEvent *pendingEvent = new NewtorkBearerSelectionPendingEvent((void *)this, event);
258
259     if (connection_open_profile(m_connectionHandle, m_profileHandle, connection_opened_callback, pendingEvent) != CONNECTION_ERROR_NONE) {
260         LoggerD("Connection open Failed");
261         makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
262         delete pendingEvent;
263         pendingEvent = NULL;
264     }
265 }
266
267 void NetworkBearerSelection::registStateChangeListener(const EventNetworkBearerSelectionPtr &event)
268 {
269     LoggerD("enter");
270     char *interfaceName = NULL;
271     char *hostAddr = NULL;
272     struct hostent *host_entry;
273
274         if (connection_profile_get_network_interface_name(m_profileHandle, &interfaceName) != CONNECTION_ERROR_NONE) {
275         LoggerD("Fail to get interface name!");
276         makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
277     }
278         else {
279         LoggerD("Interface name : " << interfaceName);
280         }
281
282     host_entry = gethostbyname(event->getDomainName().c_str());
283
284     if(!host_entry) {
285         LoggerD("gethostbyname is failed");
286         makeCallback(event, CONNECTION_STATE_INVALID_VALUES_ERROR);
287
288         if (connection_close_profile(m_connectionHandle, m_profileHandle, connection_closed_callback2, NULL) != CONNECTION_ERROR_NONE) {
289             LoggerD("connection close failed");
290             makeCallback(event, CONNECTION_STATE_PLATFORM_ERROR);
291         }
292         m_profileHandle = NULL;
293         return;
294     }
295
296     hostAddr = inet_ntoa( *(struct in_addr*)host_entry->h_addr_list[0]);
297     LoggerD("hostAddr : " << hostAddr);
298
299     NewtorkBearerSelectionPendingEvent *pendingEvent = new NewtorkBearerSelectionPendingEvent((void *)this, event);
300     connection_profile_set_state_changed_cb(m_profileHandle, connection_state_changed_callback, pendingEvent);
301     connection_add_route(m_connectionHandle, interfaceName, hostAddr);
302 }
303
304 void NetworkBearerSelection::deregistStateChangeListener(const EventNetworkBearerReleasePtr &event)
305 {
306     LoggerD("enter");
307     m_profileHandle = NULL;
308     m_connectionState = NETWORK_DISCONNECTED;
309         EventRequestReceiver<EventNetworkBearerRelease>::ManualAnswer(event);         
310 }
311
312 void NetworkBearerSelection::makeCallback(const EventNetworkBearerSelectionPtr &event, connectionStateType state)
313 {
314     LoggerD("state : " << state);
315     OnNetworkBearerSelectionStateChangedEmitterPtr emitter = event->getEmitter();
316         OnNetworkBearerSelectionStateChangedPtr listener(new OnNetworkBearerSelectionStateChanged());    
317
318     m_domainName = event->getDomainName();    
319     listener->setConnectionStateType(state);
320
321     if (state == CONNECTION_STATE_INVALID_VALUES_ERROR) {
322         m_connectionState = NETWORK_CONNECTION_FAILED;
323         listener->setExceptionCode(ExceptionCodes::InvalidArgumentException);
324     } else if (state == CONNECTION_STATE_PLATFORM_ERROR) {
325         m_connectionState = NETWORK_CONNECTION_FAILED;
326         listener->setExceptionCode(ExceptionCodes::PlatformException);
327     } else if (state == CONNECTION_STATE_DISCONNECTED) {
328         m_connectionState = NETWORK_DISCONNECTED;
329     } else if (state == CONNECTION_STATE_CONNECTED) {
330         m_connectionState = NETWORK_CONNECTED;
331     }
332     emitter->emit(listener);
333 }
334
335 bool NetworkBearerSelection::checkProfileHandle()
336 {
337     if(m_profileHandle == NULL) {
338         return true;
339     }
340     return false;
341 }
342
343 bool NetworkBearerSelection::checkCellularNetworkEnable()
344 {
345         connection_cellular_state_e cellularState;
346
347     if (connection_get_cellular_state(m_connectionHandle, &cellularState) != CONNECTION_ERROR_NONE) {
348                 LoggerD("Fail to get Cellular state");
349         return false;
350     }
351
352     LoggerD("celluar network state is " << cellularState);
353
354     if (cellularState == CONNECTION_CELLULAR_STATE_AVAILABLE || cellularState == CONNECTION_CELLULAR_STATE_CONNECTED) {
355         return true;
356     }
357     return false;
358 }
359
360 }
361 }