This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to upload OTA again after successful first Buttonless OTA upload?

Hi, Everyone

My development environment is PCA10028, SoftDevice 130, SDK12.3.0

I downloaded the application using nRF5_SDK_12.3.0_d7731ad \ examples \ dfu \ bootloader_secure

A downloaded program works fine

I tried "Experimental: Buttonless DFU Template Application"

I download the application download using \nRF5_SDK_12.3.0_d7731ad \ examples \ ble_peripheral \ experimental_ble_app_buttonless_dfu

Downloaded as a testing procedure at the address below

(https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v12.0.0%2Fgroup__nrf__dfu__settings.html)

A downloaded program works fine

(DFUTARG -> Nordic_Buttonless -> application program works fine)

I will try to download a modified application program

How can i download ?

In nRF Toolbox i can not find 'Nordic_Buttonless'

Regards

Alex

  • Hi Alex,

    I am slightly confused. Did you follow the testing procedure provided here

    Did you first do a regular DFU where you updated the application to Nordic buttonless & now you want to do a new DFU via the smartphone? Once you finished the first DFU, the buttonless application did not advertise as Nordic_Buttonless, right?

     

  • Did you first do a regular DFU

     => yes, build bootloader_secure

                  run nrfutil settings

                  mregehex bootloader_secure, settings file

                  download pca10028

    the buttonless application did not advertise as Nordic_Buttonless, right?

    => no, advertise as Nordic_Buttonless

         download my application program via nRF toolbox in smartphone

     now you want to do a new DFU via the smartphone?

    = > no, i want to do a modified application program via smartphone

    How do I re-download a modified program via smartphone using buttonless while the application(ex: ble_app_hrs) is running?

    If I run scan from dfu in nRFTool Box, Nordic Buttonless will not appear

  • This is because the modified program (ble_app_hrs) does not include the DFU service. What you can do is merge the ble_app_hrs with the buttonless_dfu application (e.g. using the buttonless dfu example as the base example). That way, you should get the functionality of the hrs example (or whatever other app you want to use), while still being able to write to the bootloader settings page (see Section "Buttonless DFU" in link for more info). These links should also be helpful: link 1, link 2.

  • Thank you for your kind advice.
    But I have not yet solved the buttonless dfu.
    According to your advice I merged the ble_app_nus with the buttonless_dfu application
    In the DfuTarg state, the program is normally downloaded.
    If I set #define TEST 0 in main.c, 'Buttonless dfu' appears in scan using nRFConnect.
    However, if I set #define TEST 1 in main.c and scan using nRFConnect, nothing is scanned.

    Other modifications can be found in softdevice_handler.c:

      p_ble_enable_params-> common_enable_params.vs_uuid_count = 2;     //orig 1

    I attach main.c and nrfLog.
    regards,

    nRF Connect, 2018-07-23
    DfuTarg (C4:58:36:55:8C:1B)
    V	16:07:22.993	Connecting to C4:58:36:55:8C:1B...
    D	16:07:22.993	gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE)
    D	16:07:23.406	[Callback] Connection state changed with status: 0 and new state: CONNECTED (2)
    I	16:07:23.406	Connected to C4:58:36:55:8C:1B
    D	16:07:23.408	[Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED
    V	16:07:23.422	Discovering services...
    D	16:07:23.422	gatt.discoverServices()
    D	16:07:24.330	[Callback] Services discovered with status: 0
    I	16:07:24.331	Services discovered
    V	16:07:24.357	Generic Access (0x1800)
    - Device Name [R W] (0x2A00)
    - Appearance [R] (0x2A01)
    - Peripheral Preferred Connection Parameters [R] (0x2A04)
    Generic Attribute (0x1801)
    Secure DFU Service (0xFE59)
    - DFU Packet [WNR] (8ec90002-f315-4f60-9fb8-838830daea50)
    - DFU Control Point [N W] (8ec90001-f315-4f60-9fb8-838830daea50)
       Client Characteristic Configuration (0x2902)
    D	16:07:24.358	gatt.setCharacteristicNotification(8ec90001-f315-4f60-9fb8-838830daea50, true)
    V	16:07:41.590	[DFU] DFU service started
    V	16:07:41.590	[DFU] Opening file...
    I	16:07:41.590	[DFU] Firmware file opened successfully
    V	16:07:41.590	[DFU] Connecting to DFU target...
    D	16:07:41.590	[DFU] gatt = device.connectGatt(autoConnect = false)
    I	16:07:41.716	[DFU] Connected to C4:58:36:55:8C:1B
    V	16:07:41.716	[DFU] Discovering services...
    D	16:07:41.716	[DFU] gatt.discoverServices()
    I	16:07:41.716	[DFU] Services discovered
    D	16:07:41.717	[DFU] wait(1000)
    V	16:07:42.736	[DFU] Requesting new MTU...
    D	16:07:42.736	[DFU] gatt.requestMtu(517)
    I	16:07:42.803	[DFU] MTU changed to: 23
    V	16:07:42.804	[DFU] Enabling notifications for 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:42.804	[DFU] gatt.setCharacteristicNotification(8ec90001-f315-4f60-9fb8-838830daea50, true)
    D	16:07:42.804	[DFU] gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
    I	16:07:42.854	[DFU] Data written to descr.8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-00
    V	16:07:42.854	[DFU] Notifications enabled for 8ec90001-f315-4f60-9fb8-838830daea50
    A	16:07:42.855	[DFU] Notifications enabled
    D	16:07:42.855	[DFU] wait(1000)
    V	16:07:43.850	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:43.850	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:43.884	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-06-01-00-01-00-00-00-00-00-00-00-00-00-00
    A	16:07:43.884	"Response for: Read Object Info
    Status: Success
    Max object size: 256 bytes
    Current offset: 0 bytes
    CRC-32: 00000000" received
    I	16:07:43.892	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 06-01
    I	16:07:43.892	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-06-01-00-01-00-00-00-00-00-00-00-00-00-00
    A	16:07:43.892	[DFU] Command object info received (Max size = 256, Offset = 0, CRC = 00000000)
    V	16:07:43.892	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:43.892	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:43.944	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-02-01
    A	16:07:43.944	"Response for: Set PRN value
    Status: Success" received
    I	16:07:43.960	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 02-00-00
    I	16:07:43.960	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-02-01
    A	16:07:43.960	[DFU] Packet Receipt Notif disabled (Op Code = 2, Value = 0)
    V	16:07:43.960	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:43.960	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:44.002	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:44.002	"Response for: Create Object
    Status: Success" received
    I	16:07:44.013	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-01-87-00-00-00
    I	16:07:44.013	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:44.013	[DFU] Command object created
    V	16:07:44.013	[DFU] Writing to characteristic 8ec90002-f315-4f60-9fb8-838830daea50
    D	16:07:44.013	[DFU] gatt.writeCharacteristic(8ec90002-f315-4f60-9fb8-838830daea50)
    I	16:07:44.013	[DFU] Data written to 8ec90002-f315-4f60-9fb8-838830daea50, value (0x): 12-84-01-0A-3E-08-01-12-3A-08-00-10-33-1A-02-87-01-20-00-28
    V	16:07:44.013	[DFU] Writing to characteristic 8ec90002-f315-4f60-9fb8-838830daea50
    D	16:07:44.013	[DFU] gatt.writeCharacteristic(8ec90002-f315-4f60-9fb8-838830daea50)
    I	16:07:44.013	[DFU] Data written to 8ec90002-f315-4f60-9fb8-838830daea50, value (0x): 00-30-00-38-FC-E4-01-42-24-08-03-12-20-B2-2C-36-92-4F-8E-06
    V	16:07:44.013	[DFU] Writing to characteristic 8ec90002-f315-4f60-9fb8-838830daea50
    D	16:07:44.013	[DFU] gatt.writeCharacteristic(8ec90002-f315-4f60-9fb8-838830daea50)
    I	16:07:44.013	[DFU] Data written to 8ec90002-f315-4f60-9fb8-838830daea50, value (0x): 3D-1A-5D-FF-D8-13-E4-96-C6-14-64-E7-FB-95-B3-AA-6B-DE-FE-38
    V	16:07:44.027	[DFU] Writing to characteristic 8ec90002-f315-4f60-9fb8-838830daea50
    D	16:07:44.027	[DFU] gatt.writeCharacteristic(8ec90002-f315-4f60-9fb8-838830daea50)
    I	16:07:44.027	[DFU] Data written to 8ec90002-f315-4f60-9fb8-838830daea50, value (0x): FA-94-98-F7-E1-48-00-10-00-1A-40-B7-30-EF-34-3D-6E-35-93-4E
    V	16:07:44.027	[DFU] Writing to characteristic 8ec90002-f315-4f60-9fb8-838830daea50
    D	16:07:44.027	[DFU] gatt.writeCharacteristic(8ec90002-f315-4f60-9fb8-838830daea50)
    I	16:07:44.027	[DFU] Data written to 8ec90002-f315-4f60-9fb8-838830daea50, value (0x): 5E-2A-6A-A9-96-11-80-03-DE-B8-5C-ED-EE-81-85-66-E2-36-96-89
    V	16:07:44.027	[DFU] Writing to characteristic 8ec90002-f315-4f60-9fb8-838830daea50
    D	16:07:44.027	[DFU] gatt.writeCharacteristic(8ec90002-f315-4f60-9fb8-838830daea50)
    I	16:07:44.027	[DFU] Data written to 8ec90002-f315-4f60-9fb8-838830daea50, value (0x): 66-CF-B4-0C-D3-0A-7E-AB-3F-E0-CA-A7-7B-56-93-F3-1E-C7-CC-55
    V	16:07:44.027	[DFU] Writing to characteristic 8ec90002-f315-4f60-9fb8-838830daea50
    D	16:07:44.027	[DFU] gatt.writeCharacteristic(8ec90002-f315-4f60-9fb8-838830daea50)
    I	16:07:44.045	[DFU] Data written to 8ec90002-f315-4f60-9fb8-838830daea50, value (0x): D3-B4-7A-49-2F-B9-81-82-C6-21-08-19-E6-C9-A3
    A	16:07:44.045	[DFU] Command object sent (CRC = CB024E74)
    V	16:07:44.045	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:44.045	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:44.094	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-87-00-00-00-74-4E-02-CB
    A	16:07:44.095	"Response for: Calculate Checksum
    Status: Success
    Current offset: 135 bytes
    CRC-32: CB024E74" received
    I	16:07:44.096	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:44.096	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-87-00-00-00-74-4E-02-CB
    A	16:07:44.096	[DFU] Checksum received (Offset = 135, CRC = CB024E74)
    V	16:07:44.096	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:44.096	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:44.161	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:45.323	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:45.323	"Response for: Execute
    Status: Success" received
    I	16:07:45.352	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:45.352	[DFU] Command object executed
    V	16:07:45.352	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:45.352	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:45.383	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-06-01-00-10-00-00-00-00-00-00-00-00-00-00
    A	16:07:45.384	"Response for: Read Object Info
    Status: Success
    Max object size: 4096 bytes
    Current offset: 0 bytes
    CRC-32: 00000000" received
    I	16:07:45.405	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 06-02
    I	16:07:45.405	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-06-01-00-10-00-00-00-00-00-00-00-00-00-00
    A	16:07:45.405	[DFU] Data object info received (Max size = 4096, Offset = 0, CRC = 00000000)
    V	16:07:45.407	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:45.407	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:45.443	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:45.443	"Response for: Create Object
    Status: Success" received
    I	16:07:45.456	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-02-00-10-00-00
    I	16:07:45.456	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:45.456	[DFU] Data object (1/8) created
    A	16:07:45.456	[DFU] Uploading firmware...
    V	16:07:45.456	[DFU] Sending firmware to characteristic 8ec90002-f315-4f60-9fb8-838830daea50...
    V	16:07:45.685	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:45.685	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:46.733	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-00-10-00-00-26-33-09-F7
    A	16:07:46.733	"Response for: Calculate Checksum
    Status: Success
    Current offset: 4096 bytes
    CRC-32: F7093326" received
    I	16:07:46.744	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:46.744	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-00-10-00-00-26-33-09-F7
    A	16:07:46.744	[DFU] Checksum received (Offset = 4096, CRC = F7093326)
    V	16:07:46.744	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:46.744	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:46.793	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:46.793	"Response for: Execute
    Status: Success" received
    I	16:07:46.795	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:46.795	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:46.795	[DFU] Data object executed
    V	16:07:46.795	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:46.795	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:46.852	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:46.852	"Response for: Create Object
    Status: Success" received
    I	16:07:46.861	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-02-00-10-00-00
    I	16:07:46.861	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:46.861	[DFU] Data object (2/8) created
    A	16:07:46.861	[DFU] Uploading firmware...
    V	16:07:46.861	[DFU] Sending firmware to characteristic 8ec90002-f315-4f60-9fb8-838830daea50...
    V	16:07:47.089	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:47.089	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:48.143	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-00-20-00-00-38-FD-49-00
    A	16:07:48.143	"Response for: Calculate Checksum
    Status: Success
    Current offset: 8192 bytes
    CRC-32: 0049FD38" received
    I	16:07:48.152	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:48.152	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-00-20-00-00-38-FD-49-00
    A	16:07:48.152	[DFU] Checksum received (Offset = 8192, CRC = 0049FD38)
    V	16:07:48.152	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:48.152	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:48.203	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:48.203	"Response for: Execute
    Status: Success" received
    I	16:07:48.219	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:48.219	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:48.219	[DFU] Data object executed
    V	16:07:48.219	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:48.219	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:48.262	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:48.262	"Response for: Create Object
    Status: Success" received
    I	16:07:48.270	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-02-00-10-00-00
    I	16:07:48.270	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:48.270	[DFU] Data object (3/8) created
    A	16:07:48.270	[DFU] Uploading firmware...
    V	16:07:48.270	[DFU] Sending firmware to characteristic 8ec90002-f315-4f60-9fb8-838830daea50...
    V	16:07:48.512	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:48.512	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:49.582	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-00-30-00-00-11-1C-21-5F
    A	16:07:49.582	"Response for: Calculate Checksum
    Status: Success
    Current offset: 12288 bytes
    CRC-32: 5F211C11" received
    I	16:07:49.594	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:49.594	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-00-30-00-00-11-1C-21-5F
    A	16:07:49.594	[DFU] Checksum received (Offset = 12288, CRC = 5F211C11)
    V	16:07:49.594	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:49.594	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:49.642	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:49.642	"Response for: Execute
    Status: Success" received
    I	16:07:49.646	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:49.646	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:49.646	[DFU] Data object executed
    V	16:07:49.646	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:49.646	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:49.702	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:49.702	"Response for: Create Object
    Status: Success" received
    I	16:07:49.712	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-02-00-10-00-00
    I	16:07:49.712	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:49.712	[DFU] Data object (4/8) created
    A	16:07:49.712	[DFU] Uploading firmware...
    V	16:07:49.712	[DFU] Sending firmware to characteristic 8ec90002-f315-4f60-9fb8-838830daea50...
    V	16:07:49.963	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:49.963	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:51.023	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-00-40-00-00-44-CF-35-30
    A	16:07:51.023	"Response for: Calculate Checksum
    Status: Success
    Current offset: 16384 bytes
    CRC-32: 3035CF44" received
    I	16:07:51.036	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:51.036	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-00-40-00-00-44-CF-35-30
    A	16:07:51.036	[DFU] Checksum received (Offset = 16384, CRC = 3035CF44)
    V	16:07:51.036	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:51.036	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:51.082	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:51.082	"Response for: Execute
    Status: Success" received
    I	16:07:51.087	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:51.087	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:51.087	[DFU] Data object executed
    V	16:07:51.087	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:51.087	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:51.142	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:51.142	"Response for: Create Object
    Status: Success" received
    I	16:07:51.154	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-02-00-10-00-00
    I	16:07:51.154	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:51.154	[DFU] Data object (5/8) created
    A	16:07:51.154	[DFU] Uploading firmware...
    V	16:07:51.154	[DFU] Sending firmware to characteristic 8ec90002-f315-4f60-9fb8-838830daea50...
    V	16:07:51.419	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:51.419	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:52.463	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-00-50-00-00-EF-EF-A7-2C
    A	16:07:52.463	"Response for: Calculate Checksum
    Status: Success
    Current offset: 20480 bytes
    CRC-32: 2CA7EFEF" received
    I	16:07:52.478	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:52.478	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-00-50-00-00-EF-EF-A7-2C
    A	16:07:52.478	[DFU] Checksum received (Offset = 20480, CRC = 2CA7EFEF)
    V	16:07:52.478	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:52.478	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:52.522	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:52.522	"Response for: Execute
    Status: Success" received
    I	16:07:52.545	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:52.545	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:52.545	[DFU] Data object executed
    V	16:07:52.545	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:52.545	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:52.582	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:52.582	"Response for: Create Object
    Status: Success" received
    I	16:07:52.614	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-02-00-10-00-00
    I	16:07:52.614	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:52.614	[DFU] Data object (6/8) created
    A	16:07:52.614	[DFU] Uploading firmware...
    V	16:07:52.614	[DFU] Sending firmware to characteristic 8ec90002-f315-4f60-9fb8-838830daea50...
    V	16:07:52.817	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:52.817	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:53.873	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-00-60-00-00-F9-31-89-5B
    A	16:07:53.873	"Response for: Calculate Checksum
    Status: Success
    Current offset: 24576 bytes
    CRC-32: 5B8931F9" received
    I	16:07:53.903	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:53.903	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-00-60-00-00-F9-31-89-5B
    A	16:07:53.903	[DFU] Checksum received (Offset = 24576, CRC = 5B8931F9)
    V	16:07:53.903	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:53.903	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:53.932	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:53.932	"Response for: Execute
    Status: Success" received
    I	16:07:53.954	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:53.955	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:53.955	[DFU] Data object executed
    V	16:07:53.955	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:53.955	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:53.992	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:53.992	"Response for: Create Object
    Status: Success" received
    I	16:07:54.023	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-02-00-10-00-00
    I	16:07:54.023	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:54.023	[DFU] Data object (7/8) created
    A	16:07:54.023	[DFU] Uploading firmware...
    V	16:07:54.023	[DFU] Sending firmware to characteristic 8ec90002-f315-4f60-9fb8-838830daea50...
    V	16:07:54.223	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:54.223	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:55.283	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-00-70-00-00-4D-5C-EC-E6
    A	16:07:55.283	"Response for: Calculate Checksum
    Status: Success
    Current offset: 28672 bytes
    CRC-32: E6EC5C4D" received
    I	16:07:55.295	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:55.295	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-00-70-00-00-4D-5C-EC-E6
    A	16:07:55.295	[DFU] Checksum received (Offset = 28672, CRC = E6EC5C4D)
    V	16:07:55.295	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:55.295	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:55.342	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:55.342	"Response for: Execute
    Status: Success" received
    I	16:07:55.346	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:55.346	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:55.347	[DFU] Data object executed
    V	16:07:55.347	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:55.347	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:55.402	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-01-01
    A	16:07:55.402	"Response for: Create Object
    Status: Success" received
    I	16:07:55.413	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 01-02-7C-02-00-00
    I	16:07:55.413	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-01-01
    A	16:07:55.413	[DFU] Data object (8/8) created
    A	16:07:55.413	[DFU] Uploading firmware...
    V	16:07:55.413	[DFU] Sending firmware to characteristic 8ec90002-f315-4f60-9fb8-838830daea50...
    V	16:07:55.507	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:55.507	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:55.642	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-03-01-7C-72-00-00-85-11-9F-02
    A	16:07:55.642	"Response for: Calculate Checksum
    Status: Success
    Current offset: 29308 bytes
    CRC-32: 029F1185" received
    I	16:07:55.648	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 03
    I	16:07:55.648	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-7C-72-00-00-85-11-9F-02
    A	16:07:55.648	[DFU] Checksum received (Offset = 29308, CRC = 029F1185)
    V	16:07:55.648	[DFU] Writing to characteristic 8ec90001-f315-4f60-9fb8-838830daea50
    D	16:07:55.648	[DFU] gatt.writeCharacteristic(8ec90001-f315-4f60-9fb8-838830daea50)
    I	16:07:55.714	[DFU] Data written to 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 04
    I	16:07:56.212	Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value: (0x) 60-04-01
    A	16:07:56.212	"Response for: Execute
    Status: Success" received
    I	16:07:56.217	[DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-04-01
    A	16:07:56.217	[DFU] Data object executed
    A	16:07:56.217	[DFU] Upload completed in 10818 ms
    D	16:08:00.395	[Callback] Connection state changed with status: 8 and new state: DISCONNECTED (0)
    E	16:08:00.395	Error 8 (0x8): GATT CONN TIMEOUT
    I	16:08:00.395	Disconnected
    I	16:08:00.412	[DFU] Disconnected by the remote device
    D	16:08:00.417	[DFU] gatt.refresh() (hidden)
    D	16:08:00.417	[DFU] gatt.close()
    D	16:08:00.417	[DFU] wait(1400)
    D	16:08:00.435	[Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED
    D	16:08:00.446	[DFU] [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED
    D	16:08:01.856	gatt.close()
    D	16:08:01.858	wait(200)
    V	16:08:02.061	Connecting to C4:58:36:55:8C:1B...
    D	16:08:02.061	gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE)
    D	16:08:07.190	[Callback] Connection state changed with status: 133 and new state: DISCONNECTED (0)
    E	16:08:07.190	Error 133 (0x85): GATT ERROR
    I	16:08:07.190	Disconnected
    
    /**
     * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA
     * 
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     * 
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     * 
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     * 
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     * 
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     * 
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * 
     */
    
    /** @file
     *
     * @defgroup ble_sdk_app_template_main main.c
     * @{
     * @ingroup ble_sdk_app_template
     * @brief Template project main file.
     *
     * This file contains a template for creating a new application. It has the code necessary to wakeup
     * from button, advertise, get a connection restart advertising on disconnect and if no new
     * connection created go back to system-off mode.
     * It can easily be used as a starting point for creating a new application, the comments identified
     * with 'YOUR_JOB' indicates where and how you can customize.
     */
    
    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    
    #include "nordic_common.h"
    #include "nrf.h"
    #include "app_error.h"
    #include "ble.h"
    #include "ble_hci.h"
    #include "ble_srv_common.h"
    #include "ble_advdata.h"
    #include "ble_advertising.h"
    #include "ble_conn_params.h"
    #include "boards.h"
    #include "softdevice_handler.h"
    #include "app_timer.h"
    #include "fstorage.h"
    #include "fds.h"
    #include "peer_manager.h"
    
    #include "bsp.h"
    #include "bsp_btn_ble.h"
    #include "sensorsim.h"
    #include "nrf_gpio.h"
    #include "ble_hci.h"
    #include "ble_advdata.h"
    #include "ble_advertising.h"
    #include "ble_conn_state.h"
    
    #include "ble_dfu.h"
    
    #define TEST 1
    
    #if TEST
    #include "ble_nus.h"
    #include "app_uart.h"
    #endif
    
    #define NRF_LOG_MODULE_NAME "APP"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    
    #define IS_SRVC_CHANGED_CHARACT_PRESENT 1                                           /**< Include or not the service_changed characteristic. if not enabled, the server's database cannot be changed for the lifetime of the device*/
    
    #if (NRF_SD_BLE_API_VERSION == 3)
    #define NRF_BLE_MAX_MTU_SIZE            GATT_MTU_SIZE_DEFAULT                       /**< MTU size used in the softdevice enabling and to reply to a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. */
    #endif
    
    #define APP_FEATURE_NOT_SUPPORTED       BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2        /**< Reply when unsupported features are requested. */
    
    #define CENTRAL_LINK_COUNT              0                                           /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/
    #define PERIPHERAL_LINK_COUNT           1                                           /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/
    
    #define DEVICE_NAME                     "Nordic_NUS"                           /**< Name of device. Will be included in the advertising data. */
    #define MANUFACTURER_NAME               "NordicSemiconductor"                       /**< Manufacturer. Will be passed to Device Information Service. */
    #define APP_ADV_INTERVAL                300                                         /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */
    #define APP_ADV_TIMEOUT_IN_SECONDS      180                                         /**< The advertising timeout in units of seconds. */
    
    #define APP_TIMER_PRESCALER             0                                           /**< Value of the RTC1 PRESCALER register. */
    #define APP_TIMER_OP_QUEUE_SIZE         4                                           /**< Size of timer operation queues. */
    
    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(100, UNIT_1_25_MS)            /**< Minimum acceptable connection interval (0.1 seconds). */
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(200, UNIT_1_25_MS)            /**< Maximum acceptable connection interval (0.2 second). */
    #define SLAVE_LATENCY                   0                                           /**< Slave latency. */
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds). */
    
    #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000, APP_TIMER_PRESCALER)  /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
    #define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */
    
    #define SEC_PARAM_BOND                  1                                           /**< Perform bonding. */
    #define SEC_PARAM_MITM                  0                                           /**< Man In The Middle protection not required. */
    #define SEC_PARAM_LESC                  0                                           /**< LE Secure Connections not enabled. */
    #define SEC_PARAM_KEYPRESS              0                                           /**< Keypress notifications not enabled. */
    #define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_NONE                        /**< No I/O capabilities. */
    #define SEC_PARAM_OOB                   0                                           /**< Out Of Band data not available. */
    #define SEC_PARAM_MIN_KEY_SIZE          7                                           /**< Minimum encryption key size. */
    #define SEC_PARAM_MAX_KEY_SIZE          16                                          /**< Maximum encryption key size. */
    
    #define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    
    #if TEST
    //#define LEDBUTTON_LED_PIN               BSP_BOARD_LED_2                             /**< LED to be toggled with the help of the LED Button Service. */
    //#define LEDBUTTON_BUTTON_PIN            BSP_BUTTON_0                                /**< Button that will trigger the notification event with the LED Button Service */
    
    static ble_nus_t                        m_nus;                                      /**< Structure to identify the Nordic UART Service. */
    
    #endif
    
    static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;                            /**< Handle of the current connection. */
    
    static ble_dfu_t m_dfus;                                                            /**< Structure used to identify the DFU service. */
    
    
    static void ble_dfu_evt_handler(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
    {
        switch (p_evt->type)
        {
            case BLE_DFU_EVT_INDICATION_DISABLED:
                NRF_LOG_INFO("Indication for BLE_DFU is disabled\r\n");
                break;
    
            case BLE_DFU_EVT_INDICATION_ENABLED:
                NRF_LOG_INFO("Indication for BLE_DFU is enabled\r\n");
                break;
    
            case BLE_DFU_EVT_ENTERING_BOOTLOADER:
                NRF_LOG_INFO("Device is entering bootloader mode!\r\n");
                break;
            default:
                NRF_LOG_INFO("Unknown event from ble_dfu\r\n");
                break;
        }
    }
    
    // YOUR_JOB: Use UUIDs for service(s) used in your application.
    #if TEST
    static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_NUS_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN}};  /**< Universally unique service identifier. */
    #else
    static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}}; /**< Universally unique service identifiers. */
    #endif
    
    static void advertising_start(void);
    
    /**@brief Callback function for asserts in the SoftDevice.
     *
     * @details This function will be called in case of an assert in the SoftDevice.
     *
     * @warning This handler is an example only and does not fit a final product. You need to analyze
     *          how your product is supposed to react in case of Assert.
     * @warning On assert from the SoftDevice, the system can only recover on reset.
     *
     * @param[in] line_num   Line number of the failing ASSERT call.
     * @param[in] file_name  File name of the failing ASSERT call.
     */
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(DEAD_BEEF, line_num, p_file_name);
    }
    
    
    /**@brief Function for handling Peer Manager events.
     *
     * @param[in] p_evt  Peer Manager event.
     */
    static void pm_evt_handler(pm_evt_t const * p_evt)
    {
        ret_code_t err_code;
    
        switch (p_evt->evt_id)
        {
            case PM_EVT_BONDED_PEER_CONNECTED:
            {
                NRF_LOG_DEBUG("Connected to previously bonded device\r\n");
                err_code = pm_peer_rank_highest(p_evt->peer_id);
                if (err_code != NRF_ERROR_BUSY)
                {
                    APP_ERROR_CHECK(err_code);
                }
            } break; // PM_EVT_BONDED_PEER_CONNECTED
    
            case PM_EVT_CONN_SEC_START:
                break; // PM_EVT_CONN_SEC_START
    
            case PM_EVT_CONN_SEC_SUCCEEDED:
            {
                NRF_LOG_DEBUG("Link secured. Role: %d. conn_handle: %d, Procedure: %d\r\n",
                                     ble_conn_state_role(p_evt->conn_handle),
                                     p_evt->conn_handle,
                                     p_evt->params.conn_sec_succeeded.procedure);
                err_code = pm_peer_rank_highest(p_evt->peer_id);
                if (err_code != NRF_ERROR_BUSY)
                {
                    APP_ERROR_CHECK(err_code);
                }
            } break; // PM_EVT_CONN_SEC_SUCCEEDED
    
            case PM_EVT_CONN_SEC_FAILED:
            {
                /** Often, when securing fails, it shouldn't be restarted, for security reasons.
                 *  Other times, it can be restarted directly.
                 *  Sometimes it can be restarted, but only after changing some Security Parameters.
                 *  Sometimes, it cannot be restarted until the link is disconnected and reconnected.
                 *  Sometimes it is impossible, to secure the link, or the peer device does not support it.
                 *  How to handle this error is highly application dependent. */
            } break; // PM_EVT_CONN_SEC_FAILED
    
            case PM_EVT_CONN_SEC_CONFIG_REQ:
            {
                // Reject pairing request from an already bonded peer.
                pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
                pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
            } break; // PM_EVT_CONN_SEC_CONFIG_REQ
    
            case PM_EVT_STORAGE_FULL:
            {
                // Run garbage collection on the flash.
                err_code = fds_gc();
                if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
                {
                    // Retry.
                }
                else
                {
                    APP_ERROR_CHECK(err_code);
                }
            } break; // PM_EVT_STORAGE_FULL
    
            case PM_EVT_ERROR_UNEXPECTED:
                // Assert.
                APP_ERROR_CHECK(p_evt->params.error_unexpected.error);
                break; // PM_EVT_ERROR_UNEXPECTED
    
            case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
                break; // PM_EVT_PEER_DATA_UPDATE_SUCCEEDED
    
            case PM_EVT_PEER_DATA_UPDATE_FAILED:
                // Assert.
                APP_ERROR_CHECK_BOOL(false);
                break; // PM_EVT_PEER_DATA_UPDATE_FAILED
    
            case PM_EVT_PEER_DELETE_SUCCEEDED:
                break; // PM_EVT_PEER_DELETE_SUCCEEDED
    
            case PM_EVT_PEER_DELETE_FAILED:
                // Assert.
                APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error);
                break; // PM_EVT_PEER_DELETE_FAILED
    
            case PM_EVT_PEERS_DELETE_SUCCEEDED:
                advertising_start();
                break; // PM_EVT_PEERS_DELETE_SUCCEEDED
    
            case PM_EVT_PEERS_DELETE_FAILED:
                // Assert.
                APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error);
                break; // PM_EVT_PEERS_DELETE_FAILED
    
            case PM_EVT_LOCAL_DB_CACHE_APPLIED:
                break; // PM_EVT_LOCAL_DB_CACHE_APPLIED
    
            case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
                // The local database has likely changed, send service changed indications.
                pm_local_database_has_changed();
                break; // PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED
    
            case PM_EVT_SERVICE_CHANGED_IND_SENT:
                break; // PM_EVT_SERVICE_CHANGED_IND_SENT
    
            case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
                break; // PM_EVT_SERVICE_CHANGED_IND_SENT
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    /**@brief Function for the Timer initialization.
     *
     * @details Initializes the timer module. This creates and starts application timers.
     */
    static void timers_init(void)
    {
    
        // Initialize timer module.
        APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
    
        // Create timers.
    
        /* YOUR_JOB: Create any timers to be used by the application.
                     Below is an example of how to create a timer.
                     For every new timer needed, increase the value of the macro APP_TIMER_MAX_TIMERS by
                     one.
           uint32_t err_code;
           err_code = app_timer_create(&m_app_timer_id, APP_TIMER_MODE_REPEATED, timer_timeout_handler);
           APP_ERROR_CHECK(err_code); */
    
    }
    
    
    /**@brief Function for the GAP initialization.
     *
     * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
     *          device including the device name, appearance, and the preferred connection parameters.
     */
    static void gap_params_init(void)
    {
        uint32_t                err_code;
        ble_gap_conn_params_t   gap_conn_params;
        ble_gap_conn_sec_mode_t sec_mode;
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *)DEVICE_NAME,
                                              strlen(DEVICE_NAME));
        APP_ERROR_CHECK(err_code);
    
        /* YOUR_JOB: Use an appearance value matching the application's use case.
           err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_);
           APP_ERROR_CHECK(err_code); */
    
        memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    
        gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
        gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
        gap_conn_params.slave_latency     = SLAVE_LATENCY;
        gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
        err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the YYY Service events.
     * YOUR_JOB implement a service handler function depending on the event the service you are using can generate
     *
     * @details This function will be called for all YY Service events which are passed to
     *          the application.
     *
     * @param[in]   p_yy_service   YY Service structure.
     * @param[in]   p_evt          Event received from the YY Service.
     *
     *
       static void on_yys_evt(ble_yy_service_t     * p_yy_service,
                           ble_yy_service_evt_t * p_evt)
       {
        switch (p_evt->evt_type)
        {
            case BLE_YY_NAME_EVT_WRITE:
                APPL_LOG("[APPL]: charact written with value %s. \r\n", p_evt->params.char_xx.value.p_str);
                break;
    
            default:
                // No implementation needed.
                break;
        }
       }*/
    
    #if TEST
    
    /**@brief Function for handling the data from the Nordic UART Service.
     *
     * @details This function will process the data received from the Nordic UART BLE Service and send
     *          it to the UART module.
     *
     * @param[in] p_nus    Nordic UART Service structure.
     * @param[in] p_data   Data to be send to UART module.
     * @param[in] length   Length of the data.
     */
    /**@snippet [Handling the data received over BLE] */
    static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
    {
        for (uint32_t i = 0; i < length; i++)
        {
            while (app_uart_put(p_data[i]) != NRF_SUCCESS);
        }
        while (app_uart_put('\r') != NRF_SUCCESS);
        while (app_uart_put('\n') != NRF_SUCCESS);
    }
    /**@snippet [Handling the data received over BLE] */
    #endif
    
    /**@brief Function for initializing services that will be used by the application.
     */
    static void services_init(void)
    {
        uint32_t err_code;
        ble_dfu_init_t dfus_init;
    
        // Initialize the Device Firmware Update Service.
        memset(&dfus_init, 0, sizeof(dfus_init));
    
        dfus_init.evt_handler                               = ble_dfu_evt_handler;
        dfus_init.ctrl_point_security_req_write_perm        = SEC_SIGNED;
        dfus_init.ctrl_point_security_req_cccd_write_perm   = SEC_SIGNED;
    
        err_code = ble_dfu_init(&m_dfus, &dfus_init);
        APP_ERROR_CHECK(err_code);
        
        /* YOUR_JOB: Add code to initialize the services used by the application.
           uint32_t                           err_code;
           ble_xxs_init_t                     xxs_init;
           ble_yys_init_t                     yys_init;
    
           // Initialize XXX Service.
           memset(&xxs_init, 0, sizeof(xxs_init));
    
           xxs_init.evt_handler                = NULL;
           xxs_init.is_xxx_notify_supported    = true;
           xxs_init.ble_xx_initial_value.level = 100;
    
           err_code = ble_bas_init(&m_xxs, &xxs_init);
           APP_ERROR_CHECK(err_code);
    
           // Initialize YYY Service.
           memset(&yys_init, 0, sizeof(yys_init));
           yys_init.evt_handler                  = on_yys_evt;
           yys_init.ble_yy_initial_value.counter = 0;
    
           err_code = ble_yy_service_init(&yys_init, &yy_init);
           APP_ERROR_CHECK(err_code);
         */
    #if TEST
        ble_nus_init_t nus_init;
    
        memset(&nus_init, 0, sizeof(nus_init));
    
        nus_init.data_handler = nus_data_handler;
    
        err_code = ble_nus_init(&m_nus, &nus_init);
        APP_ERROR_CHECK(err_code);
    #endif
    }
    
    
    /**@brief Function for handling the Connection Parameters Module.
     *
     * @details This function will be called for all events in the Connection Parameters Module which
     *          are passed to the application.
     *          @note All this function does is to disconnect. This could have been done by simply
     *                setting the disconnect_on_fail config parameter, but instead we use the event
     *                handler mechanism to demonstrate its use.
     *
     * @param[in] p_evt  Event received from the Connection Parameters Module.
     */
    static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    {
        uint32_t err_code;
    
        if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
        {
            err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
            APP_ERROR_CHECK(err_code);
        }
    }
    
    
    /**@brief Function for handling a Connection Parameters error.
     *
     * @param[in] nrf_error  Error code containing information about what went wrong.
     */
    static void conn_params_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    
    
    /**@brief Function for initializing the Connection Parameters module.
     */
    static void conn_params_init(void)
    {
        uint32_t               err_code;
        ble_conn_params_init_t cp_init;
    
        memset(&cp_init, 0, sizeof(cp_init));
    
        cp_init.p_conn_params                  = NULL;
        cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
        cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
        cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
        cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
        cp_init.disconnect_on_fail             = false;
        cp_init.evt_handler                    = on_conn_params_evt;
        cp_init.error_handler                  = conn_params_error_handler;
    
        err_code = ble_conn_params_init(&cp_init);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for starting timers.
     */
    static void application_timers_start(void)
    {
        /* YOUR_JOB: Start your timers. below is an example of how to start a timer.
           uint32_t err_code;
           err_code = app_timer_start(m_app_timer_id, TIMER_INTERVAL, NULL);
           APP_ERROR_CHECK(err_code); */
    
    }
    
    
    /**@brief Function for putting the chip into sleep mode.
     *
     * @note This function will not return.
     */
    static void sleep_mode_enter(void)
    {
        uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    
        APP_ERROR_CHECK(err_code);
    
        // Prepare wakeup buttons.
        err_code = bsp_btn_ble_sleep_mode_prepare();
        APP_ERROR_CHECK(err_code);
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        err_code = sd_power_system_off();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling advertising events.
     *
     * @details This function will be called for advertising events which are passed to the application.
     *
     * @param[in] ble_adv_evt  Advertising event.
     */
    static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
    {
        uint32_t err_code;
    
        switch (ble_adv_evt)
        {
            case BLE_ADV_EVT_FAST:
                err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_ADV_EVT_IDLE:
                sleep_mode_enter();
                break;
    
            default:
                break;
        }
    }
    
    
    /**@brief Function for handling the Application's BLE Stack events.
     *
     * @param[in] p_ble_evt  Bluetooth stack event.
     */
    static void on_ble_evt(ble_evt_t * p_ble_evt)
    {
        uint32_t err_code = NRF_SUCCESS;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_DISCONNECTED:
                err_code = bsp_indication_set(BSP_INDICATE_IDLE);
                APP_ERROR_CHECK(err_code);
                break; // BLE_GAP_EVT_DISCONNECTED
    
            case BLE_GAP_EVT_CONNECTED:
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                break; // BLE_GAP_EVT_CONNECTED
    
            case BLE_GATTC_EVT_TIMEOUT:
                // Disconnect on GATT Client timeout event.
                NRF_LOG_DEBUG("GATT Client Timeout.\r\n");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break; // BLE_GATTC_EVT_TIMEOUT
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                NRF_LOG_DEBUG("GATT Server Timeout.\r\n");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break; // BLE_GATTS_EVT_TIMEOUT
    
            case BLE_EVT_USER_MEM_REQUEST:
                err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL);
                APP_ERROR_CHECK(err_code);
                break; // BLE_EVT_USER_MEM_REQUEST
    
            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
            {
                ble_gatts_evt_rw_authorize_request_t  req;
                ble_gatts_rw_authorize_reply_params_t auth_reply;
    
                req = p_ble_evt->evt.gatts_evt.params.authorize_request;
    
                if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
                {
                    if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)     ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                    {
                        if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                        }
                        else
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                        }
                        auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
                        err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                                   &auth_reply);
                        APP_ERROR_CHECK(err_code);
                    }
                }
            } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST
    
    #if (NRF_SD_BLE_API_VERSION == 3)
            case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
                err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                           NRF_BLE_MAX_MTU_SIZE);
                APP_ERROR_CHECK(err_code);
                break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST
    #endif
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    /**@brief Function for dispatching a BLE stack event to all modules with a BLE stack event handler.
     *
     * @details This function is called from the BLE Stack event interrupt handler after a BLE stack
     *          event has been received.
     *
     * @param[in] p_ble_evt  Bluetooth stack event.
     */
    static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
    {
        /** The Connection state module has to be fed BLE events in order to function correctly
         * Remember to call ble_conn_state_on_ble_evt before calling any ble_conns_state_* functions. */
        ble_conn_state_on_ble_evt(p_ble_evt);
        pm_on_ble_evt(p_ble_evt);
        ble_conn_params_on_ble_evt(p_ble_evt);
        bsp_btn_ble_on_ble_evt(p_ble_evt);
        on_ble_evt(p_ble_evt);
        ble_advertising_on_ble_evt(p_ble_evt);
        ble_dfu_on_ble_evt(&m_dfus, p_ble_evt);
        /*YOUR_JOB add calls to _on_ble_evt functions from each service your application is using
           ble_xxs_on_ble_evt(&m_xxs, p_ble_evt);
           ble_yys_on_ble_evt(&m_yys, p_ble_evt);
    	     */
    	#if TEST
        ble_nus_on_ble_evt(&m_nus, p_ble_evt);
    	#endif
    }
    
    
    /**@brief Function for dispatching a system event to interested modules.
     *
     * @details This function is called from the System event interrupt handler after a system
     *          event has been received.
     *
     * @param[in] sys_evt  System stack event.
     */
    static void sys_evt_dispatch(uint32_t sys_evt)
    {
        // Dispatch the system event to the fstorage module, where it will be
        // dispatched to the Flash Data Storage (FDS) module.
        fs_sys_event_handler(sys_evt);
    
        // Dispatch to the Advertising module last, since it will check if there are any
        // pending flash operations in fstorage. Let fstorage process system events first,
        // so that it can report correctly to the Advertising module.
        ble_advertising_on_sys_evt(sys_evt);
    }
    
    
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        uint32_t err_code;
    
        nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
    
        // Initialize the SoftDevice handler module.
        SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
    
        ble_enable_params_t ble_enable_params;
        err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
                                                        PERIPHERAL_LINK_COUNT,
                                                        &ble_enable_params);
        APP_ERROR_CHECK(err_code);
    
        // Check the ram settings against the used number of links
        CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT, PERIPHERAL_LINK_COUNT);
    
        // Enable BLE stack.
    #if (NRF_SD_BLE_API_VERSION == 3)
        ble_enable_params.gatt_enable_params.att_mtu = NRF_BLE_MAX_MTU_SIZE;
    #endif
        err_code = softdevice_enable(&ble_enable_params);
        APP_ERROR_CHECK(err_code);
    
        // Register with the SoftDevice handler module for BLE events.
        err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
        APP_ERROR_CHECK(err_code);
    
        // Register with the SoftDevice handler module for BLE events.
        err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for the Peer Manager initialization.
     *
     * @param[in] erase_bonds  Indicates whether bonding information should be cleared from
     *                         persistent storage during initialization of the Peer Manager.
     */
    static void peer_manager_init(bool erase_bonds)
    {
        ble_gap_sec_params_t sec_param;
        ret_code_t           err_code;
    
        err_code = pm_init();
        APP_ERROR_CHECK(err_code);
    
        if (erase_bonds)
        {
            err_code = pm_peers_delete();
            APP_ERROR_CHECK(err_code);
        }
    
        memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
    
        // Security parameters to be used for all security procedures.
        sec_param.bond           = SEC_PARAM_BOND;
        sec_param.mitm           = SEC_PARAM_MITM;
        sec_param.lesc           = SEC_PARAM_LESC;
        sec_param.keypress       = SEC_PARAM_KEYPRESS;
        sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
        sec_param.oob            = SEC_PARAM_OOB;
        sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
        sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
        sec_param.kdist_own.enc  = 1;
        sec_param.kdist_own.id   = 1;
        sec_param.kdist_peer.enc = 1;
        sec_param.kdist_peer.id  = 1;
    
        err_code = pm_sec_params_set(&sec_param);
        APP_ERROR_CHECK(err_code);
    
        err_code = pm_register(pm_evt_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling events from the BSP module.
     *
     * @param[in]   event   Event generated when button is pressed.
     */
    static void bsp_event_handler(bsp_event_t event)
    {
        uint32_t err_code;
    
        switch (event)
        {
            case BSP_EVENT_SLEEP:
                sleep_mode_enter();
                break; // BSP_EVENT_SLEEP
    
            case BSP_EVENT_DISCONNECT:
                err_code = sd_ble_gap_disconnect(m_conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
                break; // BSP_EVENT_DISCONNECT
    
            case BSP_EVENT_WHITELIST_OFF:
                if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
                {
                    err_code = ble_advertising_restart_without_whitelist();
                    if (err_code != NRF_ERROR_INVALID_STATE)
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                }
                break; // BSP_EVENT_KEY_0
    
            default:
                break;
        }
    }
    
    
    /**@brief Function for initializing the Advertising functionality.
     */
    void advertising_init(void)
    {
        uint32_t               err_code;
        ble_advdata_t          advdata;
        ble_adv_modes_config_t options;
    
        // Build advertising data struct to pass into @ref ble_advertising_init.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        advdata.include_appearance      = true;
        advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        advdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        memset(&options, 0, sizeof(options));
        options.ble_adv_fast_enabled  = true;
        options.ble_adv_fast_interval = APP_ADV_INTERVAL;
        options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;
    
        err_code = ble_advertising_init(&advdata, NULL, &options, on_adv_evt, NULL);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing buttons and leds.
     *
     * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
     */
    static void buttons_leds_init(bool * p_erase_bonds)
    {
        bsp_event_t startup_event;
    
        uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,
                                     APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),
                                     bsp_event_handler);
    
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_btn_ble_init(NULL, &startup_event);
        APP_ERROR_CHECK(err_code);
    
        *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
    }
    
    
    /**@brief Function for the Power manager.
     */
    static void power_manage(void)
    {
        uint32_t err_code = sd_app_evt_wait();
    
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for starting advertising.
     */
    void advertising_start(void)
    {
        uint32_t err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for application main entry.
     */
    int main(void)
    {
        uint32_t err_code;
        bool     erase_bonds;
    
        // Initialize.
        err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        timers_init();
        buttons_leds_init(&erase_bonds);
        ble_stack_init();
        peer_manager_init(erase_bonds);
        if (erase_bonds == true)
        {
            NRF_LOG_DEBUG("Bonds erased!\r\n");
        }
        gap_params_init();
        advertising_init();
        services_init();
        NRF_LOG_DEBUG("Services are initialized\r\n");
        conn_params_init();
        NRF_LOG_DEBUG("conn params are initialized\r\n");
        // Start execution.
        application_timers_start();
        NRF_LOG_DEBUG("app timers are started\r\n");
        err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_DEBUG("advertising is started\r\n");
        // Enter main loop.
        for (;;)
        {
            if (NRF_LOG_PROCESS() == false)
            {
                power_manage();
            }
        }
    }
    
    
    /**
     * @}
     */
    

Related