5 * Copyright (C) 2007-2009 Intel Corporation. All rights reserved.
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.
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.
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
33 enum connman_dhcp_state state;
35 struct connman_element *element;
37 struct connman_dhcp_driver *driver;
43 * @dhcp: DHCP structure
45 * Increase reference counter of DHCP
47 struct connman_dhcp *connman_dhcp_ref(struct connman_dhcp *dhcp)
49 g_atomic_int_inc(&dhcp->refcount);
56 * @dhcp: DHCP structure
58 * Decrease reference counter of DHCP
60 void connman_dhcp_unref(struct connman_dhcp *dhcp)
62 if (g_atomic_int_dec_and_test(&dhcp->refcount) == TRUE)
67 * connman_dhcp_get_index:
68 * @dhcp: DHCP structure
70 * Get network index of DHCP
72 int connman_dhcp_get_index(struct connman_dhcp *dhcp)
78 * connman_dhcp_get_interface:
79 * @dhcp: DHCP structure
81 * Get network interface of DHCP
83 char *connman_dhcp_get_interface(struct connman_dhcp *dhcp)
85 return connman_inet_ifname(dhcp->index);
90 * @dhcp: DHCP structure
92 * Report successful bound of the interface
94 void connman_dhcp_bound(struct connman_dhcp *dhcp)
96 struct connman_element *element;
100 element = connman_element_create(NULL);
104 element->type = CONNMAN_ELEMENT_TYPE_IPV4;
105 element->index = dhcp->index;
107 connman_element_update(dhcp->element);
109 if (connman_element_register(element, dhcp->element) < 0)
110 connman_element_unref(element);
114 * connman_dhcp_renew:
115 * @dhcp: DHCP structure
117 * Report successful renew of the interface
119 void connman_dhcp_renew(struct connman_dhcp *dhcp)
121 DBG("dhcp %p", dhcp);
123 connman_element_update(dhcp->element);
128 * @dhcp: DHCP structure
130 * Report DHCP failure of the interface
132 void connman_dhcp_fail(struct connman_dhcp *dhcp)
134 DBG("dhcp %p", dhcp);
136 connman_element_set_error(dhcp->element,
137 CONNMAN_ELEMENT_ERROR_FAILED);
140 static GSList *driver_list = NULL;
142 static gint compare_priority(gconstpointer a, gconstpointer b)
144 const struct connman_dhcp_driver *driver1 = a;
145 const struct connman_dhcp_driver *driver2 = b;
147 return driver2->priority - driver1->priority;
151 * connman_dhcp_driver_register:
152 * @driver: DHCP driver definition
154 * Register a new DHCP driver
156 * Returns: %0 on success
158 int connman_dhcp_driver_register(struct connman_dhcp_driver *driver)
160 DBG("driver %p name %s", driver, driver->name);
162 driver_list = g_slist_insert_sorted(driver_list, driver,
169 * connman_dhcp_driver_unregister:
170 * @driver: DHCP driver definition
172 * Remove a previously registered DHCP driver
174 void connman_dhcp_driver_unregister(struct connman_dhcp_driver *driver)
176 DBG("driver %p name %s", driver, driver->name);
178 driver_list = g_slist_remove(driver_list, driver);
181 static int dhcp_probe(struct connman_element *element)
183 struct connman_dhcp *dhcp;
186 DBG("element %p name %s", element, element->name);
188 dhcp = g_try_new0(struct connman_dhcp, 1);
193 dhcp->index = element->index;
194 dhcp->state = CONNMAN_DHCP_STATE_IDLE;
196 dhcp->element = element;
198 connman_element_set_data(element, dhcp);
200 for (list = driver_list; list; list = list->next) {
201 struct connman_dhcp_driver *driver = list->data;
203 DBG("driver %p name %s", driver, driver->name);
205 if (driver->request(dhcp) == 0) {
206 dhcp->driver = driver;
211 if (dhcp->driver == NULL) {
212 connman_dhcp_unref(dhcp);
219 static void dhcp_remove(struct connman_element *element)
221 struct connman_dhcp *dhcp = connman_element_get_data(element);
223 DBG("element %p name %s", element, element->name);
225 connman_element_set_data(element, NULL);
228 dhcp->driver->release(dhcp);
232 connman_dhcp_unref(dhcp);
235 static void dhcp_change(struct connman_element *element)
237 DBG("element %p name %s", element, element->name);
239 if (element->state == CONNMAN_ELEMENT_STATE_ERROR)
240 connman_element_set_error(element->parent,
241 CONNMAN_ELEMENT_ERROR_DHCP_FAILED);
244 static struct connman_driver dhcp_driver = {
246 .type = CONNMAN_ELEMENT_TYPE_DHCP,
247 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
249 .remove = dhcp_remove,
250 .change = dhcp_change,
253 int __connman_dhcp_init(void)
255 return connman_driver_register(&dhcp_driver);
258 void __connman_dhcp_cleanup(void)
260 connman_driver_unregister(&dhcp_driver);