Exemple #1
0
def main(serial_port):
    # Create and open the device
    ble_device = BleDevice(serial_port)
    ble_device.configure()
    ble_device.open()

    # Set up desired security parameters
    ble_device.client.security.set_security_params(passcode_pairing=False, bond=False, lesc_pairing=False,
                                                   io_capabilities=IoCapabilities.DISPLAY_ONLY, out_of_band=False)
    ble_device.client.security.on_pairing_complete.register(on_client_pairing_complete)
    ble_device.client.security.on_passkey_display_required.register(on_passkey_display)
    ble_device.client.security.on_passkey_required.register(on_passkey_entry)
    ble_device.client.security.on_security_level_changed.register(on_security_level_changed)

    # Create and add the math service
    service = ble_device.database.add_service(constants.MATH_SERVICE_UUID)

    # Create and add the hex conversion characteristic to the service
    hex_conv_char = service.add_characteristic(constants.HEX_CONVERT_CHAR_UUID,
                                               constants.HEX_CONVERT_CHAR_PROPERTIES, "Test Data")
    # Register the callback for when a write occurs and subscription state changes
    hex_conv_char.on_write.register(on_hex_conversion_characteristic_write)
    hex_conv_char.on_subscription_change.register(on_gatts_subscription_state_changed)

    # Create and add the counting characteristic, initializing the data to [0, 0, 0, 0]
    counting_char = service.add_characteristic(constants.COUNTING_CHAR_UUID, constants.COUNTING_CHAR_PROPERTIES, [0]*4)
    counting_char.on_subscription_change.register(on_gatts_subscription_state_changed)

    # Create the thread for the counting characteristic
    counting_char_thread = CountingCharacteristicThread(counting_char)

    # Create and add the time service
    time_service = ble_device.database.add_service(constants.TIME_SERVICE_UUID)

    # Add the time characteristic and register the callback for when its read
    time_char = time_service.add_characteristic(constants.TIME_CHAR_UUID, constants.TIME_CHAR_PROPERTIES, "Time")
    time_char.on_read.register(on_time_char_read)

    # Initialize the advertising and scan response data
    adv_data = advertising.AdvertisingData(local_name=constants.PERIPHERAL_NAME, flags=0x06)
    scan_data = advertising.AdvertisingData(service_uuid128s=constants.TIME_SERVICE_UUID, has_more_uuid128_services=True)
    ble_device.advertiser.set_advertise_data(adv_data, scan_data)

    # Start advertising
    logger.info("Advertising")
    ble_device.client.on_connect.register(on_connect)
    ble_device.client.on_disconnect.register(on_disconnect)
    ble_device.advertiser.start(timeout_sec=0, auto_restart=True)

    # Create a waitable that will never fire, and wait for some time
    w = GenericWaitable()
    w.wait(60*30, exception_on_timeout=False)  # Keep device active for 30 mins

    # Cleanup
    counting_char_thread.join()
    logger.info("Done")
    ble_device.close()
Exemple #2
0
def main(serial_port):
    # Create and open te device
    ble_device = BleDevice(serial_port)
    ble_device.open()

    # Create and add the Device Info Service to the database
    dis = device_info.add_device_info_service(ble_device.database)

    # Set some characteristics in the DIS. The service only contains characteristics which
    # have values set. The other ones are not present
    dis.set_software_revision("14.2.1")
    dis.set_hardware_revision("A")
    dis.set_firmware_revision("1.0.4")
    dis.set_serial_number("AB1234")
    pnp_id = device_info.PnpId(device_info.PnpVendorSource.bluetooth_sig, 0x0058, 0x0002, 0x0013)
    dis.set_pnp_id(pnp_id)

    # Initiate the advertising data. Advertise the name and DIS service UUID
    name = "Peripheral DIS"
    adv_data = advertising.AdvertisingData(local_name=name, service_uuid16s=device_info.DIS_SERVICE_UUID)
    ble_device.advertiser.set_advertise_data(adv_data)

    # Start advertising
    logger.info("Advertising")
    ble_device.client.on_connect.register(on_connect)
    ble_device.client.on_disconnect.register(on_disconnect)
    ble_device.advertiser.start(timeout_sec=0, auto_restart=True)

    # Create a waitable that will never fire, and wait for some time
    w = GenericWaitable()
    w.wait(60*30, exception_on_timeout=False)  # Keep device active for 30 mins

    # Cleanup
    logger.info("Done")
    ble_device.close()
Exemple #3
0
def main(serial_port):
    # Create and open the device
    ble_device = BleDevice(serial_port)
    ble_device.open()

    # Create and add the current time service to the database.
    # Tweak the flags below to change how the service is set up
    current_time_service = current_time.add_current_time_service(ble_device.database,
                                                                 enable_writes=True,
                                                                 enable_local_time_info=True,
                                                                 enable_reference_info=False)

    # Register handlers for when the characteristics are written to.
    # These will only be triggered if enable_writes above is true
    current_time_service.on_current_time_write.register(on_current_time_write)
    current_time_service.on_local_time_info_write.register(on_local_time_info_write)

    # Demo of the different ways to manually or automatically control the reported time

    # Example 1: Automatically reference system time.
    #            All logic is handled within the service and reports the time whenever the characteristic is read
    # Example 2: Manually report the time 1 day behind using callback method.
    #            Register a user-defined callback to retrieve the current time to report back to the client
    # Example 3: Manually report the time 1 hour ahead by setting the base time
    #            Set the characteristic's base time to 1 day ahead and allow the service to auto-increment from there
    example_mode = 1

    if example_mode == 1:
        # configure_automatic() also sets up the Local Time characteristic (if enabled)
        # to just set the automatic time and leave Local Time unconfigured, use set_time() with no parameters
        current_time_service.configure_automatic()
    elif example_mode == 2:
        def on_time_read():
            d = datetime.datetime.now() - datetime.timedelta(days=1)
            logger.info("Getting time: {}".format(d))
            return d
        current_time_service.set_time(characteristic_read_callback=on_time_read)
    elif example_mode == 3:
        base_time = datetime.datetime.now() + datetime.timedelta(hours=1)
        current_time_service.set_time(base_time)

    # Register listeners for when the client connects and disconnects
    ble_device.client.on_connect.register(on_connect)
    ble_device.client.on_disconnect.register(on_disconnect)

    # Advertise the Current Time service
    adv_data = advertising.AdvertisingData(local_name="Current Time", flags=0x06,
                                           service_uuid16s=current_time.CURRENT_TIME_SERVICE_UUID)
    ble_device.advertiser.set_advertise_data(adv_data)

    logger.info("Advertising")
    ble_device.advertiser.start(timeout_sec=0, auto_restart=True)

    # Create a waitable that waits 5 minutes, then exits
    w = GenericWaitable()
    w.wait(5 * 60, exception_on_timeout=False)

    logger.info("Done")
    ble_device.close()
def main(serial_port):
    # Create and open the device
    ble_device = BleDevice(serial_port)
    ble_device.open()

    # Create a database to store the readings
    glucose_database = glucose.BasicGlucoseDatabase()
    # Add the service to the BLE database, using the glucose database just created, require encryption at the minimum
    service = glucose.add_glucose_service(ble_device.database,
                                          glucose_database,
                                          glucose.SecurityLevel.JUST_WORKS)

    # Set the features of this "glucose sensor"
    features = glucose.GlucoseFeatures(
        GlucoseFeatureType.low_battery_detection,
        GlucoseFeatureType.strip_insertion_error_detection)
    service.set_features(features)

    # Add some measurements to the glucose database
    add_fake_glucose_readings(glucose_database)

    # Register listeners for when the client connects and disconnects
    ble_device.client.on_connect.register(on_connect)
    ble_device.client.on_disconnect.register(on_disconnect)

    # Set the connection parameters for the client
    ble_device.client.set_connection_parameters(15, 30, 4000)

    # Set the function to display the passkey
    ble_device.client.security.on_passkey_display_required.register(
        display_passkey)

    # Set the security parameters for the client
    ble_device.client.security.set_security_params(
        passcode_pairing=False,
        bond=False,
        io_capabilities=IoCapabilities.DISPLAY_ONLY,
        out_of_band=False)

    # Advertise the Glucose service
    adv_data = advertising.AdvertisingData(
        local_name="Glucose Test",
        flags=0x06,
        service_uuid16s=glucose.GLUCOSE_SERVICE_UUID)
    ble_device.advertiser.set_advertise_data(adv_data)

    logger.info("Advertising")
    ble_device.advertiser.start(timeout_sec=0, auto_restart=True)

    # Create a waitable that will never fire, and wait for some time
    w = GenericWaitable()
    w.wait(60 * 30,
           exception_on_timeout=False)  # Keep device active for 30 mins

    logger.info("Done")
    ble_device.close()
Exemple #5
0
def main(serial_port):
    ble_device = BleDevice(serial_port)
    # Configure the BLE device to support MTU sizes which allow the max data length extension PDU size
    # Note this isn't 100% necessary as the default configuration sets the max to this value also
    ble_device.configure(att_mtu_max_size=MTU_SIZE_FOR_MAX_DLE)
    ble_device.open()

    # Create and add the Nordic UART service
    nus = nordic_uart.add_nordic_uart_service(ble_device.database)
    nus.on_data_received.register(on_data_rx)
    nus.on_write_complete.register(on_tx_complete)

    # Register listeners for when the client connects and disconnects
    ble_device.client.on_connect.register(on_connect)
    ble_device.client.on_disconnect.register(on_disconnect)
    ble_device.client.on_mtu_size_updated.register(on_mtu_size_update)

    # Configure the client to prefer the max MTU size
    ble_device.client.preferred_mtu_size = ble_device.max_mtu_size
    ble_device.client.set_connection_parameters(7.5, 15, 4000)

    # Advertise the service UUID
    adv_data = advertising.AdvertisingData(flags=0x06,
                                           local_name="Nordic UART Server")
    scan_data = advertising.AdvertisingData(
        service_uuid128s=nordic_uart.NORDIC_UART_SERVICE_UUID)

    ble_device.advertiser.set_advertise_data(adv_data, scan_data)

    logger.info("Advertising")

    ble_device.advertiser.start(timeout_sec=0, auto_restart=True)

    # Create a waitable that waits 5 minutes then exits
    w = GenericWaitable()
    try:
        w.wait(5 * 60, exception_on_timeout=False)
    except KeyboardInterrupt:
        pass
    finally:
        ble_device.close()
