コード例 #1
0
	def getPacket(self):
		"""
		Adds start token, header and CRC to payload. Escapes bytes.
		"""
		# Construct the packet for CRC calculation
		packet = []
		packet.append(self.protocolMajor)
		packet.append(self.protocolMinor)
		packet.append(int(self.messageType))
		packet += self.payload

		# Calculate the CRC of the packet
		packetCrc = crc16ccitt(packet)

		# Append the CRC to the base packet to escape the entire thing
		packet += Conversion.uint16_to_uint8_array(packetCrc)

		# Prepend the size field.
		sizeField = len(packet)
		packet = Conversion.uint16_to_uint8_array(sizeField) + packet

		# Escape everything except the start token
		packet = self.escapeCharacters(packet)

		# Prepend the start token.
		packet = [START_TOKEN] + packet
		return packet
コード例 #2
0
ファイル: RC5.py プロジェクト: crownstone/programmer
    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
コード例 #3
0
ファイル: RC5.py プロジェクト: crownstone/programmer
    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
コード例 #4
0
    def getIBeaconConfigIdPacket(id, timestamp, interval):
        data = []
        data.append(id)
        data += Conversion.uint32_to_uint8_array(timestamp)
        data += Conversion.uint16_to_uint8_array(interval)

        return ControlPacket(
            ControlType.SET_IBEACON_CONFIG_ID).loadByteArray(data).serialize()
コード例 #5
0
    def serialize(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
コード例 #6
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
コード例 #7
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]))
コード例 #8
0
 def getPacket(self):
     # TODO: make use of the base class, now there is a double implementation of the control packet.
     arr = [SUPPORTED_PROTOCOL_VERSION]
     arr += Conversion.uint16_to_uint8_array(self.type)
     arr += Conversion.uint16_to_uint8_array(
         self.length + 6
     )  # the + 2 is for the stateType uint16, +2 for the id, +2 for persistenceMode and reserved
     arr += self.payload  # this is the state type
     arr += Conversion.uint16_to_uint8_array(self.id)
     arr.append(self.persistenceMode)
     arr.append(0)
     return arr
コード例 #9
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 CrownstoneBleException(
                EncryptionError.ENCRYPTION_VALIDATION_FAILED,
                "Failed to validate result, Could not decrypt")
コード例 #10
0
    def process(self):
        """
        Process a buffer.

        Check CRC, and emit a uart packet.

        Buffer starts after size header, and includes wrapper header and tail (CRC).

        Return: processing success
        """

        # Check size
        bufferSize = len(self.buffer)
        wrapperSize = WRAPPER_HEADER_SIZE + CRC_SIZE
        if bufferSize < wrapperSize:
            _LOGGER.warning("Buffer too small")
            return False

        # Get the buffer between size field and CRC:
        baseBuffer = self.buffer[0 : bufferSize - CRC_SIZE]

        # Check CRC
        calculatedCrc = crc16ccitt(baseBuffer)
        sourceCrc = Conversion.uint8_array_to_uint16(self.buffer[bufferSize - CRC_SIZE : ])

        if calculatedCrc != sourceCrc:
            _LOGGER.warning("Failed CRC: {0} != {1} (data: {2})".format(calculatedCrc, sourceCrc, baseBuffer))
            UartEventBus.emit(DevTopics.uartNoise, "crc mismatch")
            return False

        wrapperPacket = UartWrapperPacket()
        if wrapperPacket.parse(baseBuffer):
            UartEventBus.emit(SystemTopics.uartNewPackage, wrapperPacket)
            return True
コード例 #11
0
    def getPacket(self):
        packet = [SUPPORTED_PROTOCOL_VERSION]
        packet += Conversion.uint16_to_uint8_array(self.type)
        packet += self.lengthAsUint8Array
        packet += self.payload

        return packet
コード例 #12
0
ファイル: DebugHandler.py プロジェクト: crownstone/programmer
	async def getUptime(self):
		""" Get the uptime of the crownstone in seconds. """
		controlPacket = ControlPacket(ControlType.GET_UPTIME).getPacket()
		result = await self._writeControlAndGetResult(controlPacket)
		if result.resultCode != ResultValue.SUCCESS:
			raise CrownstoneException(CrownstoneError.RESULT_NOT_SUCCESS, "Result: " + str(result.resultCode))
		return Conversion.uint8_array_to_uint32(result.payload)
コード例 #13
0
    def getPacket(self):
        arr = []

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

        return arr
