From 94e098478a4701a2935c2c2d757e973ecbf9e888 Mon Sep 17 00:00:00 2001 From: John Klug Date: Mon, 19 Mar 2018 17:52:26 -0500 Subject: Add rfcomm package to bluez --- recipes-connectivity/bluez/bluez5.inc | 11 +- recipes-connectivity/bluez/bluez5/rfcomm/init | 39 ++ recipes-connectivity/bluez/bluez5/rfcomm/rfcomm.py | 447 +++++++++++++++++---- 3 files changed, 420 insertions(+), 77 deletions(-) create mode 100755 recipes-connectivity/bluez/bluez5/rfcomm/init (limited to 'recipes-connectivity/bluez') diff --git a/recipes-connectivity/bluez/bluez5.inc b/recipes-connectivity/bluez/bluez5.inc index 844f38b..601cd6f 100644 --- a/recipes-connectivity/bluez/bluez5.inc +++ b/recipes-connectivity/bluez/bluez5.inc @@ -10,7 +10,8 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e \ DEPENDS = "udev libusb dbus-glib glib-2.0 libcheck readline" RDEPENDS_${PN}-pand += "bash" DEPENDS_${PN}-pand += "python-dbus python-logging python-syslog" -DEPENDS_${PN}-rfcomm += "python-dbus python-pygobject" +RDEPENDS_${PN}-rfcomm += "bash" +DEPENDS_${PN}-rfcomm += "python-dbus python-logging python-syslog python-glib" PROVIDES += "bluez-hcidump" RPROVIDES_${PN} += "bluez-hcidump" @@ -115,8 +116,10 @@ FILES_${PN}-obex = "${libexecdir}/bluetooth/obexd \ " FILES_${PN}-pand = "${libexecdir}/bluetooth/bt-pan ${sysconfdir}/default/bt-pan ${sysconfdir}/init.d/bt-pan" -FILES_${PN}-rfcomm = "${libexecdir}/bluetooth/rfcomm" +FILES_${PN}-rfcomm = "${libexecdir}/bluetooth/bt-pan ${sysconfdir}/default/bt-pan ${sysconfdir}/init.d/bt-pan" +FILES_${PN}-rfcomm = "${libexecdir}/bluetooth/rfcomm ${sysconfdir}/default/rfcomm ${sysconfdir}/init.d/rfcomm" CONFFILES_${PN}-pand = "${sysconfdir}/default/bt-pan" +CONFFILES_${PN}-rfcomm = "${sysconfdir}/default/rfcomm" SYSTEMD_SERVICE_${PN}-obex = "obex.service" FILES_${PN}-testtools = "${libdir}/bluez/test/*" @@ -134,11 +137,13 @@ 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} ${PN}-pand" +INITSCRIPT_PACKAGES = "${PN} ${PN}-pand ${PN}-rfcomm" INITSCRIPT_NAME_${PN} = "bluetooth" INITSCRIPT_NAME_${PN}-pand = "bt-pan" +INITSCRIPT_NAME_${PN}-rfcomm = "rfcomm" INITSCRIPT_PARAMS_${PN} = "defaults 20 20" INITSCRIPT_PARAMS_${PN}-pand = "defaults 22 22" +INITSCRIPT_PARAMS_${PN}-rfcomm = "defaults 22 22" EXCLUDE_FROM_WORLD = "1" diff --git a/recipes-connectivity/bluez/bluez5/rfcomm/init b/recipes-connectivity/bluez/bluez5/rfcomm/init new file mode 100755 index 0000000..69455d8 --- /dev/null +++ b/recipes-connectivity/bluez/bluez5/rfcomm/init @@ -0,0 +1,39 @@ +#!/bin/bash + +NAME=rfcomm +SERVER=/usr/libexec/bluetooth/${NAME} +PYTHON=$(readlink -f /usr/bin/python2) +PIDFILE="/run/${NAME}.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 ${NAME}" + echo /usr/sbin/start-stop-daemon -S -p ${PIDFILE} -x ${PYTHON} -b -- ${SERVER} ${RFCOMMOPTS} + /usr/sbin/start-stop-daemon -S -p ${PIDFILE} -x ${PYTHON} -b -- ${SERVER} ${RFCOMMOPTS} + ;; + + 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/rfcomm/rfcomm.py b/recipes-connectivity/bluez/bluez5/rfcomm/rfcomm.py index 294268b..992de45 100644 --- a/recipes-connectivity/bluez/bluez5/rfcomm/rfcomm.py +++ b/recipes-connectivity/bluez/bluez5/rfcomm/rfcomm.py @@ -4,7 +4,7 @@ import os import dbus import dbus.service import dbus.mainloop.glib -from gi.repository import GObject +from gi.repository import GObject, GLib import sys import time import threading @@ -14,23 +14,57 @@ import logging.handlers import syslog import grp import stat +import atexit +import re +import mmap +import subprocess +import threading +import struct +import fcntl +import termios +import signal +import time + +# Do we need stty onlcr???? + +#SerialPortProfile = '00001101-0000-1000-8000-00805f9b34fb' global lg global opts global RFCOMMDIR RFCOMMDIR = '/run/rfcomm' -global TTY_GID # Group-ID number of the TTY group -global doterm -doterm = True +SLAVEDIR='/dev/pts' +BLUEZLIB='/var/lib/bluetooth' +global TTY_GID # Group-ID number of the TTY group +global doterm # If true, this python program is a terminal console. +global needpseudot # Login option and pseudoterminal option +needpseudot = False +global terminatenow +terminatenow = False # 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__) +class dopidfile(object): + pidPath = "/" + + def writePidFile(self): + global pidPath + pid = str(os.getpid()) + pidPath = '/run/rfcomm' + '.pid' + f = open(pidPath, 'w') + f.write(pid) + f.close() + + def rmPidFile(self): + try: + os.remove(pidPath) + except OSError: + pass -#SerialPortProfile = '00001101-0000-1000-8000-00805f9b34fb' # Log formating class class flog: @@ -141,24 +175,121 @@ class flog: # End of log handler + +# Thread to create login process, with +# stdin, stdout, stderr matching the file descriptor +# This is because NewConnection cannot create threads or +# use a mutex. Workarounds are pipes, IPC semamphores, +# IPC messaging +class logins(object): + slavefd = -1 + + # Thread to wait on our children + def IgnoreWait(self,pid): + lg.debug("IgnoreWait: Waiting on process pid: %d" % (pid.pid)) + pid.wait() + lg.debug("login terminated: %d" % (pid.pid)) + + def StartLogin(self,rpipe,mainloop): + datafd='' + masters = [] + lg.debug("StartLogin enter: rpipe fd=%d" % (rpipe)) + while 1: + try: + datafd=os.read(rpipe,8) + except Exception as e: + lg.error('os.read error: %s' % (e)) + lg.debug('Done with StartLogin, calling quit') + for fd in masters: + os.close(fd) + os.kill(os.getpid(), signal.SIGINT) + thread.exit() + # Single integer. + (slavefd,masterfd) = struct.unpack("ii",bytearray(datafd)) + if masterfd > 0: + masters.append(masterfd) + lg.debug("StartLogin: slavefd %d" % (slavefd)) + if slavefd < 0: + lg.debug("Told to exit, so exiting StartLogin thread") + os.close(rpipe) + # We try to close all the masters, as it gets + # things wound down in a hurry. + for fd in masters: + lg.debug('StartLogin: Try to close fd %d' % (fd)) + try: + os.close(fd) + except Exception as e: + lg.debug('StartLogin (ignore error): OK: Did not close fd: %d %s' % (fd,e)) + sys.exc_clear() + os.kill(os.getpid(), signal.SIGINT) + thread.exit() + # Start login with fd, and close it. + Env = {'TERM': 'dumb'} + self.slavefd = slavefd + lg.debug('Popen slavefd: %d' % (slavefd)) + try: + # Mar 16 14:23:35 mtcdt daemon.err ERROR rfcomm.py Popen login: global name 's' is not defined + pid = subprocess.Popen(['/bin/login','--'],env=Env,preexec_fn = lambda: ( os.setsid(),fcntl.ioctl(0, termios.TIOCSCTTY, 0) ),stdin=slavefd,stdout=slavefd,stderr=slavefd,close_fds=True,cwd='/') + lg.debug('Start IgnoreWait thread') + try: + IgnoreWaitThread = threading.Thread(target=self.IgnoreWait,args=[pid]) + except Exception as e: + lg.error('IgnoreWaitThread: threading.Thread: %s' % (e)) + try: + IgnoreWaitThread.start() + except Exception as e: + lg.error('IgnoreWaitThread: start: %s' % (e)) + except Exception as e: + lg.error('Popen login: %s' % (e)) + os.close(slavefd) + class Profile(dbus.service.Object): fd = -1 readThread = None path = None io_id = -1 io_id2 = -1 + hup_id = -1 + hup_id2 = -1 io_pty_master = -1 io_pty_slave = -1 - myPath = None - + slavePath = None + linkPath = None + w = -1 + # True False pseudonyms for making code readable (or not!) + exiting = True + notexiting = False + @dbus.service.method('org.bluez.Profile1', in_signature='', out_signature='') def Release(self): - print('Release') - log.info('Release') + lg.info('Release/quit') mainloop.quit() + @dbus.service.method("org.bluez.Profile1", + in_signature="", out_signature="") + def Cancel(self): + lg.info("Cancel") + + def removeLink(self,state): + lg.debug('removeLink: state: %r' % (state)) + path = self.linkPath + lg.debug('removeLink: path %s' % (path)) + if state == self.exiting: + lg.debug('Clearing out linkPath') + self.linkPath = None # Burn bridges, do it once. + if path and os.path.lexists(path): + try: + os.remove(path) + except Exception as e: + lg.error("os.remove(self.linkPath): Tried to remove %s" % (path)) + lg.error('%s' % (e)) + + + + # New Connection is called when a new Bluetooth + # is established @dbus.service.method('org.bluez.Profile1', in_signature='oha{sv}', out_signature='') @@ -166,112 +297,220 @@ class Profile(dbus.service.Object): dbus.mainloop.glib.threads_init() self.fd = fd.take() # Extract File Descriptor from dbus UnixFD class. self.path = path - print('NewConnection(%s, %s:%d)' % (path,type(fd).__name__,self.fd)) - lg.info('NewConnection(%s, %d)' % (path, self.fd)) - - if opts.pseudoterminal: + + # Complete directory does not exist test + address = os.path.basename(self.path) + + # Search for connected device by address + for localdir in os.listdir(BLUEZLIB): + fp_localdir = BLUEZLIB + '/' + localdir # Full path + lg.debug('Localdir: %s' % (fp_localdir)) + if os.path.isdir(fp_localdir) and localdir.count(':') == 5: + lg.debug('Localdir is directory and 5 colons: %s' % (fp_localdir)) + # We have MAC address + for clientdir in os.listdir(fp_localdir): + lg.debug('Clientdir is directory: %s' % (clientdir)) + fp_clientdir = fp_localdir + '/' + clientdir + if os.path.isdir(fp_clientdir) and clientdir.count(':') == 5: + lg.debug('Clientdir is directory and 5 colons: %s' % (fp_clientdir)) + infofile = fp_clientdir + '/' + 'info' + lg.debug('infofile: %s' % (infofile)) + try: + file = open(infofile,'r') + lg.debug('Opened info file') + except: + continue + else: + continue + # Have an open file + s = mmap.mmap(file.fileno(),0,access=mmap.ACCESS_READ) + lg.debug('past mmap') + try: + cre = re.compile(br'[General][^[]*\nName=(?P[^\n]*)') + except Exception as e: + lg.debug('Compile failed: %s' % (e)) + lg.debug('past compile') + mname = cre.search(s) + lg.debug('past search') + try: + Name = mname.group('name') + break + except: + Name = 'unknown' + + print('NewConnection(%s, %s, %s:%d)' % (path,Name,type(fd).__name__,self.fd)) + lg.info('NewConnection(%s, %s, %s:%d)' % (path,Name,type(fd).__name__,self.fd)) + atexit.register(self.RequestDisconnection,self.path) + lg.debug('Past atexit.register') + + # Following code shows noting (why?) + lg.debug('Look for a key len(properties): %d',len(properties)) + for key in properties.keys(): + lg.debug('found a key!!!!!') + lg.debug(' %s = %s' % (key, properties[key])) + if key == 'Version' or key == 'Features': + lg.debug(' %s = 0x%04x' % (key, properties[key])) + lg.debug(' %s = 0x%04x' % (key, properties[key])) + else: + lg.debug(' %s = %s' % (key, properties[key])) + lg.info(' %s = %s' % (key, properties[key])) + lg.debug('Past keys, needpseudot: %s' % (needpseudot)) + + # Get a pseudoterminal to provide an I/O driver for + # a program that needs a TTY. + if needpseudot: (self.io_pty_master,self.io_pty_slave) = os.openpty() - print('Acquired pseudoterminal master and slave fd: (%d %d)' % (self.io_pty_master,self.io_pty_slave)) slavestat = os.fstat(self.io_pty_slave) - lg.debug('pseudoterminal major and minor: (%d,%d)' % (os.major(slavestat.st_rdev),os.minor(slavestat.st_rdev))) + self.minor = os.minor(slavestat.st_rdev) + lg.debug('pseudoterminal major and minor: (%d,%d)' % (os.major(slavestat.st_rdev),self.minor)) if not os.path.isdir(RFCOMMDIR): lg.debug('Before mkdir: RFCOMMDIR %s' % (RFCOMMDIR)) os.mkdir(RFCOMMDIR,0755) - # Complete directory does not exist test - - address = os.path.basename(path) + + lg.debug('Address %s' % (address)) - self.myPath = RFCOMMDIR + '/' + address - lg.debug('termPath %s' % (self.myPath)) - if os.path.lexists(self.myPath): - lg.debug('termPath %s already exists so remove it' % (self.myPath)) - os.remove(self.myPath) - print('os.mknod(%s,0%o,0%o)' % (self.myPath,0660,slavestat.st_rdev)) + self.linkPath = RFCOMMDIR + '/' + address + '_' + Name + '_pts' + str(self.minor) + self.slavePath = SLAVEDIR + '/' + str(self.minor) + lg.debug('termPath %s' % (self.linkPath)) + self.removeLink(self.notexiting) + # linkPath was removed + + lg.debug('os.symlink(%s,%s)' % (self.slavePath,self.linkPath)) old = os.umask(002) + lg.debug('past umask') try: - os.mknod(self.myPath,0660 | stat.S_IFCHR,slavestat.st_rdev) + os.symlink(self.slavePath,self.linkPath) + try: + atexit.register(self.removeLink,self.exiting); + except Exception as e: + lg.error('Register atexit: %s' % (e)) except Exception as e: - print '%s' % (e) - lg.error('%s' % (e)) + lg.error('symlink failed: %s' % (e)) return False + lg.debug('Before umask') os.umask(old) - os.chown(self.myPath,0,TTY_GID) - # Completed pseudoterminal case to create device and node + lg.debug('After umask') + # os.chown(self.myPath,0,TTY_GID) - # Following code shows noting (why?) - for key in properties.keys(): - if key == 'Version' or key == 'Features': - print(' %s = 0x%04x' % (key, properties[key])) - log.debug(' %s = 0x%04x' % (key, properties[key])) - else: - print(' %s = %s' % (key, properties[key])) - log.info(' %s = %s' % (key, properties[key])) + # Completed pseudoterminal case to create device and node - # + For loopback, we only monitor the RFCOMM line (self.fd). # + For interactive (not pseudoterminal or loopback option, # we monitor the stdin (0) and the RFCOMM line for input # + For pseudoterminal, we monitor input on the RFCOMM line, # and the slave pseudoterminal. + # Note that io_add_watch causes a poll to be done by the + # python GI library. The callback functions (io_term and io_cb) + # will be called when there is an event on the file descriptor + # being polled. sys.stdout.flush() if not opts.loopback: - if opts.pseudoterminal: + if needpseudot: local_fd = self.io_pty_master + lg.debug('NewConnection: master_fd: %d slave_fd: %d' % (local_fd,self.io_pty_slave)) #success to here. else: + # stdin local_fd = 0 - self.io_id2 = GObject.io_add_watch(local_fd, + lg.debug('Ready to do io_add_watch on local_fd: %d' % (local_fd)) + try: + self.io_id2 = GObject.io_add_watch(local_fd, GObject.PRIORITY_DEFAULT, - GObject.IO_IN | GObject.IO_PRI, + GObject.IO_IN | GObject.IO_PRI | GObject.IO_HUP | GObject.IO_ERR, self.io_term) + except Exception as e: + lg.error('io_addwatch failed for local_fd %d: IO_IN, IO_PRI %s' % (local_fd,e)) + + if opts.login: + # Writing the slave file descriptor causes the login process to start. + lg.debug('opts.login is true slave fd: %d pipe: %d' % (self.io_pty_slave,self.w)) + try: + os.write(self.w,struct.pack('ii',self.io_pty_slave,self.io_pty_master)) + except Exception as e: + lg.error('os.write of slave fd:%d master fd: %d failed: %s' % (self.io_pty_slave,self.io_pty_slave,e)) + os.close(self.io_pty_slave) + self.io_pty_slave = -1 + return False + self.io_pty_slave = -1 + if doterm: + lg.debug('Profile: Write the prompt') os.write(1,'TTY> ') - elif opts.pseudoterminal: - os.write(io_pty_master,'TTY> ') + + lg.debug('NewConnection: doterm: %s, io_add_watch is next' % doterm) self.io_id = GObject.io_add_watch(self.fd, GObject.PRIORITY_DEFAULT, - GObject.IO_IN | GObject.IO_PRI, + GObject.IO_IN | GObject.IO_PRI | GObject.IO_HUP | GObject.IO_ERR, self.io_cb) lg.debug('io_id(remote input) = %d io_id2(local input) = %d' % (self.io_id,self.io_id2)) + + # I/O read from Bluetooth remote to local application. def io_cb(self, fd, conditions): + if terminatenow: + self.RequestDisconnection(self.path) + + if (conditions & GObject.IO_HUP or conditions & GObject.IO_ERR): + lg.debug('Found HUP on fd: %d, so terminate' % (fd)) + self.RequestDisconnection(self.path) + return False # Read from remote data = None try: data = os.read(fd, 1024) except: return True + lg.debug('io_cb: past read: doterm: %s' % doterm) if opts.loopback: + toutput = fd # same as input + else: + toutput = self.io_pty_master + + if opts.loopback or needpseudot or opts.login: if data: start = 0 remain = len(data) - while remain: + result = 1 + lg.debug('remain is %d entering the loop' % (remain)) + while remain > 0 and result > 0: try: - result = os.write(fd,len(data)) - except: - lg.debut + result = os.write(toutput,data) + except Exception as e: + lg.debug('os.write failed: %s' % (e)) return True - if remain != result: + lg.debug('os.write returned %d for %s remain: %d' % (result,data,remain)) + if remain != result and remain > 0: remain -= result - data = data[-result:] + lg.debug('remain is now %d result is %d' % (remain,result)) + data = data[-remain:] + lg.debug('remain to print %s' % (data)) + else: + remain = 0 + lg.debug('returning true to end this routing') return True if data and len(data) > 0: final = data[-1] if data[-1] == '\n': date = data[:-1] - if opts.pseudoterminal: - # Write to master - os.write(io_pty_master,'\r\n'+data.decode('ascii')+'\r\nTTY>') - else: + if doterm: print('\n'+data.decode('ascii')) os.write(1,'TTY> ') + return True + # I/O written to bluetooth from local slave (application write to remote) def io_term(self, fd0, conditions): + if terminatenow: + self.RequestDisconnection(self.path) + if (conditions & GObject.IO_HUP or conditions & GObject.IO_ERR): + lg.debug('Found HUP on fd0: %d, so terminate' % (fd0)) + self.RequestDisconnection(self.path) + return False # Read from local (not used for loopback) data = None data = os.read(fd0, 1024) + lg.debug('io_term: fd0: %d len(data): %d' % (fd0,len(data))) if not data: # No Data == EOF self.RequestDisconnection(self.path) @@ -285,10 +524,8 @@ class Profile(dbus.service.Object): lg.error('%s' % (e)) self.RequestDisconnection(self.path) return True - if opts.pseudoterminal: + if doterm: os.write(fd0,'TTY> ') - else: - os.write(1,'TTY> ') return True @dbus.service.method('org.bluez.Profile1', @@ -298,35 +535,56 @@ class Profile(dbus.service.Object): print('RequestDisconnection(%s)' % (path)) lg.info('RequestDisconnection(%s)' % (path)) if self.fd != -1: - lg.debug('closing fd: %s',self.fd) + lg.debug('closing fd: %s' % (self.fd)) s = socket.fromfd(self.fd,socket.AF_INET,socket.SOCK_STREAM) result = s.shutdown(socket.SHUT_RDWR) - lg.debug('After shutdown fd: %s %s %s',self.fd,' result:',result) + lg.debug('After shutdown fd: %s %s %s' % (self.fd,' result:',result)) result = os.close(self.fd) - lg.debug('After closing fd: %s %s %s',self.fd,' result:',result) + lg.debug('After closing fd: %s %s %s' % (self.fd,' result:',result)) self.fd = -1 if self.io_id != -1: - lg.debug('remove id: %s',self.io_id) + lg.debug('remove id: %s' % (self.io_id)) rmv = GObject.source_remove(self.io_id) - # lg.debug('removed id: %s %s %s',self.io_id,'result: ',rmv) self.io_id = -1 if self.io_id2 != -1: - lg.debug('closing id2: %s',self.io_id2) + lg.debug('closing id2: %s' % (self.io_id2)) rmv = GObject.source_remove(self.io_id2) - lg.debug('removed id2: %s %s %s',self.io_id2,'result: ',rmv) + lg.debug('removed id2: %s %s %s' % (self.io_id2,'result: ',rmv)) self.io_id2 = -1 - if opts.pseudoterminal: + if self.hup_id != -1: + lg.debug('closing hup_id: %s' % (self.hup_id)) + rmv = GObject.source_remove(self.hup_id) + lg.debug('removed id2: %s %s %s' % (self.hup_id,'result: ',rmv)) + self.hup_id = -1 + if self.hup_id2 != -1: + lg.debug('closing hup_id2: %s' % (self.hup_id2)) + rmv = GObject.source_remove(self.hup_id2) + lg.debug('removed id2: %s %s %s' % (self.hup_id2,'result: ',rmv)) + self.hup_id2 = -1 + if needpseudot: if self.io_pty_slave != -1: os.close(self.io_pty_slave) + self.io_pty_slave = -1 if self.io_pty_master != -1: - os.close(self.io_pty_master) - if self.myPath and os.path.lexists(self.myPath): - os.remove(self.myPath) - self.myPath = None + try: + savefd = self.io_pty_master + self.io_pty_master = -1 + os.close(savefd) + except Exception as e: + lg.error("close(io_pty_master): Tried to close %d" % (savefd)) + lg.error('%s' % (e)) + + self.removeLink(self.exiting) + +def terminationHandler(mainloop): + lg.debug('SIGTERM: terminationHandler was called') + mainloop.quit() + if __name__ == '__main__': import argparse + doterm = False TTY_GID = grp.getgrnam('tty').gr_gid # Set up logging initially info and above lg = flog(myscript,'daemon','info') @@ -345,6 +603,8 @@ if __name__ == '__main__': help='Echo data for testing (exclusive with pseudoterminal)') parser.add_argument('--debug', action='store_true', help='Verbose operation mode.') + parser.add_argument('--login', + action='store_true', help='Use RFCOMM to log into this device.') opts = parser.parse_args() if opts.debug: @@ -355,10 +615,17 @@ if __name__ == '__main__': print msg lg.error(msg) exit(1) - if not opts.pseudoterminal and not opts.loopback: + if not opts.pseudoterminal and not opts.loopback and not opts.login: doterm = True + print "main: doterm is %s" % (str(doterm)) + + if opts.pseudoterminal or opts.login: + needpseudot = True + + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + bus = dbus.SystemBus() manager = dbus.Interface(bus.get_object('org.bluez', @@ -367,6 +634,26 @@ if __name__ == '__main__': mainloop = GObject.MainLoop() + GLib.unix_signal_add(GLib.PRIORITY_HIGH,signal.SIGTERM,terminationHandler,mainloop) + mypidfile = dopidfile() + mypidfile.writePidFile() + + if opts.login: + # Need to create thead to exec logins. + rpipe,wpipe = os.pipe() + loginProcess = logins() + Profile.w = wpipe + lg.debug('Call threading next') + try: + StartLoginThread = threading.Thread(target=loginProcess.StartLogin,args=[rpipe,mainloop]) + except Exception as e: + lg.error('threading.Thread: StartLogin %s' % (e)) + try: + StartLoginThread.start() + except Exception as e: + lg.error('StartLogin.start: %s' % (e)) + + profile_path = '/foo/bar/profile' SPP_opts = { @@ -389,12 +676,24 @@ if __name__ == '__main__': print 'Try running as root' exit(1) + lg.debug('Completed Register Profile...') dbus.mainloop.glib.threads_init() + lg.debug('Completed threads init... Now mainloop.run') try: mainloop.run() except KeyboardInterrupt: pass - finally: - print '\nSerial Port Profile: Goodbye' - lg.info('Serial Port Profile: Goodbye') - exit + except Exception as e: + lg.error('mainloop exception: %s' % (e)) + print '\nSerial Port Profile: ERROR Goodbye' + lg.error('Serial Port Profile: ERROR Goodbye') + data = struct.pack('i',-1) + os.write(wpipe,data) + mainloop.quit() + + lg.info('Serial Port Profile: Goodbye') + if opts.login: + data = struct.pack('ii',-1,-1) + os.write(wpipe,data) + mypidfile.rmPidFile() + mainloop.quit() -- cgit v1.2.3