Add support for exporting IP configuration properties
[framework/connectivity/connman.git] / src / ipconfig.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <gdbus.h>
27
28 #include "connman.h"
29
30 struct connman_ipconfig {
31         gint refcount;
32         enum connman_ipconfig_method method;
33 };
34
35 /**
36  * connman_ipconfig_create:
37  *
38  * Allocate a new ipconfig structure.
39  *
40  * Returns: a newly-allocated #connman_ipconfig structure
41  */
42 struct connman_ipconfig *connman_ipconfig_create(void)
43 {
44         struct connman_ipconfig *ipconfig;
45
46         DBG("");
47
48         ipconfig = g_try_new0(struct connman_ipconfig, 1);
49         if (ipconfig == NULL)
50                 return NULL;
51
52         DBG("ipconfig %p", ipconfig);
53
54         return ipconfig;
55 }
56
57 /**
58  * connman_ipconfig_ref:
59  * @ipconfig: ipconfig structure
60  *
61  * Increase reference counter of ipconfig
62  */
63 struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig)
64 {
65         g_atomic_int_inc(&ipconfig->refcount);
66
67         return ipconfig;
68 }
69
70 /**
71  * connman_ipconfig_unref:
72  * @ipconfig: ipconfig structure
73  *
74  * Decrease reference counter of ipconfig
75  */
76 void connman_ipconfig_unref(struct connman_ipconfig *ipconfig)
77 {
78         if (g_atomic_int_dec_and_test(&ipconfig->refcount) == TRUE) {
79                 g_free(ipconfig);
80         }
81 }
82
83 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
84 {
85         switch (method) {
86         case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
87                 return "unknown";
88         case CONNMAN_IPCONFIG_METHOD_OFF:
89                 return "off";
90         case CONNMAN_IPCONFIG_METHOD_STATIC:
91                 return "static";
92         case CONNMAN_IPCONFIG_METHOD_DHCP:
93                 return "dhcp";
94         }
95
96         return "unknown";
97 }
98
99 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
100 {
101         if (g_strcmp0(method, "off") == 0)
102                 return CONNMAN_IPCONFIG_METHOD_OFF;
103         else if (g_strcmp0(method, "static") == 0)
104                 return CONNMAN_IPCONFIG_METHOD_STATIC;
105         else if (g_strcmp0(method, "dhcp") == 0)
106                 return CONNMAN_IPCONFIG_METHOD_DHCP;
107         else
108                 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
109 }
110
111 static void append_variant(DBusMessageIter *iter, const char *prefix,
112                                         const char *key, int type, void *val)
113 {
114         char *str;
115
116         if (prefix == NULL) {
117                 connman_dbus_dict_append_variant(iter, key, type, val);
118                 return;
119         }
120
121         str = g_strdup_printf("%s%s", prefix, key);
122         if (str != NULL)
123                 connman_dbus_dict_append_variant(iter, str, type, val);
124
125         g_free(str);
126 }
127
128 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
129                                 DBusMessageIter *iter, const char *prefix)
130 {
131         const char *str;
132
133         str = __connman_ipconfig_method2string(ipconfig->method);
134         if (str == NULL)
135                 return;
136
137         append_variant(iter, prefix, "Method", DBUS_TYPE_STRING, &str);
138 }
139
140 int __connman_ipconfig_set_ipv4(struct connman_ipconfig *ipconfig,
141                                 const char *key, DBusMessageIter *value)
142 {
143         int type = dbus_message_iter_get_arg_type(value);
144
145         DBG("ipconfig %p key %s type %d", ipconfig, key, type);
146
147         if (g_strcmp0(key, "Method") == 0) {
148                 const char *method;
149
150                 if (type != DBUS_TYPE_STRING)
151                         return -EINVAL;
152
153                 dbus_message_iter_get_basic(value, &method);
154
155                 ipconfig->method = __connman_ipconfig_string2method(method);
156         } else
157                 return -EINVAL;
158
159         return 0;
160 }
161
162 static GSList *driver_list = NULL;
163
164 static gint compare_priority(gconstpointer a, gconstpointer b)
165 {
166         const struct connman_ipconfig_driver *driver1 = a;
167         const struct connman_ipconfig_driver *driver2 = b;
168
169         return driver2->priority - driver1->priority;
170 }
171
172 /**
173  * connman_ipconfig_driver_register:
174  * @driver: IP configuration driver
175  *
176  * Register a new IP configuration driver
177  *
178  * Returns: %0 on success
179  */
180 int connman_ipconfig_driver_register(struct connman_ipconfig_driver *driver)
181 {
182         DBG("driver %p name %s", driver, driver->name);
183
184         driver_list = g_slist_insert_sorted(driver_list, driver,
185                                                         compare_priority);
186
187         return 0;
188 }
189
190 /**
191  * connman_ipconfig_driver_unregister:
192  * @driver: IP configuration driver
193  *
194  * Remove a previously registered IP configuration driver.
195  */
196 void connman_ipconfig_driver_unregister(struct connman_ipconfig_driver *driver)
197 {
198         DBG("driver %p name %s", driver, driver->name);
199
200         driver_list = g_slist_remove(driver_list, driver);
201 }