};
enum connman_iface_flags {
- CONNMAN_IFACE_FLAG_CARRIER_DETECT = (1 << 0),
+ CONNMAN_IFACE_FLAG_RTNL = (1 << 0),
CONNMAN_IFACE_FLAG_IPV4 = (1 << 1),
CONNMAN_IFACE_FLAG_IPV6 = (1 << 2),
+ CONNMAN_IFACE_FLAG_CARRIER_DETECT = (1 << 3),
+};
+
+enum connman_iface_state {
+ CONNMAN_IFACE_STATE_UNKNOWN = 0,
+ CONNMAN_IFACE_STATE_ACTIVE = 1,
+ CONNMAN_IFACE_STATE_CONNECTED = 2,
+ CONNMAN_IFACE_STATE_READY = 3,
};
struct connman_ipv4 {
struct in_addr nameserver;
};
+struct connman_network {
+};
+
struct connman_iface {
struct connman_iface_driver *driver;
char *path;
char *udi;
char *sysfs;
+ int index;
enum connman_iface_type type;
enum connman_iface_flags flags;
+ enum connman_iface_state state;
struct connman_ipv4 ipv4;
};
const char *capability;
int (*probe) (struct connman_iface *iface);
void (*remove) (struct connman_iface *iface);
+ int (*activate) (struct connman_iface *iface);
+ int (*shutdown) (struct connman_iface *iface);
int (*get_ipv4) (struct connman_iface *iface,
struct connman_ipv4 *ipv4);
int (*set_ipv4) (struct connman_iface *iface,
struct connman_ipv4 *ipv4);
+ int (*scan) (struct connman_iface *iface);
+ int (*connect) (struct connman_iface *iface,
+ struct connman_network *network);
};
extern int connman_iface_register(struct connman_iface_driver *driver);
extern void connman_iface_unregister(struct connman_iface_driver *driver);
+extern int connman_iface_update(struct connman_iface *iface,
+ enum connman_iface_state state);
+
#ifdef __cplusplus
}
#endif
static int iface_probe(struct connman_iface *iface)
{
- char *ifname;
-
- ifname = __net_ifname(iface->sysfs);
- if (ifname == NULL)
- return -1;
-
- printf("[802.03] probe interface %s\n", ifname);
+ printf("[802.03] probe interface index %d\n", iface->index);
iface->type = CONNMAN_IFACE_TYPE_80203;
- iface->flags = CONNMAN_IFACE_FLAG_CARRIER_DETECT |
- CONNMAN_IFACE_FLAG_IPV4;
-
- __net_free(ifname);
+ iface->flags = CONNMAN_IFACE_FLAG_RTNL |
+ CONNMAN_IFACE_FLAG_IPV4 |
+ CONNMAN_IFACE_FLAG_CARRIER_DETECT;
return 0;
}
static void iface_remove(struct connman_iface *iface)
{
- printf("[802.03] remove interface\n");
+ printf("[802.03] remove interface index %d\n", iface->index);
- __net_clear(iface->sysfs);
+ __net_clear(iface->index);
}
static int iface_get_ipv4(struct connman_iface *iface,
struct connman_ipv4 *ipv4)
{
- if (__net_ifaddr(iface->sysfs, &ipv4->address) < 0)
+ if (__net_ifaddr(iface->index, &ipv4->address) < 0)
return -1;
printf("[802.03] get address %s\n", inet_ntoa(ipv4->address));
printf("[802.03] set netmask %s\n", inet_ntoa(ipv4->netmask));
printf("[802.03] set gateway %s\n", inet_ntoa(ipv4->gateway));
- __net_set(iface->sysfs, &ipv4->address, &ipv4->netmask,
+ __net_set(iface->index, &ipv4->address, &ipv4->netmask,
&ipv4->gateway, &ipv4->broadcast,
&ipv4->nameserver);
static int iface_probe(struct connman_iface *iface)
{
- char *ifname;
-
- ifname = __net_ifname(iface->sysfs);
- if (ifname == NULL)
- return -1;
-
- printf("[802.11] probe interface %s\n", ifname);
+ printf("[802.11] probe interface index %d\n", iface->index);
iface->type = CONNMAN_IFACE_TYPE_80211;
- iface->flags = CONNMAN_IFACE_FLAG_IPV4;
-
- __net_free(ifname);
+ iface->flags = CONNMAN_IFACE_FLAG_RTNL |
+ CONNMAN_IFACE_FLAG_IPV4;
return 0;
}
static void iface_remove(struct connman_iface *iface)
{
- printf("[802.11] remove interface\n");
+ printf("[802.11] remove interface index %d\n", iface->index);
+
+ __net_clear(iface->index);
+}
+
+static int iface_activate(struct connman_iface *iface)
+{
+ printf("[802.11] activate interface index %d\n", iface->index);
- __net_clear(iface->sysfs);
+ connman_iface_update(iface, CONNMAN_IFACE_STATE_ACTIVE);
+
+ return 0;
}
static int iface_get_ipv4(struct connman_iface *iface,
struct connman_ipv4 *ipv4)
{
- if (__net_ifaddr(iface->sysfs, &ipv4->address) < 0)
+ if (__net_ifaddr(iface->index, &ipv4->address) < 0)
return -1;
printf("[802.11] get address %s\n", inet_ntoa(ipv4->address));
printf("[802.11] set netmask %s\n", inet_ntoa(ipv4->netmask));
printf("[802.11] set gateway %s\n", inet_ntoa(ipv4->gateway));
- __net_set(iface->sysfs, &ipv4->address, &ipv4->netmask,
+ __net_set(iface->index, &ipv4->address, &ipv4->netmask,
&ipv4->gateway, &ipv4->broadcast,
&ipv4->nameserver);
return 0;
}
+static int iface_scan(struct connman_iface *iface)
+{
+ printf("[802.11] scanning interface index %d\n", iface->index);
+
+ return 0;
+}
+
+static int iface_connect(struct connman_iface *iface,
+ struct connman_network *network)
+{
+ printf("[802.11] connect interface index %d\n", iface->index);
+
+ return 0;
+}
+
static struct connman_iface_driver iface_driver = {
.name = "80211",
.capability = "net.80211",
.probe = iface_probe,
.remove = iface_remove,
+ .activate = iface_activate,
.get_ipv4 = iface_get_ipv4,
.set_ipv4 = iface_set_ipv4,
+ .scan = iface_scan,
+ .connect = iface_connect,
};
static int plugin_init(void)
char *ifname, *argv[16], address[128], pidfile[PATH_MAX];
char leases[PATH_MAX], config[PATH_MAX], script[PATH_MAX];
- ifname = __net_ifname(iface->sysfs);
+ ifname = __net_ifname(iface->index);
if (ifname == NULL)
return -1;
{
char *ifname;
- ifname = __net_ifname(iface->sysfs);
+ ifname = __net_ifname(iface->index);
if (ifname == NULL)
return -1;
#include "net.h"
-static int __net_ifindex(const char *sysfs)
-{
- char *pathname;
- char buf[8];
- size_t size;
- ssize_t len;
- int fd, val = -EIO;
-
- if (sysfs == NULL)
- return -1;
-
- size = strlen(sysfs) + 9;
-
- pathname = malloc(size);
-
- sprintf(pathname, "%s/ifindex", sysfs);
-
- fd = open(pathname, O_RDONLY);
-
- free(pathname);
-
- if (fd < 0)
- return -errno;
-
- memset(buf, 0, sizeof(buf));
-
- len = read(fd, buf, sizeof(buf) - 1);
- if (len < 0) {
- val = -errno;
- goto done;
- }
-
- val = atoi(buf);
-
-done:
- close(fd);
-
- return val;
-}
-
-int __net_ifaddr(const char *sysfs, struct in_addr *addr)
+int __net_ifaddr(int ifindex, struct in_addr *addr)
{
struct ifreq ifr;
- int sk, ifindex;
-
- ifindex = __net_ifindex(sysfs);
- if (ifindex < 0)
- return ifindex;
+ int sk;
sk = socket(PF_INET, SOCK_DGRAM, 0);
if (sk < 0)
return 0;
}
-char *__net_ifname(const char *sysfs)
+char *__net_ifname(int ifindex)
{
struct ifreq ifr;
- int sk, err, ifindex;
-
- ifindex = __net_ifindex(sysfs);
- if (ifindex < 0)
- return NULL;
+ int sk, err;
sk = socket(PF_INET, SOCK_DGRAM, 0);
if (sk < 0)
free(ptr);
}
-int __net_clear(const char *sysfs)
+int __net_clear(int ifindex)
{
char *ifname, cmd[128];
- ifname = __net_ifname(sysfs);
+ ifname = __net_ifname(ifindex);
if (ifname == NULL)
return -1;
return 0;
}
-int __net_set(const char *sysfs, struct in_addr *addr, struct in_addr *mask,
+int __net_set(int ifindex, struct in_addr *addr, struct in_addr *mask,
struct in_addr *route, struct in_addr *bcast,
struct in_addr *namesrv)
{
char *ifname, cmd[128], msk[32], brd[32];
- ifname = __net_ifname(sysfs);
+ ifname = __net_ifname(ifindex);
if (ifname == NULL)
return -1;
- __net_clear(sysfs);
+ __net_clear(ifindex);
sprintf(msk, "%s", "24");
sprintf(brd, "%s", inet_ntoa(*bcast));
*
*/
-int __net_ifaddr(const char *sysfs, struct in_addr *addr);
-char *__net_ifname(const char *sysfs);
+#include <arpa/inet.h>
+
+int __net_ifaddr(int ifindex, struct in_addr *addr);
+char *__net_ifname(int ifindex);
void __net_free(void *ptr);
-int __net_clear(const char *sysfs);
-int __net_set(const char *sysfs, struct in_addr *addr, struct in_addr *mask,
+int __net_clear(int ifindex);
+int __net_set(int ifindex, struct in_addr *addr, struct in_addr *mask,
struct in_addr *route, struct in_addr *bcast,
struct in_addr *namesrv);
iface->driver->set_ipv4(iface, ipv4);
iface->ipv4 = *ipv4;
}
+
+ connman_iface_update(iface, CONNMAN_IFACE_STATE_READY);
}
return 0;
static GSList *interfaces = NULL;
+int connman_iface_update(struct connman_iface *iface,
+ enum connman_iface_state state)
+{
+ switch (state) {
+ case CONNMAN_IFACE_STATE_ACTIVE:
+ if (iface->type == CONNMAN_IFACE_TYPE_80211) {
+ if (iface->driver->scan)
+ iface->driver->scan(iface);
+
+ if (iface->driver->connect)
+ iface->driver->connect(iface, NULL);
+ }
+ break;
+
+ case CONNMAN_IFACE_STATE_CONNECTED:
+ __connman_dhcp_request(iface);
+ break;
+
+ default:
+ break;
+ }
+
+ iface->state = state;
+
+ return 0;
+}
+
static void device_free(void *data)
{
struct connman_iface *iface = data;
if (sysfs != NULL)
iface->sysfs = g_strdup(sysfs);
+ iface->index = -1;
+
+ if (g_str_has_prefix(driver->capability, "net") == TRUE)
+ iface->index = libhal_device_get_property_int(ctx, udi,
+ "net.linux.ifindex", NULL);
+
iface->type = CONNMAN_IFACE_TYPE_UNKNOWN;
iface->flags = 0;
+ iface->state = CONNMAN_IFACE_STATE_UNKNOWN;
DBG("iface %p", iface);
DBG("address %s", inet_ntoa(iface->ipv4.address));
}
+ if (driver->activate)
+ driver->activate(iface);
+
return 0;
}