1
0
Fork 0
mirror of https://github.com/albfan/miraclecast.git synced 2025-03-09 23:38:56 +00:00

Add new miracle-wifid daemon

The miracle-wifid daemon is a rewrite of the wifi-related parts of
miracled. Unlike miracled, we no longer integrate the wifi-part directly
into the core daemon. This way, we can easily replace the wifi-bridge with
other network managers once they gain P2P capabilities.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
This commit is contained in:
David Herrmann 2014-03-19 13:08:25 +01:00
parent b0b53f986c
commit 18a5094bc0
9 changed files with 4512 additions and 0 deletions

262
src/wifi/wifid-link.c Normal file
View file

@ -0,0 +1,262 @@
/*
* MiracleCast - Wifi-Display/Miracast Implementation
*
* Copyright (c) 2013-2014 David Herrmann <dh.herrmann@gmail.com>
*
* MiracleCast is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* MiracleCast is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with MiracleCast; If not, see <http://www.gnu.org/licenses/>.
*/
#define LOG_SUBSYSTEM "link"
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <systemd/sd-bus.h>
#include "shl_dlist.h"
#include "shl_log.h"
#include "shl_util.h"
#include "util.h"
#include "wifid.h"
/*
* Link Handling
*/
struct peer *link_find_peer(struct link *l, const char *p2p_mac)
{
char **elem;
bool res;
res = shl_htable_lookup_str(&l->peers, p2p_mac, NULL, &elem);
if (!res)
return NULL;
return peer_from_htable(elem);
}
struct peer *link_find_peer_by_label(struct link *l, const char *label)
{
char mac[MAC_STRLEN];
reformat_mac(mac, label);
return link_find_peer(l, mac);
}
int link_new(struct manager *m,
unsigned int ifindex,
const char *ifname,
struct link **out)
{
struct link *l;
int r;
if (!m || !ifindex || !ifname)
return log_EINVAL();
if (shl_htable_lookup_uint(&m->links, ifindex, NULL))
return -EALREADY;
log_debug("new link: %s (%u)", ifname, ifindex);
l = calloc(1, sizeof(*l));
if (!l)
return log_ENOMEM();
l->m = m;
l->ifindex = ifindex;
shl_htable_init_str(&l->peers);
l->ifname = strdup(ifname);
if (!l->ifname) {
r = log_ENOMEM();
goto error;
}
r = supplicant_new(l, &l->s);
if (r < 0)
goto error;
r = shl_htable_insert_uint(&m->links, &l->ifindex);
if (r < 0) {
log_vERR(r);
goto error;
}
++m->link_cnt;
log_info("add link: %s", l->ifname);
if (out)
*out = l;
return 0;
error:
link_free(l);
return r;
}
void link_free(struct link *l)
{
if (!l)
return;
log_debug("free link: %s (%u)", l->ifname, l->ifindex);
link_set_managed(l, false);
if (shl_htable_remove_uint(&l->m->links, l->ifindex, NULL)) {
log_info("remove link: %s", l->ifname);
--l->m->link_cnt;
}
supplicant_free(l->s);
/* link_set_managed(l, false) already removed all peers */
shl_htable_clear_str(&l->peers, NULL, NULL);
free(l->friendly_name);
free(l->ifname);
free(l);
}
void link_set_managed(struct link *l, bool set)
{
int r;
if (!l)
return log_vEINVAL();
if (l->managed == set)
return;
if (set) {
log_info("manage link %s", l->ifname);
r = supplicant_start(l->s);
if (r < 0) {
log_error("cannot start supplicant on %s", l->ifname);
return;
}
} else {
log_info("link %s no longer managed", l->ifname);
supplicant_stop(l->s);
}
l->managed = set;
}
int link_renamed(struct link *l, const char *ifname)
{
char *t;
if (!l || !ifname)
return log_EINVAL();
if (!strcmp(l->ifname, ifname))
return 0;
log_info("link %s (%u) was renamed to %s",
l->ifname, l->ifindex, ifname);
t = strdup(ifname);
if (!t)
return log_ENOMEM();
free(l->ifname);
l->ifname = t;
link_dbus_properties_changed(l, "InterfaceName", NULL);
return 0;
}
int link_set_friendly_name(struct link *l, const char *name)
{
char *t;
int r;
if (!l || !name || !*name)
return log_EINVAL();
t = strdup(name);
if (!t)
return log_ENOMEM();
if (supplicant_is_ready(l->s)) {
r = supplicant_set_friendly_name(l->s, name);
if (r < 0) {
free(t);
return r;
}
}
free(l->friendly_name);
l->friendly_name = t;
link_dbus_properties_changed(l, "FriendlyName", NULL);
return 0;
}
const char *link_get_friendly_name(struct link *l)
{
if (!l)
return NULL;
return l->friendly_name;
}
int link_set_p2p_scanning(struct link *l, bool set)
{
if (!l)
return log_EINVAL();
if (set) {
return supplicant_p2p_start_scan(l->s);
} else {
supplicant_p2p_stop_scan(l->s);
return 0;
}
}
bool link_get_p2p_scanning(struct link *l)
{
return l && supplicant_p2p_scanning(l->s);
}
void link_supplicant_started(struct link *l)
{
if (!l || l->public)
return;
log_debug("link %s started", l->ifname);
l->public = true;
link_dbus_added(l);
}
void link_supplicant_stopped(struct link *l)
{
if (!l || !l->public)
return;
log_debug("link %s stopped", l->ifname);
link_dbus_removed(l);
l->public = false;
}
void link_supplicant_p2p_scan_changed(struct link *l, bool new_value)
{
if (!l)
return;
link_dbus_properties_changed(l, "P2PScanning", NULL);
}