<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/42974/bonding-with-pc-ble-driver-py</link><description>Hello 
 System: 
 Windows 10 
 nRF Connect v2.6.0 and Bluetooth Low Energy v2.2.0 
 Python 2.7.13 
 
 After some research I didn&amp;#39;t find any examples of bonding with pc-ble-driver-py so I decided to ask here. 
 When I&amp;#39;m trying to do bond using nRF Connect</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 24 Apr 2019 19:47:07 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/42974/bonding-with-pc-ble-driver-py" /><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/183602?ContentTypeID=1</link><pubDate>Wed, 24 Apr 2019 19:47:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3445971b-a4c9-438b-914c-21079376e65a</guid><dc:creator>Dmitry_s</dc:creator><description>&lt;p&gt;Hi there, I don&amp;#39;t have any code or devices right now, so I writed something may help you&lt;/p&gt;
&lt;p&gt;I didn&amp;#39;t tested bonding with passcode, so it probably will not work without some changes&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;import sys
import time
import Queue
import logging

from pc_ble_driver_py.observers     import *

TARGET_DEV_ID = &amp;quot;000&amp;quot;       #Put your target MAC here (in format like ABCDABCDABCD not AB:CD:AB:CD:AB:CD)
CONNECTIONS   = 1

def init(conn_ic_id):
    global BLEDriver,        \
           BLEAdvData,       \
           BLEEvtID,         \
           BLEAdapter,       \
           BLEEnableParams,  \
           BLEGapTimeoutSrc, \
           BLEGapIOCaps,     \
           BLEUUID,          \
           BLEUUIDBase,      \
           BLEGapSecKDist,   \
           BLEGapSecParams,  \
           BLEGapSecStatus
           
    from pc_ble_driver_py import config
    config.__conn_ic_id__ = conn_ic_id

    from pc_ble_driver_py.ble_driver    import BLEDriver,        \
                                               BLEAdvData,       \
                                               BLEEvtID,         \
                                               BLEEnableParams,  \
                                               BLEGapTimeoutSrc, \
                                               BLEGapIOCaps,     \
                                               BLEUUID,          \
                                               BLEUUIDBase,      \
                                               BLEGapSecKDist,   \
                                               BLEGapSecParams,  \
                                               BLEGapSecStatus
                                               
    from pc_ble_driver_py.ble_adapter   import BLEAdapter

    global nrf_sd_ble_api_ver
    nrf_sd_ble_api_ver = config.sd_api_ver_get()

class HRCollector(BLEDriverObserver, BLEAdapterObserver):
    def __init__(self, adapter):
        super(HRCollector, self).__init__()
        self.adapter    = adapter
        self.conn_q     = Queue.Queue()
        self.adapter.observer_register(self)
        self.adapter.driver.observer_register(self)
        
        self.keyset = None       # There we will store keys after bonding
        self.conn_handle = None  # Connection handler


    def open(self):
        self.adapter.driver.open()

        ble_enable_params = BLEEnableParams(vs_uuid_count      = 1,
                                            service_changed    = False,
                                            periph_conn_count  = 0,
                                            central_conn_count = CONNECTIONS,
                                            central_sec_count  = CONNECTIONS)
        if nrf_sd_ble_api_ver &amp;gt;= 3:
            print(&amp;quot;Enabling larger ATT MTUs&amp;quot;)
            ble_enable_params.att_mtu = 50

        self.adapter.driver.ble_enable(ble_enable_params)


    def close(self):
        self.adapter.driver.close()


    def connect_and_discover(self):
        self.adapter.driver.ble_gap_scan_start()
        new_conn = self.conn_q.get(timeout = 60)

        if nrf_sd_ble_api_ver &amp;gt;= 3:
            att_mtu = self.adapter.att_mtu_exchange(new_conn)

        self.adapter.service_discovery(new_conn)
        #self.adapter.enable_notification(new_conn, BLEUUID(BLEUUID.Standard.battery_level))
        #self.adapter.enable_notification(new_conn, BLEUUID(BLEUUID.Standard.heart_rate))
        return new_conn

    # Don&amp;#39;t remember exactly on which event we have to reply after encryption (1 or 2)
    # 1
    #def on_gap_evt_sec_params_request(self, ble_driver, conn_handle, peer_params):
    #    pass
     
    # 2
    #def on_gap_evt_sec_info_request(self, ble_driver, conn_handle, peer_addr, master_id, enc_info, id_info, sign_info):
    #    pass

    def on_gap_evt_connected(self, ble_driver, conn_handle, peer_addr, role, conn_params):
        print(&amp;#39;New connection: {}&amp;#39;.format(conn_handle))
        self.conn_q.put(conn_handle)
        
        self.conn_handle = conn_handle
        
        if self.keyset is not None:
            keys    = self.keyset
            
            ediv    = keys.enc_key.master_id.ediv
            rand    = keys.enc_key.master_id.rand
            
            ltk     = keys.enc_key.enc_info.ltk
            auth    = keys.enc_key.enc_info.auth
            lesc    = keys.enc_key.enc_info.auth
            ltk_len = keys.enc_key.enc_info.ltk_len
        
            self.adapter.encrypt(conn_handle,
                                 ediv=ediv,
                                 rand=rand,
                                 ltk=ltk,
                                 auth=auth,
                                 lesc=lesc,
                                 ltk_len=ltk_len)

    def on_gap_evt_disconnected(self, ble_driver, conn_handle, reason):
        print(&amp;#39;Disconnected: {} {}&amp;#39;.format(conn_handle, reason))
        
        self.conn_handle = None


    def on_gap_evt_timeout(self, ble_driver, conn_handle, src):
        if src == BLEGapTimeoutSrc.scan:
            ble_driver.ble_gap_scan_start()


    def on_gap_evt_adv_report(self, ble_driver, conn_handle, peer_addr, rssi, adv_type, adv_data):
        dev_name_list = None
        if BLEAdvData.Types.complete_local_name in adv_data.records:
            dev_name_list = adv_data.records[BLEAdvData.Types.complete_local_name]

        elif BLEAdvData.Types.short_local_name in adv_data.records:
            dev_name_list = adv_data.records[BLEAdvData.Types.short_local_name]

        else:
            return

        dev_name        = &amp;quot;&amp;quot;.join(chr(e) for e in dev_name_list)
        address_string  = &amp;quot;&amp;quot;.join(&amp;quot;{0:02X}&amp;quot;.format(b) for b in peer_addr.addr)
        print(&amp;#39;Received advertisment report, address: 0x{}, device_name: {}&amp;#39;.format(address_string,
                                                                                    dev_name))

        if (address_string == TARGET_DEV_ID):
            self.adapter.connect(peer_addr)

    def authenticate(self):
        &amp;quot;&amp;quot;&amp;quot;Do bonding
        
        :return: Success status (True/False)
        &amp;quot;&amp;quot;&amp;quot;
        if self.conn_handle is None:
            return False
    
        adapter    = self.adapter
        driver     = self.adapter.driver
        
        kdist_own   = BLEGapSecKDist(enc  = 1,
                                     id   = 1,
                                     sign = 0,
                                     link = 0)
                                     
        kdist_peer  = BLEGapSecKDist(enc  = 1,
                                     id   = 1,
                                     sign = 0,
                                     link = 0)
        
        sec_params  = BLEGapSecParams(bond          = True,
                                      mitm          = True,
                                      lesc          = True,
                                      oob           = True,
                                      keypress      = True,
                                      io_caps       = BLEGapIOCaps.keyboard_display,
                                      min_key_size  = 7,
                                      max_key_size  = 16,
                                      kdist_own     = kdist_own,
                                      kdist_peer    = kdist_peer)
        
        # Authenticate
        driver.ble_gap_authenticate(conn_handle, sec_params)
        
        # Reply after event
        adapter.evt_sync[conn_handle].wait(evt = BLEEvtID.gap_evt_sec_params_request)
        driver.ble_gap_sec_params_reply(conn_handle,
                                        BLEGapSecStatus.success,
                                        sec_params=None)
        # Save keys on success
        result = self.evt_sync[conn_handle].wait(evt = BLEEvtID.gap_evt_auth_status)
        if result[&amp;#39;auth_status&amp;#39;] ==  BLEGapSecStatus.success:
            self.keyset = adapter.db_conns[conn_handle]._keyset
            return True
           
        return False

    def save_keys(self):
        &amp;quot;&amp;quot;&amp;quot;Saving keys into the file
        &amp;quot;&amp;quot;&amp;quot;
        
        # Save self.keyset
        
        pass
        
    def load_keys(self):
        &amp;quot;&amp;quot;&amp;quot;Load keys from the file
        &amp;quot;&amp;quot;&amp;quot;
        
        # Load into self.keyset from file
        
        adapter.db_conns[conn_handle]._keyset = self.keyset # And load it into the driver
        
        pass
     
    def on_notification(self, ble_adapter, conn_handle, uuid, data):
        print(&amp;#39;Connection: {}, {} = {}&amp;#39;.format(conn_handle, uuid, data))


    def on_att_mtu_exchanged(self, ble_driver, conn_handle, att_mtu):
        print(&amp;#39;ATT MTU exchanged: conn_handle={} att_mtu={}&amp;#39;.format(conn_handle, att_mtu))


    def on_gattc_evt_exchange_mtu_rsp(self, ble_driver, conn_handle, **kwargs):
        print(&amp;#39;ATT MTU exchange response: conn_handle={}&amp;#39;.format(conn_handle))
    

def main(serial_port):
    print(&amp;#39;Serial port used: {}&amp;#39;.format(serial_port))
    driver    = BLEDriver(serial_port=serial_port, auto_flash=False)
    adapter   = BLEAdapter(driver)
    collector = HRCollector(adapter)
    collector.open()
    for i in xrange(CONNECTIONS):
        conn_handle = collector.connect_and_discover()  # Connect
        collector.authenticate()                        # Do bonding (Note: don&amp;#39;t use this method in any event handler defined in pc_ble_driver_py.observers
                                                        # such as on_connected(), so that program will not hang)
        
        collector.save_keys()                           # Save keys so in the next program&amp;#39;s run we don&amp;#39;t have to do bonding again
        #collector.load_keys()
        
        # wait for the device ready to connect
        # wait_ms(5000)
        
        collector.connect_and_discover()                # Connect

    time.sleep(30)
    print(&amp;#39;Closing&amp;#39;)
    collector.close()


def item_choose(item_list):
    for i, it in enumerate(item_list):
        print(&amp;#39;\t{} : {}&amp;#39;.format(i, it))
    print(&amp;#39; &amp;#39;)

    while True:
        try:
            choice = int(raw_input(&amp;#39;Enter your choice: &amp;#39;))
            if ((choice &amp;gt;= 0) and (choice &amp;lt; len(item_list))):
                break
        except Exception:
            pass
        print (&amp;#39;\tTry again...&amp;#39;)
    return choice


if __name__ == &amp;quot;__main__&amp;quot;:
    serial_port = None
    if len(sys.argv) &amp;lt; 2:
        print(&amp;quot;Please specify connectivity IC identifier (NRF51, NRF52)&amp;quot;)
        exit(1)
    init(sys.argv[1])
    if len(sys.argv) == 3:
        serial_port = sys.argv[2]
    else:
        descs       = BLEDriver.enum_serial_ports()
        choices     = [&amp;#39;{}: {}&amp;#39;.format(d.port, d.serial_number) for d in descs]
        choice      = item_choose(choices)
        serial_port = descs[choice].port
    main(serial_port)
    quit()
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/182476?ContentTypeID=1</link><pubDate>Tue, 16 Apr 2019 23:02:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:98677ab9-0c30-400f-a1e6-94d363fbaeee</guid><dc:creator>Rob_NF</dc:creator><description>&lt;p&gt;Thanks &lt;a href="https://devzone.nordicsemi.com/members/dmitry_5f00_s"&gt;Dmitry_s&lt;/a&gt;.&amp;nbsp; I&amp;#39;m attempting to do a project that uses a passcode as well.&amp;nbsp; Do you mind sharing your working example?&amp;nbsp; I&amp;#39;ve looked elsewhere but I&amp;#39;m finding it surprisingly hard to find any Python examples.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/168329?ContentTypeID=1</link><pubDate>Mon, 28 Jan 2019 20:27:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d9212c63-46f3-4780-95fb-281a28237f5b</guid><dc:creator>Dmitry_s</dc:creator><description>&lt;p&gt;I solved the problem above, what I had to do is authenticate with display_only iocaps.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/168068?ContentTypeID=1</link><pubDate>Sat, 26 Jan 2019 17:52:22 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2d41957a-5c39-4c72-b9b6-a39a1386240c</guid><dc:creator>Dmitry_s</dc:creator><description>&lt;p&gt;But I still can&amp;#39;t perform bond.&lt;/p&gt;
&lt;p&gt;As you will see in the logs below, I&amp;#39;m facing BLE_GAP_SEC_STATUS_CONFIRM_VALUE error,&amp;nbsp;but ble_gap_authenticate(),&amp;nbsp;ble_gap_sec_params_reply() and&amp;nbsp;sd_ble_gap_auth_key_reply() has done succsessfully(I was checking their output&amp;nbsp;from ble_driver.py when they called a softdevice api functions)&lt;/p&gt;
&lt;p&gt;Here is the log from the console output with debug log:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;Auth 1
Auth completed
DEBUG:pc_ble_driver_py.observers:evt&amp;gt; sec_params_request conn(0)
peer_params(Security Parameters bond(1) mitm(1) lesc(0) keypress(0) io_caps(BLEGapIOCaps.display_only) oob(0) max_key_size(16) min_key_size(0) kdist_own(enc(1) id(1) sign(0) link(0)) kdist_peer(enc(1) id(1) sign(0) link(0)))
Sec params replying done
DEBUG:pc_ble_driver_py.observers:evt&amp;gt; auth_key_request conn(0)
key_type(1)
Key reply finished with code: 0
DEBUG:pc_ble_driver_py.observers:evt&amp;gt; auth_status conn(0)
error_src(1)
bonded(0)
sm1_levels(&amp;lt;pc_ble_driver_sd_api_v3.ble_gap_sec_levels_t; proxy of &amp;lt;Swig Object of type &amp;#39;ble_gap_sec_levels_t *&amp;#39; at 0x01ADF1D0&amp;gt; &amp;gt;)
sm2_levels(&amp;lt;pc_ble_driver_sd_api_v3.ble_gap_sec_levels_t; proxy of &amp;lt;Swig Object of type &amp;#39;ble_gap_sec_levels_t *&amp;#39; at 0x01ADF2D8&amp;gt; &amp;gt;)
kdist_own(enc(0) id(1) sign(1) link(1))
kdist_peer(enc(0) id(1) sign(1) link(1))
auth_status(BLEGapSecStatus.confirm_value)
Result: 1
Pairing done&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And the code I&amp;#39;m using:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;def authenticate(self, conn_handle):
        
        adapter    = self.adapter                # adapter
        driver     = self.adapter.driver         # driver
        sd_driver  = BLESoftDevice               # softdevice api
        
        kdist_own   = BLEGapSecKDist(enc  = 1,
                                     id   = 1,
                                     sign = 0,
                                     link = 0)
                                     
        kdist_peer  = BLEGapSecKDist(enc  = 1,
                                     id   = 1,
                                     sign = 0,
                                     link = 0)
        
        sec_params  = BLEGapSecParams(bond          = True,
                                      mitm          = True,
                                      lesc          = True,
                                      oob           = True,
                                      keypress      = False,
                                      io_caps       = BLEGapIOCaps.keyboard_display,
                                      min_key_size  = 7,
                                      max_key_size  = 16,
                                      kdist_own     = kdist_own,
                                      kdist_peer    = kdist_peer)
        
        print(&amp;quot;Auth 1&amp;quot;)
        driver.ble_gap_authenticate(conn_handle, sec_params)
        
        print(&amp;quot;Auth completed&amp;quot;)
        # Send sec params
        adapter.evt_sync[conn_handle].wait(evt = BLEEvtID.gap_evt_sec_params_request)
        driver.ble_gap_sec_params_reply(conn_handle,
                                        BLEGapSecStatus.success,
                                        None)
                                                     
        print(&amp;quot;Sec params replying done&amp;quot;)
      
        # Send passcode
        adapter.evt_sync[conn_handle].wait(evt = BLEEvtID.gap_evt_auth_key_request)
        
        key = util.list_to_uint8_array([0x30,0x30,0x30,0x30,0x30,0x30]).cast()
        res = sd_driver.sd_ble_gap_auth_key_reply(driver.rpc_adapter,
                                                  conn_handle,
                                                  0x01,     # PASSCODE
                                                  key)      # ASCII: 000000
        
        print(&amp;quot;Key reply finished with code: {}&amp;quot;.format(res))       
                
        # Get pairing results and save key
        result = adapter.evt_sync[conn_handle].wait(evt = BLEEvtID.gap_evt_auth_status)
        
        print(&amp;quot;Result: {}&amp;quot;.format(result[&amp;#39;error_src&amp;#39;]))
        if result[&amp;#39;auth_status&amp;#39;] ==  BLEGapSecStatus.success:
            print(&amp;quot;Success&amp;quot;)
            adapter.db_conns[conn_handle]._keyset = BLEGapSecKeyset.from_c(sd_driver._keyset)
            
        print(&amp;quot;Pairing done&amp;quot;)&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/168065?ContentTypeID=1</link><pubDate>Sat, 26 Jan 2019 16:42:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:27f74d62-0a1f-4ed2-9748-a833b36cca28</guid><dc:creator>Dmitry_s</dc:creator><description>&lt;p&gt;Well, now I think I resolved the problem with crushes by moving authentication method into the main function instead of event handler.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/167997?ContentTypeID=1</link><pubDate>Fri, 25 Jan 2019 15:18:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ade6600e-22fc-4bfe-a5d0-74d664fad371</guid><dc:creator>Dmitry_s</dc:creator><description>&lt;p&gt;Sure:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;import sys
import time
import Queue
import logging

from pc_ble_driver_py.observers     import *

TARGET_DEV_ID = &amp;quot;E364492DC7B3&amp;quot;
CONNECTIONS   = 1

def init(conn_ic_id):
    global BLEDriver,        \
           BLEAdvData,       \
           BLEEvtID,         \
           BLEAdapter,       \
           BLEEnableParams,  \
           BLEGapTimeoutSrc, \
           BLEGapIOCaps,     \
           BLEUUID,          \
           BLEUUIDBase,      \
           BLEGapSecKDist,   \
           BLEGapSecParams,  \
           BLEGapSecStatus
           
    from pc_ble_driver_py import config
    config.__conn_ic_id__ = conn_ic_id

    from pc_ble_driver_py.ble_driver    import BLEDriver,        \
                                               BLEAdvData,       \
                                               BLEEvtID,         \
                                               BLEEnableParams,  \
                                               BLEGapTimeoutSrc, \
                                               BLEGapIOCaps,     \
                                               BLEUUID,          \
                                               BLEUUIDBase,      \
                                               BLEGapSecKDist,   \
                                               BLEGapSecParams,  \
                                               BLEGapSecStatus
                                               
    from pc_ble_driver_py.ble_adapter   import BLEAdapter

    global nrf_sd_ble_api_ver
    nrf_sd_ble_api_ver = config.sd_api_ver_get()

class HRCollector(BLEDriverObserver, BLEAdapterObserver):
    def __init__(self, adapter):
        super(HRCollector, self).__init__()
        self.adapter    = adapter
        self.conn_q     = Queue.Queue()
        self.adapter.observer_register(self)
        self.adapter.driver.observer_register(self)


    def open(self):
        self.adapter.driver.open()

        ble_enable_params = BLEEnableParams(vs_uuid_count      = 1,
                                            service_changed    = False,
                                            periph_conn_count  = 0,
                                            central_conn_count = CONNECTIONS,
                                            central_sec_count  = CONNECTIONS)
        if nrf_sd_ble_api_ver &amp;gt;= 3:
            print(&amp;quot;Enabling larger ATT MTUs&amp;quot;)
            ble_enable_params.att_mtu = 50

        self.adapter.driver.ble_enable(ble_enable_params)


    def close(self):
        self.adapter.driver.close()


    def connect_and_discover(self):
        self.adapter.driver.ble_gap_scan_start()
        new_conn = self.conn_q.get(timeout = 60)

        if nrf_sd_ble_api_ver &amp;gt;= 3:
            att_mtu = self.adapter.att_mtu_exchange(new_conn)

        self.adapter.service_discovery(new_conn)
        #self.adapter.enable_notification(new_conn, BLEUUID(BLEUUID.Standard.battery_level))
        #self.adapter.enable_notification(new_conn, BLEUUID(BLEUUID.Standard.heart_rate))
        return new_conn


    def on_gap_evt_connected(self, ble_driver, conn_handle, peer_addr, role, conn_params):
        print(&amp;#39;New connection: {}&amp;#39;.format(conn_handle))
        #self.conn_q.put(conn_handle)
        
        self.authenticate(conn_handle)

    def on_gap_evt_disconnected(self, ble_driver, conn_handle, reason):
        print(&amp;#39;Disconnected: {} {}&amp;#39;.format(conn_handle, reason))


    def on_gap_evt_timeout(self, ble_driver, conn_handle, src):
        if src == BLEGapTimeoutSrc.scan:
            ble_driver.ble_gap_scan_start()


    def on_gap_evt_adv_report(self, ble_driver, conn_handle, peer_addr, rssi, adv_type, adv_data):
        dev_name_list = None
        if BLEAdvData.Types.complete_local_name in adv_data.records:
            dev_name_list = adv_data.records[BLEAdvData.Types.complete_local_name]

        elif BLEAdvData.Types.short_local_name in adv_data.records:
            dev_name_list = adv_data.records[BLEAdvData.Types.short_local_name]

        else:
            return

        dev_name        = &amp;quot;&amp;quot;.join(chr(e) for e in dev_name_list)
        address_string  = &amp;quot;&amp;quot;.join(&amp;quot;{0:02X}&amp;quot;.format(b) for b in peer_addr.addr)
        print(&amp;#39;Received advertisment report, address: 0x{}, device_name: {}&amp;#39;.format(address_string,
                                                                                    dev_name))

        if (address_string == TARGET_DEV_ID):
            self.adapter.connect(peer_addr)

    def authenticate(self, conn_handle):
        adapter    = self.adapter
        driver     = self.adapter.driver
        
        kdist_own   = BLEGapSecKDist(enc  = 1,
                                     id   = 1,
                                     sign = 0,
                                     link = 0)
                                     
        kdist_peer  = BLEGapSecKDist(enc  = 1,
                                     id   = 1,
                                     sign = 0,
                                     link = 0)
        
        sec_params  = BLEGapSecParams(bond          = True,
                                      mitm          = True,
                                      lesc          = True,
                                      oob           = True,
                                      keypress      = True,
                                      io_caps       = BLEGapIOCaps.keyboard_display,
                                      min_key_size  = 7,
                                      max_key_size  = 16,
                                      kdist_own     = kdist_own,
                                      kdist_peer    = kdist_peer)
        
        # Authenticate
        driver.ble_gap_authenticate(conn_handle, sec_params)
        
        # Reply after event
        adapter.evt_sync[conn_handle].wait(evt = BLEEvtID.gap_evt_sec_params_request)
        driver.ble_gap_sec_params_reply(conn_handle,
                                        BLEGapSecStatus.success,
                                        sec_params=None)
        # Save keys on success
        result = self.evt_sync[conn_handle].wait(evt = BLEEvtID.gap_evt_auth_status)
        if result[&amp;#39;auth_status&amp;#39;] ==  BLEGapSecStatus.success:
            adapter.db_conns[conn_handle]._keyset = BLEGapSecKeyset.from_c(self.driver._keyset)
            
        return result[&amp;#39;auth_status&amp;#39;]

    def on_notification(self, ble_adapter, conn_handle, uuid, data):
        print(&amp;#39;Connection: {}, {} = {}&amp;#39;.format(conn_handle, uuid, data))


    def on_att_mtu_exchanged(self, ble_driver, conn_handle, att_mtu):
        print(&amp;#39;ATT MTU exchanged: conn_handle={} att_mtu={}&amp;#39;.format(conn_handle, att_mtu))


    def on_gattc_evt_exchange_mtu_rsp(self, ble_driver, conn_handle, **kwargs):
        print(&amp;#39;ATT MTU exchange response: conn_handle={}&amp;#39;.format(conn_handle))
    

def main(serial_port):
    print(&amp;#39;Serial port used: {}&amp;#39;.format(serial_port))
    driver    = BLEDriver(serial_port=serial_port, auto_flash=False)
    adapter   = BLEAdapter(driver)
    collector = HRCollector(adapter)
    collector.open()
    for i in xrange(CONNECTIONS):
        conn_handle = collector.connect_and_discover()

    time.sleep(30)
    print(&amp;#39;Closing&amp;#39;)
    collector.close()


def item_choose(item_list):
    for i, it in enumerate(item_list):
        print(&amp;#39;\t{} : {}&amp;#39;.format(i, it))
    print(&amp;#39; &amp;#39;)

    while True:
        try:
            choice = int(raw_input(&amp;#39;Enter your choice: &amp;#39;))
            if ((choice &amp;gt;= 0) and (choice &amp;lt; len(item_list))):
                break
        except Exception:
            pass
        print (&amp;#39;\tTry again...&amp;#39;)
    return choice


if __name__ == &amp;quot;__main__&amp;quot;:
    serial_port = None
    if len(sys.argv) &amp;lt; 2:
        print(&amp;quot;Please specify connectivity IC identifier (NRF51, NRF52)&amp;quot;)
        exit(1)
    init(sys.argv[1])
    if len(sys.argv) == 3:
        serial_port = sys.argv[2]
    else:
        descs       = BLEDriver.enum_serial_ports()
        choices     = [&amp;#39;{}: {}&amp;#39;.format(d.port, d.serial_number) for d in descs]
        choice      = item_choose(choices)
        serial_port = descs[choice].port
    main(serial_port)
    quit()
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I resolved the problem when I couldn&amp;#39;t pass more agruments to the authenticate method, but still can&amp;#39;t pair. Also I don&amp;#39;t know kdist_own and kdist_peer parameters that used in nRF Connect by default, may it can help to avoid crashes if I put it correctly.&lt;/p&gt;
&lt;p&gt;EDIT: It just slightly edited heart_rate_collector.py&amp;nbsp;but with authenticate() method that is called by on_gap_evt_connected()&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/167985?ContentTypeID=1</link><pubDate>Fri, 25 Jan 2019 14:58:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3c7b7c87-f57c-4ff5-afab-60252b547452</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Can you post the code you are using, for reproducing and debugging this?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/167973?ContentTypeID=1</link><pubDate>Fri, 25 Jan 2019 14:37:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f1541f26-02b4-4568-b703-4ec6f9c0b3b5</guid><dc:creator>Dmitry_s</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;I haven&amp;#39;t got any errors when it crash, but I found that the program crashes while executing&amp;nbsp;sd_ble_gap_sec_params_reply()&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Bonding with pc-ble-driver-py</title><link>https://devzone.nordicsemi.com/thread/167957?ContentTypeID=1</link><pubDate>Fri, 25 Jan 2019 14:00:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7e4cb6bc-ed43-4b01-8f59-31da90409aed</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Do you get any error codes when it crash? Have you seen &lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/39468/ble-bonding-pairing-with-pc-ble-driver-py"&gt;this thread&lt;/a&gt;? Unfortunately, we do not have any examples of this in the Python version.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;br /&gt;Jørgen&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>