forked from enlightenment/enlightenment
e/bluez4: include bluez4 module
Patch by: Lucas Joia <lucasjoia@profusion.mobi> SVN revision: 82185
This commit is contained in:
parent
271bc56cdd
commit
21c0a5381b
11
configure.ac
11
configure.ac
|
@ -799,6 +799,15 @@ dnl AC_E_CHECK_PKG(DUMMY, [ connman >= 1.0 ], [], [CONNMAN=false])
|
|||
AC_SUBST(ECONNMAN_CFLAGS)
|
||||
AC_SUBST(ECONNMAN_LIBS)
|
||||
|
||||
AM_CONDITIONAL(HAVE_BLUEZ4, false)
|
||||
AM_CONDITIONAL(HAVE_DUMMY, false)
|
||||
define([CHECK_MODULE_BLUEZ4],
|
||||
[
|
||||
AC_E_CHECK_PKG(BLUEZ4, [ edbus2 ],)
|
||||
])
|
||||
AC_SUBST(EBLUEZ4_CFLAGS)
|
||||
AC_SUBST(EBLUEZ4_LIBS)
|
||||
|
||||
have_wayland_clients=no
|
||||
AC_ARG_ENABLE([wayland-clients],
|
||||
AS_HELP_STRING([--enable-wayland-clients],[enable wayland clients in composite module @<:@default=disabled@:>@]),
|
||||
|
@ -857,6 +866,7 @@ AC_E_OPTIONAL_MODULE([conf_interaction], true)
|
|||
AC_E_OPTIONAL_MODULE([gadman], true)
|
||||
AC_E_OPTIONAL_MODULE([mixer], true, [CHECK_MODULE_MIXER])
|
||||
AC_E_OPTIONAL_MODULE([connman], true, [CHECK_MODULE_CONNMAN])
|
||||
AC_E_OPTIONAL_MODULE([bluez4], true, [CHECK_MODULE_BLUEZ4])
|
||||
AC_E_OPTIONAL_MODULE([illume2], true)
|
||||
AC_E_OPTIONAL_MODULE([syscon], true)
|
||||
AC_E_OPTIONAL_MODULE([everything], true)
|
||||
|
@ -957,6 +967,7 @@ src/modules/conf_randr/module.desktop
|
|||
src/modules/gadman/module.desktop
|
||||
src/modules/mixer/module.desktop
|
||||
src/modules/connman/module.desktop
|
||||
src/modules/bluez4/module.desktop
|
||||
src/modules/illume2/doc/illume.dox
|
||||
src/modules/illume2/module.desktop
|
||||
src/modules/illume-home/module.desktop
|
||||
|
|
|
@ -30,6 +30,10 @@ if USE_MODULE_CONNMAN
|
|||
include Makefile_connman.am
|
||||
endif
|
||||
|
||||
if USE_MODULE_BLUEZ4
|
||||
include Makefile_bluez4.am
|
||||
endif
|
||||
|
||||
if USE_MODULE_IBAR
|
||||
include Makefile_ibar.am
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
bluez4dir = $(MDIR)/bluez4
|
||||
bluez4_DATA = bluez4/e-module-bluez4.edj \
|
||||
bluez4/module.desktop
|
||||
|
||||
EXTRA_DIST += $(bluez4_DATA)
|
||||
|
||||
bluez4pkgdir = $(MDIR)/bluez4/$(MODULE_ARCH)
|
||||
bluez4pkg_LTLIBRARIES = bluez4/module.la
|
||||
|
||||
bluez4_module_la_SOURCES = bluez4/e_mod_main.h \
|
||||
bluez4/e_mod_main.c \
|
||||
bluez4/ebluez4.h \
|
||||
bluez4/ebluez4.c \
|
||||
bluez4/agent.h \
|
||||
bluez4/agent.c
|
||||
|
||||
bluez4_module_la_CFLAGS = $(AM_CFLAGS) -Wno-unused-parameter
|
||||
bluez4_module_la_LIBADD = @BLUEZ4_LIBS@
|
||||
|
||||
.PHONY: bluez4 install-bluez4
|
||||
bluez4: $(bluez4pkg_LTLIBRARIES) $(bluez4_DATA)
|
||||
install-bluez4: install-bluez4DATA install-bluez4pkgLTLIBRARIES
|
|
@ -0,0 +1,133 @@
|
|||
#include <inttypes.h>
|
||||
#include "e.h"
|
||||
#include "agent.h"
|
||||
|
||||
#define AGENT_INTERFACE "org.bluez.Agent"
|
||||
#define BLUEZ_ERROR_FAILED "org.bluez.Error.Failed"
|
||||
#define GET_ERROR_MSG "edbus_message_arguments_get() error"
|
||||
|
||||
static EDBus_Message *
|
||||
_agent_release(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
DBG("Agent Released.");
|
||||
return edbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_agent_request_pin_code(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
//FIXME: generate random number and show it in dialog
|
||||
EDBus_Message *reply = edbus_message_method_return_new(message);
|
||||
edbus_message_arguments_set(reply, "s", "123456");
|
||||
DBG("Pin Code Requested.");
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_agent_request_passkey(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
//FIXME: generate random number and show it in dialog
|
||||
EDBus_Message *reply = edbus_message_method_return_new(message);
|
||||
edbus_message_arguments_set(reply, "s", "123456");
|
||||
DBG("Passkey Requested.");
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_agent_display_passkey(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
//FIXME: show passkey in dialog
|
||||
const char *device;
|
||||
uint32_t passkey;
|
||||
uint16_t entered;
|
||||
if(!edbus_message_arguments_get(message, "ouq", &device, &passkey, &entered))
|
||||
return edbus_message_error_new(message, BLUEZ_ERROR_FAILED, GET_ERROR_MSG);
|
||||
DBG("Device: %s", device);
|
||||
DBG("Passkey: %u", passkey);
|
||||
DBG("Entered: %d", entered);
|
||||
return edbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_agent_display_pin_code(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
//FIXME: show passkey in dialog
|
||||
const char *device, *pincode;
|
||||
if(!edbus_message_arguments_get(message, "os", &device, &pincode))
|
||||
return edbus_message_error_new(message, BLUEZ_ERROR_FAILED, GET_ERROR_MSG);
|
||||
DBG("Device: %s", device);
|
||||
DBG("Passkey: %s", pincode);
|
||||
return edbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_agent_request_confirmation(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
//FIXME: Ask for confirmation in dialog
|
||||
const char *device;
|
||||
uint32_t passkey;
|
||||
if(!edbus_message_arguments_get(message, "ou", &device, &passkey))
|
||||
return edbus_message_error_new(message, BLUEZ_ERROR_FAILED, GET_ERROR_MSG);
|
||||
DBG("Confirming request of %u for device %s", passkey, device);
|
||||
return edbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_agent_authorize(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
//FIXME: Ask for authorization in dialog
|
||||
const char *device, *uuid;
|
||||
if(!edbus_message_arguments_get(message, "os", &device, &uuid))
|
||||
return edbus_message_error_new(message, BLUEZ_ERROR_FAILED, GET_ERROR_MSG);
|
||||
DBG("Authorizing request for %s", device);
|
||||
return edbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_agent_cancel(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
DBG("Request canceled.");
|
||||
return edbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static const EDBus_Method agent_methods[] = {
|
||||
{ "Release", NULL, NULL, _agent_release, 0 },
|
||||
{
|
||||
"RequestPinCode", EDBUS_ARGS({"o", "device"}),
|
||||
EDBUS_ARGS({"s", "pincode"}), _agent_request_pin_code, 0
|
||||
},
|
||||
{
|
||||
"RequestPasskey", EDBUS_ARGS({"o", "device"}),
|
||||
EDBUS_ARGS({"u", "passkey"}), _agent_request_passkey, 0
|
||||
},
|
||||
{
|
||||
"DisplayPasskey",
|
||||
EDBUS_ARGS({"o", "device"},{"u", "passkey"},{"q", "entered"}),
|
||||
NULL, _agent_display_passkey, 0
|
||||
},
|
||||
{
|
||||
"DisplayPinCode", EDBUS_ARGS({"o", "device"},{"s", "pincode"}),
|
||||
NULL, _agent_display_pin_code, 0
|
||||
},
|
||||
{
|
||||
"RequestConfirmation", EDBUS_ARGS({"o", "device"},{"u", "passkey"}),
|
||||
NULL, _agent_request_confirmation, 0
|
||||
},
|
||||
{
|
||||
"Authorize", EDBUS_ARGS({"o", "device"},{"s", "uuid"}),
|
||||
NULL, _agent_authorize, 0
|
||||
},
|
||||
{ "Cancel", NULL, NULL, _agent_cancel, 0 },
|
||||
{ NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static const EDBus_Service_Interface_Desc agent_iface = {
|
||||
AGENT_INTERFACE, agent_methods, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
void ebluez4_register_agent_interfaces(EDBus_Connection *conn)
|
||||
{
|
||||
edbus_service_interface_register(conn, AGENT_PATH, &agent_iface);
|
||||
edbus_service_interface_register(conn, REMOTE_AGENT_PATH, &agent_iface);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#include "EDBus.h"
|
||||
|
||||
#define AGENT_PATH "/org/bluez/Agent"
|
||||
#define REMOTE_AGENT_PATH "/org/bluez/RemoteAgent"
|
||||
|
||||
void ebluez4_register_agent_interfaces(EDBus_Connection *conn);
|
Binary file not shown.
|
@ -0,0 +1,235 @@
|
|||
#include <e.h>
|
||||
#include <EDBus.h>
|
||||
#include "e_mod_main.h"
|
||||
#include "ebluez4.h"
|
||||
|
||||
/* Local Variables */
|
||||
static Eina_List *instances = NULL;
|
||||
static E_Module *mod = NULL;
|
||||
static char tmpbuf[1024];
|
||||
|
||||
EAPI E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Bluez4"};
|
||||
|
||||
/* Local Functions */
|
||||
static void
|
||||
_ebluez4_cb_pair(void *data, void *data2 __UNUSED__)
|
||||
{
|
||||
Instance *inst = data;
|
||||
const char *addr = e_widget_ilist_selected_value_get(inst->list);
|
||||
|
||||
if(!addr)
|
||||
return;
|
||||
e_gadcon_popup_hide(inst->popup);
|
||||
DBG("Pairing with : %s", addr);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ebluez4_cb_stop_search(void *data)
|
||||
{
|
||||
Instance *inst = data;
|
||||
ebluez4_stop_discovery();
|
||||
e_widget_disabled_set(inst->bt, 0);
|
||||
DBG("Stopping discovery...");
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_search(void *data, void *data2 __UNUSED__)
|
||||
{
|
||||
Instance *inst = data;
|
||||
ebluez4_start_discovery();
|
||||
e_widget_disabled_set(inst->bt, 1);
|
||||
ecore_timer_add(60, _ebluez4_cb_stop_search, inst);
|
||||
DBG("Starting discovery...");
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_popup_new(Instance *inst)
|
||||
{
|
||||
Evas_Object *list, *tb, *bt2;
|
||||
Evas_Coord mw, mh;
|
||||
Evas *evas;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN(inst->popup == NULL);
|
||||
|
||||
inst->popup = e_gadcon_popup_new(inst->gcc);
|
||||
evas = inst->popup->win->evas;
|
||||
|
||||
list = e_widget_list_add(evas, 0, 0);
|
||||
inst->list = e_widget_ilist_add(evas, 0, 0, NULL);
|
||||
e_widget_list_object_append(list, inst->list, 1, 1, 0.5);
|
||||
|
||||
e_widget_ilist_header_append(inst->list, NULL, "Devices Found");
|
||||
|
||||
inst->bt = e_widget_button_add(evas, "Search Devices", NULL,
|
||||
_ebluez4_cb_search, inst, NULL);
|
||||
bt2 = e_widget_button_add(evas, "Connect", NULL, _ebluez4_cb_pair, inst, NULL);
|
||||
|
||||
tb = e_widget_table_add(evas, 0);
|
||||
|
||||
e_widget_table_object_append(tb, inst->bt, 0, 0, 1, 1, 1, 1, 1, 1);
|
||||
e_widget_table_object_append(tb, bt2, 1, 0, 1, 1, 1, 1, 1, 1);
|
||||
e_widget_list_object_append(list, tb, 1, 0, 0.5);
|
||||
|
||||
e_widget_size_min_get(list, &mw, &mh);
|
||||
if (mh < 220)
|
||||
mh = 220;
|
||||
if (mw < 250)
|
||||
mw = 250;
|
||||
e_widget_size_min_set(list, mw, mh);
|
||||
|
||||
e_gadcon_popup_content_set(inst->popup, list);
|
||||
e_gadcon_popup_show(inst->popup);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_popup_del(Instance *inst)
|
||||
{
|
||||
if (!inst->popup) return;
|
||||
e_object_del(E_OBJECT(inst->popup));
|
||||
inst->popup = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event)
|
||||
{
|
||||
Instance *inst = NULL;
|
||||
Evas_Event_Mouse_Down *ev = event;
|
||||
|
||||
if (!(inst = data)) return;
|
||||
if (ev->button != 1) return;
|
||||
|
||||
if (!inst->popup)
|
||||
_ebluez4_popup_new(inst);
|
||||
else if (inst->popup->win->visible)
|
||||
e_gadcon_popup_hide(inst->popup);
|
||||
else
|
||||
e_gadcon_popup_show(inst->popup);
|
||||
}
|
||||
|
||||
/* Gadcon */
|
||||
static E_Gadcon_Client *
|
||||
_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
|
||||
{
|
||||
Instance *inst = NULL;
|
||||
char buf[1024];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/e-module-bluez4.edj", mod->dir);
|
||||
|
||||
inst = E_NEW(Instance, 1);
|
||||
|
||||
inst->o_bluez4 = edje_object_add(gc->evas);
|
||||
if (!e_theme_edje_object_set(inst->o_bluez4, "base/theme/modules/bluez4",
|
||||
"modules/bluez4/main"))
|
||||
edje_object_file_set(inst->o_bluez4, buf, "modules/bluez4/main");
|
||||
|
||||
inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->o_bluez4);
|
||||
inst->gcc->data = inst;
|
||||
|
||||
evas_object_event_callback_add(inst->o_bluez4, EVAS_CALLBACK_MOUSE_DOWN,
|
||||
_ebluez4_cb_mouse_down, inst);
|
||||
|
||||
instances = eina_list_append(instances, inst);
|
||||
|
||||
return inst->gcc;
|
||||
}
|
||||
|
||||
static void
|
||||
_gc_shutdown(E_Gadcon_Client *gcc)
|
||||
{
|
||||
Instance *inst = NULL;
|
||||
|
||||
if (!(inst = gcc->data)) return;
|
||||
instances = eina_list_remove(instances, inst);
|
||||
|
||||
if (inst->o_bluez4)
|
||||
{
|
||||
evas_object_event_callback_del(inst->o_bluez4, EVAS_CALLBACK_MOUSE_DOWN,
|
||||
_ebluez4_cb_mouse_down);
|
||||
evas_object_del(inst->o_bluez4);
|
||||
}
|
||||
|
||||
_ebluez4_popup_del(inst);
|
||||
|
||||
E_FREE(inst);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_gc_id_new(const E_Gadcon_Client_Class *client_class)
|
||||
{
|
||||
snprintf(tmpbuf, sizeof(tmpbuf), "bluez4.%d", eina_list_count(instances));
|
||||
return tmpbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
_gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient)
|
||||
{
|
||||
e_gadcon_client_aspect_set(gcc, 16, 16);
|
||||
e_gadcon_client_min_size_set(gcc, 16, 16);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_gc_label(const E_Gadcon_Client_Class *client_class)
|
||||
{
|
||||
return "Bluez4";
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_gc_icon(const E_Gadcon_Client_Class *client_class, Evas *evas)
|
||||
{
|
||||
Evas_Object *o = NULL;
|
||||
char buf[4096];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/e-module-bluez4.edj", mod->dir);
|
||||
|
||||
o = edje_object_add(evas);
|
||||
|
||||
edje_object_file_set(o, buf, "icon");
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
static const E_Gadcon_Client_Class _gc_class =
|
||||
{
|
||||
GADCON_CLIENT_CLASS_VERSION, "bluez4",
|
||||
{_gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon,
|
||||
_gc_id_new, NULL, NULL},
|
||||
E_GADCON_CLIENT_STYLE_PLAIN
|
||||
};
|
||||
|
||||
/* Module Functions */
|
||||
EAPI void *
|
||||
e_modapi_init(E_Module *m)
|
||||
{
|
||||
mod = m;
|
||||
|
||||
ebluez4_edbus_init();
|
||||
|
||||
e_gadcon_provider_register(&_gc_class);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
e_modapi_shutdown(E_Module *m)
|
||||
{
|
||||
ebluez4_edbus_shutdown();
|
||||
return 1;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
e_modapi_save(E_Module *m)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Public Functions */
|
||||
void
|
||||
ebluez4_disabled_set_all_search_buttons(Eina_Bool disabled)
|
||||
{
|
||||
Eina_List *iter;
|
||||
Instance *inst;
|
||||
|
||||
EINA_LIST_FOREACH(instances, iter, inst)
|
||||
e_widget_disabled_set(inst->bt, disabled);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef E_MOD_MAIN_H
|
||||
#define E_MOD_MAIN_H
|
||||
|
||||
typedef struct _Instance Instance;
|
||||
struct _Instance
|
||||
{
|
||||
E_Gadcon_Client *gcc;
|
||||
E_Gadcon_Popup *popup;
|
||||
Evas_Object *o_bluez4, *bt;
|
||||
Evas_Object *list;
|
||||
};
|
||||
|
||||
EAPI extern E_Module_Api e_modapi;
|
||||
|
||||
EAPI void *e_modapi_init(E_Module *m);
|
||||
EAPI int e_modapi_shutdown(E_Module *m);
|
||||
EAPI int e_modapi_save(E_Module *m);
|
||||
|
||||
void ebluez4_disabled_set_all_search_buttons(Eina_Bool disabled);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,216 @@
|
|||
#include <unistd.h>
|
||||
#include "e.h"
|
||||
#include "agent.h"
|
||||
#include "e_mod_main.h"
|
||||
#include "ebluez4.h"
|
||||
|
||||
/* Global Module Context */
|
||||
Context *ctxt;
|
||||
|
||||
static int
|
||||
_addr_cmp(const void *d1, const void *d2)
|
||||
{
|
||||
const Device *dev = d1;
|
||||
const char *addr = d2;
|
||||
|
||||
return strcmp(dev->addr, addr);
|
||||
}
|
||||
|
||||
static void
|
||||
_free_dev(Device *dev)
|
||||
{
|
||||
eina_stringshare_del(dev->addr);
|
||||
dev->addr = NULL;
|
||||
eina_stringshare_del(dev->name);
|
||||
dev->name = NULL;
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
_free_dev_list(Eina_List **list)
|
||||
{
|
||||
Device *dev;
|
||||
|
||||
EINA_LIST_FREE(*list, dev)
|
||||
_free_dev(dev);
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_unset_adapter()
|
||||
{
|
||||
if (!ctxt->adap_obj)
|
||||
return;
|
||||
|
||||
DBG("Remove adapter %s", edbus_object_path_get(ctxt->adap_obj));
|
||||
|
||||
_free_dev_list(&ctxt->devices);
|
||||
ctxt->devices = NULL;
|
||||
edbus_object_unref(ctxt->adap_obj);
|
||||
ctxt->adap_obj = NULL;
|
||||
ebluez4_disabled_set_all_search_buttons(EINA_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_device_found(void *context, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message_Iter *dict, *entry, *variant;
|
||||
const char *addr, *key, *name;
|
||||
Device *dev;
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "sa{sv}", &addr, &dict))
|
||||
{
|
||||
ERR("Error reading device address");
|
||||
return;
|
||||
}
|
||||
|
||||
if(eina_list_search_unsorted(ctxt->devices, _addr_cmp, addr))
|
||||
return;
|
||||
|
||||
while (edbus_message_iter_get_and_next(dict,'e', &entry))
|
||||
{
|
||||
if(!edbus_message_iter_arguments_get(entry, "sv", &key, &variant))
|
||||
{
|
||||
ERR("Error reading device property");
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcmp(key,"Name"))
|
||||
continue;
|
||||
|
||||
if(!edbus_message_iter_arguments_get(variant, "s", &name))
|
||||
{
|
||||
ERR("Error reading device name");
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("Device Found --- Name: %s", name);
|
||||
dev = malloc(sizeof(Device));
|
||||
dev->addr = eina_stringshare_add(addr);
|
||||
dev->name = eina_stringshare_add(name);
|
||||
ctxt->devices = eina_list_append(ctxt->devices, dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_set_adapter(const EDBus_Message *msg)
|
||||
{
|
||||
const char *adap_path;
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "o", &adap_path))
|
||||
{
|
||||
ERR("Error reading path of Default Adapter");
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("Setting adapter to %s", adap_path);
|
||||
|
||||
if (ctxt->adap_obj)
|
||||
_unset_adapter();
|
||||
|
||||
ctxt->adap_obj = edbus_object_get(ctxt->conn, BLUEZ_BUS, adap_path);
|
||||
ctxt->adap_proxy = edbus_proxy_get(ctxt->adap_obj, ADAPTER_INTERFACE);
|
||||
|
||||
ebluez4_disabled_set_all_search_buttons(EINA_FALSE);
|
||||
edbus_proxy_signal_handler_add(ctxt->adap_proxy, "DeviceFound",
|
||||
_on_device_found, NULL);
|
||||
edbus_proxy_call(ctxt->adap_proxy, "RegisterAgent", NULL, NULL, -1, "os",
|
||||
REMOTE_AGENT_PATH, "KeyboardDisplay");
|
||||
}
|
||||
|
||||
static void
|
||||
_default_adapter_get(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *err_name, *err_msg;
|
||||
|
||||
/*
|
||||
* If bluetoothd is starting up, we can fail here and wait for the
|
||||
* DefaultAdapterChanged signal later
|
||||
*/
|
||||
if (edbus_message_error_get(msg, &err_name, &err_msg))
|
||||
return;
|
||||
|
||||
if (!ctxt->adap_obj)
|
||||
_set_adapter(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_adapter_changed(void *context, const EDBus_Message *msg)
|
||||
{
|
||||
_set_adapter(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_adapter_removed(void *context, const EDBus_Message *msg)
|
||||
{
|
||||
const char *adap_path;
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "o", &adap_path))
|
||||
{
|
||||
ERR("Error reading path of Removed Adapter");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(edbus_object_path_get(ctxt->adap_obj), adap_path))
|
||||
_unset_adapter();
|
||||
}
|
||||
|
||||
static void
|
||||
_bluez_monitor(void *data, const char *bus, const char *old_id, const char *new_id)
|
||||
{
|
||||
if (!strcmp(old_id,"") && strcmp(new_id,""))
|
||||
// Bluez up
|
||||
edbus_proxy_call(ctxt->man_proxy, "DefaultAdapter", _default_adapter_get,
|
||||
NULL, -1, "");
|
||||
else if (strcmp(old_id,"") && !strcmp(new_id,""))
|
||||
// Bluez down
|
||||
_unset_adapter();
|
||||
}
|
||||
|
||||
/* Public Functions */
|
||||
void
|
||||
ebluez4_edbus_init()
|
||||
{
|
||||
EDBus_Object *obj;
|
||||
|
||||
ctxt = calloc(1, sizeof(Context));
|
||||
|
||||
edbus_init();
|
||||
|
||||
ctxt->conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SYSTEM);
|
||||
obj = edbus_object_get(ctxt->conn, BLUEZ_BUS, MANAGER_PATH);
|
||||
ctxt->man_proxy = edbus_proxy_get(obj, MANAGER_INTERFACE);
|
||||
|
||||
ebluez4_register_agent_interfaces(ctxt->conn);
|
||||
|
||||
edbus_proxy_signal_handler_add(ctxt->man_proxy,
|
||||
"DefaultAdapterChanged", _on_adapter_changed, NULL);
|
||||
edbus_proxy_signal_handler_add(ctxt->man_proxy, "AdapterRemoved",
|
||||
_on_adapter_removed, NULL);
|
||||
|
||||
edbus_name_owner_changed_callback_add(ctxt->conn, BLUEZ_BUS, _bluez_monitor,
|
||||
NULL, EINA_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_edbus_shutdown()
|
||||
{
|
||||
_free_dev_list(&ctxt->devices);
|
||||
edbus_connection_unref(ctxt->conn);
|
||||
free(ctxt);
|
||||
|
||||
edbus_shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_start_discovery()
|
||||
{
|
||||
_free_dev_list(&ctxt->devices);
|
||||
edbus_proxy_call(ctxt->adap_proxy, "StartDiscovery", NULL, NULL, -1, "");
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_stop_discovery()
|
||||
{
|
||||
edbus_proxy_call(ctxt->adap_proxy, "StopDiscovery", NULL, NULL, -1, "");
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#include "EDBus.h"
|
||||
|
||||
#define BLUEZ_BUS "org.bluez"
|
||||
#define MANAGER_PATH "/"
|
||||
#define ADAPTER_INTERFACE "org.bluez.Adapter"
|
||||
#define MANAGER_INTERFACE "org.bluez.Manager"
|
||||
|
||||
typedef struct _Device
|
||||
{
|
||||
const char *addr;
|
||||
const char *name;
|
||||
} Device;
|
||||
|
||||
typedef struct _Context
|
||||
{
|
||||
EDBus_Connection *conn;
|
||||
const char *default_adap_path;
|
||||
EDBus_Object *adap_obj;
|
||||
EDBus_Proxy *man_proxy;
|
||||
EDBus_Proxy *adap_proxy;
|
||||
Eina_List *devices;
|
||||
} Context;
|
||||
|
||||
void ebluez4_edbus_init();
|
||||
void ebluez4_edbus_shutdown();
|
||||
void ebluez4_start_discovery();
|
||||
void ebluez4_stop_discovery();
|
|
@ -0,0 +1,6 @@
|
|||
[Desktop Entry]
|
||||
Type=Link
|
||||
Name=Bluez4
|
||||
Icon=e-module-bluez4
|
||||
#Several different types available here. NEED TO DOC THESE.
|
||||
X-Enlightenment-ModuleType=utils
|
Loading…
Reference in New Issue