device: renew dhcp leases on awake for software devices
[NetworkManager.git] / libnm-glib / nm-types.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /*
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the
15  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  * Boston, MA 02110-1301 USA.
17  *
18  * Copyright 2008 Red Hat, Inc.
19  */
20
21 #include "nm-default.h"
22
23 #include <dbus/dbus-glib.h>
24 #include <string.h>
25
26 #include "nm-types.h"
27 #include "nm-types-private.h"
28 #include "nm-object-private.h"
29 #include "nm-object-cache.h"
30 #include "nm-dbus-glib-types.h"
31 #include "nm-setting-ip6-config.h"
32
33 static gpointer
34 _nm_ssid_copy (GByteArray *src)
35 {
36         GByteArray *dest;
37
38         dest = g_byte_array_sized_new (src->len);
39         g_byte_array_append (dest, src->data, src->len);
40         return dest;
41 }
42
43 static void
44 _nm_ssid_free (GByteArray *ssid)
45 {
46         g_byte_array_free (ssid, TRUE);
47 }
48
49 GType
50 nm_ssid_get_type (void)
51 {
52         static GType our_type = 0;
53
54         if (our_type == 0)
55                 our_type = g_boxed_type_register_static (g_intern_static_string ("NMSsid"),
56                                                          (GBoxedCopyFunc) _nm_ssid_copy,
57                                                          (GBoxedFreeFunc) _nm_ssid_free);
58         return our_type;
59 }
60
61 gboolean
62 _nm_ssid_demarshal (GValue *value, GByteArray **dest)
63 {
64         GByteArray *array;
65
66         if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY))
67                 return FALSE;
68
69         if (*dest) {
70                 g_boxed_free (NM_TYPE_SSID, *dest);
71                 *dest = NULL;
72         }
73
74         array = (GByteArray *) g_value_get_boxed (value);
75         if (array && (array->len > 0)) {
76                 *dest = g_byte_array_sized_new (array->len);
77                 (*dest)->len = array->len;
78                 memcpy ((*dest)->data, array->data, array->len);
79         }
80
81         return TRUE;
82 }
83
84 /*****************************/
85
86 static gpointer
87 _nm_uint_array_copy (GArray *src)
88 {
89         GArray *dest;
90
91         dest = g_array_sized_new (FALSE, TRUE, sizeof (guint32), src->len);
92         g_array_append_vals (dest, src->data, src->len);
93         return dest;
94 }
95
96 static void
97 _nm_uint_array_free (GArray *array)
98 {
99         g_array_free (array, TRUE);
100 }
101
102 GType
103 nm_uint_array_get_type (void)
104 {
105         static GType our_type = 0;
106
107         if (our_type == 0)
108                 our_type = g_boxed_type_register_static (g_intern_static_string ("NMUintArray"),
109                                                          (GBoxedCopyFunc) _nm_uint_array_copy,
110                                                          (GBoxedFreeFunc) _nm_uint_array_free);
111         return our_type;
112 }
113
114 gboolean
115 _nm_uint_array_demarshal (GValue *value, GArray **dest)
116 {
117         GArray *array;
118
119         if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_UINT_ARRAY))
120                 return FALSE;
121
122         if (*dest) {
123                 g_boxed_free (NM_TYPE_UINT_ARRAY, *dest);
124                 *dest = NULL;
125         }
126
127         array = (GArray *) g_value_get_boxed (value);
128         if (array && (array->len > 0)) {
129                 *dest = g_array_sized_new (FALSE, TRUE, sizeof (guint32), array->len);
130                 g_array_append_vals (*dest, array->data, array->len);
131         }
132
133         return TRUE;
134 }
135
136 /*****************************/
137
138 static gpointer
139 _nm_string_array_copy (GPtrArray *src)
140 {
141         GPtrArray *dest;
142         int i;
143
144         dest = g_ptr_array_sized_new (src->len);
145         for (i = 0; i < src->len; i++)
146                 g_ptr_array_add (dest, g_strdup (g_ptr_array_index (src, i)));
147         return dest;
148 }
149
150 static void
151 _nm_string_array_free (GPtrArray *array)
152 {
153         int i;
154
155         for (i = 0; i < array->len; i++)
156                 g_free (g_ptr_array_index (array, i));
157         g_ptr_array_free (array, TRUE);
158 }
159
160 GType
161 nm_string_array_get_type (void)
162 {
163         static GType our_type = 0;
164
165         if (our_type == 0)
166                 our_type = g_boxed_type_register_static (g_intern_static_string ("NMStringArray"),
167                                                          (GBoxedCopyFunc) _nm_string_array_copy,
168                                                          (GBoxedFreeFunc) _nm_string_array_free);
169         return our_type;
170 }
171
172 gboolean
173 _nm_string_array_demarshal (GValue *value, GPtrArray **dest)
174 {
175         char **array;
176
177         if (!G_VALUE_HOLDS (value, G_TYPE_STRV))
178                 return FALSE;
179
180         if (*dest) {
181                 g_boxed_free (NM_TYPE_STRING_ARRAY, *dest);
182                 *dest = NULL;
183         }
184
185         array = (char **) g_value_get_boxed (value);
186         if (array && array[0]) {
187                 int i;
188
189                 *dest = g_ptr_array_new ();
190                 for (i = 0; array[i]; i++)
191                         g_ptr_array_add (*dest, g_strdup (array[i]));
192         }
193
194         return TRUE;
195 }
196
197 /*****************************/
198
199 static gpointer
200 _nm_object_array_copy (GPtrArray *src)
201 {
202         GPtrArray *dest;
203         int i;
204
205         dest = g_ptr_array_sized_new (src->len);
206         for (i = 0; i < src->len; i++)
207                 g_ptr_array_add (dest, g_object_ref (g_ptr_array_index (src, i)));
208         return dest;
209 }
210
211 static void
212 _nm_object_array_free (GPtrArray *array)
213 {
214         int i;
215
216         for (i = 0; i < array->len; i++)
217                 g_object_unref (g_ptr_array_index (array, i));
218         g_ptr_array_free (array, TRUE);
219 }
220
221 GType
222 nm_object_array_get_type (void)
223 {
224         static GType our_type = 0;
225
226         if (our_type == 0)
227                 our_type = g_boxed_type_register_static (g_intern_static_string ("NMObjectArray"),
228                                                          (GBoxedCopyFunc) _nm_object_array_copy,
229                                                          (GBoxedFreeFunc) _nm_object_array_free);
230         return our_type;
231 }
232
233 gboolean
234 _nm_object_array_demarshal (GValue *value,
235                             GPtrArray **dest,
236                             DBusGConnection *connection,
237                             NMObjectCreatorFunc func)
238 {
239         GPtrArray *temp = NULL;
240         GPtrArray *array;
241
242         if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH))
243                 return FALSE;
244
245         array = (GPtrArray *) g_value_get_boxed (value);
246         if (array && array->len) {
247                 int i;
248
249                 temp = g_ptr_array_sized_new (array->len);
250                 for (i = 0; i < array->len; i++) {
251                         const char *path;
252                         GObject *object;
253
254                         path = g_ptr_array_index (array, i);
255                         object = G_OBJECT (_nm_object_cache_get (path));
256                         if (object)
257                                 g_ptr_array_add (temp, object);
258                         else {
259                                 object = (*func) (connection, path);
260                                 if (object)
261                                         g_ptr_array_add (temp, object);
262                                 else
263                                         g_warning ("%s: couldn't create object for %s", __func__, path);
264                         }
265                 }
266         } else
267                 temp = g_ptr_array_new ();
268
269         /* Deallocate after to ensure that an object that might already
270          * be in the array doesn't get destroyed due to refcounting.
271          */
272         if (*dest)
273                 g_boxed_free (NM_TYPE_OBJECT_ARRAY, *dest);
274         *dest = temp;
275
276         return TRUE;
277 }
278
279 /*****************************/
280
281 static gpointer
282 _nm_ip6_address_object_array_copy (GPtrArray *src)
283 {
284         GPtrArray *dest;
285         int i;
286
287         dest = g_ptr_array_sized_new (src->len);
288         for (i = 0; i < src->len; i++)
289                 g_ptr_array_add (dest, nm_ip6_address_dup (g_ptr_array_index (src, i)));
290         return dest;
291 }
292
293 static void
294 _nm_ip6_address_object_array_free (GPtrArray *array)
295 {
296         int i;
297
298         for (i = 0; i < array->len; i++)
299                 nm_ip6_address_unref (g_ptr_array_index (array, i));
300         g_ptr_array_free (array, TRUE);
301 }
302
303 GType
304 nm_ip6_address_object_array_get_type (void)
305 {
306         static GType our_type = 0;
307
308         if (our_type == 0)
309                 our_type = g_boxed_type_register_static (g_intern_static_string ("NMIP6AddressObjectArray"),
310                                                          (GBoxedCopyFunc) _nm_ip6_address_object_array_copy,
311                                                          (GBoxedFreeFunc) _nm_ip6_address_object_array_free);
312         return our_type;
313 }
314
315 /*****************************/
316
317 static gpointer
318 _nm_ip6_address_array_copy (GPtrArray *src)
319 {
320         GPtrArray *dest;
321         int i;
322
323         dest = g_ptr_array_sized_new (src->len);
324         for (i = 0; i < src->len; i++) {
325                 struct in6_addr *addr = g_ptr_array_index (src, i);
326                 struct in6_addr *copy;
327
328                 copy = g_malloc0 (sizeof (struct in6_addr));
329                 memcpy (copy, addr, sizeof (struct in6_addr));
330                 g_ptr_array_add (dest, copy);
331         }
332         return dest;
333 }
334
335 static void
336 _nm_ip6_address_array_free (GPtrArray *array)
337 {
338         int i;
339
340         for (i = 0; i < array->len; i++)
341                 g_free (g_ptr_array_index (array, i));
342         g_ptr_array_free (array, TRUE);
343 }
344
345 GType
346 nm_ip6_address_array_get_type (void)
347 {
348         static GType our_type = 0;
349
350         if (our_type == 0)
351                 our_type = g_boxed_type_register_static (g_intern_static_string ("NMIP6AddressArray"),
352                                                          (GBoxedCopyFunc) _nm_ip6_address_array_copy,
353                                                          (GBoxedFreeFunc) _nm_ip6_address_array_free);
354         return our_type;
355 }
356
357 gboolean
358 _nm_ip6_address_array_demarshal (GValue *value, GSList **dest)
359 {
360         GPtrArray *array;
361
362         if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR))
363                 return FALSE;
364
365         if (*dest) {
366                 g_slist_free_full (*dest, g_free);
367                 *dest = NULL;
368         }
369
370         array = (GPtrArray *) g_value_get_boxed (value);
371         if (array && array->len) {
372                 int i;
373
374                 for (i = 0; i < array->len; i++) {
375                         GByteArray *bytearray = (GByteArray *) g_ptr_array_index (array, i);
376                         struct in6_addr *addr;
377
378                         addr = g_malloc0 (sizeof (struct in6_addr));
379                         memcpy (addr->s6_addr, bytearray->data, bytearray->len);
380                         *dest = g_slist_append (*dest, addr);
381                 }
382         }
383
384         return TRUE;
385 }
386
387 /*****************************/
388
389 static gpointer
390 _nm_ip6_route_object_array_copy (GPtrArray *src)
391 {
392         GPtrArray *dest;
393         int i;
394
395         dest = g_ptr_array_sized_new (src->len);
396         for (i = 0; i < src->len; i++)
397                 g_ptr_array_add (dest, nm_ip6_route_dup (g_ptr_array_index (src, i)));
398         return dest;
399 }
400
401 static void
402 _nm_ip6_route_object_array_free (GPtrArray *array)
403 {
404         int i;
405
406         for (i = 0; i < array->len; i++)
407                 nm_ip6_route_unref (g_ptr_array_index (array, i));
408         g_ptr_array_free (array, TRUE);
409 }
410
411 GType
412 nm_ip6_route_object_array_get_type (void)
413 {
414         static GType our_type = 0;
415
416         if (our_type == 0)
417                 our_type = g_boxed_type_register_static (g_intern_static_string ("NMIP6RouteObjectArray"),
418                                                          (GBoxedCopyFunc) _nm_ip6_route_object_array_copy,
419                                                          (GBoxedFreeFunc) _nm_ip6_route_object_array_free);
420         return our_type;
421 }