예제 #1
0
    def _probe_characteristics_finished(self, result):
        """Callback when BLE adapter has finished probing services and characteristics for a device

        Args:
            result (dict): Result from the probe_characteristics command
        """

        handle = result['context']['handle']
        conn_id = result['context']['connection_id']

        conndata = self._get_connection(handle, 'preparing')

        if conndata is None:
            self._logger.info(
                'Connection disconnected before probe_char... finished, conn_id=%d',
                conn_id)
            return

        callback = conndata['callback']

        if result['result'] is False:
            conndata['failed'] = True
            conndata['failure_reason'] = 'Could not probe GATT characteristics'
            self.disconnect_async(conn_id, self._on_connection_failed)
            return

        # Validate that this is a proper IOTile device
        services = result['return_value']['services']
        if TileBusService not in services:
            conndata['failed'] = True
            conndata[
                'failure_reason'] = 'TileBus service not present in GATT services'
            self.disconnect_async(conn_id, self._on_connection_failed)
            return

        conndata['chars_done_time'] = time.time()
        service_time = conndata['services_done_time'] - conndata['connect_time']
        char_time = conndata['chars_done_time'] - conndata['services_done_time']
        total_time = service_time + char_time
        conndata['state'] = 'connected'
        conndata['services'] = services

        # Create a report parser for this connection for when reports are streamed to us
        conndata['parser'] = IOTileReportParser(
            report_callback=self._on_report,
            error_callback=self._on_report_error)
        conndata['parser'].context = conn_id

        del conndata['disconnect_handler']

        with self.count_lock:
            self.connecting_count -= 1

        self._logger.info(
            "Total time to connect to device: %.3f (%.3f enumerating services, %.3f enumerating chars)",
            total_time, service_time, char_time)
        callback(conndata['connection_id'], self.id, True, None)
예제 #2
0
    def _open_streaming_interface(self, connection_id, callback):
        """Enable streaming interface for this IOTile device

        Args:
            connection_id (int): The unique identifier for the connection
            callback (callback): Callback to be called when this command finishes
                callback(conn_id, adapter_id, success, failure_reason)
        """

        try:
            context = self.connections.get_context(connection_id)
        except ArgumentError:
            callback(connection_id, self.id, False,
                     "Could not find connection information")
            return

        self._logger.info("Attempting to enable streaming")
        self.connections.begin_operation(connection_id, 'open_interface',
                                         callback,
                                         self.get_config('default_timeout'))

        try:
            characteristic = context['services'][TileBusService][StreamingChar]
        except KeyError:
            self.connections.finish_operation(
                connection_id, False,
                "Can't find characteristic to open streaming interface")
            return

        context['parser'] = IOTileReportParser(
            report_callback=self._on_report,
            error_callback=self._on_report_error)
        context['parser'].context = connection_id

        def on_report_chunk_received(report_chunk):
            """Callback function called when a report chunk has been received."""
            context['parser'].add_data(report_chunk)

        # Register our callback function in the notifications callbacks
        self._register_notification_callback(context['connection_handle'],
                                             characteristic.value_handle,
                                             on_report_chunk_received)

        self.bable.set_notification(
            enabled=True,
            connection_handle=context['connection_handle'],
            characteristic=characteristic,
            on_notification_set=[self._on_interface_opened, context],
            on_notification_received=self._on_notification_received,
            timeout=1.0,
            sync=False)