Python Forum
Sending response delay
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sending response delay
#1
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 C I've got this delay when I want to read a data from the input FIFO using fgets function. My code:

#!/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()
Reply
#2
Not my field of expertise, but it almost sounds as if there is a problem with the buffer size? Or perhaps the transmit speed is to fast, filling the buffer faster than it can empty itself?
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Mesure delay time in network (graph) leemao 0 4,756 Jul-02-2020, 04:06 PM
Last Post: leemao
  PySerial delay mikeybg 1 5,208 May-08-2020, 05:24 PM
Last Post: mikeybg

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020