def _onResponseRecv(self, xAsyncTCPClient, data, arg): uid = arg[0] if len(arg) == 2: trackingNbr, code, dataFormat, formatOpt, dataLen = arg[1] data = data.tobytes() else: hdr = IoTSocketStruct.DecodeResponseHdr(data.tobytes()) trackingNbr, code, dataFormat, formatOpt, dataLen = hdr if dataLen > 0: self._recv(dataLen, self._onResponseRecv, (uid, hdr)) return data = b'' if uid: strUID = ('{%s}' % IoTSocketStruct.UIDFromBin128(uid)) else: strUID = 'CENTRAL' self._router.Log('SESSION %s > RESPONSE TO %s RECEIVED (#%s)' % (self._getSessionName(), strUID, trackingNbr)) self._router.RouteResponse( fromUID=None if self._isCentral else self._uid, toUID=uid, trackingNbr=trackingNbr, code=code, dataFormat=dataFormat, formatOpt=formatOpt, data=data) self._waitDataTransmission()
def RouteTelemetry(self, token, dataFormat, formatOpt, data): if token and data: uid, exp = self._telemetryTokens.get(token, (None, None)) if uid: self.Log( 'ROUTER > TELEMETRY RECEIVED FROM {%s} WITH TOKEN %s' % (IoTSocketStruct.UIDFromBin128(uid), self.TelemetryTokenToStr(token))) if self.CentralSessionExists(): session = self._centralSession if session: data = IoTSocketStruct.MakeIdentTelemetryTRHdr( uid, dataFormat, formatOpt, len(data) ) \ + data if session.Send(data): return True elif self._onGetWebHookTelemetry: plFormat, plObject = IoTSocketStruct.DecodeJSONPayload( data, dataFormat) if plFormat is not None and plObject is not None: webHook = self._onGetWebHookTelemetry(self) if webHook: webHook.Post(self._centralAuthKeyHex, uid, plObject, plFormat) return True self.Log('ROUTER > ERROR TO OPEN WEBHOOK OF TELEMETRY') self.Log('ROUTER > NO DESTINATION FOR TELEMETRY') return False
def _processPOSTRequest(self, content): try: o = self._getJSONContent(content) except Exception as ex: self._logRefused('BAD REQUEST, %s' % ex) self._sendHTTPResponse(400, '400 : Bad Request (%s)' % ex) return try: uid = IoTSocketStruct.UIDToBin128(o['UID']) timeout = int(o.get('Timeout', self._maxSecWaitResponse)) fmt, data = IoTSocketStruct.EncodeJSONPayload( o['Payload'], o['Format']) if uid and timeout > 0 and fmt is not None and data is not None: if timeout > self._maxSecWaitResponse: timeout = self._maxSecWaitResponse exp = time() + timeout self._trackingNbr = self._router.AddCentralHTTPRequest( self, exp) strUID = ('{%s}' % IoTSocketStruct.UIDFromBin128(uid)) self._log('REQUEST TO %s RECEIVED (#%s)' % (strUID, self._trackingNbr)) if not self._router.RouteRequest( fromUID=None, toUID=uid, trackingNbr=self._trackingNbr, dataFormat=fmt, formatOpt=IoTSocketStruct.PLDATA_FMT_OPT_NONE, data=data): self._router.RemoveCentralHTTPRequest(self) self.SendResponseErrNoDest() return except: pass self._logRefused('BAD REQUEST, INCORRECT JSON DATA') self._sendHTTPResponse(400, '400 : Bad Request (incorrect json data)')
def GetNewTelemetryToken(self, uid, expirationMin): with self._lock: while True: token = token_bytes(8) if not token in self._telemetryTokens: if isinstance(expirationMin, int) and expirationMin > 0: exp = time() + (expirationMin * 60) else: exp = None self._telemetryTokens[token] = (uid, exp) break self.Log('NEW TELEMETRY TOKEN FOR {%s} EXPIRING IN %s MIN (%s)' % (IoTSocketStruct.UIDFromBin128(uid), expirationMin, self.TelemetryTokenToStr(token))) return token
def Post(self, centralAuthKeyHex, uid, plObject, plFormat): o = { "UID": IoTSocketStruct.UIDFromBin128(uid), "Payload": plObject, "Format": plFormat } data = json.dumps(o).encode('UTF-8') self._sendLine('POST %s HTTP/1.0' % self._url.Path) self._sendLine('Host: %s' % self._url.Host) self._sendLine('Authorization: Bearer %s' % centralAuthKeyHex) self._sendLine('Content-Type: application/json; charset=UTF-8') self._sendLine('Content-Length: %s' % len(data)) self._sendLine() self._send(data) self._recvResponseFirstLine(self._onFirstLineRecv)
def SaveACL(self): try: o = {} with self._lock: for uid in self._acl: o[IoTSocketStruct.UIDFromBin128(uid)] = { "GroupName": IoTSocketStruct.GroupNameFromBin128(self._acl[uid][0]), "AuthKey": hexlify(self._acl[uid][1]).decode() } with open(self._aclFilename, 'wb') as file: file.write(json.dumps(o).encode('UTF-8')) return True except: return False
def _startSession(self): self._authenticated = True self._isCentral = (self._uid == IoTSocketStruct.CENTRAL_EMPTY_UID) if not self._isCentral: self._strUID = IoTSocketStruct.UIDFromBin128(self._uid) self._router.Log('SESSION %s STARTED FROM %s' % (self._getSessionName(), self._xasTCPCli.CliAddr[0])) if not self._isCentral: self._groupID = self._router.GetACLAccess(self._uid)[0] if self._router.GetGroupOption(self._groupID, 'Telemetry'): expMin = self._router.GetGroupOption(self._groupID, 'TelemetryTokenExpMin') self._telemetryToken = self._router.GetNewTelemetryToken( self._uid, expMin) tr = IoTSocketStruct.MakeTelemetryTokenTR(self._telemetryToken) self.Send(tr) self._waitDataTransmission()
def _onRequestRecv(self, xAsyncTCPClient, data, arg): uid = arg[0] if len(arg) == 2: trackingNbr, dataFormat, formatOpt, dataLen = arg[1] data = data.tobytes() else: hdr = IoTSocketStruct.DecodeRequestHdr(data.tobytes()) trackingNbr, dataFormat, formatOpt, dataLen = hdr if dataLen > 0: self._recv(dataLen, self._onRequestRecv, (uid, hdr)) return data = b'' if uid: strUID = ('{%s}' % IoTSocketStruct.UIDFromBin128(uid)) else: strUID = 'CENTRAL' errCode = None with self._requestsLock: self._router.Log('SESSION %s > REQUEST TO %s RECEIVED (#%s)' % (self._getSessionName(), strUID, trackingNbr)) if not trackingNbr in self._requests: if self._router.RouteRequest( fromUID=None if self._isCentral else self._uid, toUID=uid, trackingNbr=trackingNbr, dataFormat=dataFormat, formatOpt=formatOpt, data=data): exp = time() + self._reqTimeout self._requests[trackingNbr] = (uid, exp) else: errCode = IoTSocketStruct.RESP_CODE_ERR_NO_DEST else: self._router.Log( 'SESSION %s > TRACKING NUMBER #%s ALREADY EXISTS' % (self._getSessionName(), trackingNbr)) errCode = IoTSocketStruct.RESP_CODE_ERR_SAME_TRK_NBR if errCode: self.Send( IoTSocketStruct.MakeResponseErrTR(uid, trackingNbr, errCode)) self._waitDataTransmission()