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
Пример #2
0
    def _switch_crownstone(self, crownstone_id: int, switch_val: int):
        """
        :param crownstone_id:
        :param switch_val: 0% .. 100% or special value (SwitchValSpecial).
        :return:
        """

        # create a stone switch state packet to go into the multi switch
        stoneSwitchPacket = StoneMultiSwitchPacket(crownstone_id, switch_val)

        # wrap it in a mesh multi switch packet
        meshMultiSwitchPacket = MeshMultiSwitchPacket([stoneSwitchPacket
                                                       ]).getPacket()

        # wrap that in a control packet
        controlPacket = ControlPacket(ControlType.MULTISWITCH).loadByteArray(
            meshMultiSwitchPacket).getPacket()

        # wrap that in a uart message
        uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                        controlPacket).getPacket()

        # finally wrap it in a uart wrapper packet
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                       uartMessage).getPacket()

        # send over uart
        UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)
Пример #3
0
 def writeHello(self):
     helloPacket = UartCommandHelloPacket().getPacket()
     uartMessage = UartMessagePacket(UartTxType.HELLO,
                                     helloPacket).getPacket()
     uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                    uartMessage).getPacket()
     UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)
Пример #4
0
    async def _command_via_mesh_broadcast(self, packet: bytearray):
        # this is only for time and noop
        # broadcast to all:
        # value: 1
        corePacket = MeshBroadcastPacket(packet).getPacket()
        controlPacket = ControlPacket(
            ControlType.MESH_COMMAND).loadByteArray(corePacket).getPacket()
        uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                        controlPacket).getPacket()
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                       uartMessage).getPacket()

        resultCollector = Collector(timeout=2, topic=SystemTopics.resultPacket)

        # send the message to the Crownstone
        UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)

        # wait for the collectors to fill
        commandResultData = await resultCollector.receive()

        if commandResultData is not None:
            if commandResultData.resultCode is ResultValue.BUSY:
                await asyncio.sleep(0.2)
                return await self._command_via_mesh_broadcast(packet)
            elif commandResultData.resultCode is not ResultValue.SUCCESS:
                raise CrownstoneException(commandResultData.resultCode,
                                          "Command has failed.")

        await asyncio.sleep(0.1)
Пример #5
0
 def echo(self, string):
     controlPacket = ControlPacket(
         ControlType.UART_MESSAGE).loadString(string).getPacket()
     uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                     controlPacket).getPacket()
     uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                    uartMessage).getPacket()
     UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)
Пример #6
0
def getRamStats():
    controlPacket = ControlPacket(ControlType.GET_RAM_STATS).getPacket()
    uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                    controlPacket).getPacket()
    uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                   uartMessage).getPacket()
    try:
        result = UartWriter(uartPacket).write_with_result_sync()
        if result.resultCode is ResultValue.SUCCESS:
            return RamStatsPacket(result.payload)
        logging.log(logging.WARN, f"Get ram stats failed, result={result}")
    except CrownstoneException as e:
        logging.log(logging.WARN, f"Get ram stats failed: {e}")
    return None
 def disable_microapp(self, index: int):
     """
     Disable a running microapp in Bluenet by removing it from RAM. Return True if message is
     send correctly, it doesn't check if the command is set correctly in Bluenet. For now only
     an index of 0 can be given, since Bluenet only supports a single app to run.
     """
     packet = MicroappHeaderPacket(index)
     controlPacket = ControlPacket(
         ControlType.MICROAPP_DISABLE).loadByteArray(
             packet.serialize()).serialize()
     uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                     controlPacket).serialize()
     uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                    uartMessage).serialize()
     UartWriter(uartPacket).write_sync()
 def validate_microapp(self, index: int):
     """
     validate the binary of a microapp saved in Bluenet flash memory. Return True if message is
     send correctly, it doesn't check if the command is set correctly in Bluenet. For now only
     an index of 0 can be given, since Bluenet only supports a single app to run.
     """
     packet = MicroappHeaderPacket(index)
     controlPacket = ControlPacket(
         ControlType.MICROAPP_VALIDATE).loadByteArray(
             packet.serialize()).serialize()
     uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                     controlPacket).serialize()
     uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                    uartMessage).serialize()
     UartWriter(uartPacket).write_sync()
Пример #9
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)
Пример #10
0
    def uart_echo(self, payloadString):
        # wrap that in a control packet
        controlPacket = ControlPacket(
            ControlType.UART_MESSAGE).loadString(payloadString).getPacket()

        # wrap that in a uart message
        uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                        controlPacket).getPacket()

        # finally, wrap it in an uart wrapper packet
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                       uartMessage).getPacket()

        # send over uart
        result = UartWriter(uartPacket).write_sync()
 def enable_microapp(self, index: int):
     """
     Enable microapp in Bluenet and load it in RAM. Return True if message is send correctly,
     it doesn't check if the command is set correctly in Bluenet. For now only an index of 0
     can be given, since Bluenet only supports a single app to run. It is recommended to run
     the validation function before enabling the microapp to make sure a microapp is able to
     run.
     """
     packet = MicroappHeaderPacket(index)
     controlPacket = ControlPacket(
         ControlType.MICROAPP_ENABLE).loadByteArray(
             packet.serialize()).serialize()
     uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                     controlPacket).serialize()
     uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                    uartMessage).serialize()
     UartWriter(uartPacket).write_sync()
Пример #12
0
def setup() -> bool:
    logging.log(logging.INFO, "Perform setup")
    try:
        controlPacket = ControlPacketsGenerator.getSetupPacket(
            crownstoneId=crownstoneId,
            sphereId=sphereId,
            adminKey=Conversion.ascii_or_hex_string_to_16_byte_array(adminKey),
            memberKey=Conversion.ascii_or_hex_string_to_16_byte_array(
                memberKey),
            basicKey=Conversion.ascii_or_hex_string_to_16_byte_array(basicKey),
            serviceDataKey=Conversion.ascii_or_hex_string_to_16_byte_array(
                serviceDataKey),
            localizationKey=Conversion.ascii_or_hex_string_to_16_byte_array(
                localizationKey),
            meshDeviceKey=Conversion.ascii_or_hex_string_to_16_byte_array(
                meshDeviceKey),
            meshAppKey=Conversion.ascii_or_hex_string_to_16_byte_array(
                meshAppKey),
            meshNetworkKey=Conversion.ascii_or_hex_string_to_16_byte_array(
                meshNetworkKey),
            ibeaconUUID=ibeaconUUID,
            ibeaconMajor=ibeaconMajor,
            ibeaconMinor=ibeaconMinor)
        uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                        controlPacket).getPacket()
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                       uartMessage).getPacket()
        result = UartWriter(uartPacket).write_with_result_sync(
            [ResultValue.SUCCESS, ResultValue.WAIT_FOR_SUCCESS])
        if result.resultCode is ResultValue.SUCCESS:
            return True
        if result.resultCode is ResultValue.WAIT_FOR_SUCCESS:
            # Actually we should wait for the next result code..
            time.sleep(3.0)
            return True
        logging.log(logging.WARN, f"Setup failed, result={result}")
        return False

    except CrownstoneException as e:
        logging.log(logging.WARN, f"Failed to setup: {e}")
        return False
Пример #13
0
    async def _write(self, controlPacket: [int], successCodes = [ResultValue.SUCCESS, ResultValue.SUCCESS_NO_CHANGE, ResultValue.WAIT_FOR_SUCCESS]) -> [int] or None:
        """
        Returns the result payload.
        TODO: return result packet.
        TODO: use a ControlPacket as param, instead of int array.
        """
        _LOGGER.debug(f"Write control packet {controlPacket}")
        uartMessage = UartMessagePacket(UartTxType.CONTROL, controlPacket).serialize()
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE, uartMessage).serialize()

        resultCollector = Collector(timeout=1, topic=SystemTopics.resultPacket)
        # send the message to the Crownstone
        UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)

        # wait for the collectors to fill
        commandResultData = await resultCollector.receive()

        if commandResultData is not None:
            if commandResultData.resultCode not in successCodes:
                raise CrownstoneException(commandResultData.resultCode, f"Command has failed: result code is {commandResultData.resultCode}")
            return commandResultData.payload
        return None
    async def setPowerZero(self, mW: int):
        controlPacket = ControlStateSetPacket(
            StateType.POWER_ZERO).loadInt32(mW).serialize()
        uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                        controlPacket).serialize()
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                       uartMessage).serialize()

        resultCollector = Collector(timeout=1, topic=SystemTopics.resultPacket)
        # send the message to the Crownstone
        UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)

        # wait for the collectors to fill
        commandResultData = await resultCollector.receive()

        if commandResultData is not None:
            if commandResultData.resultCode is ResultValue.BUSY:
                await asyncio.sleep(0.2)
                return await self.setPowerZero(mW)
            elif commandResultData.resultCode is not ResultValue.SUCCESS:
                raise CrownstoneException(commandResultData.resultCode,
                                          "Command has failed.")
Пример #15
0
    async def _command_via_mesh_broadcast_acked(
            self, crownstone_uid_array: List[int],
            packet: bytearray) -> MeshResult:
        # this is only for the set_iBeacon_config_id
        # broadcast to all, but retry until ID's in list have acked or timeout
        # value: 3
        corePacket = MeshBroadcastAckedPacket(crownstone_uid_array,
                                              packet).getPacket()
        controlPacket = ControlPacket(
            ControlType.MESH_COMMAND).loadByteArray(corePacket).getPacket()
        uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                        controlPacket).getPacket()
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                       uartMessage).getPacket()

        resultCollector = Collector(timeout=2, topic=SystemTopics.resultPacket)
        individualCollector = BatchCollector(
            timeout=15, topic=SystemTopics.meshResultPacket)
        finalCollector = Collector(timeout=15,
                                   topic=SystemTopics.meshResultFinalPacket)

        # send the message to the Crownstone
        UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)

        # wait for the collectors to fill
        commandResultData = await resultCollector.receive()
        if commandResultData is not None:
            if commandResultData.resultCode is ResultValue.BUSY:
                await asyncio.sleep(0.2)
                return await self._command_via_mesh_broadcast_acked(
                    crownstone_uid_array, packet)
            elif commandResultData.resultCode is not ResultValue.SUCCESS:
                raise CrownstoneException(commandResultData.resultCode,
                                          "Command has failed.")

        return await self._handleCollectors(crownstone_uid_array,
                                            individualCollector,
                                            finalCollector)
Пример #16
0
def factoryReset() -> bool:
    logging.log(logging.INFO, "Factory reset")
    try:
        controlPacket = ControlPacketsGenerator.getCommandFactoryResetPacket()
        uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                        controlPacket).getPacket()
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                       uartMessage).getPacket()
        result = UartWriter(uartPacket).write_with_result_sync(
            [ResultValue.SUCCESS, ResultValue.WAIT_FOR_SUCCESS])
        if result.resultCode is ResultValue.SUCCESS:
            # This always returns SUCCESS, while we should actually wait.
            time.sleep(10.0)
            return True
        if result.resultCode is ResultValue.WAIT_FOR_SUCCESS:
            # Actually we should wait for the next result code..
            time.sleep(10.0)
            return True
        logging.log(logging.WARN, f"Factory reset failed, result={result}")
        return False

    except CrownstoneException as e:
        logging.log(logging.WARN, f"Failed to factory reset: {e}")
        return False
Пример #17
0
    async def _set_state_via_mesh_acked(self, crownstone_id: int,
                                        packet: bytearray) -> MeshResult:
        # 1:1 message to N crownstones with acks (only N = 1 supported for now)
        # flag value: 2
        corePacket = MeshSetStatePacket(crownstone_id, packet).getPacket()
        controlPacket = ControlPacket(
            ControlType.MESH_COMMAND).loadByteArray(corePacket).getPacket()
        uartMessage = UartMessagePacket(UartTxType.CONTROL,
                                        controlPacket).getPacket()
        uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                       uartMessage).getPacket()

        resultCollector = Collector(timeout=2, topic=SystemTopics.resultPacket)
        individualCollector = BatchCollector(
            timeout=15, topic=SystemTopics.meshResultPacket)
        finalCollector = Collector(timeout=15,
                                   topic=SystemTopics.meshResultFinalPacket)

        # send the message to the Crownstone
        UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)

        # wait for the collectors to fill
        commandResultData = await resultCollector.receive()

        if commandResultData is not None:
            if commandResultData.resultCode is ResultValue.BUSY:
                await asyncio.sleep(0.2)
                return await self._set_state_via_mesh_acked(
                    crownstone_id, packet)
            elif commandResultData.resultCode is not ResultValue.SUCCESS:
                raise CrownstoneException(commandResultData.resultCode,
                                          "Command has failed.")

        return await self._handleCollectors([crownstone_id],
                                            individualCollector,
                                            finalCollector)
Пример #18
0
 def _send(self, opCode: UartTxType, payload: list):
     # send over uart
     uartMessage = UartMessagePacket(opCode, payload).getPacket()
     uartPacket = UartWrapperPacket(UartMessageType.UART_MESSAGE,
                                    uartMessage).getPacket()
     UartEventBus.emit(SystemTopics.uartWriteData, uartPacket)