1 Reply Latest reply on Feb 14, 2018 4:37 AM by Intel Corporation

    Reading message from Bluetooth socket delay

    michalt38

      Hello I'm having some trouble with a Python's socket and FIFO files. I'm communicating with a device through Bluetooth - I'm sending a command and receiving a response. A command needs to be written to a FIFO file and a response is read from another FIFO and when a script finds '\n' - it sends it. The problem is that at the beginning the system works fine but after some time I have a big delay in receiving a response from device - about 100ms, then it works fast and again have this delay and again. I think the problem is in writing data to FIFO or receiving incoming data from socket because in my code in Arduino C I've got this delay when I want to read a data from the input FIFO using fgets function. My Python's script:

       

      #!/usr/bin/python

       

      from __future__ import absolute_import, print_function, unicode_literals

       

      from optparse import OptionParser, make_option

      import os

      import errno

      import sys

      import socket

      import uuid

      import dbus

      import dbus.service

      import dbus.mainloop.glib

      import time

       

      from threading import Thread

      try:

        from gi.repository import GObject

      except ImportError:

        import gobject as GObject

       

      class ArduinoFifo:

          fifofile = -1

          OUT_PIPE_FILE = '/tmp/ble_pipe_out'

       

          def removeFile(self, filename):

              try:

                  os.remove(filename)

              except OSError as e: # this would be "except OSError, e:" before Python 2.6

                  if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory

                      print(e)

                      raise # re-raise exception if a different error occured

       

          def createFifo(self):

              print('removing pipe file\n')

              self.removeFile(self.OUT_PIPE_FILE)

       

              print('making pipe\n')

              try:

                  os.mkfifo(self.OUT_PIPE_FILE, 0777)

              except OSError as err:

                  print (err)

                  raise

       

          def openFifo(self):

              print('waiting to open pipe\n')

              try:

                  self.fifofile = os.open(self.OUT_PIPE_FILE, os.O_WRONLY) # | os.O_NONBLOCK)

              except OSError as err:

                  print (err)

       

          def writeFifo(self, data):

              try:

                  if (self.fifofile == -1):

                      openFifo(self)

                  os.write(self.fifofile, data)

              except OSError as err:

                  print (err)

       

      class FIFOReader(Thread):

          def __init__(self, server_sock):

              super(FIFOReader, self).__init__()

              self.server_sock = server_sock

              self.daemon = True

              self.received_msg = ""

              self.cancelled = False

              print('remove in fifo')

              try:

                  os.remove("/tmp/ble_pipe_in")

              except OSError as e: # this would be "except OSError, e:" before Python 2.6

                      if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory

                              print(e)

                      raise

       

              print('create in fifo')

              try:

                  os.mkfifo("/tmp/ble_pipe_in", 0777)

              except OSError as err:

                      print (err)

                  raise

       

              print('open in fifo')

              try:

                  self.fifofile = os.open("/tmp/ble_pipe_in", os.O_RDWR)

              except OSError as err:

                      print (err)

              print('fifo in opened')

             

          def run(self):

              while not self.cancelled:

                  print("READING")

                  self.received_msg = os.read(self.fifofile, 1024)

                  print("read: %s\n" % self.received_msg)

                  if "\n" in self.received_msg :

                      print("Sending Message...")

                      self.server_sock.send(self.received_msg)

                      self.received_msg = ""

                 

          def cancel(self):

              self.cancelled = True

       

      myfifo = ArduinoFifo()

       

      class Profile(dbus.service.Object):

          fd = -1

       

          @dbus.service.method("org.bluez.Profile1",

                          in_signature="", out_signature="")

          def Release(self):

              print("Release")

              mainloop.quit()

       

          @dbus.service.method("org.bluez.Profile1",

                          in_signature="", out_signature="")

          def Cancel(self):

              print("Cancel")

       

       

          @dbus.service.method("org.bluez.Profile1",

                      in_signature="oha{sv}", out_signature="")

          def NewConnection(self, path, fd, properties):

              global received_msg

              self.fd = fd.take()

              print("NewConnection(%s, %d)" % (path, self.fd))

       

       

              server_sock = socket.fromfd(self.fd, socket.AF_UNIX, socket.SOCK_STREAM)

              server_sock.setblocking(1)

              server_sock.send("Hi! It's Intel Edison How are you?\n")

       

              myfifo.openFifo()

              infifo = FIFOReader(server_sock)

              infifo.start()

       

              print('enter recv loop\n')

              try:

                  while True:

                      data = server_sock.recv(1024)

                      #print("received: %s" % data)

                  if data:

                          myfifo.writeFifo(data)

                  #if data == "h":

                      #server_sock.send("Hello!\n")

              except IOError as err:

                  print (err)

                  pass

       

              server_sock.close()

              print("all done")

              os.kill(os.getpid(), 9)

       

       

       

          @dbus.service.method("org.bluez.Profile1",

                      in_signature="o", out_signature="")

          def RequestDisconnection(self, path):

              print("RequestDisconnection(%s)" % (path))

       

              if (self.fd > 0):

                  os.close(self.fd)

                  self.fd = -1

       

      if __name__ == '__main__':

          dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

       

          bus = dbus.SystemBus()

       

          manager = dbus.Interface(bus.get_object("org.bluez",

                      "/org/bluez"), "org.bluez.ProfileManager1")

       

          option_list = [

                  make_option("-C", "--channel", action="store",

                          type="int", dest="channel",

                          default=None),

                  ]

       

          parser = OptionParser(option_list=option_list)

       

          (options, args) = parser.parse_args()

       

          options.uuid = "1101"

          options.psm = "3"

          options.role = "server"

          options.name = "Edison SPP Loopback"

          options.service = "spp char loopback"

          options.path = "/foo/bar/profile"

          options.auto_connect = False

          options.record = ""

       

          profile = Profile(bus, options.path)

       

          mainloop = GObject.MainLoop()

       

          opts = {

                  "AutoConnect" : options.auto_connect,

              }

       

          if (options.name):

              opts["Name"] = options.name

       

          if (options.role):

              opts["Role"] = options.role

       

          if (options.psm is not None):

              opts["PSM"] = dbus.UInt16(options.psm)

       

          if (options.channel is not None):

              opts["Channel"] = dbus.UInt16(options.channel)

       

          if (options.record):

              opts["ServiceRecord"] = options.record

       

          if (options.service):

              opts["Service"] = options.service

       

          if not options.uuid:

              options.uuid = str(uuid.uuid4())

       

          manager.RegisterProfile(options.path, options.uuid, opts)

       

          myfifo.createFifo()

       

          mainloop.run()