mod bz5 - fix hw that comes with bt rfkill on and bz adapters empty
so - it seems on some hardware and./or os combinations the list of bt adapters is empty from bluez5 entirely if the adapter is rfkilled off. this means e doesnt see it at all - has no idea it's there. bz doesnt expose it. without that we can't turn it on even. so - if our bt adapter list is empty, then assume this is an error and manually list rfkillable devines and forcibly unblock them ot make them appear in bulez5... not so much a bug fix as a system brokenness workaround with bz5 just ignoring rfkill bnlocked devices and not even telling us about them. @fix
This commit is contained in:
parent
128459b6bf
commit
f9607a9084
|
@ -1,12 +1,20 @@
|
||||||
#include "e_system.h"
|
#include "e_system.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RFKILL_BLOCK,
|
||||||
|
RFKILL_UNBLOCK,
|
||||||
|
RFKILL_LIST,
|
||||||
|
} RFKill_Action;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *dev;
|
char *dev;
|
||||||
Ecore_Event_Handler *handle_del, *handle_data;
|
Ecore_Event_Handler *handle_del, *handle_data;
|
||||||
Ecore_Exe *exe;
|
Ecore_Exe *exe;
|
||||||
int id;
|
int id;
|
||||||
Eina_Bool block : 1;
|
RFKill_Action act;
|
||||||
|
Eina_Strbuf *list_ret;
|
||||||
Eina_Bool doit : 1;
|
Eina_Bool doit : 1;
|
||||||
} Action;
|
} Action;
|
||||||
|
|
||||||
|
@ -21,7 +29,8 @@ _rfkill_dev_verify(const char *dev)
|
||||||
((*s >= 'A') && (*s <= 'Z')) ||
|
((*s >= 'A') && (*s <= 'Z')) ||
|
||||||
((*s >= '0') && (*s <= '9')) ||
|
((*s >= '0') && (*s <= '9')) ||
|
||||||
(*s == '-') || (*s == '+') || (*s == ',') || (*s == '.') ||
|
(*s == '-') || (*s == '+') || (*s == ',') || (*s == '.') ||
|
||||||
(*s == '/') || (*s == ':') || (*s == '=') || (*s == '@')))
|
(*s == '/') || (*s == ':') || (*s == '=') || (*s == '@') ||
|
||||||
|
(*s == '_')))
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -34,6 +43,7 @@ _rfkill_action_free(Action *a)
|
||||||
// if (a->exe) ecore_exe_free(a->exe);
|
// if (a->exe) ecore_exe_free(a->exe);
|
||||||
if (a->handle_del) ecore_event_handler_del(a->handle_del);
|
if (a->handle_del) ecore_event_handler_del(a->handle_del);
|
||||||
if (a->handle_data) ecore_event_handler_del(a->handle_data);
|
if (a->handle_data) ecore_event_handler_del(a->handle_data);
|
||||||
|
if (a->list_ret) eina_strbuf_free(a->list_ret);
|
||||||
free(a->dev);
|
free(a->dev);
|
||||||
free(a);
|
free(a);
|
||||||
}
|
}
|
||||||
|
@ -48,10 +58,10 @@ _cb_rfkill_exe_del(void *data, int ev_type EINA_UNUSED, void *event)
|
||||||
{
|
{
|
||||||
if (a->doit)
|
if (a->doit)
|
||||||
{
|
{
|
||||||
if (a->block)
|
if (a->act == RFKILL_BLOCK)
|
||||||
e_system_inout_command_send("rfkill-block", "%i %s",
|
e_system_inout_command_send("rfkill-block", "%i %s",
|
||||||
ev->exit_code, a->dev);
|
ev->exit_code, a->dev);
|
||||||
else
|
else if (a->act == RFKILL_UNBLOCK)
|
||||||
e_system_inout_command_send("rfkill-unblock", "%i %s",
|
e_system_inout_command_send("rfkill-unblock", "%i %s",
|
||||||
ev->exit_code, a->dev);
|
ev->exit_code, a->dev);
|
||||||
_rfkill_action_free(a);
|
_rfkill_action_free(a);
|
||||||
|
@ -63,31 +73,52 @@ _cb_rfkill_exe_del(void *data, int ev_type EINA_UNUSED, void *event)
|
||||||
// a->exe can stay - exe's are auto-freed by ecore on exit
|
// a->exe can stay - exe's are auto-freed by ecore on exit
|
||||||
// ecore_exe_free(a->exe);
|
// ecore_exe_free(a->exe);
|
||||||
a->exe = NULL;
|
a->exe = NULL;
|
||||||
if (snprintf(cmd, sizeof(cmd), "rfkill %s %i",
|
if ((a->act == RFKILL_BLOCK) || (a->act == RFKILL_UNBLOCK))
|
||||||
a->block ? "block" : "unblock", a->id) <
|
|
||||||
(int)(sizeof(cmd) - 1))
|
|
||||||
{
|
{
|
||||||
a->doit = EINA_TRUE;
|
if (snprintf(cmd, sizeof(cmd), "rfkill %s %i",
|
||||||
a->exe = ecore_exe_pipe_run(cmd,
|
(a->act == RFKILL_BLOCK) ? "block" : "unblock",
|
||||||
ECORE_EXE_NOT_LEADER |
|
a->id) < (int)(sizeof(cmd) - 1))
|
||||||
ECORE_EXE_TERM_WITH_PARENT |
|
{
|
||||||
ECORE_EXE_PIPE_READ |
|
a->doit = EINA_TRUE;
|
||||||
ECORE_EXE_PIPE_WRITE |
|
a->exe = ecore_exe_pipe_run(cmd,
|
||||||
ECORE_EXE_PIPE_READ_LINE_BUFFERED, NULL);
|
ECORE_EXE_NOT_LEADER |
|
||||||
if (!a->exe) _rfkill_action_free(a);
|
ECORE_EXE_TERM_WITH_PARENT |
|
||||||
|
ECORE_EXE_PIPE_READ |
|
||||||
|
ECORE_EXE_PIPE_WRITE |
|
||||||
|
ECORE_EXE_PIPE_READ_LINE_BUFFERED, NULL);
|
||||||
|
if (!a->exe) _rfkill_action_free(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (a->act == RFKILL_LIST)
|
||||||
|
{
|
||||||
|
e_system_inout_command_send("rfkill-list", "-");
|
||||||
|
_rfkill_action_free(a);
|
||||||
}
|
}
|
||||||
else _rfkill_action_free(a);
|
else _rfkill_action_free(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (a->block)
|
if (a->act == RFKILL_BLOCK)
|
||||||
e_system_inout_command_send("rfkill-block", "%i %s",
|
e_system_inout_command_send("rfkill-block", "%i %s",
|
||||||
123, a->dev);
|
123, a->dev);
|
||||||
else
|
else if (a->act == RFKILL_UNBLOCK)
|
||||||
e_system_inout_command_send("rfkill-unblock", "%i %s",
|
e_system_inout_command_send("rfkill-unblock", "%i %s",
|
||||||
123, a->dev);
|
123, a->dev);
|
||||||
_rfkill_action_free(a);
|
else if (a->act == RFKILL_LIST)
|
||||||
|
{
|
||||||
|
if (a->list_ret)
|
||||||
|
{
|
||||||
|
const char *s = eina_strbuf_string_get(a->list_ret);
|
||||||
|
if (s)
|
||||||
|
e_system_inout_command_send("rfkill-list", "%s", s);
|
||||||
|
else
|
||||||
|
e_system_inout_command_send("rfkill-list", "-");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
e_system_inout_command_send("rfkill-list", "-");
|
||||||
|
_rfkill_action_free(a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -104,16 +135,26 @@ _cb_rfkill_exe_data(void *data, int ev_type EINA_UNUSED, void *event)
|
||||||
for (i = 0; ev->lines[i].line; i++)
|
for (i = 0; ev->lines[i].line; i++)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
char dev[1024];
|
char dev[1024], type[1024];
|
||||||
|
|
||||||
id = -1;
|
id = -1;
|
||||||
if (sscanf(ev->lines[i].line, "%i: %1023[^:] %*s", &id, dev) == 2)
|
if (sscanf(ev->lines[i].line, "%i: %1023[^:]: %1023[^\n]", &id, dev, type) == 3)
|
||||||
{
|
{
|
||||||
if (!strcmp(a->dev, dev))
|
if ((a->act == RFKILL_BLOCK) || (a->act == RFKILL_UNBLOCK))
|
||||||
{
|
{
|
||||||
a->id = id;
|
if (!strcmp(a->dev, dev))
|
||||||
// wait for exit to spawn rfkill again...
|
{
|
||||||
break;
|
a->id = id;
|
||||||
|
// wait for exit to spawn rfkill again...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!a->list_ret) a->list_ret = eina_strbuf_new();
|
||||||
|
if (a->list_ret)
|
||||||
|
eina_strbuf_append_printf(a->list_ret, "%s\t%s\n",
|
||||||
|
dev, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,14 +162,14 @@ _cb_rfkill_exe_data(void *data, int ev_type EINA_UNUSED, void *event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_rfkill_do(Eina_Bool block, const char *dev)
|
_rfkill_do(RFKill_Action act, const char *dev)
|
||||||
{
|
{
|
||||||
Action *a = calloc(1, sizeof(Action));
|
Action *a = calloc(1, sizeof(Action));
|
||||||
if (!a) return;
|
if (!a) return;
|
||||||
a->dev = strdup(dev);
|
a->dev = strdup(dev);
|
||||||
if (!a->dev) goto err;
|
if (!a->dev) goto err;
|
||||||
a->id = -1;
|
a->id = -1;
|
||||||
a->block = block;
|
a->act = act;
|
||||||
a->handle_del = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
a->handle_del = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
||||||
_cb_rfkill_exe_del, a);
|
_cb_rfkill_exe_del, a);
|
||||||
a->handle_data = ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
|
a->handle_data = ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
|
||||||
|
@ -152,14 +193,20 @@ static void
|
||||||
_cb_rfkill_block(void *data EINA_UNUSED, const char *params)
|
_cb_rfkill_block(void *data EINA_UNUSED, const char *params)
|
||||||
{
|
{
|
||||||
if (!_rfkill_dev_verify(params)) return;
|
if (!_rfkill_dev_verify(params)) return;
|
||||||
_rfkill_do(EINA_TRUE, params);
|
_rfkill_do(RFKILL_BLOCK, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cb_rfkill_unblock(void *data EINA_UNUSED, const char *params)
|
_cb_rfkill_unblock(void *data EINA_UNUSED, const char *params)
|
||||||
{
|
{
|
||||||
if (!_rfkill_dev_verify(params)) return;
|
if (!_rfkill_dev_verify(params)) return;
|
||||||
_rfkill_do(EINA_FALSE, params);
|
_rfkill_do(RFKILL_UNBLOCK, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_rfkill_list(void *data EINA_UNUSED, const char *params EINA_UNUSED)
|
||||||
|
{
|
||||||
|
_rfkill_do(RFKILL_LIST, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -167,6 +214,7 @@ e_system_rfkill_init(void)
|
||||||
{
|
{
|
||||||
e_system_inout_command_register("rfkill-block", _cb_rfkill_block, NULL);
|
e_system_inout_command_register("rfkill-block", _cb_rfkill_block, NULL);
|
||||||
e_system_inout_command_register("rfkill-unblock", _cb_rfkill_unblock, NULL);
|
e_system_inout_command_register("rfkill-unblock", _cb_rfkill_unblock, NULL);
|
||||||
|
e_system_inout_command_register("rfkill-list", _cb_rfkill_list, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -9,6 +9,8 @@ static E_Config_DD *conf_device_edd = NULL;
|
||||||
static E_Config_DD *conf_edd = NULL;
|
static E_Config_DD *conf_edd = NULL;
|
||||||
Config *ebluez5_config = NULL;
|
Config *ebluez5_config = NULL;
|
||||||
|
|
||||||
|
static Ecore_Timer *zero_adapters_check_timer = NULL;
|
||||||
|
|
||||||
E_API E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Bluez5"};
|
E_API E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Bluez5"};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -210,6 +212,48 @@ _cb_rfkill_unblock(void *datam EINA_UNUSED, const char *params)
|
||||||
"users and groups there to be sure."));
|
"users and groups there to be sure."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_rfkill_list(void *datam EINA_UNUSED, const char *params)
|
||||||
|
{
|
||||||
|
if ((!params) || (!strcmp(params, "-"))) return;
|
||||||
|
// params is:
|
||||||
|
// hci0\tBluetooth\n
|
||||||
|
// phy0\tWireless LAN\n
|
||||||
|
// ...
|
||||||
|
// we got a list of possible rf-killable devices and this list callback
|
||||||
|
// will only have happened if we requested a list which we only do if
|
||||||
|
// tjhe list of adapters is empty still 5 seconds after init - something
|
||||||
|
// possibly wrong with them being blocked and thbus bluez not even listing
|
||||||
|
// them, so unblock them to get them listed
|
||||||
|
char **lines = eina_str_split(params, "\n", 0);
|
||||||
|
if (lines)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
char *line = lines[i];
|
||||||
|
|
||||||
|
while (line)
|
||||||
|
{
|
||||||
|
char **fields = eina_str_split(line, "\t", 0);
|
||||||
|
if (fields)
|
||||||
|
{
|
||||||
|
if ((fields[0]) && (fields[1]))
|
||||||
|
{
|
||||||
|
if (!strcasecmp(fields[1], "bluetooth"))
|
||||||
|
{
|
||||||
|
ebluez5_rfkill_unblock(fields[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(fields[0]);
|
||||||
|
free(fields);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
line = lines[i];
|
||||||
|
}
|
||||||
|
free(lines[0]);
|
||||||
|
free(lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ebluez5_rfkill_unblock(const char *name)
|
ebluez5_rfkill_unblock(const char *name)
|
||||||
{
|
{
|
||||||
|
@ -329,6 +373,15 @@ ebluez5_device_prop_unlock_set(const char *address, Eina_Bool enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_cb_zero_adapters_check(void *data EINA_UNUSED)
|
||||||
|
{
|
||||||
|
zero_adapters_check_timer = NULL;
|
||||||
|
if (!ebluez5_popup_adapters_get())
|
||||||
|
e_system_send("rfkill-list", "-");
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/* Module Functions */
|
/* Module Functions */
|
||||||
|
@ -364,6 +417,7 @@ e_modapi_init(E_Module *m)
|
||||||
E_CONFIG_LIST(D, T, devices, conf_device_edd);
|
E_CONFIG_LIST(D, T, devices, conf_device_edd);
|
||||||
|
|
||||||
e_system_handler_add("rfkill-unblock", _cb_rfkill_unblock, NULL);
|
e_system_handler_add("rfkill-unblock", _cb_rfkill_unblock, NULL);
|
||||||
|
e_system_handler_add("rfkill-list", _cb_rfkill_list, NULL);
|
||||||
|
|
||||||
ebluez5_config = e_config_domain_load("module.ebluez5", conf_edd);
|
ebluez5_config = e_config_domain_load("module.ebluez5", conf_edd);
|
||||||
if (!ebluez5_config) ebluez5_config = E_NEW(Config, 1);
|
if (!ebluez5_config) ebluez5_config = E_NEW(Config, 1);
|
||||||
|
@ -373,6 +427,8 @@ e_modapi_init(E_Module *m)
|
||||||
|
|
||||||
e_gadcon_provider_register(&_gc_class);
|
e_gadcon_provider_register(&_gc_class);
|
||||||
|
|
||||||
|
zero_adapters_check_timer = ecore_timer_add(5.0, _cb_zero_adapters_check, NULL);
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,6 +438,12 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED)
|
||||||
Config_Adapter *ad;
|
Config_Adapter *ad;
|
||||||
Config_Device *dev;
|
Config_Device *dev;
|
||||||
|
|
||||||
|
if (zero_adapters_check_timer)
|
||||||
|
{
|
||||||
|
ecore_timer_del(zero_adapters_check_timer);
|
||||||
|
zero_adapters_check_timer = NULL;
|
||||||
|
}
|
||||||
|
e_system_handler_del("rfkill-list", _cb_rfkill_list, NULL);
|
||||||
e_system_handler_del("rfkill-unblock", _cb_rfkill_unblock, NULL);
|
e_system_handler_del("rfkill-unblock", _cb_rfkill_unblock, NULL);
|
||||||
EINA_LIST_FREE(ebluez5_config->adapters, ad)
|
EINA_LIST_FREE(ebluez5_config->adapters, ad)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue