def _onDataTransmissionRecv(self, xAsyncTCPClient, data, arg):
     if arg:
         tot = arg
         uid = data.tobytes()
     else:
         tot, rte = IoTSocketStruct.DecodeDataTRHdr(data)
         if rte:
             self._recv(16, self._onDataTransmissionRecv, tot)
             return
         uid = None
     if tot == IoTSocketStruct.TOT_ACL and self._isCentral:
         self._recv(4, self._onACLItemsCountRecv)
     elif tot == IoTSocketStruct.TOT_PING:
         self._router.Log('SESSION %s > PING RECEIVED' %
                          self._getSessionName())
         self.Send(IoTSocketStruct.MakePongTR())
         self._waitDataTransmission()
     elif tot == IoTSocketStruct.TOT_PONG:
         self._router.Log('SESSION %s > PONG RECEIVED' %
                          self._getSessionName())
         self._waitDataTransmission()
     elif tot == IoTSocketStruct.TOT_REQUEST:
         self._recv(5, self._onRequestRecv, (uid, ))
     elif tot == IoTSocketStruct.TOT_RESPONSE:
         self._recv(6, self._onResponseRecv, (uid, ))
     elif tot == IoTSocketStruct.TOT_CLOSE_CONN:
         self._recv(1, self._onCloseConnCodeRecv)
     else:
         self.Send(
             IoTSocketStruct.MakeCloseConnTR(
                 IoTSocketStruct.CLOSE_CODE_PROTO_ERR))
         self.Close()
예제 #2
0
 def _onDataTransmissionRecv(self, xAsyncTCPClient, data, arg) :
     if arg :
         tot = arg
         uid = data.tobytes()
     else :
         tot, rte = IoTSocketStruct.DecodeDataTRHdr(data)
         if rte :
             self._recv(16, self._onDataTransmissionRecv, tot)
             return
         uid = None
     if tot == IoTSocketStruct.TOT_PING :
         self._send(IoTSocketStruct.MakePongTR())
         self._waitDataTransmission()
     elif tot == IoTSocketStruct.TOT_PONG :
         self._waitDataTransmission()
     elif tot == IoTSocketStruct.TOT_REQUEST :
         self._recv(5, self._onRequestRecv, (uid, ))
     elif tot == IoTSocketStruct.TOT_RESPONSE :
         self._recv(6, self._onResponseRecv, (uid, ))
     elif tot == IoTSocketStruct.TOT_TELTOKEN :
         self._recv(8, self._onTelemetryTokenRecv)
     elif tot == IoTSocketStruct.TOT_CLOSE_CONN :
         self._recv(1, self._onCloseConnCodeRecv)
     else :
         self._send(IoTSocketStruct.MakeCloseConnTR(IoTSocketStruct.CLOSE_CODE_PROTO_ERR))
         self.Close()
예제 #3
0
 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 _processPOSTACL(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:
         acl = []
         ok = True
         for ac in o:
             groupID = IoTSocketStruct.GroupNameToBin128(ac['GroupName'])
             uid = IoTSocketStruct.UIDToBin128(ac['UID'])
             authKey = unhexlify(ac['AuthKey'])
             if groupID and uid and authKey and len(authKey) == 16:
                 acl.append((groupID, uid, authKey))
             else:
                 ok = False
                 break
         if ok:
             self._router.ClearACL()
             for ac in acl:
                 self._router.AddACLAccess(*ac)
             self._router.SaveACL()
             self._log('%s ACL SETUP RECEIVED' % len(acl))
             self._sendHTTPResponse(200)
             return
     except:
         pass
     self._logRefused('BAD REQUEST, INCORRECT JSON DATA')
     self._sendHTTPResponse(400, '400 : Bad Request (incorrect json data)')
 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)')
예제 #6
0
 def RouteResponse(self, fromUID, toUID, trackingNbr, code, dataFormat,
                   formatOpt, data):
     if toUID or self.CentralSessionExists():
         if toUID:
             session = self._objectsSessions.get(toUID, None)
         else:
             session = self._centralSession
         if session:
             session.EndTrackingRequest(trackingNbr)
             data = IoTSocketStruct.MakeResponseTRHdr( fromUID,
                                                       trackingNbr,
                                                       code,
                                                       dataFormat,
                                                       formatOpt,
                                                       len(data) ) \
                  + data
             return session.Send(data)
     else:
         httpReq, exp = self._centralHTTPRequests.get(
             trackingNbr, (None, None))
         if httpReq:
             plFormat, plObject = IoTSocketStruct.DecodeJSONPayload(
                 data, dataFormat)
             if plFormat is not None and plObject is not None:
                 self.RemoveCentralHTTPRequest(httpReq)
                 return httpReq.SendResponse(code, plObject, plFormat)
     self.Log('ROUTER > NO DESTINATION FOR RESPONSE (#%s)' % trackingNbr)
     return False
예제 #7
0
 def AuthenticateSession(self, session, token128, hmac256):
     if session.UID == IoTSocketStruct.CENTRAL_EMPTY_UID:
         central = True
         authKey = self._centralAuthKey
     else:
         groupID, authKey = self.GetACLAccess(session.UID)
         central = False
     if authKey:
         hmac256srv = hmac.new(authKey, token128, hashlib.sha256).digest()
         if hmac.compare_digest(hmac256, hmac256srv):
             if central:
                 if self._centralSession:
                     self._centralSession.Close()
                 self._centralSession = session
             else:
                 existingSession = self._objectsSessions.get(
                     session.UID, None)
                 if existingSession:
                     existingSession.Close()
                 self._objectsSessions[session.UID] = session
             session.Send(IoTSocketStruct.MakeAuthValidation(True))
             with self._lock:
                 sessionData, exp = self._keepSessionsData.get(
                     session.UID, (None, None))
                 if sessionData is not None:
                     for data in sessionData:
                         session.Send(data)
                     del self._keepSessionsData[session.UID]
             return True
     session.Send(IoTSocketStruct.MakeAuthValidation(False))
     session.Close()
     return False
 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 _onInitiationReqRecv(self, xAsyncTCPClient, data, arg):
     tls, ver, opt, maxTrLen = IoTSocketStruct.DecodeInitiationReq(data)
     ok = (ver == self.IOTSOCKET_VER
           and (not tls or self._sslContext is not None))
     data = IoTSocketStruct.MakeInitiationResp(
         ok=ok, ruleType=IoTSocketStruct.INIT_NO_RULE)
     if ok:
         self.Send(data, self._onInitiationRespSent, tls)
     else:
         self.Send(data)
         self.Close()
예제 #10
0
 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''
     print('ON REQUEST [%s] RECV' % trackingNbr)
     self._send(IoTSocketStruct.MakeResponseTRHdr(uid, trackingNbr, 0, dataFormat, 0, dataLen) + data)
     self._waitDataTransmission()
예제 #11
0
 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
예제 #12
0
 def _doInitiationReq(self) :
     data = IoTSocketStruct.MakeInitiationReq( tls      = True,
                                               ver      = self.IOTSOCKET_VER,
                                               opt      = 0x00,
                                               maxTrLen = self.MAX_TR_LEN )
     self._send(data)
     self._recv(2, self._onInitiationRespRecv)
예제 #13
0
 def AddGroup(self, groupName, options={}):
     if groupName and type(options) is dict:
         groupID = IoTSocketStruct.GroupNameToBin128(groupName)
         if groupID:
             self._groups[groupID] = options
             return True
     return False
예제 #14
0
 def _onAuthValidationRecv(self, xAsyncTCPClient, data, arg) :
     if IoTSocketStruct.DecodeAuthValidation(data) :
         print('Authentication ok')
         self._startSession()
     else :
         print('Authentication error')
         self.Close()
 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()
예제 #16
0
def SendTelemetryData(data) :
    if telemetryToken and data :
        datagram = IoTSocketStruct.MakeTelemetryPacket( token      = telemetryToken,
                                                        dataFormat = IoTSocketStruct.PLDATA_FORMAT_BIN,
                                                        formatOpt  = IoTSocketStruct.PLDATA_FMT_OPT_NONE,
                                                        data       = data )
        return xasUDPCli.AsyncSendDatagram(datagram, udpSrvAddr)
    return False
예제 #17
0
 def _onChallengeRecv(self, xAsyncTCPClient, data, arg) :
     #uid = IoTSocketStruct.CENTRAL_EMPTY_UID
     #key = b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF'
     uid     = IoTSocketStruct.UIDToBin128("ObjTest")
     authKey = b'CCCCCCCCDDDDDDDD'
     hmac256 = hmac.new(authKey, data, hashlib.sha256).digest()
     self._send(uid + hmac256)
     self._recv(1, self._onAuthValidationRecv)
 def _onACLItemRecv(self, xAsyncTCPClient, data, arg):
     groupID, uid, authKey = IoTSocketStruct.DecodeACLItem(data.tobytes())
     self._router.AddACLAccess(groupID, uid, authKey)
     if arg > 1:
         self._recv(48, self._onACLItemRecv, arg - 1)
     else:
         self._router.SaveACL()
         self._waitDataTransmission()
예제 #19
0
 def _onWebHookClosed(self, centralHTTPWebHook):
     uid, trackingNbr = centralHTTPWebHook.ObjRef
     if uid and trackingNbr:
         session = self._objectsSessions.get(uid, None)
         if session:
             session.EndTrackingRequest(trackingNbr)
             data = IoTSocketStruct.MakeResponseErrTR(
                 None, trackingNbr, IoTSocketStruct.RESP_CODE_REQ_NOK)
             session.Send(data)
예제 #20
0
 def LoadACL(self):
     try:
         with open(self._aclFilename, 'r') as file:
             o = json.load(file)
         acl = {}
         for strUID in o:
             uid = IoTSocketStruct.UIDToBin128(strUID)
             groupID = IoTSocketStruct.GroupNameToBin128(
                 o[strUID]["GroupName"])
             authKey = unhexlify(o[strUID]["AuthKey"])
             if not uid or not groupID or len(authKey) != 16 or \
                not groupID in self._groups :
                 return False
             acl[uid] = (groupID, authKey)
         with self._lock:
             self._acl = acl
         return True
     except:
         return False
예제 #21
0
 def _onInitiationRespRecv(self, xAsyncTCPClient, data, arg) :
     ok, ruleType, ruleFlags = IoTSocketStruct.DecodeInitiationResp(data)
     if ok and ruleType == IoTSocketStruct.INIT_NO_RULE :
         try :
             self._xasTCPCli.StartSSL()
             self._recv(16, self._onChallengeRecv)
             return
         except :
             pass
     self.Close()
예제 #22
0
def SendBinaryRequest(data) :
    if data :
        data = IoTSocketStruct.MakeRequestTRHdr( uid         = None,
                                                 trackingNbr = 30303,
                                                 dataFormat  = IoTSocketStruct.PLDATA_FORMAT_BIN,
                                                 formatOpt   = IoTSocketStruct.PLDATA_FMT_OPT_NONE,
                                                 dataLen     = len(data) ) \
             + data
        return xasTCPCli.AsyncSendData(data)
    return False
 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()
 def CheckRequestsTimeout(self, nowSec):
     if self._requests:
         with self._requestsLock:
             for trackingNbr in list(self._requests):
                 uid, exp = self._requests[trackingNbr]
                 if nowSec >= exp:
                     del self._requests[trackingNbr]
                     self.Send(
                         IoTSocketStruct.MakeResponseErrTR(
                             uid, trackingNbr,
                             IoTSocketStruct.RESP_CODE_ERR_TIMEOUT))
                     self._router.Log('SESSION %s > REQUEST TIMEOUT (#%s)' %
                                      (self._getSessionName(), trackingNbr))
예제 #25
0
 def _onWebHookResponseOk(self, centralHTTPWebHook, o):
     if o:
         uid, trackingNbr = centralHTTPWebHook.ObjRef
         try:
             code = int(o['Code'])
             fmt, data = IoTSocketStruct.EncodeJSONPayload(
                 o['Payload'], o['Format'])
             if fmt is not None and data is not None:
                 centralHTTPWebHook.ObjRef = (None, None)
                 session = self._objectsSessions.get(uid, None)
                 if session:
                     session.EndTrackingRequest(trackingNbr)
                     data = IoTSocketStruct.MakeResponseTRHdr( None,
                                                               trackingNbr,
                                                               code,
                                                               fmt,
                                                               IoTSocketStruct.PLDATA_FMT_OPT_NONE,
                                                               len(data) ) \
                          + data
                     session.Send(data)
         except:
             pass
예제 #26
0
 def RouteRequest(self, fromUID, toUID, trackingNbr, dataFormat, formatOpt,
                  data):
     if toUID or self.CentralSessionExists():
         if toUID:
             session = self._objectsSessions.get(toUID, None)
         else:
             session = self._centralSession
         data = IoTSocketStruct.MakeRequestTRHdr( fromUID,
                                                  trackingNbr,
                                                  dataFormat,
                                                  formatOpt,
                                                  len(data) ) \
              + data
         if session and session.Send(data):
             return True
         if not toUID:
             toUID = IoTSocketStruct.CENTRAL_EMPTY_UID
         sessionData, exp = self._keepSessionsData.get(toUID, (None, None))
         if sessionData is not None:
             sessionData.append(data)
             self.Log('ROUTER > REQUEST KEPT (#%s)' % trackingNbr)
             return True
     else:
         if self._onGetWebHookRequest:
             plFormat, plObject = IoTSocketStruct.DecodeJSONPayload(
                 data, dataFormat)
             if plFormat is not None and plObject is not None:
                 webHook = self._onGetWebHookRequest(self)
                 if webHook:
                     webHook.ObjRef = (fromUID, trackingNbr)
                     webHook.OnResponseOk = self._onWebHookResponseOk
                     webHook.OnClosed = self._onWebHookClosed
                     webHook.Post(self._centralAuthKeyHex, fromUID,
                                  plObject, plFormat)
                     return True
                 self.Log('ROUTER > ERROR TO OPEN WEBHOOK OF REQUEST')
     self.Log('ROUTER > NO DESTINATION FOR REQUEST (#%s)' % trackingNbr)
     return False
예제 #27
0
 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''
     print('ON RESPONSE [%s] RECV (%s)' % (trackingNbr, code))
     self._waitDataTransmission()
 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)
예제 #29
0
 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
예제 #30
0
def OnUDPSrvDataRecv(xAsyncUDPDatagram, remoteAddr, datagram) :
    token, dataFormat, formatOpt, data = IoTSocketStruct.DecodeTelemetryPacket(datagram.tobytes())
    router.RouteTelemetry(token, dataFormat, formatOpt, data)