Exemple #6
0
def main(serial_port):
    # Create and open the device
    ble_device = BleDevice(serial_port)
    ble_device.open()

    # Create and add the battery service to the database
    battery_service = battery.add_battery_service(ble_device.database,
                                                  enable_notifications=True)
    battery_service.set_battery_level(100, False)

    # Register listeners for when the client connects and disconnects
    ble_device.client.on_connect.register(on_connect)
    ble_device.client.on_disconnect.register(on_disconnect)

    # Leaving security and connection parameters as defaults (don't care)

    # Advertise the Battery Service
    adv_data = advertising.AdvertisingData(
        local_name="Battery Test",
        flags=0x06,
        service_uuid16s=battery.BATTERY_SERVICE_UUID)
    ble_device.advertiser.set_advertise_data(adv_data)

    logger.info("Advertising")
    ble_device.advertiser.start(timeout_sec=0, auto_restart=True)

    battery_level = 100
    battery_level_decrement_steps = 1
    time_between_steps = 10

    # Decrement the battery level until it runs out
    while battery_level >= 0:
        time.sleep(time_between_steps)
        battery_level -= battery_level_decrement_steps
        logger.info("Updating battery level to {}".format(battery_level))
        battery_service.set_battery_level(battery_level)

    logger.info("Done")
    ble_device.close()
Exemple #7
0
def main(serial_port):
    # Create and open the device
    ble_device = BleDevice(serial_port)
    ble_device.configure()
    ble_device.open()

    # Create the service
    service = ble_device.database.add_service(
        constants.DESC_EXAMPLE_SERVICE_UUID)

    # Create a characteristic and add some descriptors
    # NOTE: Some descriptors MUST be added during creation: SCCD, User Description, and Presentation Format
    #       CCCD is added automatically based on the characteristic's Notify and Indicate properties

    # Define the User Description properties and make it writable
    # The simplest use-case in which the user description is read-only can provide just the first parameter
    user_desc_props = gatts.GattsUserDescriptionProperties(
        "UTC Time",
        write=True,
        security_level=smp.SecurityLevel.OPEN,
        max_length=20,
        variable_length=True)
    # Define the presentation format. Returning the time in seconds so set exponent to 0
    presentation_format = PresentationFormat(fmt=Format.uint32,
                                             exponent=0,
                                             unit=Units.time_second)
    # Create the characteristic properties, including the SCCD, User Description, and Presentation Format
    char_props = gatts.GattsCharacteristicProperties(
        read=True,
        write=False,
        notify=True,
        max_length=Uint32.byte_count,
        variable_length=False,
        sccd=True,
        user_description=user_desc_props,
        presentation_format=presentation_format)
    char = service.add_characteristic(constants.DESC_EXAMPLE_CHAR_UUID,
                                      char_props, Uint32.encode(0))
    char.on_read.register(on_read)

    # Add another descriptor to the list
    char_range_value = Uint32.encode(5555) + Uint32.encode(2**32 - 1000)
    desc_props = GattsAttributeProperties(read=True,
                                          write=False,
                                          variable_length=False,
                                          max_length=len(char_range_value))
    char.add_descriptor(DescriptorUuid.valid_range, desc_props,
                        char_range_value)

    # Initialize the advertising and scan response data
    adv_data = advertising.AdvertisingData(
        local_name=constants.PERIPHERAL_NAME, flags=0x06)
    scan_data = advertising.AdvertisingData(
        service_uuid128s=constants.DESC_EXAMPLE_SERVICE_UUID,
        has_more_uuid128_services=False)
    ble_device.advertiser.set_advertise_data(adv_data, scan_data)

    # Start advertising
    logger.info("Advertising")
    ble_device.client.on_connect.register(on_connect)
    ble_device.client.on_disconnect.register(on_disconnect)
    ble_device.advertiser.start(timeout_sec=0, auto_restart=True)

    # Create a waitable that will never fire, and wait for some time
    w = GenericWaitable()
    w.wait(60 * 30,
           exception_on_timeout=False)  # Keep device active for 30 mins

    logger.info("Done")
    ble_device.close()