コード例 #14
0
    def getSetupPacket(crownstoneId: int, sphereId: int, adminKey, memberKey,
                       basicKey, serviceDataKey, localizationKey,
                       meshDeviceKey, meshAppKey, meshNetworkKey,
                       ibeaconUUID: str, ibeaconMajor: int, ibeaconMinor: int):
        """
        :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).serialize()
コード例 #15
0
    def getPacket(self):
        # Header: 1B device ID, 2B opcode

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

        return uartMsg
コード例 #16
0
    def add(self, byte):
        self.rawBuffer.append(byte)

        # An escape shouldn't be followed by a special byte.
        if self.escapingNextByte and (byte is START_TOKEN or byte is ESCAPE_TOKEN):
            _LOGGER.warning("Received special byte after escape token.")
            self.reset(True)
            return

        # Activate on start token.
        if byte is START_TOKEN:
            if self.active:
                _LOGGER.warning("Received multiple start tokens.")
                self.reset(True)
            else:
                # Reset to be sure.
                self.reset()

            self.active = True
            return

        if not self.active:
            # Since the start token was not received, we discard this byte.
            self.reset(True)
            return

        # Escape next byte on escape token.
        if byte is ESCAPE_TOKEN:
            self.escapingNextByte = True
            return

        if self.escapingNextByte:
            byte ^= BIT_FLIP_MASK
            self.escapingNextByte = False

        self.buffer.append(byte)
        bufferSize = len(self.buffer)

        if self.sizeToRead == 0:
            # We didn't parse the size yet.
            if bufferSize == SIZE_HEADER_SIZE:
                # Now we know the remaining size to read
                self.sizeToRead = Conversion.uint8_array_to_uint16(self.buffer)

                # Size to read shouldn't be 0.
                if self.sizeToRead == 0:
                    self.reset(True)
                    return

                self.buffer = []
                return

        elif bufferSize >= self.sizeToRead:
            processSuccessful = self.process()
            self.reset(not processSuccessful)
            return
コード例 #17
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]
コード例 #18
0
    def add(self, byte):
        # An escape shouldn't be followed by a special byte.
        if self.escapingNextByte and (byte is START_TOKEN
                                      or byte is ESCAPE_TOKEN):
            _LOGGER.warning("Special byte after escape token")
            UartEventBus.emit(DevTopics.uartNoise,
                              "special byte after escape token")
            self.reset()
            return

        # Activate on start token.
        if byte is START_TOKEN:
            if self.active:
                _LOGGER.warning("MULTIPLE START TOKENS")
                _LOGGER.debug(
                    f"Multiple start tokens: sizeToRead={self.sizeToRead} bufLen={len(self.buffer)} buffer={self.buffer}"
                )
                UartEventBus.emit(DevTopics.uartNoise, "multiple start token")
            self.reset()
            self.active = True
            return

        if not self.active:
            return

        # Escape next byte on escape token.
        if byte is ESCAPE_TOKEN:
            self.escapingNextByte = True
            return

        if self.escapingNextByte:
            byte ^= BIT_FLIP_MASK
            self.escapingNextByte = False

        self.buffer.append(byte)
        bufferSize = len(self.buffer)

        if self.sizeToRead == 0:
            # We didn't parse the size yet.
            if bufferSize == SIZE_HEADER_SIZE:
                # Now we know the remaining size to read
                self.sizeToRead = Conversion.uint8_array_to_uint16(self.buffer)

                # Size to read shouldn't be 0.
                if self.sizeToRead == 0:
                    self.reset()
                    return

                self.buffer = []
                return

        elif bufferSize >= self.sizeToRead:
            self.process()
            self.reset()
            return
コード例 #19
0
    def __init__(self, byte):
        self.type = AdvType.CROWNSTONE_FLAGS

        bitmaskArray = Conversion.uint8_to_bit_array(byte)

        self.dimmerReady = bitmaskArray[0]
        self.dimmingAllowed = bitmaskArray[1]
        self.hasError = bitmaskArray[2]
        self.switchLocked = bitmaskArray[3]
        self.timeIsSet = bitmaskArray[4]
        self.switchCraftEnabled = bitmaskArray[5]
        self.tapToToggleEnabled = bitmaskArray[6]
        self.behaviourOverridden = bitmaskArray[7]
コード例 #20
0
    def __init__(self, bitMask):
        self.type = AdvType.CROWNSTONE_ERRORS

        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]
コード例 #21
0
    def __init__(self, byte):
        self.type = AdvType.ALTERNATIVE_STATE

        bitmaskArray = Conversion.uint8_to_bit_array(byte)

        self.uartAlive = bitmaskArray[0]
        self.uartAliveEncrypted = bitmaskArray[1]
        self.uartEncryptionRequiredByCrownstone = bitmaskArray[2]
        self.uartEncryptionRequiredByHub = bitmaskArray[3]
        self.hubHasBeenSetUp = bitmaskArray[4]
        self.hubHasInternet = bitmaskArray[5]
        self.hubHasError = bitmaskArray[6]
        self.timeIsSet = bitmaskArray[7]
コード例 #22
0
def test_add_contains():
    """
    Checks if
    _add(0), _add(1), ..., _add(max_items),
    _contains(0), _contains(1), ..., _contains(max_items),
    does what it 's supposed to do. A load factor is incorporated
    since cuckoo filters will not fit their theoretical max load.
    """

    # Settings for this test
    max_buckets_log2 = 7
    nests_per_bucket = 4
    load_factor = 0.75

    filter = CuckooFilter(max_buckets_log2, nests_per_bucket)

    # setup test variables
    max_items = filter.fingerprintcount()
    num_items_to_test = int(max_items * load_factor)
    fails = 0

    # Add a lot of integers
    for i in range(num_items_to_test):
        i_as_uint8_list = Conversion.uint32_to_uint8_array(i)
        if not filter.add(i_as_uint8_list):
            fails += 1

    assert fails == 0, "Add failed"
    fails = 0

    # check if they ended up in the filter
    for i in range(num_items_to_test):
        i_as_uint8_list = Conversion.uint32_to_uint8_array(i)
        if not filter.contains(i_as_uint8_list):
            fails += 1

    assert fails == 0, "Contains failed"
    fails = 0
コード例 #23
0
    def loadKeys(self, adminKey, memberKey, basicKey, serviceDataKey,
                 localizationKey, meshApplicationKey, meshNetworkKey):
        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.basicKey = Conversion.ascii_or_hex_string_to_16_byte_array(
            basicKey)
        self.serviceDataKey = Conversion.ascii_or_hex_string_to_16_byte_array(
            serviceDataKey)
        self.localizationKey = Conversion.ascii_or_hex_string_to_16_byte_array(
            localizationKey)
        self.meshApplicationKey = Conversion.ascii_or_hex_string_to_16_byte_array(
            meshApplicationKey)
        self.meshNetworkKey = Conversion.ascii_or_hex_string_to_16_byte_array(
            meshNetworkKey)

        self.initializedKeys = True
        self.determineUserLevel()
コード例 #24
0
    def __init__(self, payload):
        if len(payload) < 1:
            print("ERROR: INVALID PAYLOAD LENGTH", len(payload), payload)
            return

        self.channels = []

        index = 0
        self.amountOfChannels = payload[index]
        index += 1
        self.packetSize = self.amountOfChannels * self.channelSize + 1 + 4  # 4 for sampling period, 1 for count

        if len(payload) < self.packetSize:
            print("ERROR: INVALID PAYLOAD LENGTH", len(payload), payload)
            return

        for i in range(0, self.amountOfChannels):
            self.channels.append(
                AdcChannelPacket(payload[index:index + self.channelSize], i))
            index += self.channelSize

        self.samplingPeriod = Conversion.uint8_array_to_uint32(
            payload[index:index + 4])
コード例 #25
0
    def process(self):
        """
        Process a buffer.

        Check CRC, and emit a uart packet.

        Buffer starts after size header, and includes wrapper header and tail (CRC).
        """

        # Check size
        bufferSize = len(self.buffer)
        wrapperSize = WRAPPER_HEADER_SIZE + CRC_SIZE
        if bufferSize < wrapperSize:
            _LOGGER.warning("Buffer too small")
            UartEventBus.emit(DevTopics.uartNoise, "buffer too small")
            return

        # Get the buffer between size field and CRC:
        baseBuffer = self.buffer[0:bufferSize - CRC_SIZE]

        # Check CRC
        calculatedCrc = crc16ccitt(baseBuffer)
        sourceCrc = Conversion.uint8_array_to_uint16(self.buffer[bufferSize -
                                                                 CRC_SIZE:])

        if calculatedCrc != sourceCrc:
            _LOGGER.warning("Failed CRC")
            _LOGGER.debug(
                f"Failed CRC: sourceCrc={sourceCrc} calculatedCrc={calculatedCrc} bufSize={len(self.buffer)} buffer={self.buffer}"
            )
            UartEventBus.emit(DevTopics.uartNoise, "crc mismatch")
            return

        wrapperPacket = UartWrapperPacket()
        if wrapperPacket.parse(baseBuffer):
            UartEventBus.emit(SystemTopics.uartNewPackage, wrapperPacket)
コード例 #26
0
def write_uint16(outfile, val):
    for byt in Conversion.uint16_to_uint8_array(val):
        write_uint8(outfile, byt)
コード例 #27
0
    def __init__(self, byte):
        self.type = AdvType.MICROAPP_FLAGS

        bitmaskArray = Conversion.uint8_to_bit_array(byte)

        self.behaviourEnabled = bitmaskArray[0]
コード例 #28
0
 def getFloat(self):
     """ Get a float from the current position, and advance the position. """
     return Conversion.uint8_array_to_float(self._request(4))
コード例 #29
0
 def getUInt64(self):
     """ Get a uint64 from the current position, and advance the position. """
     return Conversion.uint8_array_to_uint64(self._request(8))
コード例 #30
0
 def getInt32(self):
     """ Get an int32 from the current position, and advance the position. """
     return Conversion.uint8_array_to_int32(self._request(4))