Merge "Add the exception handling when using manual cert mode" into tizen_2.1
[platform/framework/native/net.git] / src / FNet_LocalDhcpServerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 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  * @file                FNet_LocalDhcpServerImpl.cpp
19  * @brief               This is the implementation file for the __LocalDhcpServerImpl Class.
20  *
21  * This header file contains implementation of the __LocalDhcpServerImpl Class.
22  */
23
24 #include <dlfcn.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/ioctl.h>
28 #include <net/if.h>
29 #include <string.h>
30
31 #include <arpa/inet.h>
32 #include <stdio.h>
33 #include <FBaseObject.h>
34 #include <FBaseResult.h>
35 #include <FBaseString.h>
36 #include <FNetNetTypes.h>
37 #include <FNetIp4Address.h>
38 #include <FNetNetConnectionInfo.h>
39 #include <FNetNetConnection.h>
40 #include <FNetDhcpClientInfo.h>
41 #include <FNetLocalDhcpServer.h>
42 #include <FBaseSysLog.h>
43 #include "FNet_NetTypes.h"
44 #include <FNetWifiWifiDirectDevice.h>
45 #include <FNetWifiWifiDirectDeviceInfo.h>
46 #include "FNet_NetConnectionImpl.h"
47 #include "FNet_LocalDhcpServerImpl.h"
48 #include "FNet_DhcpClientInfoImpl.h"
49 #include "FNet_LocalDhcpServerEvent.h"
50 #include "FNet_LocalDhcpServerEventArg.h"
51
52 using namespace std;
53 using namespace Tizen::Base;
54 using namespace Tizen::Base::Collection;
55 using namespace Tizen::Net::Wifi;
56
57 namespace Tizen { namespace Net
58 {
59
60 static const int  _MAX_DHCP_CLIENT_COUNT = 8; //dependent on DHCP server config
61
62 static const char _PLATFORM_MAC_ADDRESS_DELIMITER = ':';
63 static const char _MAC_ADDRESS_DELIMITER = '-';
64 static const char* _WIFI_DIRECT_LIBRARY_NAME = "libosp-wifi.so";
65
66 /*
67  * The _DhcpNetConnectionEventListenerImpl class can call listener's method. So, when an NetConnection event occurs,
68  * application can handle it appropriately.
69  */
70 class _DhcpNetConnectionEventListenerImpl
71         : public INetConnectionEventListener
72 {
73
74 public:
75         _DhcpNetConnectionEventListenerImpl(void);
76
77         virtual ~_DhcpNetConnectionEventListenerImpl(void);
78
79 public:
80         void SetConstructParams(_LocalDhcpServerEvent* pLocalDhcpServerEvent, tethering_h pUsbTetheringHandle);
81
82 public:
83
84         void OnNetConnectionStarted(NetConnection& netConnection, result r);
85
86         void OnNetConnectionStopped(NetConnection& netConnection, result r);
87
88         void OnNetConnectionSuspended(NetConnection& netConnection);
89
90         void OnNetConnectionResumed(NetConnection& netConnection);
91
92 private:
93
94         _DhcpNetConnectionEventListenerImpl(const _DhcpNetConnectionEventListenerImpl& value);
95
96         _DhcpNetConnectionEventListenerImpl& operator =(const _DhcpNetConnectionEventListenerImpl& rhs);
97
98 private:
99
100         _LocalDhcpServerEvent* __pLocalDhcpServerEvent;// reference, no ownership
101         tethering_h __pUsbTetheringHandle;// no ownership
102
103 };
104
105 _DhcpNetConnectionEventListenerImpl::_DhcpNetConnectionEventListenerImpl()
106 : __pLocalDhcpServerEvent(null)
107 , __pUsbTetheringHandle(null)
108 {
109
110 }
111
112 _DhcpNetConnectionEventListenerImpl::~_DhcpNetConnectionEventListenerImpl(void)
113 {
114 }
115
116 void
117 _DhcpNetConnectionEventListenerImpl::OnNetConnectionStarted(NetConnection& netConnection, result r)
118 {
119         SysLog(NID_NET, "DhcpNetConnectionEventListener received an event, OnNetConnectionStarted.");
120
121         // check, if listener is null
122         if (__pLocalDhcpServerEvent == null)
123         {
124                 // log error
125                 SysLogException(NID_NET, E_SYSTEM,
126                     "__DhcpNetConnectionEventListenerImpl::OnNetConnectionStarted Invalid state.");
127
128                 return;
129         }
130
131         // process connected event
132         _LocalDhcpServerImpl* pLocalDhcpServerImpl = null;
133         pLocalDhcpServerImpl = _LocalDhcpServerImpl::GetInstance(*__pLocalDhcpServerEvent->GetLocalDhcpServer());
134         SysTryReturnVoidResult(NID_NET, pLocalDhcpServerImpl != null, E_SYSTEM,
135                         "[%s] A system error has been occurred. Failed to retrieve LocalDhcpServer instance.", GetErrorMessage(E_SYSTEM));
136
137         // set flag
138         pLocalDhcpServerImpl->__isConnectedNetwork = true;
139         // save the list
140         pLocalDhcpServerImpl->SetDhcpConnectedPeerInfoList(pLocalDhcpServerImpl->GetDhcpClientInfoListN(false));
141
142         if (netConnection.GetNetAccountId() == _DEFAULT_USB_ACCOUNT_ID)
143         {
144                 SysLog(NID_NET, "OnNetConnectionStarted, Get DHCP Client info for USB");
145
146                 ArrayList* pDhcpClientInfoList = null;
147                 DhcpClientInfo* pDhcpClientInfo = null;
148                 _LocalDhcpServerEventArg* pDhcpServerEventArg = null;
149                 _NetDhcpServerEventType eventCode = NET_DHCP_SERVER_EVENT_CONNECT;
150                 
151                 pDhcpClientInfoList = dynamic_cast<ArrayList*>(pLocalDhcpServerImpl->GetDhcpConnectedPeerInfoList());
152                 SysTryReturnVoidResult(NID_NET, pDhcpClientInfoList != null, E_SYSTEM,
153                                 "[%s] A system error has been occurred. Failed to retrieve DhcpClientInfoList.", GetErrorMessage(E_SYSTEM));
154                 
155                 // we know USB case only one entry exists
156                 pDhcpClientInfo = dynamic_cast<DhcpClientInfo*>(pDhcpClientInfoList->GetAt(0));
157                 SysTryReturnVoidResult(NID_NET, pDhcpClientInfo != null, E_SYSTEM,
158                                 "[%s] A system error has been occurred. Failed to retrieve DhcpClientInfo.", GetErrorMessage(E_SYSTEM));
159                 
160                 pDhcpServerEventArg = new (std::nothrow) _LocalDhcpServerEventArg(eventCode, *pDhcpClientInfo);
161                 SysTryReturnVoidResult(NID_NET, pDhcpServerEventArg != null, E_OUT_OF_MEMORY,
162                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
163
164                 __pLocalDhcpServerEvent->Fire(*pDhcpServerEventArg);
165         }
166         else if (netConnection.GetNetAccountId() == _DEFAULT_WIFI_DIRECT_ACCOUNT_ID)
167         {
168                 SysLog(NID_NET, "OnNetConnectionStarted, Get DHCP Client info for WIFI-DIRECT");
169
170                 //register for events
171
172                 WifiDirectDevice*(*pRegisterListenerFunction)(IWifiDirectDeviceListener* pDeviceListener, IWifiDirectGroupOwnerListener* pOwnerListener,
173                                                         IWifiDirectGroupClientListener* pClientListener) = null;
174
175                 pLocalDhcpServerImpl->__pDllHandle = dlopen(_WIFI_DIRECT_LIBRARY_NAME, RTLD_LAZY);
176                 SysTryReturnVoidResult(NID_NET, pLocalDhcpServerImpl->__pDllHandle != null, E_SYSTEM,
177                                 "[%s] A system error has been occurred. Failed to open wifi library.", GetErrorMessage(E_SYSTEM));
178
179                 pRegisterListenerFunction = reinterpret_cast<WifiDirectDevice*(*)(IWifiDirectDeviceListener* pDeviceListener, IWifiDirectGroupOwnerListener* pOwnerListener,
180                                         IWifiDirectGroupClientListener* pClientListener)>( dlsym(pLocalDhcpServerImpl->__pDllHandle,                                                                                            "_WifiDirectDeviceManagerImpl_GetWifiDirectDeviceN"));
181                 SysTryReturnVoidResult(NID_NET, pRegisterListenerFunction != null, E_SYSTEM,
182                                 "[%s] A system error has been occurred. Failed to get a function pointer.", GetErrorMessage(E_SYSTEM));
183
184                 pLocalDhcpServerImpl->__pDevice = pRegisterListenerFunction(null, pLocalDhcpServerImpl, null);
185                 SysTryReturnVoidResult(NID_NET, pLocalDhcpServerImpl->__pDevice != null, E_SYSTEM,
186                                 "[%s] A system error has been occurred. Failed to get a WifiDirectDevice instance.", GetErrorMessage(E_SYSTEM));
187         }
188         else
189         {
190                 // should not reach here.
191                 SysAssertf(false, "OnNetConnectionStarted, Bearer not supported for DHCP");
192                 return;
193         }
194         
195         return;
196 }
197
198 void
199 _DhcpNetConnectionEventListenerImpl::OnNetConnectionStopped(NetConnection& netConnection, result r)
200 {
201         SysLog(NID_NET, "DhcpNetConnectionEventListener received an event, OnNetConnectionStopped.");
202
203         result error = E_SUCCESS;
204         _LocalDhcpServerEventArg* pDhcpServerEventArg = null;
205         _NetDhcpServerEventType eventCode = NET_DHCP_SERVER_EVENT_DISCONNECT;
206         
207         // check
208         if (__pLocalDhcpServerEvent == null)
209         {
210                 // log error
211                 SysLogException(NID_NET, E_SYSTEM,
212                     "__DhcpNetConnectionEventListenerImpl::OnNetConnectionStopped pDhcpServerEvent is null.");
213
214                 return;
215         }
216
217         // process disconnect event
218         ArrayList* pDhcpConnectedPeerInfoList = null;
219         _LocalDhcpServerImpl* pLocalDhcpServerImpl = null;
220
221         pLocalDhcpServerImpl = _LocalDhcpServerImpl::GetInstance(*__pLocalDhcpServerEvent->GetLocalDhcpServer());
222         SysTryReturnVoidResult(NID_NET, pLocalDhcpServerImpl != null, E_SYSTEM,
223                         "[%s] A system error has been occurred. Failed to retrieve LocalDhcpServer instance.", GetErrorMessage(E_SYSTEM));
224
225         if (netConnection.GetNetAccountId() == _DEFAULT_USB_ACCOUNT_ID)
226         {
227                 SysLog(NID_NET, "OnNetConnectionStopped event received for USB");               
228         }
229         else if (netConnection.GetNetAccountId() == _DEFAULT_WIFI_DIRECT_ACCOUNT_ID)
230         {
231                 SysLog(NID_NET, "OnNetConnectionStopped event received for WIFI-DIRECT");
232
233                 //un-register for events
234                 if (pLocalDhcpServerImpl->__pDllHandle != null)
235                 {
236                         if (pLocalDhcpServerImpl->__pDevice != null)
237                         {
238                                 void(*pUnRegisterListenerFunction)(WifiDirectDevice* pWifiDirectDevice, IWifiDirectDeviceListener* pDeviceListener,
239                                          IWifiDirectGroupOwnerListener* pOwnerListener, IWifiDirectGroupClientListener* pClientListener) = null;
240
241                                 pUnRegisterListenerFunction = reinterpret_cast<void(*)(WifiDirectDevice* pWifiDirectDevice, IWifiDirectDeviceListener* pDeviceListener,  
242                                                         IWifiDirectGroupOwnerListener* pOwnerListener, IWifiDirectGroupClientListener* pClientListener)>(
243                                                         dlsym(pLocalDhcpServerImpl->__pDllHandle, "_WifiDirectDeviceImpl_DeleteWifiDirectDevice"));
244                                 if (pUnRegisterListenerFunction != null)
245                                 {
246                                         pUnRegisterListenerFunction(pLocalDhcpServerImpl->__pDevice, null, pLocalDhcpServerImpl, null);
247                                         pLocalDhcpServerImpl->__pDevice = null;
248                                         SysLog(NID_NET, "Deleted an instance of WifiDirectDevice.");
249                                 }
250                         }
251                         dlclose(pLocalDhcpServerImpl->__pDllHandle);
252                         pLocalDhcpServerImpl->__pDllHandle = null;
253                 }       
254         }
255         else
256         {
257                 // should not reach here.
258                 SysAssertf(false, "OnNetConnectionStopped, Bearer not supported for DHCP");
259
260                 return;
261         }
262
263         // notify user about disconnect, call for each peer info
264         pDhcpConnectedPeerInfoList = dynamic_cast<ArrayList*>(pLocalDhcpServerImpl->GetDhcpConnectedPeerInfoList());
265         SysTryReturnVoidResult(NID_NET, pDhcpConnectedPeerInfoList != null, E_SYSTEM,
266                         "[%s] A system error has been occurred. Failed to retrieve DhcpConnectedPeerInfoList.", GetErrorMessage(E_SYSTEM));
267
268         unique_ptr<IEnumerator> pListEnumerator(pDhcpConnectedPeerInfoList->GetEnumeratorN());
269
270         SysTryReturnVoidResult(NID_NET, pListEnumerator != null, E_SYSTEM,
271                         "[%s] A system error has been occurred. pListEnumerator is null.", GetErrorMessage(E_SYSTEM));
272
273         // send notify to user about disconnect         
274         while (pListEnumerator->MoveNext() == E_SUCCESS)
275         {
276                 DhcpClientInfo* pDhcpClientInfo = null;
277                 pDhcpClientInfo = dynamic_cast<DhcpClientInfo*>(pListEnumerator->GetCurrent());
278                 
279                 if (pDhcpClientInfo != null)
280                 {                       
281                         pDhcpServerEventArg = new (std::nothrow) _LocalDhcpServerEventArg(eventCode, *pDhcpClientInfo);
282                         SysTryReturnVoidResult(NID_NET, pDhcpServerEventArg != null, E_OUT_OF_MEMORY,
283                                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
284
285                         __pLocalDhcpServerEvent->Fire(*pDhcpServerEventArg);
286                 }
287         }
288         // Operation is complete, delete the elements
289         pDhcpConnectedPeerInfoList->RemoveAll(true);
290
291         // Remove NetConnectionListener
292         pLocalDhcpServerImpl->__isConnectedNetwork = false;
293
294         error = pLocalDhcpServerImpl->__pNetConnectionClone->RemoveNetConnectionListener(*pLocalDhcpServerImpl->__pNetConnectionListener);
295         SysTryReturnVoidResult(NID_NET, error == E_SUCCESS, E_SYSTEM,
296                         "[%s] A system error has been occurred. Failed to remove the NetConnection listener.", GetErrorMessage(E_SYSTEM));
297
298         return;
299 }
300
301 void
302 _DhcpNetConnectionEventListenerImpl::OnNetConnectionSuspended(NetConnection& netConnection)
303 {
304         SysLog(NID_NET, "DhcpNetConnectionEventListener received an event, OnNetConnectionSuspended.");
305 }
306
307 void
308 _DhcpNetConnectionEventListenerImpl::OnNetConnectionResumed(NetConnection& netConnection)
309 {
310         SysLog(NID_NET, "DhcpNetConnectionEventListener received an event, OnNetConnectionResumed.");
311 }
312
313 void
314 _DhcpNetConnectionEventListenerImpl::SetConstructParams(_LocalDhcpServerEvent* pLocalDhcpServerEvent,
315                 tethering_h pUsbTetheringHandle)
316 {
317         __pLocalDhcpServerEvent = pLocalDhcpServerEvent;
318         __pUsbTetheringHandle = pUsbTetheringHandle;
319 }
320
321
322 //LocalDhcpServerImpl Implementation
323
324 _LocalDhcpServerImpl::_LocalDhcpServerImpl(void)
325         : __pLocalDhcpServerEvent(null)
326         , __pNetConnection(null)
327         , __pNetConnectionClone(null)
328         , __pNetConnectionListener(null)
329         , __pUsbTetheringHandle(null)
330         , __pDhcpConnectedPeerInfoList(null)
331         , __pDevice(null)
332         , __pDllHandle(null)
333         , __isConstructed(false)
334         , __isConnectedNetwork(false)
335 {
336 }
337
338 _LocalDhcpServerImpl::~_LocalDhcpServerImpl(void)
339 {
340         // deallocate memory for handle
341         if (__pUsbTetheringHandle != null)
342         {
343                 tethering_destroy(__pUsbTetheringHandle);
344                 __pUsbTetheringHandle = null;
345         }
346
347         if (__pDllHandle != null)
348         {
349                 if (__pDevice != null)
350                 {
351                         void(*pUnRegisterListenerFunction)(WifiDirectDevice* pWifiDirectDevice, IWifiDirectDeviceListener* pDeviceListener, 
352                                 IWifiDirectGroupOwnerListener* pOwnerListener,  IWifiDirectGroupClientListener* pClientListener) = null;
353
354                         pUnRegisterListenerFunction = reinterpret_cast<void(*)(WifiDirectDevice* pWifiDirectDevice, IWifiDirectDeviceListener* pDeviceListener,
355                                         IWifiDirectGroupOwnerListener* pOwnerListener, IWifiDirectGroupClientListener* pClientListener)>
356                                         (dlsym(__pDllHandle, "_WifiDirectDeviceImpl_DeleteWifiDirectDevice"));
357                         if (pUnRegisterListenerFunction != null)
358                         {
359                                 pUnRegisterListenerFunction(__pDevice, null, this, null);
360                                 __pDevice = null;                               
361                         }
362                 }
363
364                 dlclose(__pDllHandle);
365         }
366 }
367
368 result
369 _LocalDhcpServerImpl::Construct(const LocalDhcpServer* pLocalDhcpServer, const NetConnection& netConnection)
370 {
371         result r = E_SUCCESS;
372         _NetConnectionImpl* pNetConnectionImpl = null;
373         NetConnectionState netConnectionState = NET_CONNECTION_STATE_NONE;
374         unique_ptr<_DhcpNetConnectionEventListenerImpl> pNetConnectionListener(null);
375         unique_ptr<NetConnection> pNetConnectionClone(null);
376
377         SysAssertf(__isConstructed == false,
378                         "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
379
380         //check input
381         NetAccountId netAccountId = netConnection.GetNetAccountId();
382         SysTryReturnResult(NID_NET, (netAccountId == _DEFAULT_USB_ACCOUNT_ID || netAccountId == _DEFAULT_WIFI_DIRECT_ACCOUNT_ID),
383                         E_INVALID_ARG, "Invalid argument is used. The bearer type is not supported. bearerType=%d", netAccountId);
384
385         __pNetConnection = const_cast<NetConnection*>(&netConnection);
386
387         //create Event
388         unique_ptr<_LocalDhcpServerEvent> pLocalDhcpServerEvent(new (std::nothrow) _LocalDhcpServerEvent());
389         SysTryReturnResult(NID_NET, pLocalDhcpServerEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
390
391         r = pLocalDhcpServerEvent->Construct(*(const_cast < const LocalDhcpServer* >(pLocalDhcpServer)));
392         SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
393                         "A system error has been occurred. Failed to construct LocalDhcpServerEvent instance.");
394
395         // we have to listen to connection events, so clone NetConnection and set listener
396         pNetConnectionImpl = const_cast<_NetConnectionImpl*>(_NetConnectionImpl::GetInstance(netConnection));
397         SysTryReturnResult(NID_NET, pNetConnectionImpl != null, E_SYSTEM,
398                         "A system error has been occurred. Failed to retrieve NetConnection instance.");
399
400         // Creates new NetConnection for receiving the network event.
401         pNetConnectionClone.reset(pNetConnectionImpl->CopyInstanceN());
402         SysTryReturnResult(NID_NET, pNetConnectionClone != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
403
404         //set connection state
405         netConnectionState = __pNetConnection->GetConnectionState();
406
407         if (netConnectionState == NET_CONNECTION_STATE_STARTED ||
408                 netConnectionState == NET_CONNECTION_STATE_RESUMED ||
409                 netConnectionState == NET_CONNECTION_STATE_SUSPENDED)
410         {
411                 __isConnectedNetwork = true;
412         }
413
414         // New CustomNetConnectionEventListener
415         pNetConnectionListener.reset(new (std::nothrow) _DhcpNetConnectionEventListenerImpl());
416         SysTryReturnResult(NID_NET, pNetConnectionListener != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
417
418         // Add NetConnectionListener
419         r = pNetConnectionClone->AddNetConnectionListener(*pNetConnectionListener);
420         SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM, "A system error has been occurred. Failed to add the NetConnection listener.");
421
422         //check for connection type - USB or Wifi-Direct
423         if (__pNetConnection->GetNetAccountId() == _DEFAULT_USB_ACCOUNT_ID)
424         {
425                 // create usb tethering handle
426                 int err = TETHERING_ERROR_NONE;         
427
428                 err = tethering_create(&__pUsbTetheringHandle);
429                 SysLog(NID_NET, "[0x%x] Return value of tethering_create", err);
430         
431                 SysTryReturnResult(NID_NET, err == TETHERING_ERROR_NONE, E_SYSTEM,
432                                 "A system error has been occurred. Failed to create tethering handle.");
433
434                 SysTryReturnResult(NID_NET, __pUsbTetheringHandle !=  null, E_SYSTEM,
435                                 "A system error has been occurred. Failed to initialize Usb Tethering Handle.");
436
437                 //if already connected  
438                 if (__isConnectedNetwork)
439                 {                       
440                         //get already connected client information, and store locally
441                         SetDhcpConnectedPeerInfoList(GetDhcpClientInfoListN(false));
442                 }
443         }
444         else if (__pNetConnection->GetNetAccountId() == _DEFAULT_WIFI_DIRECT_ACCOUNT_ID)
445         {
446                 //if already connected, Register callbacks
447                 if (__isConnectedNetwork)
448                 {
449                         //register for events
450                         
451                         WifiDirectDevice*(*pRegisterListenerFunction)(IWifiDirectDeviceListener* pDeviceListener,
452                                         IWifiDirectGroupOwnerListener* pOwnerListener, IWifiDirectGroupClientListener* pClientListener) = null;
453
454                         __pDllHandle = dlopen(_WIFI_DIRECT_LIBRARY_NAME, RTLD_LAZY);
455                         SysTryCatch(NID_NET, __pDllHandle != null, r = E_SYSTEM, E_SYSTEM,
456                                         "[%s] A system error has been occurred. Failed to open wifi library.", GetErrorMessage(E_SYSTEM));
457
458                         pRegisterListenerFunction = reinterpret_cast<WifiDirectDevice*(*)(IWifiDirectDeviceListener* pDeviceListener,
459                                         IWifiDirectGroupOwnerListener* pOwnerListener, IWifiDirectGroupClientListener* pClientListener)>
460                                         (dlsym(__pDllHandle, "_WifiDirectDeviceManagerImpl_GetWifiDirectDeviceN"));
461                         SysTryCatch(NID_NET, pRegisterListenerFunction != null, r = E_SYSTEM, E_SYSTEM,
462                                         "[%s] A system error has been occurred. Failed to get a function pointer.", GetErrorMessage(E_SYSTEM));
463
464                         __pDevice = pRegisterListenerFunction(null, this, null);
465                         SysTryCatch(NID_NET, __pDevice != null, r = E_SYSTEM, E_SYSTEM,
466                                         "[%s] A system error has been occurred. Failed to get a WifiDirectDevice instance.", GetErrorMessage(E_SYSTEM));
467
468                         //get already connected client information, and store locally
469                         SetDhcpConnectedPeerInfoList(GetDhcpClientInfoListN(false));
470                 }       
471         }
472         else
473         {
474                 SysLogException(NID_NET, E_SYSTEM, "Bearer not supported for DHCP");
475                 
476                 SysTryReturnResult(NID_NET, false, E_SYSTEM, "A system error has been occurred. Bearer not supported for DHCP");
477         }
478
479         __isConstructed = true;
480
481         __pNetConnectionListener = move(pNetConnectionListener);
482         __pLocalDhcpServerEvent = move(pLocalDhcpServerEvent);
483         __pNetConnectionClone = move(pNetConnectionClone);
484
485         return r;
486
487 CATCH:
488         if (__pDllHandle != null)
489         {
490                 if (__pDevice != null)
491                 {
492                         void(*pUnRegisterListenerFunction)(WifiDirectDevice* pWifiDirectDevice, IWifiDirectDeviceListener* pDeviceListener, 
493                                 IWifiDirectGroupOwnerListener* pOwnerListener,  IWifiDirectGroupClientListener* pClientListener) = null;
494
495                         pUnRegisterListenerFunction = reinterpret_cast<void(*)(WifiDirectDevice* pWifiDirectDevice, IWifiDirectDeviceListener* pDeviceListener,
496                                         IWifiDirectGroupOwnerListener* pOwnerListener, IWifiDirectGroupClientListener* pClientListener)>
497                                         (dlsym(__pDllHandle, "_WifiDirectDeviceImpl_DeleteWifiDirectDevice"));
498
499                         if (pUnRegisterListenerFunction != null)
500                         {
501                                 pUnRegisterListenerFunction(__pDevice, null, this, null);
502                                 __pDevice = null;
503                         }
504                 }
505
506                 dlclose(__pDllHandle);
507         }
508         return r;
509 }
510
511 LocalDhcpServer*
512 _LocalDhcpServerImpl::GetLocalDhcpServer(const IList* pLocalDhcpServerList, const NetConnection& netConnection)
513 {
514         LocalDhcpServer* pLocalDhcpServer = null;
515
516         ClearLastResult();
517
518         int count = pLocalDhcpServerList->GetCount();
519
520         for (int index = 0; index < count; index++)
521         {
522                 pLocalDhcpServer = (LocalDhcpServer*)(pLocalDhcpServerList->GetAt(index));
523                 if (pLocalDhcpServer != null)
524                 {
525                         _LocalDhcpServerImpl* pLocalDhcpServerImpl = _LocalDhcpServerImpl::GetInstance(*pLocalDhcpServer);
526
527                         //check if dhcp server is for same connection as the argument netConnection.
528                         // and return the instance
529                         if (pLocalDhcpServerImpl != null && pLocalDhcpServerImpl->__pNetConnection == &netConnection)
530                         {
531                                 return pLocalDhcpServer;
532                         }
533                 }
534         }
535
536         return null;
537 }
538
539 result
540 _LocalDhcpServerImpl::SetLocalDhcpServerEventListener(ILocalDhcpServerEventListener* pListener)
541 {
542         result r = E_SUCCESS;
543
544         SysAssertf(__isConstructed == true, "Not yet constructed. Construct() should be called before use.");
545
546         r = __pLocalDhcpServerEvent->SetEventListener(pListener);
547
548         if (pListener)
549         {
550                 //register for event callbacks
551                 __pNetConnectionListener->SetConstructParams(__pLocalDhcpServerEvent.get(), __pUsbTetheringHandle);
552         }
553         else
554         {
555                 //unregister for event callback
556                 __pNetConnectionListener->SetConstructParams(null, null);
557         }
558
559         return r;
560 }
561
562 IList*
563 _LocalDhcpServerImpl::GetDhcpClientInfoListN(bool all)
564 {
565         result r = E_SUCCESS;
566         
567         ClearLastResult();
568         
569         ArrayList* pDhcpClientInfoList = null;
570         DhcpClientInfo* pDhcpClientInfo = null;
571
572         //check netconnection state before proceeding
573         SysTryReturn(NID_NET, __isConnectedNetwork == true, null, E_INVALID_STATE,
574                         "[%s] NET Connection already stopped.", GetErrorMessage(E_INVALID_STATE));
575
576         // create info list
577         pDhcpClientInfoList = new (std::nothrow) ArrayList();
578         SysTryReturn(NID_NET, pDhcpClientInfoList != null, null, E_OUT_OF_MEMORY,
579                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
580
581         r = pDhcpClientInfoList->Construct(_MAX_DHCP_CLIENT_COUNT);
582         SysTryCatch(NID_NET, r == E_SUCCESS, r = E_SYSTEM, r,
583                         "[%s] A system error has been occurred. Failed to construct DhcpClientInfoList.", GetErrorMessage(E_SYSTEM));
584
585         //check for connection type - USB or Wifi-Direct
586         if (__pNetConnection->GetNetAccountId() == _DEFAULT_USB_ACCOUNT_ID)
587         {
588                 SysLog(NID_NET, "Connection type is NET_BEARER_USB.");
589                 
590                 int err = TETHERING_ERROR_NONE;
591
592                 // get USB DHCP client info
593                 err = tethering_foreach_connected_clients(__pUsbTetheringHandle, TETHERING_TYPE_USB, OnUsbPeerConnected, pDhcpClientInfoList);
594                 SysLog(NID_NET, "The return value from tethering_for_each_connecetd_clients() is 0x%x", err);
595
596                 SysTryCatch(NID_NET, err == TETHERING_ERROR_NONE, r = E_SYSTEM, r,
597                     "[%s] A system error has been occurred getting DHCP USB Client info.", GetErrorMessage(E_SYSTEM));
598
599                 
600                 // if all is true add local server details to list
601                 if (all)
602                 {                       
603                         pDhcpClientInfo = _DhcpClientInfoImpl::CreateDhcpClientInfoN();
604
605                         SysTryCatch(NID_NET, pDhcpClientInfo != null, r = E_OUT_OF_MEMORY, r,
606                             "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
607
608                         r = GetLocalDhcpServerInfo(*pDhcpClientInfo);
609                         SysTryCatch(NID_NET, r == E_SUCCESS, , r, "[%s] GetDhcpUsbInterfaceInfo() failed.", GetErrorMessage(r));
610
611                         r = pDhcpClientInfoList->Add(*pDhcpClientInfo);
612                         SysTryCatch(NID_NET, r == E_SUCCESS, r = E_SYSTEM, r,
613                                         "[%s] A system error has been occurred. Failed to add DhcpClientInnfo to the list.", GetErrorMessage(E_SYSTEM));
614                 }
615                 // trim arrayList to current size
616                 pDhcpClientInfoList->Trim();
617
618         }
619         else if (__pNetConnection->GetNetAccountId() == _DEFAULT_WIFI_DIRECT_ACCOUNT_ID)
620         {
621                 SysLog(NID_NET, "Connection type is NET_BEARER_WIFI_DIRECT.");
622                 int err = WIFI_DIRECT_ERROR_NONE;
623
624                 // get WIFI Direct DHCP client info
625                 err = wifi_direct_foreach_connected_peers(OnWifiDirectPeerConnected, pDhcpClientInfoList);
626                 SysLog(NID_NET, "The return value from wifi_direct_foreach_connected_peers() is 0x%x", err);
627
628                 SysTryCatch(NID_NET, err == WIFI_DIRECT_ERROR_NONE, r = E_SYSTEM, r,
629                     "[%s] A system error has been occurred getting DHCP WIfi-Direct Client info.", GetErrorMessage(E_SYSTEM));
630
631                 //check if group owner, just for debugging
632                 bool isOwner = false;
633                 wifi_direct_is_group_owner(&isOwner);
634                 if (isOwner)
635                 {
636                         SysLog(NID_NET, "The device is group owner of wifi-direct.");
637                 }
638                 else
639                 {
640                         SysLog(NID_NET, "The device is group memeber of wifi-direct");  
641                 }
642
643                 // if all  is true add local server details to list
644                 if (all)
645                 {
646                         // add local server details to the list
647                         pDhcpClientInfo = _DhcpClientInfoImpl::CreateDhcpClientInfoN();
648
649                         SysTryCatch(NID_NET, pDhcpClientInfo != null, r = E_OUT_OF_MEMORY, r,
650                             "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
651
652                         r = GetLocalDhcpServerInfo(*pDhcpClientInfo);
653                         SysTryCatch(NID_NET, r == E_SUCCESS, , r, "[%s] GetLocalDhcpServerInfo() failed.", GetErrorMessage(r));
654
655                         r = pDhcpClientInfoList->Add(*pDhcpClientInfo);
656                         SysTryCatch(NID_NET, r == E_SUCCESS, r = E_SYSTEM, r,
657                                         "[%s] A system error has been occurred. Failed to add DhcpClientInfo to the list.", GetErrorMessage(E_SYSTEM));
658                 }
659                 // trim arrayList to current size
660                 pDhcpClientInfoList->Trim();
661
662         }
663         else
664         {
665                 SysLogException(NID_NET, E_SYSTEM, "Bearer not supported for DHCP");
666                 
667                 r = E_SYSTEM;
668                 goto CATCH;
669         }
670
671         return pDhcpClientInfoList;
672
673 CATCH:
674         if (pDhcpClientInfo)
675         {
676                 delete pDhcpClientInfo;
677                 pDhcpClientInfo = null;
678         }
679         if (pDhcpClientInfoList)
680         {
681                 pDhcpClientInfoList->RemoveAll(true);
682                 delete pDhcpClientInfoList;
683         }
684         return null;
685 }
686
687 result
688 _LocalDhcpServerImpl::ConvertDhcpClientInfo(tethering_client_h clientHandle, DhcpClientInfo& dhcpClientInfo)
689 {
690         result r = E_SUCCESS;
691         
692         _DhcpClientInfoImpl* pDhcpClientInfoImpl = null;
693         int err = TETHERING_ERROR_NONE;
694         char *pClientName = null;
695         char *pMacAddress = null;
696         char *pIpAddress = null;
697
698         pDhcpClientInfoImpl = _DhcpClientInfoImpl::GetInstance(dhcpClientInfo);
699         SysTryReturnResult(NID_NET, pDhcpClientInfoImpl != null, E_SYSTEM,
700                         "A system error has been occurred. Failed to get DhcpClientInfo instance.");
701         
702         // set peer name
703         err =  tethering_client_get_name(clientHandle, &pClientName);
704         SysLog(NID_NET, "Error value from tethering_client_get_name() is 0x%x", err);
705         SysSecureLog(NID_NET, "Network interface name is %s", pClientName);
706         
707         SysTryReturnResult(NID_NET, err == TETHERING_ERROR_NONE, E_SYSTEM,
708                         "A system error has been occurred. Failed to get tethering client name.");
709
710         pDhcpClientInfoImpl->__dhcpClientName = String(pClientName);
711         
712         //set mac-address
713         err =  tethering_client_get_mac_address(clientHandle, &pMacAddress);
714         SysLog(NID_NET, "Error value from tethering_client_get_mac_address() is 0x%x", err);
715         SysSecureLog(NID_NET, "Mac address is %s", pMacAddress);
716         
717         SysTryCatch(NID_NET, err == TETHERING_ERROR_NONE, r = E_SYSTEM, r,
718                         "[%s] A system error has been occurred. tethering_client_get_mac_address() returned error.", GetErrorMessage(E_SYSTEM));
719                         
720         pDhcpClientInfoImpl->__macAddress = ConvertMacAddress(pMacAddress);
721         
722         //set ip-address
723         err =  tethering_client_get_ip_address(clientHandle, TETHERING_ADDRESS_FAMILY_IPV4, &pIpAddress);
724         SysLog(NID_NET, "Error value from tethering_client_get_ip_address() is 0x%x", err);
725         SysSecureLog(NID_NET, "Ip address is %s", pIpAddress);
726                 
727         SysTryCatch(NID_NET, err == TETHERING_ERROR_NONE, r = E_SYSTEM, r,
728                         "[%s] A system error has been occurred. tethering_client_get_ip_address() returned error.", GetErrorMessage(E_SYSTEM));
729
730         pDhcpClientInfoImpl->__pLocalAddress.reset(new (std::nothrow) Ip4Address(pIpAddress));
731         
732         SysTryCatch(NID_NET, pDhcpClientInfoImpl->__pLocalAddress != null, r = E_OUT_OF_MEMORY, r,
733                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
734         
735         
736 CATCH:          
737         if (pClientName != null)
738         {
739                 free(pClientName);
740         }
741         
742         if (pIpAddress != null)
743         {
744                 free(pIpAddress);
745         }
746
747         if (pMacAddress != null)
748         {
749                 free(pMacAddress);
750         }
751
752         return r;
753 }
754
755 result
756 _LocalDhcpServerImpl::GetLocalDhcpServerInfo(DhcpClientInfo& dhcpClientInfo)
757 {
758         result r = E_SUCCESS;
759         
760         _DhcpClientInfoImpl* pDhcpClientInfoImpl = null;
761
762         char *pInterfaceName = null;
763         char *pMacAddress = null;
764         char *pIpAddress = null;
765
766         pDhcpClientInfoImpl = _DhcpClientInfoImpl::GetInstance(dhcpClientInfo);
767         SysTryReturnResult(NID_NET, pDhcpClientInfoImpl != null, E_SYSTEM, "A system error has been occurred. Failed to get DhcpClientInfo instance.");
768         
769         //check for connection type - USB or Wifi-Direct
770         if (__pNetConnection->GetNetAccountId() == _DEFAULT_USB_ACCOUNT_ID)
771         {
772                 int err = TETHERING_ERROR_NONE;
773                 // set peer name
774                 err =  tethering_get_network_interface_name(__pUsbTetheringHandle, TETHERING_TYPE_USB, &pInterfaceName);
775                 SysLog(NID_NET, "Error value from tethering_get_name() is 0x%x", err);
776                 SysSecureLog(NID_NET, "Network interface name is %s", pInterfaceName);
777         
778                 SysTryReturnResult(NID_NET, err == TETHERING_ERROR_NONE, E_SYSTEM,
779                                 "A system error has been occurred. tethering_get_name() returned error.");
780         
781                 //set mac-address
782                 err =  tethering_get_mac_address(__pUsbTetheringHandle, TETHERING_TYPE_USB, &pMacAddress);
783                 SysLog(NID_NET, "Error value from tethering_get_mac_address() is 0x%x", err);
784                 SysSecureLog(NID_NET, "Mac address is %s", pMacAddress);
785         
786                 SysTryCatch(NID_NET, err == TETHERING_ERROR_NONE, r = E_SYSTEM, r,
787                                 "[%s] A system error has been occurred. tethering_get_mac_address returned error.", GetErrorMessage(E_SYSTEM));
788                         
789                 //set ip-address
790                 err =  tethering_get_ip_address(__pUsbTetheringHandle, TETHERING_TYPE_USB, TETHERING_ADDRESS_FAMILY_IPV4, &pIpAddress);
791                 SysLog(NID_NET, "Error value from tethering_get_ip_address() is 0x%x", err);
792                 SysSecureLog(NID_NET, "Ip address is %s", pIpAddress);
793                 
794                 SysTryCatch(NID_NET, err == TETHERING_ERROR_NONE, r = E_SYSTEM, r,
795                                 "[%s] A system error has been occurred. tethering_get_ip_address() returned error.", GetErrorMessage(E_SYSTEM));
796         }
797         else if (__pNetConnection->GetNetAccountId() == _DEFAULT_WIFI_DIRECT_ACCOUNT_ID)
798         {
799                 int err = WIFI_DIRECT_ERROR_NONE;
800                 // set interface name
801                 err = wifi_direct_get_network_interface_name(&pInterfaceName);
802                 SysLog(NID_NET, "Error value from  wifi_direct_get_network_interface_name() is 0x%x", err);
803                 SysSecureLog(NID_NET, "Network interface name is %s", pInterfaceName);
804         
805                 SysTryReturnResult(NID_NET, err == WIFI_DIRECT_ERROR_NONE, E_SYSTEM,
806                                         "A system error has been occurred. wifi_direct_get_network_interface_name() returned error.");
807         
808                 //set mac-address
809                 err = wifi_direct_get_mac_address(&pMacAddress);
810                 SysLog(NID_NET, "Error value from wifi_direct_get_mac_address() is 0x%x", err);
811                 SysSecureLog(NID_NET, "Mac address is %s", pMacAddress);
812         
813                 SysTryCatch(NID_NET, err == WIFI_DIRECT_ERROR_NONE, r = E_SYSTEM, r,
814                                 "[%s] A system error has been occurred. wifi_direct_get_mac_address() returned error.", GetErrorMessage(E_SUCCESS));
815                         
816                 //set ip-address
817                 err = wifi_direct_get_ip_address(&pIpAddress);
818                 SysLog(NID_NET, "Error value from wifi_direct_get_ip_address() is 0x%x", err);
819                 SysSecureLog(NID_NET, "Ip address is %s", pIpAddress);
820                 
821                 SysTryCatch(NID_NET, err == WIFI_DIRECT_ERROR_NONE, r = E_SYSTEM, r,
822                                 "[%s] A system error has been occurred. wifi_direct_get_ip_address() returned error.", GetErrorMessage(E_SYSTEM));
823         }
824         else
825         {
826                 SysLogException(NID_NET, r = E_SYSTEM, "Bearer not supported for DHCP");
827                 return r;                       
828         }
829
830         pDhcpClientInfoImpl->__dhcpClientName = String(pInterfaceName);
831
832         pDhcpClientInfoImpl->__macAddress = ConvertMacAddress(pMacAddress);
833         
834         pDhcpClientInfoImpl->__pLocalAddress.reset(new (std::nothrow) Ip4Address(pIpAddress));
835
836         SysTryCatch(NID_NET, pDhcpClientInfoImpl->__pLocalAddress != null, r = E_OUT_OF_MEMORY, r,
837                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
838         
839
840 CATCH:          
841         if (pInterfaceName != null)
842         {
843                 free(pInterfaceName);
844         }
845         
846         if (pIpAddress != null)
847         {
848                 free(pIpAddress);
849         }
850
851         if (pMacAddress != null)
852         {
853                 free(pMacAddress);
854         }
855
856         return r;
857 }
858
859 String
860 _LocalDhcpServerImpl::ConvertMacAddress(char* pMacAddress)
861 {
862         if (!pMacAddress)
863         {
864                 return String("");
865         }
866
867         // format string
868         char* pTempMacAddress = pMacAddress;
869
870         while (*pTempMacAddress != '\0')
871         {
872                 if (*pTempMacAddress == _PLATFORM_MAC_ADDRESS_DELIMITER)
873                 {
874                         *pTempMacAddress = _MAC_ADDRESS_DELIMITER;
875                 }
876                 ++pTempMacAddress;
877         }
878
879         return String(pMacAddress);
880 }
881
882 void
883 _LocalDhcpServerImpl::OnWifiDirectClientAssociated(WifiDirectDeviceId localDeviceId, const WifiDirectDeviceInfo& wifiDirectClientInfo)
884 {
885         SysLog(NID_NET, "LocalDhcpServer received an event, OnWifiDirectClientAssociated.");
886
887         result r = E_SUCCESS;
888
889         _LocalDhcpServerEventArg* pDhcpServerEventArg = null;
890         _NetDhcpServerEventType eventCode = NET_DHCP_SERVER_EVENT_CONNECT;
891                         
892         String(*pGetMacAddressFunction)(const WifiDirectDeviceInfo& deviceinfo) = null;
893
894         // Get MAC address of the client
895         pGetMacAddressFunction = reinterpret_cast<String(*)(const WifiDirectDeviceInfo& deviceinfo)>(dlsym(__pDllHandle, "_WifiDirectDeviceInfoImpl_GetMacAddress"));
896         SysTryReturnVoidResult(NID_NET, pGetMacAddressFunction != null, E_SYSTEM,
897                         "[%s] A system error has been occurred. Failed to get a function pointer.", GetErrorMessage(E_SYSTEM));
898                 
899         String macAddress = pGetMacAddressFunction(wifiDirectClientInfo);
900
901         //check if we have already the info in our local list           
902         
903         if (GetDhcpConnectedPeerInfo(macAddress) == null)
904         {                       
905                 // not found, create DhcpClientInfo
906                 unique_ptr<DhcpClientInfo> pDhcpClientInfo(_DhcpClientInfoImpl::CreateDhcpClientInfoN());
907                 SysTryReturnVoidResult(NID_NET, pDhcpClientInfo != null, E_OUT_OF_MEMORY,
908                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
909
910                 r = ConvertDhcpClientInfo(wifiDirectClientInfo,*pDhcpClientInfo);
911                 SysTryReturnVoidResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
912                                 "[%s] A system error has been occurred. Failed to retrieve DhcpClientInfo.", GetErrorMessage(E_SYSTEM));
913
914                 //add the info into local list
915                 r = AddDhcpConnectedPeerInfo(*pDhcpClientInfo);
916                 SysTryReturnVoidResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
917                                 "[%s] A system error has been occurred. Failed to add DhcpConnectedPeerInfo.", GetErrorMessage(E_SYSTEM));
918                 
919                 // fire event
920                 pDhcpServerEventArg = new (std::nothrow) _LocalDhcpServerEventArg(eventCode, *pDhcpClientInfo);
921                 SysTryReturnVoidResult(NID_NET, pDhcpServerEventArg != null, E_OUT_OF_MEMORY,
922                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
923
924                 pDhcpClientInfo.release();
925
926                 __pLocalDhcpServerEvent->Fire(*pDhcpServerEventArg);
927         }
928         
929         return;
930 }
931
932 void
933 _LocalDhcpServerImpl::OnWifiDirectClientDisassociated(WifiDirectDeviceId localDeviceId, const WifiDirectDeviceInfo& wifiDirectClientInfo, WifiDirectAssociationTerminationReason reason)
934 {
935         SysLog(NID_NET, "LocalDhcpServer received an event, OnWifiDirectClientDisassociated.");
936         
937         _LocalDhcpServerEventArg* pDhcpServerEventArg = null;
938         _NetDhcpServerEventType eventCode = NET_DHCP_SERVER_EVENT_DISCONNECT;   
939         String(*pGetMacAddressFunction)(const WifiDirectDeviceInfo& deviceinfo) = null;
940
941         // Get MAC address of the client
942         pGetMacAddressFunction = reinterpret_cast<String(*)(const WifiDirectDeviceInfo& deviceinfo)>(dlsym(__pDllHandle, "_WifiDirectDeviceInfoImpl_GetMacAddress"));
943         SysTryReturnVoidResult(NID_NET, pGetMacAddressFunction != null, E_SYSTEM,
944                         "[%s] A system error has been occurred. Failed to get a function pointer.", GetErrorMessage(E_SYSTEM));
945
946         String macAddress = pGetMacAddressFunction(wifiDirectClientInfo);
947
948         //check if we have already the info in our local list
949         unique_ptr<DhcpClientInfo> pDhcpClientInfo(GetDhcpConnectedPeerInfo(macAddress, true));
950         SysTryReturnVoidResult(NID_NET, pDhcpClientInfo != null, E_SYSTEM,
951                         "[%s] A system error has been occurred. Failed to retrieve DhcpClientInfo.", GetErrorMessage(E_SYSTEM));
952
953         //fire event
954         pDhcpServerEventArg = new (std::nothrow) _LocalDhcpServerEventArg(eventCode, *pDhcpClientInfo);
955         SysTryReturnVoidResult(NID_NET, pDhcpServerEventArg != null, E_OUT_OF_MEMORY,
956                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
957
958         __pLocalDhcpServerEvent->Fire(*pDhcpServerEventArg);
959 }
960
961 void
962 _LocalDhcpServerImpl::OnWifiDirectGroupDestroyed(WifiDirectDeviceId localDeviceId, result r)
963 {
964         SysLog(NID_NET, "LocalDhcpServer received an event, OnWifiDirectGroupDestroyed.");
965 }
966
967 void
968 _LocalDhcpServerImpl::OnWifiDirectGroupMemberInfoServiceStarted(WifiDirectDeviceId localDeviceId, const NetConnection* pNetConnection, result r)
969 {
970         SysLog(NID_NET, "LocalDhcpServer received an event, OnWifiDirectGroupMemberInfoServiceStarted.");
971 }
972
973 void
974 _LocalDhcpServerImpl::OnWifiDirectGroupMemberInfoServiceStopped(WifiDirectDeviceId localDeviceId, result r)
975 {
976         SysLog(NID_NET, "LocalDhcpServer received an event, OnWifiDirectGroupMemberInfoServiceStopped.");
977 }
978
979 result
980 _LocalDhcpServerImpl::ConvertDhcpClientInfo(const WifiDirectDeviceInfo& wifiDirectdeviceInfo, DhcpClientInfo& dhcpClientInfo)
981 {
982         result r = E_SUCCESS;   
983         _DhcpClientInfoImpl* pDhcpClientInfoImpl = null;
984         
985         String(*pGetDeviceNameFunction)(const WifiDirectDeviceInfo& deviceinfo) = null;
986         String(*pGetMacAddressFunction)(const WifiDirectDeviceInfo& deviceinfo) = null;
987         IpAddress*(*pGetIpAddressFunction)(const WifiDirectDeviceInfo& deviceinfo) = null;
988
989         pGetDeviceNameFunction = reinterpret_cast<String(*)(const WifiDirectDeviceInfo& deviceinfo)>
990                         (dlsym(__pDllHandle, "_WifiDirectDeviceInfoImpl_GetDeviceName"));
991         SysTryReturnResult(NID_NET, pGetDeviceNameFunction != null, E_SYSTEM,
992                         "A system error has been occurred. Failed to get a function pointer.");
993         
994         pGetMacAddressFunction = reinterpret_cast<String(*)(const WifiDirectDeviceInfo& deviceinfo)>
995                         (dlsym(__pDllHandle, "_WifiDirectDeviceInfoImpl_GetMacAddress"));
996         SysTryReturnResult(NID_NET, pGetMacAddressFunction != null, E_SYSTEM,
997                         "A system error has been occurred. Failed to get a function pointer.");
998         
999         pGetIpAddressFunction = reinterpret_cast<IpAddress*(*)(const WifiDirectDeviceInfo& deviceinfo)>
1000                         (dlsym(__pDllHandle, "_WifiDirectDeviceInfoImpl_GetIpAddress"));
1001         SysTryReturnResult(NID_NET, pGetIpAddressFunction != null, E_SYSTEM,
1002                         "A system error has been occurred. Failed to get a function pointer.");
1003
1004         pDhcpClientInfoImpl = _DhcpClientInfoImpl::GetInstance(dhcpClientInfo);
1005         SysTryReturnResult(NID_NET, pDhcpClientInfoImpl != null, E_SYSTEM,
1006                         "A system error has been occurred. Failed to get DhcpClientInfo instance.");
1007
1008         pDhcpClientInfoImpl->__dhcpClientName = pGetDeviceNameFunction(wifiDirectdeviceInfo);
1009         pDhcpClientInfoImpl->__macAddress = pGetMacAddressFunction(wifiDirectdeviceInfo);
1010
1011         const Ip4Address* ipAddress = dynamic_cast<const Ip4Address*>(pGetIpAddressFunction(wifiDirectdeviceInfo));
1012         SysTryReturnResult(NID_NET, ipAddress != null, E_SYSTEM, "A system error has been occurred. IP Address is null.");
1013         
1014         pDhcpClientInfoImpl->__pLocalAddress.reset(new (std::nothrow) Ip4Address(*ipAddress));
1015         
1016         SysTryReturnResult(NID_NET, pDhcpClientInfoImpl->__pLocalAddress != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1017         
1018         return r;
1019 }
1020
1021 bool
1022 _LocalDhcpServerImpl::OnWifiDirectPeerConnected(wifi_direct_connected_peer_info_s* pPeerInfo, void* pUserData)
1023 {
1024         result r = E_SUCCESS;
1025
1026         ArrayList* pDhcpclientInfoList = static_cast<ArrayList*>(pUserData);
1027         
1028         //check arguments
1029         SysTryReturn(NID_NET, pDhcpclientInfoList != null, false, E_SYSTEM,
1030                         "[%s] A system error has been occurred. pDhcpclientInfoList is null.", GetErrorMessage(E_SYSTEM));
1031         SysTryReturn(NID_NET, pPeerInfo != null, false, E_SYSTEM,
1032                         "[%s] A system error has been occurred. pPeerInfo is null.", GetErrorMessage(E_SYSTEM));
1033
1034         // create DhcpClientInfo and add to local list
1035         unique_ptr<DhcpClientInfo> pDhcpClientInfo(_DhcpClientInfoImpl::CreateDhcpClientInfoN());
1036
1037         SysTryReturn(NID_NET, pDhcpClientInfo != null, false, E_OUT_OF_MEMORY,
1038                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1039
1040         r = ConvertDhcpClientInfo(pPeerInfo, *pDhcpClientInfo);
1041         SysTryReturn(NID_NET, r == E_SUCCESS, false, r, "[%s] Failed to convert DhcpWifiDirectClientInfo.", GetErrorMessage(r));
1042
1043         r = pDhcpclientInfoList->Add(*pDhcpClientInfo);
1044         SysTryReturn(NID_NET, r == E_SUCCESS, false, r, "[%s] Failed to add DhcpClientInfo to the list.", GetErrorMessage(r));
1045
1046         pDhcpClientInfo.release();
1047
1048         return true;
1049 }
1050
1051 bool
1052 _LocalDhcpServerImpl::OnUsbPeerConnected(tethering_client_h clientHandle, void* pUserData)
1053 {
1054         result r = E_SUCCESS;
1055
1056         ArrayList* pDhcpclientInfoList = static_cast<ArrayList*>(pUserData);
1057         
1058         //check arguments
1059         SysTryReturn(NID_NET, pDhcpclientInfoList != null, false, E_SYSTEM,
1060                         "[%s] A system error has been occurred. pDhcpclientInfoList is null.", GetErrorMessage(E_SYSTEM));
1061         SysTryReturn(NID_NET, clientHandle != null, false, E_SYSTEM,
1062                         "[%s] A system error has been occurred. clientHandle is null.", GetErrorMessage(E_SYSTEM));
1063
1064         // create DhcpClientInfo and add to local list
1065         unique_ptr<DhcpClientInfo> pDhcpClientInfo(_DhcpClientInfoImpl::CreateDhcpClientInfoN());
1066
1067         SysTryReturn(NID_NET, pDhcpClientInfo != null, false, E_OUT_OF_MEMORY,
1068                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1069
1070         r = _LocalDhcpServerImpl::ConvertDhcpClientInfo(clientHandle, *pDhcpClientInfo);
1071         SysTryReturn(NID_NET, r == E_SUCCESS, false, r, "[%s] Failed to convert DhcpClientInfo.", GetErrorMessage(r));
1072
1073         r = pDhcpclientInfoList->Add(*pDhcpClientInfo);
1074         SysTryReturn(NID_NET, r == E_SUCCESS, false, r, "[%s] Failed to add DhcpClientInfo to the list.", GetErrorMessage(r));
1075
1076         pDhcpClientInfo.release();
1077
1078         return true;
1079 }
1080
1081 result
1082 _LocalDhcpServerImpl::ConvertDhcpClientInfo(const wifi_direct_connected_peer_info_s* pPeerInfo, DhcpClientInfo& dhcpClientInfo)
1083 {
1084         result r = E_SUCCESS;
1085
1086         _DhcpClientInfoImpl* pDhcpClientInfoImpl = null;
1087
1088         pDhcpClientInfoImpl = _DhcpClientInfoImpl::GetInstance(dhcpClientInfo);
1089         SysTryReturnResult(NID_NET, pDhcpClientInfoImpl != null, E_SYSTEM,
1090                         "A system error has been occurred. Failed to get DhcpClientInfo instance.");
1091
1092         pDhcpClientInfoImpl->__dhcpClientName = String(pPeerInfo->device_name);
1093         pDhcpClientInfoImpl->__macAddress = ConvertMacAddress((char*)pPeerInfo->mac_address);
1094
1095         pDhcpClientInfoImpl->__pLocalAddress.reset(new (std::nothrow) Ip4Address(pPeerInfo->ip_address));
1096         SysTryReturnResult(NID_NET, pDhcpClientInfoImpl->__pLocalAddress != null, E_OUT_OF_MEMORY, "Memory allocation failed");
1097         
1098         return r;
1099 }
1100
1101 DhcpClientInfo*
1102 _LocalDhcpServerImpl::GetDhcpConnectedPeerInfo(const String& macAddress, bool remove)
1103 {
1104         DhcpClientInfo* pDhcpClientInfo = null;
1105
1106         ClearLastResult();
1107
1108         SysTryReturn(NID_NET, __pDhcpConnectedPeerInfoList != null, null, E_SYSTEM,
1109                         "[%s] A system error has been occurred. Client Info List is null.", GetErrorMessage(E_SYSTEM));
1110
1111         //search for the given mac-address
1112         for (int count = 0; count < __pDhcpConnectedPeerInfoList->GetCount(); count++)
1113         {
1114                 pDhcpClientInfo = dynamic_cast<DhcpClientInfo*>(__pDhcpConnectedPeerInfoList->GetAt(count));
1115                 if (pDhcpClientInfo != null && pDhcpClientInfo->GetMacAddress() == macAddress)
1116                 {
1117                         if (remove)
1118                         {
1119                                 __pDhcpConnectedPeerInfoList->Remove(*pDhcpClientInfo, false);
1120                         }
1121                         return pDhcpClientInfo;
1122                 }
1123         }
1124         return null;
1125 }
1126
1127 result
1128 _LocalDhcpServerImpl::AddDhcpConnectedPeerInfo(const DhcpClientInfo& dhcpClientInfo)
1129 {
1130         result r = E_SUCCESS;
1131         
1132         // create list for dhcp client info, if not created
1133         if (__pDhcpConnectedPeerInfoList == null)
1134         {
1135                 unique_ptr<Tizen::Base::Collection::ArrayList, _CollectionDeleter> pDhcpConnectedPeerInfoList(new (std::nothrow) ArrayList());
1136                 SysTryReturnResult(NID_NET, pDhcpConnectedPeerInfoList != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1137
1138                 r = pDhcpConnectedPeerInfoList->Construct(_MAX_DHCP_CLIENT_COUNT);
1139                 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
1140                                 "A system error has been occurred. Failed to construct DhcpConnectedPeerInfoList.");
1141                 __pDhcpConnectedPeerInfoList = std::move(pDhcpConnectedPeerInfoList);
1142         }
1143
1144         r = __pDhcpConnectedPeerInfoList->Add(dhcpClientInfo);
1145         SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
1146                         "A system error has been occurred. Failed to add DhcpClientInfo to the list.");
1147
1148         return r;
1149 }
1150
1151 IList*
1152 _LocalDhcpServerImpl::GetDhcpConnectedPeerInfoList()
1153 {       
1154         return __pDhcpConnectedPeerInfoList.get();
1155 }
1156
1157 void
1158 _LocalDhcpServerImpl::SetDhcpConnectedPeerInfoList(IList* pList)
1159 {       
1160         __pDhcpConnectedPeerInfoList.reset(dynamic_cast<ArrayList*>(pList));
1161 }
1162
1163 _LocalDhcpServerImpl*
1164 _LocalDhcpServerImpl::GetInstance(LocalDhcpServer& localDhcpServer)
1165 {
1166         return localDhcpServer.__pLocalDhcpServerImpl;
1167 }
1168
1169 const _LocalDhcpServerImpl*
1170 _LocalDhcpServerImpl::GetInstance(const LocalDhcpServer& localDhcpServer)
1171 {
1172         return localDhcpServer.__pLocalDhcpServerImpl;
1173 }
1174
1175 }} // Tizen::Net