enlightenment/src/modules/bluez5/bz_obj.c

930 lines
24 KiB
C
Raw Normal View History

#include "bz.h"
#include "e_mod_main.h"
static Eldbus_Object *objman_obj = NULL;
static Eldbus_Proxy *objman_proxy = NULL;
static Eldbus_Signal_Handler *sig_ifadd = NULL;
static Eldbus_Signal_Handler *sig_ifdel = NULL;
static Eldbus_Pending *pend_getobj = NULL;
static Eina_Hash *obj_table = NULL;
static void (*fn_obj_add) (Obj *o) = NULL;
/*
static void
cb_obj_prop_mandata(void *data, const void *key, Eldbus_Message_Iter *var)
{
Obj *o = data;
unsigned short *skey = key;
printf(" M KEY %x\n", (int)*skey);
}
*/
static void
cb_obj_prop_entry(void *data, const void *key, Eldbus_Message_Iter *var)
{
Obj *o = data;
const char *skey = key;
if (!strcmp(skey, "Paired"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->paired = val;
}
if (!strcmp(skey, "Connected"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->connected = val;
}
if (!strcmp(skey, "Trusted"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->trusted = val;
}
if (!strcmp(skey, "Blocked"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->blocked = val;
}
if (!strcmp(skey, "LegacyPairing"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->legacy_pairing = val;
}
if (!strcmp(skey, "ServicesResolved"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->services_resolved = val;
}
if (!strcmp(skey, "Address"))
{
const char *val = NULL;
if (eldbus_message_iter_arguments_get(var, "s", &val))
o->address = eina_stringshare_add(val);
}
if (!strcmp(skey, "AddressType"))
{
const char *val = NULL;
if (eldbus_message_iter_arguments_get(var, "s", &val))
o->address_type = eina_stringshare_add(val);
}
if (!strcmp(skey, "Name"))
{
const char *val = NULL;
if (eldbus_message_iter_arguments_get(var, "s", &val))
o->name = eina_stringshare_add(val);
}
if (!strcmp(skey, "Icon"))
{
const char *val = NULL;
if (eldbus_message_iter_arguments_get(var, "s", &val))
o->icon = eina_stringshare_add(val);
}
if (!strcmp(skey, "Alias"))
{
const char *val = NULL;
if (eldbus_message_iter_arguments_get(var, "s", &val))
o->alias = eina_stringshare_add(val);
}
if (!strcmp(skey, "Modalias"))
{
const char *val = NULL;
if (eldbus_message_iter_arguments_get(var, "s", &val))
o->modalias = eina_stringshare_add(val);
}
if (!strcmp(skey, "Adapter"))
{
const char *val = NULL;
if (eldbus_message_iter_arguments_get(var, "o", &val))
o->adapter = eina_stringshare_add(val);
}
if (!strcmp(skey, "Class"))
{
unsigned int val = 0;
if (eldbus_message_iter_arguments_get(var, "u", &val))
o->klass = val;
}
if (!strcmp(skey, "Appearance"))
{
unsigned short val = 0;
if (eldbus_message_iter_arguments_get(var, "q", &val))
o->appearance = val;
}
if (!strcmp(skey, "RSSI"))
{
short val = 0;
if (eldbus_message_iter_arguments_get(var, "n", &val))
o->rssi = val;
}
if (!strcmp(skey, "TxPower"))
{
unsigned short val = 0;
if (eldbus_message_iter_arguments_get(var, "n", &val))
o->txpower = val;
}
if (!strcmp(skey, "UUIDs"))
{
Eldbus_Message_Iter *array = NULL;
if (eldbus_message_iter_arguments_get(var, "as", &array))
{
const char *val = NULL;
while (eldbus_message_iter_get_and_next(array, 's', &val))
{
if (!o->uuids) o->uuids = eina_array_new(1);
eina_array_push(o->uuids, eina_stringshare_add(val));
}
}
}
if (!strcmp(skey, "Discoverable"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->discoverable = val;
}
if (!strcmp(skey, "Discovering"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->discovering = val;
}
if (!strcmp(skey, "Pairable"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->pairable = val;
}
if (!strcmp(skey, "Powered"))
{
Eina_Bool val = EINA_FALSE;
if (eldbus_message_iter_arguments_get(var, "b", &val))
o->powered = val;
}
if (!strcmp(skey, "DiscoverableTimeout"))
{
unsigned int val = 0;
if (eldbus_message_iter_arguments_get(var, "u", &val))
o->discoverable_timeout = val;
}
if (!strcmp(skey, "PairableTimeout"))
{
unsigned int val = 0;
if (eldbus_message_iter_arguments_get(var, "u", &val))
o->pairable_timeout = val;
}
// dict ManufacturerData [readonly, optional]
// Manufacturer specific advertisement data. Keys are
// 16 bits Manufacturer ID followed by its byte array
// value.
/*
if (!strcmp(skey, "ManufacturerData"))
{
Eldbus_Message_Iter *array = NULL;
if (eldbus_message_iter_arguments_get(var, "a{qv}", &array))
eldbus_message_iter_dict_iterate(array, "qv", cb_obj_prop_mandata, o);
}
*/
// dict ServiceData [readonly, optional]
// Service advertisement data. Keys are the UUIDs in
// string format followed by its byte array value.
//
// array{byte} AdvertisingFlags [readonly, experimental]
// The Advertising Data Flags of the remote device.
//
// dict AdvertisingData [readonly, experimental]
// The Advertising Data of the remote device. Keys are
// are 8 bits AD Type followed by data as byte array.
}
static void
_obj_clear(Obj *o)
{
o->paired = EINA_FALSE;
o->connected = EINA_FALSE;
o->trusted = EINA_FALSE;
o->blocked = EINA_FALSE;
o->legacy_pairing = EINA_FALSE;
o->services_resolved = EINA_FALSE;
eina_stringshare_del(o->address);
o->address = NULL;
eina_stringshare_del(o->address_type);
o->address_type = NULL;
eina_stringshare_del(o->name);
o->name = NULL;
eina_stringshare_del(o->icon);
o->icon = NULL;
eina_stringshare_del(o->alias);
o->alias = NULL;
eina_stringshare_del(o->adapter);
o->adapter = NULL;
eina_stringshare_del(o->modalias);
o->modalias = NULL;
eina_stringshare_del(o->modalias);
o->modalias = NULL;
o->klass = 0;
o->appearance = 0;
o->txpower = 0;
o->rssi = 0;
if (o->uuids)
{
const char *val;
while ((val = eina_array_pop(o->uuids)))
eina_stringshare_del(val);
eina_array_free(o->uuids);
o->uuids = NULL;
}
}
#define ERR_PRINT(str) \
do { const char *name, *text; \
if (eldbus_message_error_get(msg, &name, &text)) { \
printf("Error: %s.\n %s:\n %s\n", str, name, text); \
return; \
} \
} while(0)
static void
cb_obj_prop(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
{
Obj *o = data;
Eldbus_Message_Iter *array;
if (eldbus_message_error_get(msg, NULL, NULL)) return;
_obj_clear(o);
if (eldbus_message_arguments_get(msg, "a{sv}", &array))
eldbus_message_iter_dict_iterate(array, "sv", cb_obj_prop_entry, o);
bz_obj_ref(o);
if ((o->powered) && (o->path))
{
const char *s = strrchr(o->path, '/');
if (s) ebluez5_rfkill_unblock(s + 1);
}
if (!o->add_called)
{
o->add_called = EINA_TRUE;
if (fn_obj_add) fn_obj_add(o);
}
if (o->fn_change) o->fn_change(o);
bz_obj_unref(o);
}
static void
cb_obj_prop_changed(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED)
{
Obj *o = data;
if (!o->proxy) return;
eldbus_proxy_property_get_all(o->proxy, cb_obj_prop, o);
}
//static void
//cb_obj_discovery_filter(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
//{
// ERR_PRINT("Discovery Filter Clear");
//}
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
Obj *
bz_obj_add(const char *path)
{
Obj *o = calloc(1, sizeof(Obj));
o->ref = 1;
o->path = eina_stringshare_add(path);
o->obj = eldbus_object_get(bz_conn, "org.bluez", o->path);
o->type = BZ_OBJ_UNKNOWN;
o->in_table = EINA_TRUE;
eina_hash_add(obj_table, o->path, o);
if (!strcmp(o->path, "/org/bluez"))
{
o->proxy = eldbus_proxy_get(o->obj, "org.bluez.AgentManager1");
o->type = BZ_OBJ_BLUEZ;
o->add_called = EINA_TRUE;
bz_obj_ref(o);
if (fn_obj_add) fn_obj_add(o);
bz_obj_unref(o);
goto done;
}
// all devices are /org/bluez/XXX/dev_XXX so look for /dev_
else if (strstr(o->path, "/dev_"))
{
o->proxy = eldbus_proxy_get(o->obj, "org.bluez.Device1");
o->type = BZ_OBJ_DEVICE;
if (o->proxy)
{
eldbus_proxy_property_get_all(o->proxy, cb_obj_prop, o);
o->prop_proxy = eldbus_proxy_get(o->obj,
"org.freedesktop.DBus.Properties");
if (o->prop_proxy)
o->prop_sig = eldbus_proxy_signal_handler_add(o->prop_proxy,
"PropertiesChanged",
cb_obj_prop_changed, o);
}
goto done;
}
// all dadapters begin with /org/bluez/
else if (!strncmp(o->path, "/org/bluez/", 11))
{
o->proxy = eldbus_proxy_get(o->obj, "org.bluez.Adapter1");
o->type = BZ_OBJ_ADAPTER;
if (o->proxy)
{
eldbus_proxy_property_get_all(o->proxy, cb_obj_prop, o);
o->prop_proxy = eldbus_proxy_get(o->obj,
"org.freedesktop.DBus.Properties");
if (o->prop_proxy)
o->prop_sig = eldbus_proxy_signal_handler_add(o->prop_proxy,
"PropertiesChanged",
cb_obj_prop_changed, o);
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
// disable the filter for discovery later
// XXX: this doesn't seem to exist on the bluez daemons I see
// so don't do this to avoid error noise and it's useless it seems
// eldbus_proxy_call
// (o->proxy, "SetDiscoveryFilter", cb_obj_discovery_filter, o, -1, "");
}
goto done;
}
done:
return o;
}
Obj *
bz_obj_find(const char *path)
{
return eina_hash_find(obj_table, path);
}
static void
cb_power_on(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Power On");
}
void
bz_obj_power_on(Obj *o)
{
Eina_Bool val = EINA_TRUE;
if (!o->proxy) return;
eldbus_proxy_property_set
(o->proxy, "Powered", "b", (void *)(uintptr_t)val, cb_power_on, o);
}
static void
cb_power_off(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Power Off");
}
void
bz_obj_power_off(Obj *o)
{
Eina_Bool val = EINA_FALSE;
if (!o->proxy) return;
eldbus_proxy_property_set
(o->proxy, "Powered", "b", (void *)(uintptr_t)val, cb_power_off, o);
}
static void
cb_discoverable(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Discoverable");
}
void
bz_obj_discoverable(Obj *o)
{
Eina_Bool val = EINA_TRUE;
if (!o->proxy) return;
eldbus_proxy_property_set
(o->proxy, "Discoverable", "b", (void *)(uintptr_t)val, cb_discoverable, o);
}
static void
cb_undiscoverable(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Undiscoverable");
}
void
bz_obj_undiscoverable(Obj *o)
{
Eina_Bool val = EINA_FALSE;
if (!o->proxy) return;
eldbus_proxy_property_set
(o->proxy, "Discoverable", "b", (void *)(uintptr_t)val, cb_undiscoverable, o);
}
static void
cb_pairable(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Pairable");
}
void
bz_obj_pairable(Obj *o)
{
Eina_Bool val = EINA_TRUE;
if (!o->proxy) return;
eldbus_proxy_property_set
(o->proxy, "Pairable", "b", (void *)(uintptr_t)val, cb_pairable, o);
}
static void
cb_unpairable(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Unpairable");
}
void
bz_obj_unpairable(Obj *o)
{
Eina_Bool val = EINA_FALSE;
if (!o->proxy) return;
eldbus_proxy_property_set
(o->proxy, "Pairable", "b", (void *)(uintptr_t)val, cb_unpairable, o);
}
static void
cb_trust(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Trust");
}
void
bz_obj_trust(Obj *o)
{
Eina_Bool val = EINA_TRUE;
if (!o->proxy) return;
eldbus_proxy_property_set
(o->proxy, "Trusted", "b", (void *)(uintptr_t)val, cb_trust, o);
}
static void
cb_distrust(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Distrust");
}
void
bz_obj_distrust(Obj *o)
{
Eina_Bool val = EINA_FALSE;
if (!o->proxy) return;
eldbus_proxy_property_set
(o->proxy, "Trusted", "b", (void *)(uintptr_t)val, cb_distrust, o);
}
static void
cb_pair(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Pair");
}
void
bz_obj_pair(Obj *o)
{
if (!o->proxy) return;
eldbus_proxy_call(o->proxy, "Pair", cb_pair, o, -1, "");
}
static void
cb_pair_cancel(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Pair Cancel");
}
void
bz_obj_pair_cancel(Obj *o)
{
if (!o->proxy) return;
eldbus_proxy_call
(o->proxy, "CancelPairing", cb_pair_cancel, o, -1, "");
}
static void
cb_connect(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Connect");
}
void
bz_obj_connect(Obj *o)
{
if (!o->proxy) return;
eldbus_proxy_call
(o->proxy, "Connect", cb_connect, o, -1, "");
}
static void
cb_disconnect(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Disconnect");
}
void
bz_obj_disconnect(Obj *o)
{
if (!o->proxy) return;
eldbus_proxy_call
(o->proxy, "Disconnect", cb_disconnect, o, -1, "");
}
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
static void
_cb_l2ping(void *data, const char *params)
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
{
Obj *o = data;
char addr[256];
int timeout = 0;
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
if (sscanf(params, "%255s %i", addr, &timeout) == 2)
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
{
if (!strcmp(o->address, addr))
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
{
if (o->ping_busy)
{
e_system_handler_del("l2ping-ping", _cb_l2ping, o);
o->ping_busy = EINA_FALSE;
}
if (timeout >= 0)
{
if (!o->ping_ok)
{
printf("@@@PING SUCCEED\n");
o->ping_ok = EINA_TRUE;
if (o->fn_change) o->fn_change(o);
}
}
else
{
if (o->ping_ok)
{
printf("@@@PING FAIL\n");
o->ping_ok = EINA_FALSE;
if (o->fn_change) o->fn_change(o);
}
}
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
}
}
}
static int
ping_powersave_timeout_get(void)
{
int timeout = 10;
E_Powersave_Mode pm = e_powersave_mode_get();
if (pm <= E_POWERSAVE_MODE_LOW) timeout = 5;
else if (pm <= E_POWERSAVE_MODE_MEDIUM) timeout = 8;
else if (pm <= E_POWERSAVE_MODE_HIGH) timeout = 12;
else if (pm <= E_POWERSAVE_MODE_EXTREME) timeout = 30;
return timeout;
}
static void
ping_do(Obj *o)
{
int timeout = 1000 * ping_powersave_timeout_get();
if (o->ping_busy)
e_system_handler_del("l2ping-ping", _cb_l2ping, o);
o->ping_busy = EINA_TRUE;
e_system_handler_add("l2ping-ping", _cb_l2ping, o);
e_system_send("l2ping-ping", "%s %i", o->address, timeout);
printf("@@@ run new ping %s %i\n", o->address, timeout);
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
}
static Eina_Bool cb_ping_timer(void *data);
static void
ping_schedule(Obj *o)
{
double timeout = ping_powersave_timeout_get() + 1.0;
if (o->ping_timer) ecore_timer_del(o->ping_timer);
o->ping_timer = ecore_timer_add(timeout, cb_ping_timer, o);
}
static Eina_Bool
cb_ping_timer(void *data)
{
Obj *o = data;
printf("@@@ ping timer %s\n", o->address);
if (o->ping_busy)
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
{
o->ping_busy = EINA_FALSE;
e_system_handler_del("l2ping-ping", _cb_l2ping, o);
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
if (o->ping_ok)
{
o->ping_ok = EINA_FALSE;
if (o->fn_change) o->fn_change(o);
}
}
ping_do(o);
ping_schedule(o);
return EINA_TRUE;
}
void
bz_obj_ping_begin(Obj *o)
{
if (o->ping_timer) return;
if (o->ping_busy)
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
{
o->ping_busy = EINA_FALSE;
e_system_handler_del("l2ping-ping", _cb_l2ping, o);
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
}
ping_do(o);
ping_schedule(o);
}
void
bz_obj_ping_end(Obj *o)
{
if (o->ping_timer)
{
ecore_timer_del(o->ping_timer);
o->ping_timer = NULL;
}
if (o->ping_busy)
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
{
o->ping_busy = EINA_FALSE;
e_system_handler_del("l2ping-ping", _cb_l2ping, o);
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
}
if (o->ping_ok)
{
printf("@@@PING END %s\n", o->address);
o->ping_ok = EINA_FALSE;
if (o->fn_change) o->fn_change(o);
}
}
static void
cb_remove(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Remove");
}
/*
void
bz_obj_profile_connect(Obj *o, const char *uuid)
{
if (!o->proxy) return;
eldbus_proxy_call(o->proxy, "ConnectProfile", NULL, NULL, -1, "s", uuid);
}
void
bz_obj_profile_disconnect(Obj *o, const char *uuid)
{
if (!o->proxy) return;
eldbus_proxy_call(o->proxy, "DisconnectProfile", NULL, NULL, -1, "s", uuid);
}
*/
void
bz_obj_remove(Obj *o)
{
if (o->adapter)
{
Obj *adapter = bz_obj_find(o->adapter);
if (adapter)
{
if (!adapter->proxy) return;
eldbus_proxy_call(adapter->proxy, "RemoveDevice",
cb_remove, adapter, -1,
"o", o->path);
}
}
}
void
bz_obj_ref(Obj *o)
{
o->ref++;
}
void
bz_obj_unref(Obj *o)
{
o->ref--;
if (o->ref > 0) return;
if (o->in_table)
{
o->in_table = EINA_FALSE;
eina_hash_del(obj_table, o->path, o);
}
if (o->ping_busy)
{
o->ping_busy = EINA_FALSE;
e_system_handler_del("l2ping-ping", _cb_l2ping, o);
}
_obj_clear(o);
if (o->prop_sig)
{
eldbus_signal_handler_del(o->prop_sig);
o->prop_sig = NULL;
}
if (o->path)
{
eina_stringshare_del(o->path);
o->path = NULL;
}
if (o->agent_request)
{
eina_stringshare_del(o->agent_request);
o->agent_request = NULL;
}
if (o->agent_msg_err)
{
bz_agent_msg_drop(o->agent_msg_err);
o->agent_msg_err = NULL;
}
if (o->agent_msg_ok)
{
bz_agent_msg_drop(o->agent_msg_ok);
o->agent_msg_ok = NULL;
}
bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily.
2018-12-15 08:03:41 -08:00
if (o->ping_timer)
{
ecore_timer_del(o->ping_timer);
o->ping_timer = NULL;
}
if (o->proxy)
{
eldbus_proxy_unref(o->proxy);
o->proxy = NULL;
}
if (o->prop_proxy)
{
eldbus_proxy_unref(o->prop_proxy);
o->prop_proxy = NULL;
}
if (o->obj)
{
eldbus_object_unref(o->obj);
o->obj = NULL;
}
free(o);
}
static void
cb_discovery_start(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Discovery Start");
}
void
bz_obj_discover_start(Obj *o)
{
if (!o->proxy) return;
eldbus_proxy_call
(o->proxy, "StartDiscovery", cb_discovery_start, o, -1, "");
}
static void
cb_discovery_stop(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
{
ERR_PRINT("Discovery Stop");
}
void
bz_obj_discover_stop(Obj *o)
{
if (!o->proxy) return;
eldbus_proxy_call
(o->proxy, "StopDiscovery", cb_discovery_stop, o, -1, "");
}
void
bz_obj_agent_request(Obj *o, const char *req, void (*fn) (Eldbus_Message *msg, const char *str), Eldbus_Message *msg_ok, Eldbus_Message *msg_err)
{
if (o->agent_msg_ok) bz_agent_msg_drop(o->agent_msg_ok);
if (o->agent_msg_err) bz_agent_msg_reply(o->agent_msg_err);
o->agent_msg_ok = msg_ok;
o->agent_msg_err = msg_err;
o->agent_entry_fn = fn;
o->agent_alert = EINA_TRUE;
eina_stringshare_replace(&(o->agent_request), req);
bz_obj_ref(o);
if (o->fn_change) o->fn_change(o);
bz_obj_unref(o);
}
static void
cb_obj_add(void *data EINA_UNUSED, const Eldbus_Message *msg)
{
const char *path = NULL;
if (!eldbus_message_arguments_get(msg, "o", &path)) return;
if (bz_obj_find(path)) return;
bz_obj_add(path);
}
static void
cb_obj_del(void *data EINA_UNUSED, const Eldbus_Message *msg)
{
Obj *o;
const char *path = NULL;
if (!eldbus_message_arguments_get(msg, "o", &path)) return;
o = bz_obj_find(path);
if (o)
{
bz_obj_ref(o);
if (o->fn_del) o->fn_del(o);
bz_obj_unref(o);
bz_obj_unref(o);
}
}
static void
cb_getobj(void *data EINA_UNUSED, const Eldbus_Message *msg,
Eldbus_Pending *pending EINA_UNUSED)
{
Eldbus_Message_Iter *prop, *dict;
pend_getobj = NULL;
ERR_PRINT("Get Objects");
if (eldbus_message_arguments_get(msg, "a{oa{sa{sv}}}", &prop))
{
while (eldbus_message_iter_get_and_next(prop, 'e', &dict))
{
const char *path;
path = NULL;
if (!eldbus_message_iter_arguments_get(dict, "o", &path))
{
return;
}
bz_obj_add(path);
}
}
}
static void
_obj_hash_free(Obj *o)
{
o->in_table = 0;
bz_obj_unref(o);
}
void
bz_obj_init(void)
{
obj_table = eina_hash_string_superfast_new((void *)_obj_hash_free);
objman_obj = eldbus_object_get(bz_conn, "org.bluez", "/");
objman_proxy = eldbus_proxy_get(objman_obj, "org.freedesktop.DBus.ObjectManager");
sig_ifadd = eldbus_proxy_signal_handler_add(objman_proxy, "InterfacesAdded",
cb_obj_add, NULL);
sig_ifdel = eldbus_proxy_signal_handler_add(objman_proxy, "InterfacesRemoved",
cb_obj_del, NULL);
pend_getobj = eldbus_proxy_call(objman_proxy, "GetManagedObjects",
cb_getobj, NULL, -1, "");
}
void
bz_obj_shutdown(void)
{
eina_hash_free(obj_table);
obj_table = NULL;
if (pend_getobj)
{
eldbus_pending_cancel(pend_getobj);
pend_getobj = NULL;
}
if (sig_ifadd)
{
eldbus_signal_handler_del(sig_ifadd);
sig_ifadd = NULL;
}
if (sig_ifdel)
{
eldbus_signal_handler_del(sig_ifdel);
sig_ifdel = NULL;
}
if (objman_proxy)
{
eldbus_proxy_unref(objman_proxy);
objman_proxy = NULL;
}
if (objman_obj)
{
eldbus_object_unref(objman_obj);
objman_obj = NULL;
}
}
void
bz_obj_add_func_set(void (*fn) (Obj *o))
{
fn_obj_add = fn;
}