mirror of
https://github.com/albfan/miraclecast.git
synced 2025-03-09 23:38:56 +00:00
wifi: add wfd-subelement properties
Allow dbus API users to read and modify WFD subelements. Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
This commit is contained in:
parent
61db4a1d71
commit
e624d5f81a
5 changed files with 230 additions and 2 deletions
|
@ -238,6 +238,24 @@ static int peer_dbus_get_remote_address(sd_bus *bus,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int peer_dbus_get_wfd_subelements(sd_bus *bus,
|
||||||
|
const char *path,
|
||||||
|
const char *interface,
|
||||||
|
const char *property,
|
||||||
|
sd_bus_message *reply,
|
||||||
|
void *data,
|
||||||
|
sd_bus_error *err)
|
||||||
|
{
|
||||||
|
struct peer *p = data;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = sd_bus_message_append(reply, "s", peer_get_wfd_subelements(p));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static const sd_bus_vtable peer_dbus_vtable[] = {
|
static const sd_bus_vtable peer_dbus_vtable[] = {
|
||||||
SD_BUS_VTABLE_START(0),
|
SD_BUS_VTABLE_START(0),
|
||||||
SD_BUS_METHOD("Connect",
|
SD_BUS_METHOD("Connect",
|
||||||
|
@ -285,6 +303,11 @@ static const sd_bus_vtable peer_dbus_vtable[] = {
|
||||||
peer_dbus_get_remote_address,
|
peer_dbus_get_remote_address,
|
||||||
0,
|
0,
|
||||||
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("WfdSubelements",
|
||||||
|
"s",
|
||||||
|
peer_dbus_get_wfd_subelements,
|
||||||
|
0,
|
||||||
|
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_SIGNAL("ProvisionDiscovery", "ss", 0),
|
SD_BUS_SIGNAL("ProvisionDiscovery", "ss", 0),
|
||||||
SD_BUS_VTABLE_END
|
SD_BUS_VTABLE_END
|
||||||
};
|
};
|
||||||
|
@ -545,6 +568,43 @@ static int link_dbus_set_p2p_scanning(sd_bus *bus,
|
||||||
return link_set_p2p_scanning(l, val);
|
return link_set_p2p_scanning(l, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int link_dbus_get_wfd_subelements(sd_bus *bus,
|
||||||
|
const char *path,
|
||||||
|
const char *interface,
|
||||||
|
const char *property,
|
||||||
|
sd_bus_message *reply,
|
||||||
|
void *data,
|
||||||
|
sd_bus_error *err)
|
||||||
|
{
|
||||||
|
struct link *l = data;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = sd_bus_message_append(reply, "s", link_get_wfd_subelements(l));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int link_dbus_set_wfd_subelements(sd_bus *bus,
|
||||||
|
const char *path,
|
||||||
|
const char *interface,
|
||||||
|
const char *property,
|
||||||
|
sd_bus_message *value,
|
||||||
|
void *data,
|
||||||
|
sd_bus_error *err)
|
||||||
|
{
|
||||||
|
struct link *l = data;
|
||||||
|
const char *val;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = sd_bus_message_read(value, "s", &val);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return link_set_wfd_subelements(l, val);
|
||||||
|
}
|
||||||
|
|
||||||
static const sd_bus_vtable link_dbus_vtable[] = {
|
static const sd_bus_vtable link_dbus_vtable[] = {
|
||||||
SD_BUS_VTABLE_START(0),
|
SD_BUS_VTABLE_START(0),
|
||||||
SD_BUS_PROPERTY("InterfaceIndex",
|
SD_BUS_PROPERTY("InterfaceIndex",
|
||||||
|
@ -569,6 +629,12 @@ static const sd_bus_vtable link_dbus_vtable[] = {
|
||||||
link_dbus_set_p2p_scanning,
|
link_dbus_set_p2p_scanning,
|
||||||
0,
|
0,
|
||||||
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_WRITABLE_PROPERTY("WfdSubelements",
|
||||||
|
"s",
|
||||||
|
link_dbus_get_wfd_subelements,
|
||||||
|
link_dbus_set_wfd_subelements,
|
||||||
|
0,
|
||||||
|
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_VTABLE_END
|
SD_BUS_VTABLE_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ void link_free(struct link *l)
|
||||||
/* link_set_managed(l, false) already removed all peers */
|
/* link_set_managed(l, false) already removed all peers */
|
||||||
shl_htable_clear_str(&l->peers, NULL, NULL);
|
shl_htable_clear_str(&l->peers, NULL, NULL);
|
||||||
|
|
||||||
|
free(l->wfd_subelements);
|
||||||
free(l->friendly_name);
|
free(l->friendly_name);
|
||||||
free(l->ifname);
|
free(l->ifname);
|
||||||
free(l);
|
free(l);
|
||||||
|
@ -215,6 +216,41 @@ const char *link_get_friendly_name(struct link *l)
|
||||||
return l->friendly_name;
|
return l->friendly_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int link_set_wfd_subelements(struct link *l, const char *val)
|
||||||
|
{
|
||||||
|
char *t;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!l || !val)
|
||||||
|
return log_EINVAL();
|
||||||
|
|
||||||
|
t = strdup(val);
|
||||||
|
if (!t)
|
||||||
|
return log_ENOMEM();
|
||||||
|
|
||||||
|
if (supplicant_is_ready(l->s)) {
|
||||||
|
r = supplicant_set_wfd_subelements(l->s, val);
|
||||||
|
if (r < 0) {
|
||||||
|
free(t);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(l->wfd_subelements);
|
||||||
|
l->wfd_subelements = t;
|
||||||
|
link_dbus_properties_changed(l, "WfdSubelements", NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *link_get_wfd_subelements(struct link *l)
|
||||||
|
{
|
||||||
|
if (!l)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return l->wfd_subelements;
|
||||||
|
}
|
||||||
|
|
||||||
int link_set_p2p_scanning(struct link *l, bool set)
|
int link_set_p2p_scanning(struct link *l, bool set)
|
||||||
{
|
{
|
||||||
if (!l)
|
if (!l)
|
||||||
|
|
|
@ -130,6 +130,14 @@ const char *peer_get_remote_address(struct peer *p)
|
||||||
return supplicant_peer_get_remote_address(p->sp);
|
return supplicant_peer_get_remote_address(p->sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *peer_get_wfd_subelements(struct peer *p)
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return supplicant_peer_get_wfd_subelements(p->sp);
|
||||||
|
}
|
||||||
|
|
||||||
int peer_connect(struct peer *p, const char *prov, const char *pin)
|
int peer_connect(struct peer *p, const char *prov, const char *pin)
|
||||||
{
|
{
|
||||||
if (!p)
|
if (!p)
|
||||||
|
@ -174,6 +182,14 @@ void peer_supplicant_friendly_name_changed(struct peer *p)
|
||||||
peer_dbus_properties_changed(p, "FriendlyName", NULL);
|
peer_dbus_properties_changed(p, "FriendlyName", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void peer_supplicant_wfd_subelements_changed(struct peer *p)
|
||||||
|
{
|
||||||
|
if (!p || !p->public)
|
||||||
|
return;
|
||||||
|
|
||||||
|
peer_dbus_properties_changed(p, "WfdSubelements", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void peer_supplicant_provision_discovery(struct peer *p,
|
void peer_supplicant_provision_discovery(struct peer *p,
|
||||||
const char *prov,
|
const char *prov,
|
||||||
const char *pin)
|
const char *pin)
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct supplicant_peer {
|
||||||
|
|
||||||
char *friendly_name;
|
char *friendly_name;
|
||||||
char *remote_addr;
|
char *remote_addr;
|
||||||
|
char *wfd_subelements;
|
||||||
char *prov;
|
char *prov;
|
||||||
char *pin;
|
char *pin;
|
||||||
char *sta_mac;
|
char *sta_mac;
|
||||||
|
@ -647,6 +648,7 @@ static void supplicant_peer_free(struct supplicant_peer *sp)
|
||||||
free(sp->pin);
|
free(sp->pin);
|
||||||
free(sp->prov);
|
free(sp->prov);
|
||||||
free(sp->friendly_name);
|
free(sp->friendly_name);
|
||||||
|
free(sp->wfd_subelements);
|
||||||
free(sp);
|
free(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,6 +684,14 @@ const char *supplicant_peer_get_remote_address(struct supplicant_peer *sp)
|
||||||
return sp->remote_addr;
|
return sp->remote_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *supplicant_peer_get_wfd_subelements(struct supplicant_peer *sp)
|
||||||
|
{
|
||||||
|
if (!sp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return sp->wfd_subelements;
|
||||||
|
}
|
||||||
|
|
||||||
int supplicant_peer_connect(struct supplicant_peer *sp,
|
int supplicant_peer_connect(struct supplicant_peer *sp,
|
||||||
const char *prov_type,
|
const char *prov_type,
|
||||||
const char *pin)
|
const char *pin)
|
||||||
|
@ -779,7 +789,7 @@ static void supplicant_parse_peer(struct supplicant *s,
|
||||||
struct wpas_message *m)
|
struct wpas_message *m)
|
||||||
{
|
{
|
||||||
struct supplicant_peer *sp;
|
struct supplicant_peer *sp;
|
||||||
const char *mac, *name;
|
const char *mac, *name, *val;
|
||||||
char *t;
|
char *t;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -812,6 +822,18 @@ static void supplicant_parse_peer(struct supplicant *s,
|
||||||
wpas_message_get_raw(m));
|
wpas_message_get_raw(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = wpas_message_dict_read(m, "wfd_subelems", 's', &val);
|
||||||
|
if (r >= 0) {
|
||||||
|
t = strdup(val);
|
||||||
|
if (!t) {
|
||||||
|
log_vENOMEM();
|
||||||
|
} else {
|
||||||
|
free(sp->wfd_subelements);
|
||||||
|
sp->wfd_subelements = t;
|
||||||
|
peer_supplicant_wfd_subelements_changed(sp->p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (s->running)
|
if (s->running)
|
||||||
peer_supplicant_started(sp->p);
|
peer_supplicant_started(sp->p);
|
||||||
}
|
}
|
||||||
|
@ -1454,7 +1476,9 @@ static int supplicant_set_wifi_display_fn(struct wpas *w,
|
||||||
struct wpas_message *reply,
|
struct wpas_message *reply,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
|
_wpas_message_unref_ struct wpas_message *m = NULL;
|
||||||
struct supplicant *s = data;
|
struct supplicant *s = data;
|
||||||
|
int r;
|
||||||
|
|
||||||
/* SET received */
|
/* SET received */
|
||||||
--s->setup_cnt;
|
--s->setup_cnt;
|
||||||
|
@ -1464,8 +1488,49 @@ static int supplicant_set_wifi_display_fn(struct wpas *w,
|
||||||
s->has_wfd = false;
|
s->has_wfd = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->has_wfd) {
|
||||||
|
/* update subelements */
|
||||||
|
|
||||||
|
r = wpas_message_new_request(s->bus_global,
|
||||||
|
"WFD_SUBELEM_SET",
|
||||||
|
&m);
|
||||||
|
if (r < 0) {
|
||||||
|
log_vERR(r);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = wpas_message_append(m, "s", "0");
|
||||||
|
if (r < 0) {
|
||||||
|
log_vERR(r);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shl_isempty(s->l->wfd_subelements)) {
|
||||||
|
r = wpas_message_append(m, "s", s->l->wfd_subelements);
|
||||||
|
if (r < 0) {
|
||||||
|
log_vERR(r);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = wpas_call_async(s->bus_global,
|
||||||
|
m,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
if (r < 0) {
|
||||||
|
log_vERR(r);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
supplicant_try_ready(s);
|
supplicant_try_ready(s);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
supplicant_failed(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int supplicant_status_fn(struct wpas *w,
|
static int supplicant_status_fn(struct wpas *w,
|
||||||
|
@ -1718,7 +1783,7 @@ int supplicant_set_friendly_name(struct supplicant *s, const char *name)
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!s->running || !name || !*name)
|
if (!s->running || !name || !*name)
|
||||||
return log_EINVAL();;
|
return log_EINVAL();
|
||||||
|
|
||||||
r = wpas_message_new_request(s->bus_global,
|
r = wpas_message_new_request(s->bus_global,
|
||||||
"SET",
|
"SET",
|
||||||
|
@ -1745,6 +1810,45 @@ int supplicant_set_friendly_name(struct supplicant *s, const char *name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int supplicant_set_wfd_subelements(struct supplicant *s, const char *val)
|
||||||
|
{
|
||||||
|
_wpas_message_unref_ struct wpas_message *m = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!s->running || !val)
|
||||||
|
return log_EINVAL();
|
||||||
|
|
||||||
|
r = wpas_message_new_request(s->bus_global,
|
||||||
|
"WFD_SUBELEM_SET",
|
||||||
|
&m);
|
||||||
|
if (r < 0)
|
||||||
|
return log_ERR(r);
|
||||||
|
|
||||||
|
r = wpas_message_append(m, "s", "0");
|
||||||
|
if (r < 0)
|
||||||
|
return log_ERR(r);
|
||||||
|
|
||||||
|
if (!shl_isempty(val)) {
|
||||||
|
r = wpas_message_append(m, "s", val);
|
||||||
|
if (r < 0)
|
||||||
|
return log_ERR(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = wpas_call_async(s->bus_global,
|
||||||
|
m,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_ERR(r);
|
||||||
|
|
||||||
|
log_debug("send 'WFD_SUBELEM_SET 0 %s' to wpas on %s",
|
||||||
|
val, s->l->ifname);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int supplicant_p2p_start_scan(struct supplicant *s)
|
int supplicant_p2p_start_scan(struct supplicant *s)
|
||||||
{
|
{
|
||||||
_wpas_message_unref_ struct wpas_message *m = NULL;
|
_wpas_message_unref_ struct wpas_message *m = NULL;
|
||||||
|
|
|
@ -57,6 +57,7 @@ const char *supplicant_peer_get_friendly_name(struct supplicant_peer *sp);
|
||||||
const char *supplicant_peer_get_interface(struct supplicant_peer *sp);
|
const char *supplicant_peer_get_interface(struct supplicant_peer *sp);
|
||||||
const char *supplicant_peer_get_local_address(struct supplicant_peer *sp);
|
const char *supplicant_peer_get_local_address(struct supplicant_peer *sp);
|
||||||
const char *supplicant_peer_get_remote_address(struct supplicant_peer *sp);
|
const char *supplicant_peer_get_remote_address(struct supplicant_peer *sp);
|
||||||
|
const char *supplicant_peer_get_wfd_subelements(struct supplicant_peer *sp);
|
||||||
int supplicant_peer_connect(struct supplicant_peer *sp,
|
int supplicant_peer_connect(struct supplicant_peer *sp,
|
||||||
const char *prov_type,
|
const char *prov_type,
|
||||||
const char *pin);
|
const char *pin);
|
||||||
|
@ -85,6 +86,7 @@ const char *peer_get_friendly_name(struct peer *p);
|
||||||
const char *peer_get_interface(struct peer *p);
|
const char *peer_get_interface(struct peer *p);
|
||||||
const char *peer_get_local_address(struct peer *p);
|
const char *peer_get_local_address(struct peer *p);
|
||||||
const char *peer_get_remote_address(struct peer *p);
|
const char *peer_get_remote_address(struct peer *p);
|
||||||
|
const char *peer_get_wfd_subelements(struct peer *p);
|
||||||
int peer_connect(struct peer *p, const char *prov, const char *pin);
|
int peer_connect(struct peer *p, const char *prov, const char *pin);
|
||||||
void peer_disconnect(struct peer *p);
|
void peer_disconnect(struct peer *p);
|
||||||
|
|
||||||
|
@ -94,6 +96,7 @@ void peer_reject(struct peer *p);
|
||||||
void peer_supplicant_started(struct peer *p);
|
void peer_supplicant_started(struct peer *p);
|
||||||
void peer_supplicant_stopped(struct peer *p);
|
void peer_supplicant_stopped(struct peer *p);
|
||||||
void peer_supplicant_friendly_name_changed(struct peer *p);
|
void peer_supplicant_friendly_name_changed(struct peer *p);
|
||||||
|
void peer_supplicant_wfd_subelements_changed(struct peer *p);
|
||||||
void peer_supplicant_provision_discovery(struct peer *p,
|
void peer_supplicant_provision_discovery(struct peer *p,
|
||||||
const char *prov,
|
const char *prov,
|
||||||
const char *pin);
|
const char *pin);
|
||||||
|
@ -116,6 +119,7 @@ struct link {
|
||||||
|
|
||||||
char *ifname;
|
char *ifname;
|
||||||
char *friendly_name;
|
char *friendly_name;
|
||||||
|
char *wfd_subelements;
|
||||||
|
|
||||||
size_t peer_cnt;
|
size_t peer_cnt;
|
||||||
struct shl_htable peers;
|
struct shl_htable peers;
|
||||||
|
@ -145,6 +149,8 @@ int link_renamed(struct link *l, const char *ifname);
|
||||||
|
|
||||||
int link_set_friendly_name(struct link *l, const char *name);
|
int link_set_friendly_name(struct link *l, const char *name);
|
||||||
const char *link_get_friendly_name(struct link *l);
|
const char *link_get_friendly_name(struct link *l);
|
||||||
|
int link_set_wfd_subelements(struct link *l, const char *val);
|
||||||
|
const char *link_get_wfd_subelements(struct link *l);
|
||||||
int link_set_p2p_scanning(struct link *l, bool set);
|
int link_set_p2p_scanning(struct link *l, bool set);
|
||||||
bool link_get_p2p_scanning(struct link *l);
|
bool link_get_p2p_scanning(struct link *l);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue