Exemplo n.º 1
0
    def getSetupPacket(commandType, crownstoneId, adminKey, memberKey,
                       guestKey, meshAccessAddress, ibeaconUUID, ibeaconMajor,
                       ibeaconMinor):
        """
		:param commandType:      	uint8 number
		:param crownstoneId:  		uint8 number
		:param adminKey:      		byteString (no conversion required)
		:param memberKey:     		byteString (no conversion required)
		:param guestKey:      		byteString (no conversion required)
		:param meshAccessAddress: 	hexstring
		:param ibeaconUUID: 		string  (ie. "1843423e-e175-4af0-a2e4-31e32f729a8a")
		:param ibeaconMajor:        uint16 number
		:param ibeaconMinor:        uint16 number
		:return:
		"""
        data = []
        data.append(commandType)
        data.append(crownstoneId)

        data += list(adminKey)
        data += list(memberKey)
        data += list(guestKey)

        if type(meshAccessAddress) is str:
            data += Conversion.hex_string_to_uint8_array(meshAccessAddress)
        else:
            data += Conversion.uint32_to_uint8_array(meshAccessAddress)

        data += Conversion.ibeaconUUIDString_to_reversed_uint8_array(
            ibeaconUUID)
        data += Conversion.uint16_to_uint8_array(ibeaconMajor)
        data += Conversion.uint16_to_uint8_array(ibeaconMinor)

        return ControlPacket(ControlType.SETUP).loadByteArray(data).getPacket()
Exemplo n.º 2
0
    def getPacket(self):
        # get the length of the payload before escaping
        baseLength = len(self.payload)

        # construct the basePacket, which is used for CRC calculation
        basePacket = []
        basePacket += Conversion.uint16_to_uint8_array(self.opCode)
        basePacket += Conversion.uint16_to_uint8_array(baseLength)
        basePacket += self.payload

        # calculate the CRC of the packet so far
        baseCrc = UartUtil.crc16_ccitt(basePacket)

        # append the CRC to the base packet to escape the entire thing
        basePacket += Conversion.uint16_to_uint8_array(baseCrc)

        # escape everything except the START_TOKEN
        escapedPayload = self.escapeCharacters(basePacket)

        uartPacket = []
        uartPacket.append(START_TOKEN)
        uartPacket += escapedPayload

        return uartPacket

        pass
Exemplo n.º 3
0
    def encrypt(self, data: int) -> int:
        # alteration to accept numbers instead of bytes
        data = Conversion.uint32_to_uint16_reversed_array(data)
        data = bytes(Conversion.uint16_array_to_uint8_array(data))

        blocksize = self.blocksize
        key = self.key
        rounds = self.rounds

        w = blocksize // 2
        b = blocksize // 8

        expanded_key = _expand_key(key, w, rounds)

        index = b
        chunk = data[:index]
        out = []
        while chunk:
            chunk = chunk.ljust(b, b"\x00")  # padding with 0 bytes if not large enough
            encrypted_chunk = _encrypt_block(chunk, expanded_key, blocksize, rounds)
            out.append(encrypted_chunk)

            chunk = data[index : index + b]  # Read in blocksize number of bytes
            index += b
        result = b"".join(out)

        result = Conversion.uint8_array_to_uint16_array(result)
        result = Conversion.uint16_reversed_array_to_uint32(result)

        return result
Exemplo n.º 4
0
    def decrypt(self, data: int) -> bytes:
        data = Conversion.uint32_to_uint16_reversed_array(data)
        data = bytes(Conversion.uint16_array_to_uint8_array(data))

        blocksize = self.blocksize
        key = self.key
        rounds = self.rounds

        w = blocksize // 2
        b = blocksize // 8

        expanded_key = _expand_key(key, w, rounds)

        index = b
        chunk = data[:index]
        out = []
        while chunk:
            decrypted_chunk = _decrypt_block(chunk, expanded_key, blocksize, rounds)
            chunk = data[index : index + b]  # Read in blocksize number of bytes
            if not chunk:
                decrypted_chunk = decrypted_chunk.rstrip(b"\x00")

            index += b
            out.append(decrypted_chunk)
        result = b"".join(out)

        result = Conversion.uint8_array_to_uint16_array(result)
        result = Conversion.uint16_reversed_array_to_uint32(result)

        return result
Exemplo n.º 5
0
 def getPacket(self):
     arr = []
     arr += Conversion.uint16_to_uint8_array(self.type)
     arr += Conversion.uint16_to_uint8_array(self.length + 2) # 2 for the ID size
     arr += self.payload # this is the state type
     arr += Conversion.uint16_to_uint8_array(self.id)
     return arr
Exemplo n.º 6
0
    def load(self, data):
        minSize = 6

        if len(data) >= minSize:
            self.commandTypeUInt16 = Conversion.uint8_array_to_uint16(
                [data[0], data[1]])
            resultNumber = Conversion.uint8_array_to_uint16([data[2], data[3]])

            if ControlType.has_value(self.commandTypeUInt16
                                     ) and ResultValue.has_value(resultNumber):
                self.commandType = ControlType(self.commandTypeUInt16)
                self.resultCode = ResultValue(resultNumber)
                self.size = Conversion.uint8_array_to_uint16(
                    [data[4], data[5]])

                totalSize = minSize + self.size
                if len(data) >= totalSize:
                    if self.size == 0:
                        return

                    for i in range(minSize, totalSize):
                        self.payload.append(data[i])
                else:
                    self.valid = False
            else:
                self.valid = False
        else:
            self.valid = False
    def parseErrorState(self, meshErrorState):
        self.crownstoneId = meshErrorState[0]
        self.hasError = True
        self.errorMode = True
        
        self.errorsBitmask = Conversion.uint8_array_to_uint32([
            meshErrorState[1],
            meshErrorState[2],
            meshErrorState[3],
            meshErrorState[4]
        ])
        
        self.errorTimestamp = Conversion.uint8_array_to_uint32([
            meshErrorState[5],
            meshErrorState[6],
            meshErrorState[7],
            meshErrorState[8]
        ])
        
        self.flagsBitmask = meshErrorState[9]
        self.temperature = meshErrorState[10]

        self.partialTimestamp = Conversion.uint8_array_to_uint16(meshErrorState[11:13])
        self.timestamp = reconstructTimestamp(time.time(), self.partialTimestamp)
    
        if self.crownstoneId == 0:
            self.deprecated = True
Exemplo n.º 8
0
def parseOpCode5(serviceData, data):
    if len(data) == 18:

        if DeviceType.has_value(data[1]):
            serviceData.deviceType = DeviceType(data[1])
        else:
            serviceData.deviceType = DeviceType.undefined

        serviceData.dataType = data[2]

        dataSlice = data[1:]

        if serviceData.dataType == 0:
            parseOpCode3_type0(serviceData, dataSlice)
        elif serviceData.dataType == 1:
            parseOpCode3_type1(serviceData, dataSlice)
        elif serviceData.dataType == 2:
            parseOpCode3_type2(serviceData, dataSlice)
            serviceData.rssiOfExternalCrownstone = Conversion.uint8_to_int8(
                dataSlice[15])
        elif serviceData.dataType == 3:
            parseOpCode3_type3(serviceData, dataSlice)
            serviceData.rssiOfExternalCrownstone = Conversion.uint8_to_int8(
                dataSlice[15])
        else:
            parseOpCode3_type0(serviceData, dataSlice)
Exemplo n.º 9
0
    def __init__(self, address, rssi, nameText, serviceData, serviceUUID=None):
        self.address = address
        self.rssi = rssi
        self.name = nameText

        self.serviceUUID = serviceUUID
        self.serviceData = None
        self.operationMode = None

        dataString = serviceData

        if serviceData is not None:
            if isinstance(serviceData, str):
                dataArray = Conversion.hex_string_to_uint8_array(dataString)
                self.serviceUUID = Conversion.uint8_array_to_uint16(
                    [dataArray[0], dataArray[1]])
                # pop the service UUID
                dataArray.pop(0)
                dataArray.pop(0)
            else:
                dataArray = serviceData

            if dataArray:
                self.serviceData = ServiceData(dataArray)

            self.operationMode = "NORMAL"
Exemplo n.º 10
0
def obtainTimestamp(fullTimeStamp, lsb):
    timestampBytes = Conversion.uint32_to_uint8_array(int(fullTimeStamp))
    lsbBytes = Conversion.uint16_to_uint8_array(lsb)

    restoredTimestamp = Conversion.uint8_array_to_uint32(
        [lsbBytes[0], lsbBytes[1], timestampBytes[2], timestampBytes[3]])

    return restoredTimestamp
Exemplo n.º 11
0
 def getPacket(self):
     arr = []
     arr += Conversion.uint16_to_uint8_array(self.type)
     arr += Conversion.uint16_to_uint8_array(self.length + 4) # the + 2 is for the stateType uint16 and +2 for the id
     arr += Conversion.uint16_to_uint8_array(self.stateType)
     arr += Conversion.uint16_to_uint8_array(self.id)
     arr += self.payload
     return arr
Exemplo n.º 12
0
    def getPacket(self):
        arr = []

        arr.append(self.presenceType.value)
        arr += Conversion.uint64_to_uint8_array(self.getMask(self.locationIds))
        arr += Conversion.uint32_to_uint8_array(self.delayInSeconds)

        return arr
Exemplo n.º 13
0
 def loadKeys(self, encryptionEnabled, adminKey, memberKey, guestKey, referenceId):
     self.encryptionEnabled = encryptionEnabled
     
     self.adminKey  = Conversion.ascii_or_hex_string_to_16_byte_array(adminKey)
     self.memberKey = Conversion.ascii_or_hex_string_to_16_byte_array(memberKey)
     self.guestKey  = Conversion.ascii_or_hex_string_to_16_byte_array(guestKey)
     
     self.referenceId = referenceId
     
     self.initializedKeys = True
     self.determineUserLevel()
Exemplo n.º 14
0
 def _verifyDecryption(decrypted, validationKey):
     # the conversion to uint32 only takes the first 4 bytes
     if Conversion.uint8_array_to_uint32(decrypted) == Conversion.uint8_array_to_uint32(validationKey):
         # remove checksum from decryption and return payload
         result = [0] * (len(decrypted) - SESSION_KEY_LENGTH)
         for i in range(0,len(result)):
             result[i] = decrypted[i+SESSION_KEY_LENGTH]
         return result
 
     else:
         raise BluenetBleException(BleError.ENCRYPTION_VALIDATION_FAILED, "Failed to validate result, Could not decrypt")
Exemplo n.º 15
0
    def __init__(self, payload):
        if len(payload) < self.packetSize:
            print("ERROR: INVALID PAYLOAD LENGTH", len(payload), payload)
            return

        self.timestampCounter = Conversion.uint8_array_to_uint32(payload[0:4])
        self.samples = []
        for i in range(4, self.packetSize, self.sampleSize):
            self.samples.append(
                Conversion.uint8_array_to_int16(payload[i:i +
                                                        self.sampleSize]))
Exemplo n.º 16
0
 def test_switchPacket(self):
     rawData = [0, 0, 1, 0, 100]
     sessionNonce = Conversion.string_to_uint8_array("12345")
     encryptionData = EncryptionHandler.encryptCTR(
         rawData, [128, 128, 128], sessionNonce,
         Conversion.string_to_uint8_array("AdminKeyOf16Byte"))
     self.assertEqual(
         encryptionData,
         bytes([
             171, 199, 94, 51, 230, 26, 253, 144, 182, 105, 56, 210, 94,
             165, 184, 243
         ]))
Exemplo n.º 17
0
def parseOpCode3_type0(serviceData, data):
    if len(data) == 16:
        # dataType = data[0]

        serviceData.stateOfExternalCrownstone = False

        serviceData.crownstoneId = data[1]
        serviceData.switchState = data[2]
        serviceData.flagsBitmask = data[3]

        # bitmask states
        bitmaskArray = Conversion.uint8_to_bit_array(serviceData.flagsBitmask)

        serviceData.dimmerReady = bitmaskArray[0]
        serviceData.dimmingAllowed = bitmaskArray[1]
        serviceData.hasError = bitmaskArray[2]
        serviceData.switchLocked = bitmaskArray[3]
        serviceData.timeIsSet = bitmaskArray[4]
        serviceData.switchCraftEnabled = bitmaskArray[5]

        serviceData.tapToToggleEnabled = bitmaskArray[6]
        serviceData.behaviourOverridden = bitmaskArray[7]

        serviceData.temperature = Conversion.uint8_to_int8(data[4])
        powerFactor = Conversion.uint8_to_int8(data[5])
        realPower = Conversion.uint16_to_int16(
            Conversion.uint8_array_to_uint16([data[6], data[7]]))

        serviceData.powerFactor = float(powerFactor) / 127.0

        # we cannot have a 0 for a power factor.To avoid division by 0, we set it to be either 0.01 or -0.01
        if 0 <= serviceData.powerFactor < 0.01:
            serviceData.powerFactor = 0.01
        elif -0.01 < serviceData.powerFactor < 0:
            serviceData.powerFactor = -0.01

        serviceData.powerUsageReal = float(realPower) / 8.0
        serviceData.powerUsageApparent = serviceData.powerUsageReal / serviceData.powerFactor

        serviceData.accumulatedEnergy = Conversion.uint32_to_int32(
            Conversion.uint8_array_to_uint32(
                [data[8], data[9], data[10], data[11]]))

        serviceData.partialTimestamp = Conversion.uint8_array_to_uint16(
            [data[12], data[13]])
        serviceData.uniqueIdentifier = serviceData.partialTimestamp

        if serviceData.timeIsSet:
            serviceData.timestamp = reconstructTimestamp(
                time.time(), serviceData.partialTimestamp)
        else:
            serviceData.timestamp = serviceData.partialTimestamp  # this is now a counter

        globalBitmaskArray = Conversion.uint8_to_bit_array(data[14])
        serviceData.behaviourEnabled = globalBitmaskArray[0]

        serviceData.validation = data[15]
Exemplo n.º 18
0
    def parseState(self, meshStateItemState):
        self.crownstoneId       = meshStateItemState[0]
        self.switchState        = meshStateItemState[1]
        self.flagsBitmask        = meshStateItemState[2]
        self.temperature        = meshStateItemState[3]
        self.powerFactor        = float(meshStateItemState[4]) / 127
        self.powerUsageReal     = float(Conversion.uint8_array_to_int16(meshStateItemState[5:7])) / 8
        if self.powerFactor == 0:
            self.powerFactor = 1.0
        self.powerUsageApparent = self.powerUsageReal / self.powerFactor
        self.accumulatedEnergy         = Conversion.uint8_array_to_int32(meshStateItemState[7:11])
        self.partialTimestamp   = Conversion.uint8_array_to_uint16(meshStateItemState[11:13])
        self.timestamp          = reconstructTimestamp(time.time(), self.partialTimestamp)

        if self.crownstoneId == 0:
            self.deprecated = True
Exemplo n.º 19
0
    def getPacket(self):
        packet = []
        packet += Conversion.uint16_to_uint8_array(self.type)
        packet += self.lengthAsUint8Array
        packet += self.payload

        return packet
Exemplo n.º 20
0
    def __init__(self, payload):
        self.stoneStates = []

        if len(payload) != MESH_STATE_PACKET_SIZE:
            print("ERROR: INVALID PAYLOAD LENGTH", len(payload), payload)
            return
        self.stoneStates = []
        self.head = payload[0]
        self.tail = payload[1]
        self.size = payload[2]
        self.timestamp = Conversion.uint8_array_to_uint32(payload[4:8])

        expectedSizeOfStoneStates = self.size * STONE_STATE_PACKET_SIZE

        if expectedSizeOfStoneStates + 8 > MESH_STATE_PACKET_SIZE:
            print("ERROR: CANT FIT STONE STATE PACKETS IN MESSAGE",
                  expectedSizeOfStoneStates)
            return

        for i in range(0, self.size):
            self.stoneStates.append(
                StoneStatePacket(payload[8 + i * STONE_STATE_PACKET_SIZE:8 +
                                         (i + 1) * STONE_STATE_PACKET_SIZE]))

        # deprecation is when a stone id has multiple entrees in the data. Checking for this makes sure we only use the latest one.
        self._checkForDeprecation()
Exemplo n.º 21
0
    def getPacket(self):
        arr = []

        arr.append(self.timeType.value)
        arr += Conversion.int32_to_uint8_array(self.offset)

        return arr
Exemplo n.º 22
0
    def getPacket(self):
        packet = []
        packet.append(self.crownstoneId)
        packet.append(self.state)
        packet += Conversion.uint16_to_uint8_array(self.timeout)
        packet.append(self.intent)

        return packet
Exemplo n.º 23
0
    def getSetupPacket(crownstoneId, sphereId, adminKey, memberKey, basicKey,
                       serviceDataKey, localizationKey, meshDeviceKey,
                       meshAppKey, meshNetworkKey, ibeaconUUID, ibeaconMajor,
                       ibeaconMinor):
        """
		:param crownstoneId:  		uint8 number
		:param sphereId:  	     	uint8 number
		:param adminKey:      		byteString (no conversion required)
		:param memberKey:     		byteString (no conversion required)
		:param basicKey:      		byteString (no conversion required)
		:param serviceDataKey: 	    byteString (no conversion required)
		:param localizationKey: 	byteString (no conversion required)
		:param meshDeviceKey: 	    byteString (no conversion required)
		:param meshAppKey: 	        byteString (no conversion required)
		:param meshNetworkKey: 	    byteString (no conversion required)
		:param ibeaconUUID: 		string  (ie. "1843423e-e175-4af0-a2e4-31e32f729a8a")
		:param ibeaconMajor:        uint16 number
		:param ibeaconMinor:        uint16 number
		:return:
		"""
        data = []
        data.append(crownstoneId)
        data.append(sphereId)

        data += list(adminKey)
        data += list(memberKey)
        data += list(basicKey)
        data += list(serviceDataKey)
        data += list(localizationKey)

        MDKey = meshDeviceKey
        if type(meshDeviceKey) is str:
            MDKey = Conversion.ascii_or_hex_string_to_16_byte_array(
                meshDeviceKey)

        data += list(MDKey)
        data += list(meshAppKey)
        data += list(meshNetworkKey)

        data += Conversion.ibeaconUUIDString_to_reversed_uint8_array(
            ibeaconUUID)
        data += Conversion.uint16_to_uint8_array(ibeaconMajor)
        data += Conversion.uint16_to_uint8_array(ibeaconMinor)

        return ControlPacket(ControlType.SETUP).loadByteArray(data).getPacket()
Exemplo n.º 24
0
def parseOpcode3_type3(serviceData, data):
    if len(data) == 17:
        parseOpcode3_type1(serviceData, data)

        # apply differences between type 1 and type 4
        serviceData.stateOfExternalCrownstone = True
        serviceData.powerUsageReal = 0
        serviceData.validation = Conversion.uint8_array_to_uint16(
            [data[15], data[16]])
Exemplo n.º 25
0
    def getUInt16Payload(self):
        if not self.valid:
            return 65535

        if self.length >= 2:
            return Conversion.uint8_array_to_uint16(
                [self.payload[0], self.payload[1]])
        else:
            return 65535
Exemplo n.º 26
0
 def getPacket(self):
     packet = []
     packet.append(self.type)
     timeoutArray = Conversion.uint16_to_uint8_array(self.timeout)
     packet += timeoutArray
     packet.append(len(self.packets))
     for keepAlivePacket in self.packets:
         packet += keepAlivePacket.getPacket()
     return packet
Exemplo n.º 27
0
def parseOpCode5(serviceData, data):
    if len(data) == 16:
        serviceData.dataType = data[0]

        if serviceData.dataType == 0:
            parseOpCode3_type0(serviceData, data)
        elif serviceData.dataType == 1:
            parseOpCode3_type1(serviceData, data)
        elif serviceData.dataType == 2:
            parseOpCode3_type2(serviceData, data)
            serviceData.rssiOfExternalCrownstone = Conversion.uint8_to_int8(
                data[15])
        elif serviceData.dataType == 3:
            parseOpCode3_type3(serviceData, data)
            serviceData.rssiOfExternalCrownstone = Conversion.uint8_to_int8(
                data[15])
        else:
            parseOpCode3_type0(serviceData, data)
Exemplo n.º 28
0
    def __init__(self, action, state, timeout):
        packet = []
        packet.append(action)
        packet.append(state)
        timeoutByteArray = Conversion.uint16_to_uint8_array(timeout)
        packet += timeoutByteArray

        super().__init__(ControlType.KEEP_ALIVE_STATE)
        self.loadByteArray(packet)
Exemplo n.º 29
0
 def __init__(self, payload, channelIndex):
     if len(payload) < self.packetSize:
         print("ERROR: INVALID PAYLOAD LENGTH", len(payload), payload)
         return
     
     self.channelIndex = channelIndex
     
     self.pin    = payload[0]
     self.range  = Conversion.uint8_array_to_uint32(payload[1:1+4])
     self.refPin = payload[5]
Exemplo n.º 30
0
    def __init__(self, bitMask):
        self.bitMask = bitMask

        bitArray = Conversion.uint32_to_bit_array_reversed(bitMask)

        self.overCurrent = bitArray[31 - 0]
        self.overCurrentDimmer = bitArray[31 - 1]
        self.temperatureChip = bitArray[31 - 2]
        self.temperatureDimmer = bitArray[31 - 3]
        self.dimmerOnFailure = bitArray[31 - 4]
        self.dimmerOffFailure = bitArray[31 - 5]