Rearrange memory ownership of found device
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-peer.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 /**
21  * This file implements wifi direct peer functions.
22  *
23  * @file                wifi-direct-peer.c
24  * @author      Gibyoung Kim (lastkgb.kim@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <time.h>
31 #include <string.h>
32
33 #include <glib.h>
34
35 #include <wifi-direct.h>
36
37 #include "wifi-direct-ipc.h"
38 #include "wifi-direct-manager.h"
39 #include "wifi-direct-oem.h"
40 #include "wifi-direct-util.h"
41 #include "wifi-direct-peer.h"
42 #include "wifi-direct-session.h"
43 #include "wifi-direct-log.h"
44
45 void wfd_peer_destroy(wfd_device_s *peer)
46 {
47         if (!peer)
48                 return;
49
50         if (peer->vsie)
51                 g_free(peer->vsie);
52
53         g_free(peer);
54
55         return;
56 }
57
58
59 wfd_device_s *wfd_add_peer(void *data, unsigned char *dev_addr, char *dev_name)
60 {
61         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
62         wfd_manager_s *manager = (wfd_manager_s*) data;
63         wfd_device_s *peer = NULL;
64
65         if (!data || !dev_addr || !dev_name) {
66                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
67                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
68                 return NULL;
69         }
70
71         peer = wfd_peer_find_by_dev_addr(manager, dev_addr);
72         if (peer) {
73                 WDS_LOGD("Peer already exist[" MACSECSTR "]", MAC2SECSTR(dev_addr));//LCOV_EXCL_LINE
74                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
75                 return peer;
76         }
77
78         peer = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
79         if (peer == NULL) {
80                 WDS_LOGE("Failed to allocate memory for peer[" MACSTR "]", MAC2STR(dev_addr));//LCOV_EXCL_LINE
81                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
82                 return NULL;
83         }
84         memcpy(peer->dev_addr, dev_addr, MACADDR_LEN);
85         g_strlcpy(peer->dev_name, dev_name, DEV_NAME_LEN + 1);
86         peer->is_p2p = TRUE;
87
88         manager->peers = g_list_prepend(manager->peers, peer);
89         manager->peer_count++;
90         WDS_LOGD("peer_count[%d]", manager->peer_count);
91         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
92         return peer;
93 }
94
95 int wfd_remove_peer(void *data, unsigned char *dev_addr)
96 {
97         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
98         wfd_manager_s *manager = (wfd_manager_s*) data;
99         wfd_device_s *peer = NULL;
100
101         if (!data || !dev_addr) {
102                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
103                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
104                 return -1;
105         }
106
107         peer = wfd_peer_find_by_dev_addr(manager, dev_addr);
108         if (!peer) {
109                 WDS_LOGE("Failed to find peer device");//LCOV_EXCL_LINE
110                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
111                 return -1;
112         }
113
114         manager->peers = g_list_remove(manager->peers, peer);
115         manager->peer_count--;
116
117         wfd_peer_destroy(peer);
118
119         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
120         return 0;
121 }
122
123 int wfd_update_peer_time(void*data, unsigned char *peer_addr)
124 {
125         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
126         wfd_manager_s *manager = (wfd_manager_s*) data;
127         wfd_device_s *peer = NULL;
128
129         if (!manager || !peer_addr) {
130                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
131                 return -1;
132         }
133
134         peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
135         if (!peer) {
136                 WDS_LOGD("Peer not found [" MACSECSTR "]", MAC2SECSTR(peer_addr));//LCOV_EXCL_LINE
137                 return -1;
138         }
139
140 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
141         wfd_util_get_current_time(&peer->time);
142 #else
143         struct timeval tval;
144         gettimeofday(&tval, NULL);
145         peer->time = tval.tv_sec;
146 #endif
147
148         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
149         return 0;
150 }
151
152 int wfd_update_peer(void *data, wfd_device_s *peer)
153 {
154         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
155         wfd_manager_s *manager = (wfd_manager_s*) data;
156         wfd_oem_device_s *oem_dev = NULL;
157         int res = 0;
158
159         if (!peer) {
160                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
161                 return -1;
162         }
163
164 //LCOV_EXCL_START
165         //wfd_update_peer takes responsibility of the oem_dev' memory ownership.
166         res = wfd_oem_get_peer_info(manager->oem_ops, peer->dev_addr, &oem_dev);
167         if (res < 0 || !oem_dev) {
168                 WDS_LOGE("Failed to get peer information");//LCOV_EXCL_LINE
169                 return -1;
170         }
171
172         if (oem_dev->age > 30 && peer->state == WFD_PEER_STATE_DISCOVERED) {
173                 WDS_LOGE("Too old age to update peer");//LCOV_EXCL_LINE
174                 if (oem_dev->vsie)
175                         g_free(oem_dev->vsie);
176                 g_free(oem_dev);
177                 return -1;
178         }
179         g_strlcpy(peer->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
180         if (!ISZEROMACADDR(oem_dev->intf_addr))
181                 memcpy(peer->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
182         memcpy(peer->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
183         peer->channel = oem_dev->channel;
184         peer->dev_role = oem_dev->dev_role;
185         peer->config_methods = oem_dev->config_methods;
186         peer->pri_dev_type = oem_dev->pri_dev_type;
187         peer->sec_dev_type = oem_dev->sec_dev_type;
188         peer->dev_flags = oem_dev->dev_flags;
189         peer->group_flags = oem_dev->group_flags;
190         peer->wps_mode =  oem_dev->wps_mode;
191
192         if (manager->is_wifi_display_supported)
193                 memcpy(&(peer->display), &(oem_dev->display), sizeof(wfd_display_s));
194
195         if (oem_dev->vsie)
196                 g_free(oem_dev->vsie);
197
198         g_free(oem_dev);
199
200 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
201         wfd_util_get_current_time(&peer->time);
202 #else
203         struct timeval tval;
204         gettimeofday(&tval, NULL);
205         peer->time = tval.tv_sec;
206 #endif
207 //LCOV_EXCL_STOP
208         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
209         return 0;
210 }
211
212 int wfd_peer_clear_all(void *data)
213 {
214         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
215         wfd_manager_s *manager = (wfd_manager_s*) data;
216         wfd_device_s *peer = NULL;
217         wfd_session_s *session = NULL;
218         GList *temp = NULL;
219
220         if (!manager)
221                 return -1;
222
223         if (manager->peer_count == 0) {
224                 WDS_LOGD("Peer not exist");//LCOV_EXCL_LINE
225                 return -1;
226         }
227
228         temp = g_list_first(manager->peers);
229         while (temp) {
230                 peer = (wfd_device_s*) temp->data;
231                 wfd_peer_destroy(peer);
232                 temp = g_list_next(temp);
233                 manager->peer_count--;
234         }
235
236         if (manager->peers) {
237                 g_list_free(manager->peers);
238                 manager->peers = NULL;
239         }
240
241         if (manager->peer_count) {
242                 WDS_LOGE("Peer count is not synced. left count=%d", manager->peer_count);//LCOV_EXCL_LINE
243                 manager->peer_count = 0;
244                 return 1;
245         }
246
247         session = manager->session;
248         if (session)
249                 session->peer = NULL;
250
251         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
252         return 0;
253 }
254
255 wfd_device_s *wfd_peer_find_by_dev_addr(void *data, unsigned char *dev_addr)
256 {
257         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
258         wfd_manager_s *manager = (wfd_manager_s*) data;
259         wfd_device_s *peer = NULL;
260         GList *temp = NULL;
261
262         if (!data || !dev_addr) {
263                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
264                 return NULL;
265         }
266
267         if (manager->peer_count == 0) {
268                 WDS_LOGE("There is no peer data");//LCOV_EXCL_LINE
269                 return NULL;
270         }
271
272         temp = g_list_first(manager->peers);
273         while (temp) {
274                 peer = temp->data;
275                 if (!memcmp(peer->dev_addr, dev_addr, MACADDR_LEN)) {
276                         WDS_LOGD("Peer device found[" MACSECSTR "]", MAC2SECSTR(dev_addr));//LCOV_EXCL_LINE
277                         break;
278                 }
279                 temp = g_list_next(temp);
280                 peer = NULL;
281         }
282
283         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
284         return peer;
285 }
286
287 #if 0
288 wfd_device_s *wfd_peer_find_by_intf_addr(void *data, unsigned char *intf_addr)
289 {
290         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
291         wfd_manager_s *manager = (wfd_manager_s*) data;
292         wfd_device_s *peer = NULL;
293         GList *temp = NULL;
294
295         if (!data || !intf_addr) {
296                 WDS_LOGE("Invalid parameter");
297                 return NULL;
298         }
299
300         if (manager->peer_count == 0) {
301                 WDS_LOGE("There is no peer data");
302                 return NULL;
303         }
304
305         temp = g_list_first(manager->peers);
306         while (temp) {
307                 peer = temp->data;
308                 if (!memcmp(peer->intf_addr, intf_addr, MACADDR_LEN)) {
309                         WDS_LOGD("Peer device found[" MACSECSTR "]", MAC2SECSTR(intf_addr));
310                         break;
311                 }
312                 temp = g_list_next(temp);
313                 peer = NULL;
314         }
315
316         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
317         return peer;
318 }
319 #endif
320
321 wfd_device_s *wfd_peer_find_by_addr(void *data, unsigned char *addr)
322 {
323         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
324         wfd_manager_s *manager = (wfd_manager_s*) data;
325         wfd_device_s *peer = NULL;
326         GList *temp = NULL;
327
328         if (!data || !addr) {
329                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
330                 return NULL;
331         }
332
333         if (manager->peer_count == 0) {
334                 WDS_LOGE("There is no peer data");//LCOV_EXCL_LINE
335                 return NULL;
336         }
337
338         temp = g_list_first(manager->peers);
339         while (temp) {
340                 peer = temp->data;
341                 if (!memcmp(peer->dev_addr, addr, MACADDR_LEN) ||
342                                 !memcmp(peer->intf_addr, addr, MACADDR_LEN)) {
343                         WDS_LOGD("Peer device found[" MACSECSTR "]", MAC2SECSTR(addr));//LCOV_EXCL_LINE
344                         break;
345                 }
346                 temp = g_list_next(temp);
347                 peer = NULL;
348         }
349
350         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
351         return peer;
352 }
353
354 #if 0
355 wfd_device_s *wfd_peer_find_current_peer(void *data)
356 {
357         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
358         wfd_manager_s *manager = (wfd_manager_s*) data;
359         if (!manager) {
360                 WDS_LOGE("Invalid parameter");
361                 return NULL;
362         }
363
364         wfd_session_s *session = manager->session;
365         if (!session) {
366                 WDS_LOGE("Session not found");
367                 return NULL;
368         }
369
370         if (!session->peer) {
371                 WDS_LOGE("Peer not found");
372                 return NULL;
373         }
374
375         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
376         return session->peer;
377 }
378
379 int wfd_peer_set_data(unsigned char *dev_addr, int type, int data)
380 {
381         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
382         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
383         return 0;
384 }
385
386 int wfd_peer_get_data(unsigned char *dev_addr, int type, int data)
387 {
388         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
389         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
390         return 0;
391 }
392 #endif