Currently, only the peer as a client is supported. As a P2P peer is
always in IPv4 via DHCP there is just one ipconfig object, only handled
through dhcpv4.
---
plugins/wifi.c | 5 ++-
src/peer.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+), 1 deletion(-)
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 48a9cf3..3c8f26f 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -2080,6 +2080,7 @@ static void peer_found(GSupplicantPeer *peer)
struct wifi_data *wifi = g_supplicant_interface_get_data(iface);
struct connman_peer *connman_peer;
const char *identifier, *name;
+ int ret;
identifier = g_supplicant_peer_get_identifier(peer);
name = g_supplicant_peer_get_name(peer);
@@ -2094,7 +2095,9 @@ static void peer_found(GSupplicantPeer *peer)
connman_peer_set_name(connman_peer, name);
connman_peer_set_device(connman_peer, wifi->device);
- connman_peer_register(connman_peer);
+ ret = connman_peer_register(connman_peer);
+ if (ret < 0 && ret != -EALREADY)
+ connman_peer_unref(connman_peer);
}
static void peer_lost(GSupplicantPeer *peer)
diff --git a/src/peer.c b/src/peer.c
index a0134d7..80120fc 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -47,6 +47,7 @@ struct connman_peer {
char *name;
char *path;
enum connman_peer_state state;
+ struct connman_ipconfig *ipconfig;
bool registered;
};
@@ -61,6 +62,13 @@ static void peer_free(gpointer data)
peer->path = NULL;
}
+ if (peer->ipconfig) {
+ __connman_ipconfig_set_ops(peer->ipconfig, NULL);
+ __connman_ipconfig_set_data(peer->ipconfig, NULL);
+ __connman_ipconfig_unref(peer->ipconfig);
+ peer->ipconfig = NULL;
+ }
+
if (peer->device) {
connman_device_unref(peer->device);
peer->device = NULL;
@@ -335,10 +343,34 @@ struct connman_device *connman_peer_get_device(struct
connman_peer *peer)
return peer->device;
}
+static void dhcp_callback(struct connman_ipconfig *ipconfig,
+ struct connman_network *network,
+ bool success, gpointer data)
+{
+ struct connman_peer *peer = data;
+ int err;
+
+ if (!success)
+ goto error;
+
+ DBG("lease acquired for ipconfig %p", ipconfig);
+
+ err = __connman_ipconfig_address_add(ipconfig);
+ if (err < 0)
+ goto error;
+
+ return;
+
+error:
+ __connman_ipconfig_address_remove(ipconfig);
+ connman_peer_set_state(peer, CONNMAN_PEER_STATE_FAILURE);
+}
+
int connman_peer_set_state(struct connman_peer *peer,
enum connman_peer_state new_state)
{
enum connman_peer_state old_state = peer->state;
+ int err;
if (old_state == new_state)
return -EALREADY;
@@ -348,13 +380,24 @@ int connman_peer_set_state(struct connman_peer *peer,
return -EINVAL;
case CONNMAN_PEER_STATE_IDLE:
case CONNMAN_PEER_STATE_ASSOCIATION:
+ break;
case CONNMAN_PEER_STATE_CONFIGURATION:
+ __connman_ipconfig_enable(peer->ipconfig);
+
+ err = __connman_dhcp_start(peer->ipconfig,
+ NULL, dhcp_callback, peer);
+ if (err < 0)
+ return connman_peer_set_state(peer,
+ CONNMAN_PEER_STATE_FAILURE);
break;
case CONNMAN_PEER_STATE_READY:
break;
case CONNMAN_PEER_STATE_DISCONNECT:
break;
case CONNMAN_PEER_STATE_FAILURE:
+ __connman_dhcp_stop(peer->ipconfig);
+ __connman_ipconfig_disable(peer->ipconfig);
+
break;
};
@@ -364,6 +407,76 @@ int connman_peer_set_state(struct connman_peer *peer,
return 0;
}
+static void peer_up(struct connman_ipconfig *ipconfig, const char *ifname)
+{
+ DBG("%s up", ifname);
+}
+
+static void peer_down(struct connman_ipconfig *ipconfig, const char *ifname)
+{
+ DBG("%s down", ifname);
+}
+
+static void peer_lower_up(struct connman_ipconfig *ipconfig,
+ const char *ifname)
+{
+ DBG("%s lower up", ifname);
+}
+
+static void peer_lower_down(struct connman_ipconfig *ipconfig,
+ const char *ifname)
+{
+ struct connman_peer *peer = __connman_ipconfig_get_data(ipconfig);
+
+ DBG("%s lower down", ifname);
+
+ __connman_ipconfig_disable(ipconfig);
+ connman_peer_set_state(peer, CONNMAN_PEER_STATE_DISCONNECT);
+}
+
+static void peer_ip_bound(struct connman_ipconfig *ipconfig,
+ const char *ifname)
+{
+ struct connman_peer *peer = __connman_ipconfig_get_data(ipconfig);
+
+ DBG("%s ip bound", ifname);
+
+ connman_peer_set_state(peer, CONNMAN_PEER_STATE_READY);
+}
+
+static void peer_ip_release(struct connman_ipconfig *ipconfig,
+ const char *ifname)
+{
+ DBG("%s ip release", ifname);
+}
+
+static const struct connman_ipconfig_ops peer_ip_ops = {
+ .up = peer_up,
+ .down = peer_down,
+ .lower_up = peer_lower_up,
+ .lower_down = peer_lower_down,
+ .ip_bound = peer_ip_bound,
+ .ip_release = peer_ip_release,
+ .route_set = NULL,
+ .route_unset = NULL,
+};
+
+static struct connman_ipconfig *create_ipconfig(int index, void *user_data)
+{
+ struct connman_ipconfig *ipconfig;
+
+ ipconfig = __connman_ipconfig_create(index,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ if (!ipconfig)
+ return NULL;
+
+ __connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_DHCP);
+ __connman_ipconfig_set_data(ipconfig, user_data);
+ __connman_ipconfig_set_ops(ipconfig, &peer_ip_ops);
+
+ return ipconfig;
+}
+
static const GDBusMethodTable peer_methods[] = {
{ GDBUS_METHOD("GetProperties",
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
@@ -388,11 +501,18 @@ static char *get_peer_path(struct connman_device *device,
int connman_peer_register(struct connman_peer *peer)
{
+ int index;
+
DBG("peer %p", peer);
if (peer->path && peer->registered)
return -EALREADY;
+ index = connman_device_get_index(peer->device);
+ peer->ipconfig = create_ipconfig(index, peer);
+ if (!peer->ipconfig)
+ return -ENOMEM;
+
peer->path = get_peer_path(peer->device, peer->identifier);
DBG("path %s", peer->path);
--
1.8.5.5
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman