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

Error 22 (0x16): GATT_CONN_TERMINATE_LOCAL_HOST only on Samsung XCover device

When I run the BLE peripheral HRS example on the eval board and try to connect with a Samsung XCover3 using the "nRF Connect" app, I got the error 22 (0x16): GATT_CONN_TERMINATE_LOCAL_HOST.

Doing the same with a Sony Xperia ZL, I got no error. After looking in the logs, there are some interesting services discovered by the Samsung device, that are not realy advertised by the eval board.

My question is now, where comes the error from? Bluetooth chipset of Samsung or a bug in the softdevice? What can I do, to fix this problem?

  • nRF52832
  • SDK 12.2.0
  • Softdevice S132
  • Eval board PCA10040

Working device:

  • Device name: Xperia ZL
  • Android version: 6.0.1
  • Manufacturer: Sony
  • Model: XPeria ZL
  • Build version: cm_odin-userdebug 6.0.1 MOB31K 05f414329b test-keys
  • Board: MSM8960
  • Product: C6503

log_sony_xperia_zl.txt

Non working device:

  • Device name: Samsung SM-G389F
  • Android version: 6.0.1
  • Manufacturer: Samsung
  • Model: SM-G389F
  • Build version: MMB29K.G389FXX U1APK1
  • Board: universal3475
  • Product: xcover3veltexx

log_samsung_xcover3.txt

Wireshark trace with Sony XPeria ZL connecting to HRM example: nordic_hrm_sony_xperia_zl.pcapng

Wireshark trace with Samsung XCover 3 connecting to HRM example: nordic_hrm_samsung_xcover_3.pcapng

  • Hi,

    This could be caused by an old gatt table with services that you previously bonded with. Try to go into Bluetooth settings on your phone, forget all bluetooth services/devices that you have listed there (paired with) and perhaps disable Bluetooth and enable it again. Then try again and see if it works.

    If this doesn’t work, try to find any error codes reported by the nRF52(any reasons for the disconnect). See e.g. this answer on how to debug. A sniffer trace could also reveal what the problem is.

  • I did a complete factory reset on the Samsung device (wipe /data, /cache, ...): Same behaviour. Also enabling debug output of the example did not lead to any error faults.

    Interesting fakt: With the old SDK 11.0.0 and softdevice 2.0.0 the Samsung device works, but there we had problems with Apple devices :(

  • Error 22 is not very common. Could you test with the S132 version 3.1.0 SoftDevice? Download it here, and replace the headers in the folder SDK_Folder\components\softdevice\s132. Try to enable compatibility mode, and see it this solves the issue. Put this after ble_stack_init():

    ble_opt_t ble_opt;
    memset(&ble_opt, 0, sizeof(ble_opt));
    
    ble_opt.gap_opt.compat_mode_2.mode_2_enable = 1;
    
    err_code = sd_ble_opt_set(BLE_GAP_OPT_COMPAT_MODE_2,&ble_opt); 
    APP_ERROR_CHECK(err_code);
    

    If this doesn't solve the issue, a sniffer trace should be performed.

  • I did the test with S132 version 3.1.0, but I got the same error results.

    With the PCA10000 eval board I catched the two loggs attached to the question. The trace of the Samsung device is really weired: It is full of unknown LL Control PDUs. What does this mean?

  • The sniffer is not up-to-date with the newest LL packets, so the name of the newest packets are shown as unknown in the sniffer. The first “unknown” packet has opcode 0x14, if you look at the Bluetooth Specifications (Core version 4.2 or 5.0) this is a LL_LENGTH_REQ packet send from the nRF52 to the Xcover, in order to enable Data length extension (DLE)/ longer on-air data packets. According to the specifications, if the Xcover supported DLE, it should have responded with a LL_LENGTH_RSP packet, and if Xcover didn’t support DLE it should have sent a LL_UNKNOWN_RSP packet. None of these packets are sent by the Xcover.

    I suggest to use the default payload size of 27, so that the DLE procedure is not initiated (LL_LENGTH_REQ will not be sent). Call this function before you start advertising:

    void data_len_ext_set(void)
    {
        ret_code_t err_code;
        ble_opt_t  opt;
    
        memset(&opt, 0x00, sizeof(opt));
    
        opt.gap_opt.ext_len.rxtx_max_pdu_payload_size = 0;
    
        err_code = sd_ble_opt_set(BLE_GAP_OPT_EXT_LEN, &opt);
        APP_ERROR_CHECK(err_code);
    }
    
Related