summaryrefslogtreecommitdiff
path: root/recipes-connectivity/bluez
diff options
context:
space:
mode:
authorJohn Klug <john.klug@multitech.com>2017-10-18 17:46:54 -0500
committerJohn Klug <john.klug@multitech.com>2017-10-18 17:46:54 -0500
commit84591cf1f33e695add589a882653b86504f2d1e0 (patch)
tree028a820ff621c03f952c855ea32d7808b630d9fc /recipes-connectivity/bluez
parent603994e38d6ff3a319fcc269c1b235fcfd53e14e (diff)
downloadmeta-mlinux-84591cf1f33e695add589a882653b86504f2d1e0.tar.gz
meta-mlinux-84591cf1f33e695add589a882653b86504f2d1e0.tar.bz2
meta-mlinux-84591cf1f33e695add589a882653b86504f2d1e0.zip
bt-pan daemon for bluetooth pan
Diffstat (limited to 'recipes-connectivity/bluez')
-rw-r--r--recipes-connectivity/bluez/bluez5.inc34
-rwxr-xr-xrecipes-connectivity/bluez/bluez5/bt-pan/bt-pan425
-rwxr-xr-xrecipes-connectivity/bluez/bluez5/bt-pan/default2
-rwxr-xr-xrecipes-connectivity/bluez/bluez5/bt-pan/init40
-rwxr-xr-x[-rw-r--r--]recipes-connectivity/bluez/bluez5/init2
-rw-r--r--recipes-connectivity/bluez/bluez5/main.conf108
-rw-r--r--recipes-connectivity/bluez/bluez5_5.47.bb4
7 files changed, 604 insertions, 11 deletions
diff --git a/recipes-connectivity/bluez/bluez5.inc b/recipes-connectivity/bluez/bluez5.inc
index c1fed4e..b7ca007 100644
--- a/recipes-connectivity/bluez/bluez5.inc
+++ b/recipes-connectivity/bluez/bluez5.inc
@@ -1,5 +1,5 @@
SUMMARY = "Linux Bluetooth Stack Userland V5"
-PR = "m1"
+PR = "m2"
DESCRIPTION = "Linux Bluetooth stack V5 userland components. These include a system configurations, daemons, tools and system libraries."
HOMEPAGE = "http://www.bluez.org"
SECTION = "libs"
@@ -8,6 +8,8 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e \
file://COPYING.LIB;md5=fb504b67c50331fc78734fed90fb0e09 \
file://src/main.c;beginline=1;endline=24;md5=9bc54b93cd7e17bf03f52513f39f926e"
DEPENDS = "udev libusb dbus-glib glib-2.0 libcheck readline"
+RDEPENDS_${PN}-pand += "bash"
+DEPENDS_${PN}-pand += "python-dbus python-logging python-syslog"
PROVIDES += "bluez-hcidump"
RPROVIDES_${PN} += "bluez-hcidump"
@@ -25,7 +27,10 @@ SRC_URI = "\
${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '', 'file://0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch', d)} \
file://0001-tests-add-a-target-for-building-tests-without-runnin.patch \
file://default \
- file://CVE-2017-1000250.patch \
+ file://main.conf \
+ file://bt-pan/init \
+ file://bt-pan/default \
+ file://bt-pan/bt-pan \
"
S = "${WORKDIR}/bluez-${PV}"
@@ -51,10 +56,14 @@ NOINST_TOOLS = " \
${@bb.utils.contains('PACKAGECONFIG', 'experimental', '${NOINST_TOOLS_EXPERIMENTAL}', '', d)} \
"
+DBTEXEC = "${D}${libexecdir}/bluetooth/"
+
do_install_append() {
install -d ${D}${INIT_D_DIR}
install -m 0755 ${WORKDIR}/init ${D}${INIT_D_DIR}/bluetooth
-
+ install -m 0755 ${WORKDIR}/bt-pan/init ${D}${INIT_D_DIR}/bt-pan
+ install -d ${DBTEXEC}
+ install -m 0755 ${WORKDIR}/bt-pan/bt-pan ${DBTEXEC}
install -d ${D}${sysconfdir}/bluetooth/
if [ -f ${S}/profiles/audio/audio.conf ]; then
@@ -67,9 +76,9 @@ do_install_append() {
install -m 0644 ${S}/profiles/input/input.conf ${D}/${sysconfdir}/bluetooth/
fi
- if [ -f ${D}/${sysconfdir}/init.d/bluetooth ]; then
- sed -i -e 's#@LIBEXECDIR@#${libexecdir}#g' ${D}/${sysconfdir}/init.d/bluetooth
- fi
+ if [ -f ${D}/${sysconfdir}/init.d/bluetooth ]; then
+ sed -i -e 's#@LIBEXECDIR@#${libexecdir}#g' ${D}/${sysconfdir}/init.d/bluetooth
+ fi
# Install desired tools that upstream leaves in build area
for f in ${NOINST_TOOLS} ; do
@@ -82,13 +91,16 @@ do_install_append() {
install -d ${D}${sysconfdir}/default
install -m 0644 ${WORKDIR}/default ${D}${sysconfdir}/default/bluetooth
+ install -m 0644 ${WORKDIR}/bt-pan/default ${D}${sysconfdir}/default/bt-pan
+ install -m 0644 ${WORKDIR}/main.conf ${D}${sysconfdir}/bluetooth/
}
ALLOW_EMPTY_libasound-module-bluez = "1"
-PACKAGES =+ "libasound-module-bluez ${PN}-testtools ${PN}-obex ${PN}-noinst-tools"
+PACKAGES =+ "libasound-module-bluez ${PN}-testtools ${PN}-obex ${PN}-noinst-tools ${PN}-pand"
FILES_libasound-module-bluez = "${libdir}/alsa-lib/lib*.so ${datadir}/alsa"
FILES_${PN} += "${libdir}/bluetooth/plugins/*.so ${systemd_unitdir}/ ${datadir}/dbus-1"
+CONFFILES_${PN} += "${sysconfdir}/default/bluetooth ${sysconfdir}/bluetooth/main.conf ${sysconfdir}/bluetooth/input.conf ${sysconfdir}/bluetooth/network.conf"
FILES_${PN}-dev += "\
${libdir}/bluetooth/plugins/*.la \
${libdir}/alsa-lib/*.la \
@@ -98,6 +110,9 @@ FILES_${PN}-obex = "${libexecdir}/bluetooth/obexd \
${exec_prefix}/lib/systemd/user/obex.service \
${datadir}/dbus-1/services/org.bluez.obex.service \
"
+
+FILES_${PN}-pand = "${libexecdir}/bluetooth/bluetooth/bt-pan ${sysconfdir}/default/bt-pan ${sysconfdir}/init.d/bt-pan"
+CONFFILES_${PN}-pand = "${sysconfdir}/default/bt-pan"
SYSTEMD_SERVICE_${PN}-obex = "obex.service"
FILES_${PN}-testtools = "${libdir}/bluez/test/*"
@@ -115,8 +130,11 @@ FILES_${PN}-noinst-tools = "${@get_noinst_tools_paths(d, bb, d.getVar('NOINST_TO
RDEPENDS_${PN}-testtools += "python3 python3-dbus python3-pygobject"
SYSTEMD_SERVICE_${PN} = "bluetooth.service"
-INITSCRIPT_PACKAGES = "${PN}"
+INITSCRIPT_PACKAGES = "${PN} ${PN}-pand"
INITSCRIPT_NAME_${PN} = "bluetooth"
+INITSCRIPT_NAME_${PN}-pand = "bt-pan"
+INITSCRIPT_PARAMS_${PN} = "defaults 20 20"
+INITSCRIPT_PARAMS_${PN}-pand = "defaults 22 22"
EXCLUDE_FROM_WORLD = "1"
diff --git a/recipes-connectivity/bluez/bluez5/bt-pan/bt-pan b/recipes-connectivity/bluez/bluez5/bt-pan/bt-pan
new file mode 100755
index 0000000..987ecaa
--- /dev/null
+++ b/recipes-connectivity/bluez/bluez5/bt-pan/bt-pan
@@ -0,0 +1,425 @@
+#!/usr/bin/env python2
+from __future__ import absolute_import, print_function
+
+import os, sys, time, types, subprocess, signal
+
+import dbus
+import logging
+import logging.handlers
+
+# cgitb is in python-misc and requires python-pkgutil and python-pydoc
+# It is very usefull for analyzing exceptions.
+# import cgitb
+
+# who am i
+myscript = os.path.basename(__file__)
+
+# Log formating class
+class flog:
+ # priority strings to be used
+ # with the __init__ function
+ priorities = {
+ 'debug': logging.DEBUG,
+ 'info': logging.INFO,
+ 'warn': logging.WARNING,
+ 'warning': logging.WARNING,
+ 'error': logging.ERROR,
+ 'critical': logging.CRITICAL,
+ }
+
+ def __init__(self,myscript,facility,priority):
+ """
+ Initialize for logging
+
+ :param myscript: The name of the python program script
+ :param facility: The syslog facility, such as daemon or user
+ :param priority: The minimum priority to be printed to the log
+ :returns: Nothing
+ :raises TBD: logging class errors.
+ """
+ name_len = str(len(myscript))
+ self.myscript = myscript
+ self.log = logging.getLogger(myscript)
+ self.handler = logging.handlers.SysLogHandler(address=('/dev/log'),facility=facility)
+ self.default_fmt = ' %(levelname)-9s %(name)-' + name_len + 's %(message)s'
+ self.verbose_fmt1 = ' %(levelname)-9s %(name)-' + name_len + 's %(threadName)-14s '
+ self.verbose_fmt2 = ' %(message)s'
+ formatter = logging.Formatter(self.default_fmt)
+ self.handler.setFormatter(formatter)
+ self.log.setLevel(self.priorities[priority]) # Minimum infolevel to log
+ self.log.addHandler(self.handler)
+ self.handler.createLock()
+
+ def __default(self,func,*args):
+ self.handler.acquire()
+ formatter = logging.Formatter(self.default_fmt)
+ self.handler.setFormatter(formatter)
+ func(*args)
+ self.handler.release()
+
+ def setThreshold(self,threshold):
+ """
+ Change the syslog priority threshold
+
+ :param priority: Character string corresponding to the threshold
+ """
+ self.handler.acquire()
+ self.log.setLevel(self.priorities[threshold]) # Minimum infolevel to log
+ self.handler.release()
+
+ def critical(self,*args):
+ """
+ Prints a variable argument list at critical priority
+
+ :returns: logging result
+ """
+ self.__default(self.log.critical,*args)
+
+ def error(self,*args):
+ """
+ Prints a variable argument list at error priority
+
+ :returns: logging result
+ """
+ self.__default(self.log.error,*args)
+
+ def warning(self,*args):
+ """
+ Prints a variable argument list at warning priority
+
+ :returns: logging result
+ """
+ self.__default(self.log.warning,*args)
+
+ # Python has no notice level!
+
+ def info(self,*args):
+ """
+ Prints a variable argument list at info priority
+
+ :returns: logging result
+ """
+ self.__default(self.log.info,*args)
+
+ def debug(self,*args):
+ """
+ Prints a variable argument list at debug priority
+
+ Printing debug includes function name and line
+ number.
+
+ :returns: logging result
+ """
+ caller_frame = sys._getframe().f_back
+ callerfunc = caller_frame.f_code.co_name + '@' + str(caller_frame.f_lineno);
+ callerfunc = callerfunc.ljust(16)
+ self.handler.acquire()
+ log = logging.getLogger(self.myscript)
+ formatter = logging.Formatter(self.verbose_fmt1+callerfunc+self.verbose_fmt2)
+ self.handler.setFormatter(formatter)
+ log.debug(*args)
+ self.handler.release()
+
+# End of log handler
+
+### ~bluezutils.py
+
+iface_base = 'org.bluez'
+iface_dev = '{}.Device1'.format(iface_base)
+iface_adapter = '{}.Adapter1'.format(iface_base)
+iface_props = 'org.freedesktop.DBus.Properties'
+global lg
+
+# Will this write to syslog?????
+class BTError(Exception): pass
+
+def get_bus():
+ bus = getattr(get_bus, 'cached_obj', None)
+ if not bus: bus = get_bus.cached_obj = dbus.SystemBus()
+ return bus
+
+def get_manager():
+ manager = getattr(get_manager, 'cached_obj', None)
+ if not manager:
+ try:
+ manager = get_manager.cached_obj = dbus.Interface(
+ get_bus().get_object(iface_base, '/'),
+ 'org.freedesktop.DBus.ObjectManager' )
+ except dbus.exceptions.DBusException as e:
+ s=""
+ try:
+ s = e.__dict__["_dbus_error_name"]
+ except KeyError:
+ pass
+ unk = 'org.freedesktop.DBus.Error.ServiceUnknown'
+ cexit = 'org.freedesktop.DBus.Error.Spawn.ChildExited'
+ if (s == unk) or (s == cexit):
+ msg = 'Is bluetoothd running? Bluetooth tree missing from DBUS'
+ lg.error(msg)
+ print(msg)
+ exit(1)
+ else:
+ raise
+ return manager
+
+def prop_get(obj, k, iface=None):
+ if iface is None: iface = obj.dbus_interface
+ return obj.Get(iface, k, dbus_interface=iface_props)
+def prop_set(obj, k, v, iface=None):
+ if iface is None: iface = obj.dbus_interface
+ return obj.Set(iface, k, v, dbus_interface=iface_props)
+
+msg=''
+def find_adapter(pattern=None):
+ try:
+ adapter = find_adapter_in_objects(get_manager().GetManagedObjects(), pattern)
+
+ # DBusException
+ # Original code:
+ # template = "An exception of type {0} occurred. Arguments:\n{1!r}"
+ # message = template.format(type(ex).__name__, ex.args)
+ # print message
+ # dbus.exceptions.DBusException:
+ # org.freedesktop.DBus.Error.AccessDenied:
+ except dbus.exceptions.DBusException as e:
+ s=""
+ try:
+ s = e.__dict__["_dbus_error_name"]
+ except KeyError:
+ pass
+
+ if "org.freedesktop.DBus.Error.AccessDenied" == s:
+ rot="You do not have sufficient privilege to run bt-pan"
+ print(rot)
+ lg.error(rot)
+ exit(1)
+ else:
+ raise
+ return adapter
+
+def find_adapter_in_objects(objects, pattern=None):
+ bus, obj = get_bus(), None
+ for path, ifaces in objects.iteritems():
+ adapter = ifaces.get(iface_adapter)
+ if adapter is None: continue
+ if not pattern or pattern == adapter['Address'] or path.endswith(pattern):
+ obj = bus.get_object(iface_base, path)
+ yield dbus.Interface(obj, iface_adapter)
+ if obj is None:
+ msg = 'Bluetooth adapter not found'
+ lg.error(msg)
+ raise BTError(msg)
+
+def find_device(device_address, adapter_pattern=None):
+ return find_device_in_objects(get_manager().GetManagedObjects(), device_address, adapter_pattern)
+
+def find_device_in_objects(objects, device_address, adapter_pattern=None):
+ bus = get_bus()
+ path_prefix = ''
+ if adapter_pattern:
+ if not isinstance(adapter_pattern, types.StringTypes): adapter = adapter_pattern
+ else: adapter = find_adapter_in_objects(objects, adapter_pattern)
+ path_prefix = adapter.object_path
+ for path, ifaces in objects.iteritems():
+ device = ifaces.get(iface_dev)
+ if device is None: continue
+ if device['Address'] == device_address and path.startswith(path_prefix):
+ obj = bus.get_object(iface_base, path)
+ return dbus.Interface(obj, iface_dev)
+ msg = 'Bluetooth device not found'
+ lg.error(msg)
+ raise BTError(msg)
+
+pidPath = ""
+
+def writePidFile(device):
+ global pidPath
+ pid = str(os.getpid())
+ pidPath = '/run/bt-pan.' + device + '.pid'
+ f = open(pidPath, 'w')
+ f.write(pid)
+ f.close()
+
+def hexdump(string):
+ return ":".join("{:02x}".format(ord(c)) for c in string)
+
+### bt-pan
+
+def main(args=None):
+ import argparse
+ global lg
+
+ # Set up logging initially info and above
+ lg = flog(myscript,'daemon','info')
+
+ # cgitb.enable(format='text')
+
+ parser = argparse.ArgumentParser(
+ description='BlueZ bluetooth PAN network server/client.')
+
+ parser.add_argument('-i', '--device', metavar='local-addr/pattern',
+ help='Local device address/pattern to use (if not default).')
+ parser.add_argument('-a', '--device-all', action='store_true',
+ help='Use all local hci devices, not just default one.'
+ ' Only valid with "server" mode, mutually exclusive with --device option.')
+ parser.add_argument('-u', '--uuid',
+ metavar='uuid_or_shortcut', default='nap',
+ help='Service UUID to use. Can be either full UUID'
+ ' or one of the shortcuts: gn, panu, nap. Default: %(default)s.')
+ parser.add_argument('--systemd', action='store_true',
+ help='Use systemd service'
+ ' notification/watchdog mechanisms in daemon modes, if available.')
+ parser.add_argument('--debug',
+ action='store_true', help='Verbose operation mode.')
+
+ cmds = parser.add_subparsers( dest='call',
+ title='Supported operations (have their own suboptions as well)' )
+
+ cmd = cmds.add_parser('server', help='Run infinitely as a NAP network server.')
+ cmd.add_argument('iface_name',
+ help='Bridge interface name to which each link will be added by bluez.'
+ ' It must be created and configured before starting the server.')
+
+ cmd = cmds.add_parser('client', help='Connect to a PAN network.')
+ cmd.add_argument('remote_addr', help='Remote device address to connect to.')
+ cmd.add_argument('-d', '--disconnect', action='store_true',
+ help='Instead of connecting (default action), disconnect'
+ ' (if connected) and exit. Overrides all other options for this command.')
+ cmd.add_argument('-w', '--wait', action='store_true',
+ help='Go into an endless wait-loop after connection, terminating it on exit.')
+ cmd.add_argument('-c', '--if-not-connected', action='store_true',
+ help='Dont raise error if connection is already established.')
+ cmd.add_argument('-r', '--reconnect', action='store_true',
+ help='Force reconnection if some connection is already established.')
+
+ opts = parser.parse_args()
+
+ if opts.debug:
+ lg.setThreshold('debug')
+
+ if not opts.device_all: devs = [next(iter(find_adapter(opts.device)))]
+ else:
+ if opts.call != 'server':
+ parser.error('--device-all option is only valid with "server" mode.')
+ devs = list(find_adapter())
+ devs = dict((prop_get(dev, 'Address'), dev) for dev in devs)
+ for dev_addr, dev in devs.viewitems():
+ prop_set(dev, 'Powered', True)
+ lg.debug('Using local device (addr: %s): %s', dev_addr, dev.object_path)
+
+ wait_iter_noop = 3600
+ if opts.systemd:
+ from systemd import daemon
+ def wait_iter():
+ if not wait_iter.sd_ready:
+ daemon.notify('READY=1')
+ daemon.notify('STATUS=Running in {} mode...'.format(opts.call))
+ wait_iter.sd_ready = True
+ time.sleep(wait_iter.timeout)
+ if wait_iter.sd_wdt: daemon.notify('WATCHDOG=1')
+ wd_pid, wd_usec = (os.environ.get(k) for k in ['WATCHDOG_PID', 'WATCHDOG_USEC'])
+ if wd_pid and wd_pid.isdigit() and int(wd_pid) == os.getpid():
+ wd_interval = float(wd_usec) / 2e6 # half of interval in seconds
+ assert wd_interval > 0, wd_interval
+ else: wd_interval = None
+ if wd_interval:
+ lg.debug('Initializing systemd watchdog pinger with interval: %ss', wd_interval)
+ wait_iter.sd_wdt, wait_iter.timeout = True, min(wd_interval, wait_iter_noop)
+ else: wait_iter.sd_wdt, wait_iter.timeout = False, wait_iter_noop
+ wait_iter.sd_ready = False
+ else: wait_iter = lambda: time.sleep(wait_iter_noop)
+ signal.signal(signal.SIGTERM, lambda sig,frm: sys.exit(0))
+
+
+ if opts.call == 'server':
+ brctl = subprocess.Popen(
+ ['brctl', 'show', opts.iface_name],
+ stdout=open(os.devnull, 'wb'), stderr=subprocess.PIPE )
+ brctl_stderr = brctl.stderr.read()
+ p = lambda fmt='',*a,**k: print(fmt.format(*a,**k), file=sys.stderr)
+ writePidFile(opts.iface_name)
+ if brctl.wait() or brctl_stderr:
+ p = lambda fmt='',*a,**k: print(fmt.format(*a,**k), file=sys.stderr)
+ p('brctl check failed for interface: {}', opts.iface_name)
+ lg.error('brctl check failed for interface (missing?): {}', opts.iface_name)
+ p()
+ p('Bridge interface must be added and configured before starting server, e.g. with:')
+ p(' brctl addbr bnep-bridge')
+ p(' brctl setfd bnep-bridge 0')
+ p(' brctl stp bnep-bridge off')
+ p(' ip addr add 10.101.225.84/24 dev bnep-bridge')
+ p(' ip link set bnep-bridge up')
+ return 1
+
+ servers = list()
+ try:
+ for dev_addr, dev in devs.viewitems():
+ server = dbus.Interface(dev, 'org.bluez.NetworkServer1')
+ server.Unregister(opts.uuid) # in case already registered
+ server.Register(opts.uuid, opts.iface_name)
+ servers.append(server)
+ lg.debug( 'Registered uuid %r with'
+ ' bridge/dev: %s / %s', opts.uuid, opts.iface_name, dev_addr )
+ while True: wait_iter()
+ except KeyboardInterrupt: pass
+ finally:
+ if servers:
+ for server in servers: server.Unregister(opts.uuid)
+ lg.debug('Unregistered server uuids')
+
+
+ elif opts.call == 'client':
+ dev_remote = find_device(opts.remote_addr, devs.values()[0])
+ lg.debug( 'Using remote device (addr: %s): %s',
+ prop_get(dev_remote, 'Address'), dev_remote.object_path )
+ try: dev_remote.ConnectProfile(opts.uuid)
+ except: pass # no idea why it fails sometimes, but still creates dbus interface
+ net = dbus.Interface(dev_remote, 'org.bluez.Network1')
+
+ if opts.disconnect:
+ try: net.Disconnect()
+ except dbus.exceptions.DBusException as err:
+ if err.get_dbus_name() != 'org.bluez.Error.Failed': raise
+ connected = prop_get(net, 'Connected')
+ if connected: raise
+ lg.debug(
+ 'Disconnected from network'
+ ' (dev_remote: %s, addr: %s) uuid %r, by explicit command',
+ dev_remote.object_path, prop_get(dev_remote, 'Address'), opts.uuid )
+ return
+
+ for n in xrange(2):
+ try: iface = net.Connect(opts.uuid)
+ except dbus.exceptions.DBusException as err:
+ if err.get_dbus_name() != 'org.bluez.Error.Failed': raise
+ connected = prop_get(net, 'Connected')
+ if not connected: raise
+ if opts.reconnect:
+ lg.debug( 'Detected pre-established connection'
+ ' (iface: %s), reconnecting', prop_get(net, 'Interface') )
+ net.Disconnect()
+ continue
+ if not opts.if_not_connected: raise
+ else: break
+ lg.debug(
+ 'Connected to network (dev_remote: %s, addr: %s) uuid %r with iface: %s',
+ dev_remote.object_path, prop_get(dev_remote, 'Address'), opts.uuid, iface )
+
+ if opts.wait:
+ try:
+ while True: wait_iter()
+ except KeyboardInterrupt: pass
+ finally:
+ net.Disconnect()
+ lg.debug('Disconnected from network')
+
+
+ else: raise ValueError(opts.call)
+ global pidPath
+ try:
+ os.remove(pidPath)
+ except OSError:
+ pass
+ lg.debug('Finished')
+
+if __name__ == '__main__': sys.exit(main())
diff --git a/recipes-connectivity/bluez/bluez5/bt-pan/default b/recipes-connectivity/bluez/bluez5/bt-pan/default
new file mode 100755
index 0000000..9ba447e
--- /dev/null
+++ b/recipes-connectivity/bluez/bluez5/bt-pan/default
@@ -0,0 +1,2 @@
+ENABLED="yes"
+PANOPTS="--debug"
diff --git a/recipes-connectivity/bluez/bluez5/bt-pan/init b/recipes-connectivity/bluez/bluez5/bt-pan/init
new file mode 100755
index 0000000..3f7062e
--- /dev/null
+++ b/recipes-connectivity/bluez/bluez5/bt-pan/init
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+NAME=bt-pan
+SERVER=/usr/libexec/bluetooth/${NAME}
+PYTHON=$(readlink -f /usr/bin/python2)
+BRIDGE=pan0
+DNAME="${NAME}.${BRIDGE}"
+PIDFILE="/run/${DNAME}.pid"
+
+ENABLED=yes
+[ -f /etc/default/$NAME ] && . /etc/default/$NAME
+
+if [ "$ENABLED" != "yes" ]; then
+ echo "$NAME: disabled in /etc/default"
+ exit
+fi
+
+case $1 in
+ start)
+ echo "Starting ${DNAME}"
+ /usr/sbin/start-stop-daemon -S -p ${PIDFILE} -x ${PYTHON} -b -- ${SERVER} ${PANOPTS} server $BRIDGE
+ ;;
+
+ stop)
+ /usr/sbin/start-stop-daemon -K -p ${PIDFILE} -x ${PYTHON}
+ echo "Stopping ${DNAME}"
+ ;;
+
+ restart)
+ $0 stop
+ $0 start
+ ;;
+
+ *)
+ echo "Usage: $0 {start|stop|restart}"
+ exit 2
+ ;;
+esac
+
+
diff --git a/recipes-connectivity/bluez/bluez5/init b/recipes-connectivity/bluez/bluez5/init
index 033e24d..f6d0884 100644..100755
--- a/recipes-connectivity/bluez/bluez5/init
+++ b/recipes-connectivity/bluez/bluez5/init
@@ -3,7 +3,7 @@
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DESC=bluetooth
-DAEMON=@LIBEXECDIR@/bluetooth/bluetoothd
+DAEMON=/usr/libexec/bluetooth/bluetoothd
# If you want to be ignore error of "org.freedesktop.hostname1",
# please enable NOPLUGIN_OPTION.
diff --git a/recipes-connectivity/bluez/bluez5/main.conf b/recipes-connectivity/bluez/bluez5/main.conf
new file mode 100644
index 0000000..40ad113
--- /dev/null
+++ b/recipes-connectivity/bluez/bluez5/main.conf
@@ -0,0 +1,108 @@
+[General]
+
+# Default adapter name
+# Defaults to 'BlueZ X.YZ'
+Name = MTCDT-Bluez
+
+# Default device class. Only the major and minor device class bits are
+# considered. Defaults to '0x000000'.
+#Class = 0x000100
+
+# How long to stay in discoverable mode before going back to non-discoverable
+# The value is in seconds. Default is 180, i.e. 3 minutes.
+# 0 = disable timer, i.e. stay discoverable forever
+DiscoverableTimeout = 0
+
+# How long to stay in pairable mode before going back to non-discoverable
+# The value is in seconds. Default is 0.
+# 0 = disable timer, i.e. stay pairable forever
+#PairableTimeout = 0
+
+# Automatic connection for bonded devices driven by platform/user events.
+# If a platform plugin uses this mechanism, automatic connections will be
+# enabled during the interval defined below. Initially, this feature
+# intends to be used to establish connections to ATT channels. Default is 60.
+AutoConnectTimeout = 0
+
+# Use vendor id source (assigner), vendor, product and version information for
+# DID profile support. The values are separated by ":" and assigner, VID, PID
+# and version.
+# Possible vendor id source values: bluetooth, usb (defaults to usb)
+#DeviceID = bluetooth:1234:5678:abcd
+
+# Do reverse service discovery for previously unknown devices that connect to
+# us. This option is really only needed for qualification since the BITE tester
+# doesn't like us doing reverse SDP for some test cases (though there could in
+# theory be other useful purposes for this too). Defaults to 'true'.
+#ReverseServiceDiscovery = true
+
+# Enable name resolving after inquiry. Set it to 'false' if you don't need
+# remote devices name and want shorter discovery cycle. Defaults to 'true'.
+#NameResolving = true
+
+# Enable runtime persistency of debug link keys. Default is false which
+# makes debug link keys valid only for the duration of the connection
+# that they were created for.
+#DebugKeys = false
+
+# Restricts all controllers to the specified transport. Default value
+# is "dual", i.e. both BR/EDR and LE enabled (when supported by the HW).
+# Possible values: "dual", "bredr", "le"
+#ControllerMode = dual
+
+# Enables Multi Profile Specification support. This allows to specify if
+# system supports only Multiple Profiles Single Device (MPSD) configuration
+# or both Multiple Profiles Single Device (MPSD) and Multiple Profiles Multiple
+# Devices (MPMD) configurations.
+# Possible values: "off", "single", "multiple"
+#MultiProfile = off
+
+# Permanently enables the Fast Connectable setting for adapters that
+# support it. When enabled other devices can connect faster to us,
+# however the tradeoff is increased power consumptions. This feature
+# will fully work only on kernel version 4.1 and newer. Defaults to
+# 'false'.
+#FastConnectable = false
+
+# Default privacy setting.
+# Enables use of private address.
+# Possible values: "off", "device", "network"
+# "network" option not supported currently
+# Defaults to "off"
+# Privacy = off
+
+[GATT]
+# GATT attribute cache.
+# Possible values:
+# always: Always cache attributes even for devices not paired, this is
+# recommended as it is best for interoperability, with more consistent
+# reconnection times and enables proper tracking of notifications for all
+# devices.
+# yes: Only cache attributes of paired devices.
+# no: Never cache attributes
+# Default: always
+#Cache = always
+
+[Policy]
+#
+# The ReconnectUUIDs defines the set of remote services that should try
+# to be reconnected to in case of a link loss (link supervision
+# timeout). The policy plugin should contain a sane set of values by
+# default, but this list can be overridden here. By setting the list to
+# empty the reconnection feature gets disabled.
+#ReconnectUUIDs=00001112-0000-1000-8000-00805f9b34fb,0000111f-0000-1000-8000-00805f9b34fb,0000110a-0000-1000-8000-00805f9b34fb
+
+# ReconnectAttempts define the number of attempts to reconnect after a link
+# lost. Setting the value to 0 disables reconnecting feature.
+#ReconnectAttempts=7
+
+# ReconnectIntervals define the set of intervals in seconds to use in between
+# attempts.
+# If the number of attempts defined in ReconnectAttempts is bigger than the
+# set of intervals the last interval is repeated until the last attempt.
+#ReconnectIntervals=1,2,4,8,16,32,64
+
+# AutoEnable defines option to enable all controllers when they are found.
+# This includes adapters present on start as well as adapters that are plugged
+# in later on. Defaults to 'false'.
+AutoEnable=true
diff --git a/recipes-connectivity/bluez/bluez5_5.47.bb b/recipes-connectivity/bluez/bluez5_5.47.bb
index 9824aeb..fb17add 100644
--- a/recipes-connectivity/bluez/bluez5_5.47.bb
+++ b/recipes-connectivity/bluez/bluez5_5.47.bb
@@ -2,8 +2,8 @@ require bluez5.inc
REQUIRED_DISTRO_FEATURES = "bluez5"
-SRC_URI[md5sum] = "913f35d6fa4ca5772c53adb936bf1947"
-SRC_URI[sha256sum] = "ddab3d3837c1afb8ae228a94ba17709a4650bd4db24211b6771ab735c8908e28"
+SRC_URI[md5sum] = "783e15f65e70cdb8f721c659e140dd56"
+SRC_URI[sha256sum] = "cf75bf7cd5d564f21cc4a2bd01d5c39ce425397335fd47d9bbe43af0a58342c8"
# noinst programs in Makefile.tools that are conditional on READLINE
# support