diff --git a/actors/src/udsactor/ipc.py b/actors/src/udsactor/ipc.py index 7d26d318b..fc0ac6c6f 100644 --- a/actors/src/udsactor/ipc.py +++ b/actors/src/udsactor/ipc.py @@ -33,12 +33,11 @@ from __future__ import unicode_literals import socket import threading import sys -import six import traceback import pickle import errno import time -import json +import six from udsactor.utils import toUnicode from udsactor.log import logger @@ -94,9 +93,11 @@ REV_DICT = { MAGIC = b'\x55\x44\x53\x00' # UDS in hexa with a padded 0 to the right + # Allows notifying login/logout from client for linux platform ALLOW_LOG_METHODS = sys.platform != 'win32' + # States for client processor ST_SECOND_BYTE = 0x01 ST_RECEIVING = 0x02 @@ -104,9 +105,8 @@ ST_PROCESS_MESSAGE = 0x02 class ClientProcessor(threading.Thread): - def __init__(self, parent, clientSocket): - super(self.__class__, self).__init__() + super(ClientProcessor, self).__init__() self.parent = parent self.clientSocket = clientSocket self.running = False @@ -137,6 +137,7 @@ class ClientProcessor(threading.Thread): if b == b'': # Client disconnected self.running = False + self.processRequest(REQ_LOGOUT, 'CLIENT_CONNECTION_LOST') break buf = six.byte2int(b) # Empty buffer, this is set as non-blocking if state is None: @@ -191,8 +192,8 @@ class ClientProcessor(threading.Thread): try: m = msg[1] if msg[1] is not None else b'' - l = len(m) - data = MAGIC + six.int2byte(msg[0]) + six.int2byte(l & 0xFF) + six.int2byte(l >> 8) + m + ln = len(m) + data = MAGIC + six.int2byte(msg[0]) + six.int2byte(ln & 0xFF) + six.int2byte(ln >> 8) + m try: self.clientSocket.sendall(data) except socket.error as e: @@ -212,7 +213,7 @@ class ClientProcessor(threading.Thread): class ServerIPC(threading.Thread): def __init__(self, listenPort, clientMessageProcessor=None): - super(self.__class__, self).__init__() + super(ServerIPC, self).__init__() self.port = listenPort self.running = False self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -299,7 +300,6 @@ class ServerIPC(threading.Thread): class ClientIPC(threading.Thread): - def __init__(self, listenPort): super(ClientIPC, self).__init__() self.port = listenPort @@ -329,8 +329,8 @@ class ClientIPC(threading.Thread): if isinstance(data, six.text_type): # Convert to bytes if necessary data = data.encode('utf-8') - l = len(data) - msg = six.int2byte(msg) + six.int2byte(l & 0xFF) + six.int2byte(l >> 8) + data + ln = len(data) + msg = six.int2byte(msg) + six.int2byte(ln & 0xFF) + six.int2byte(ln >> 8) + data self.clientSocket.sendall(msg) def requestInformation(self): diff --git a/actors/src/udsactor/service.py b/actors/src/udsactor/service.py index 4e6ef848d..7a723163e 100644 --- a/actors/src/udsactor/service.py +++ b/actors/src/udsactor/service.py @@ -87,6 +87,7 @@ class CommonService(object): self.httpServer = None self.rebootRequested = False self.knownIps = [] + self.loggedIn = False socket.setdefaulttimeout(20) def reboot(self): @@ -166,6 +167,7 @@ class CommonService(object): # Now try to run the "runonce" element runOnce = store.runApplication() if runOnce is not None: + logger.info('Executing runOnce app: {}'.format(runOnce)) if self.execute(runOnce, 'RunOnce') is True: # operations.reboot() return False @@ -260,24 +262,26 @@ class CommonService(object): return if msg == ipc.REQ_LOGIN: + self.loggedIn = True res = self.api.login(data).split('\t') # third parameter, if exists, sets maxSession duration to this. # First & second parameters are ip & hostname of connection source if len(res) >= 3: self.api.maxSession = int(res[2]) # Third parameter is max session duration msg = ipc.REQ_INFORMATION # Senf information, requested or not, to client on login notification - elif msg == ipc.REQ_LOGOUT: + if msg == ipc.REQ_LOGOUT and self.loggedIn is True: + self.loggedIn = False self.api.logout(data) self.onLogout(data) - elif msg == ipc.REQ_INFORMATION: + if msg == ipc.REQ_INFORMATION: info = {} if self.api.idle is not None: info['idle'] = self.api.idle if self.api.maxSession is not None: info['maxSession'] = self.api.maxSession self.ipc.sendInformationMessage(info) - elif msg == ipc.REQ_TICKET: - d = json.loads('data') + if msg == ipc.REQ_TICKET: + d = json.loads(data) try: result = self.api.getTicket(d['ticketId'], d['secure']) self.ipc.sendTicketMessage(result) @@ -317,6 +321,9 @@ class CommonService(object): def endAPI(self): if self.api is not None: try: + if self.loggedIn: + self.loggedIn = False + self.api.logout('service_stopped') self.api.notifyComm(None) except Exception as e: logger.error('Couln\'t remove comms url from broker: {}'.format(e))