Ranging Pixel 6 Pro AndroidX UWB to DWM3000EVB

We are trying to evaluate UWB ranging using the new AndroidX UWB JetPack library with a DWM3000EVB plugged into a Nordic nRF52840-DK.
The Android sample code is here.
To be honest, it’s not clear if the Pixel is an initiator or a responder, but we have tried examples ex_05a and ex_05b.
The Android api says:

        /**
         * Pre-defined unicast STATIC STS DS-TWR ranging.
         *
         * deferred mode,
         * ranging interval = 240 ms,
         * slot duration = 2400 RSTU,
         * slots per ranging round = 6
         *
         * All other MAC parameters use FiRa/UCI default values.
         *
         * <p> Typical use case: device tracking tags
         */
        @JvmField
        val UWB_CONFIG_ID_1 = 1

So we assume we need to use the DS_TWR examples.
The code needs to setup the UwbAddress and UwbComplexChannel.
The examples seem to be using channel 5 rather than 9, although we have yet to see where it selects CONFIG_OPTION_33 in the Qorvo code.
What we can’t see is where to get the actual UWB MAC address from. Should we be calling something to set it?

        val uwbDevice = UwbDevice.createForAddress("42:42") // What MAC Address?
        val uwbChannel = UwbComplexChannel(5,9) // Why channel 5 and should the preamble index be 9?
        // Create the ranging parameters.
        val partnerParameters = RangingParameters(
            uwbConfigType = RangingParamters.UWB_CONFIG_ID_1,
            sessionId = 0, // What should we use for session ID?
            // SessionKeyInfo is used to encrypt the ranging session.
            sessionKeyInfo = null, // Do we need to copy the cp_key from the examples, and what is the endian byte order?
            complexChannel = uwbChannel,
            peerDevices = listOf(uwbDevice),
            updateRateType = RangingParameters.RANGING_UPDATE_RATE_AUTOMATIC
        )

        val sessionFlow = clientSession.prepareSession(partnerParameters)

The examples don’t seem to be getting any data in Segger breakpoints, so we assume that we have yet to get the correct config to talk with the Pixel 6 Pro to/from the DWM3000.
So as Qorvo created the Android kernel support and chipset for the Pixel 6 Pro, it would be really good to get some more information from you…

I guess some progress, as I tried looking at any UWB tracing in Android.
Setting the UwbAddress to FF:FF seems to have actually got an error back. It is definitely coming from the DWM3000, as sitting on a Segger Studio breakpoint gives nothing.
Presumably some other STS config needed in the sessionId / sessionKeyInfo or I need to edit the ds_twr_initiator_sts.c code.

2022-06-16 15:30:10.113 8141-8274/com.example.app D/MainActivity: Got UWB local address 6C:8A ranging capabilities: distance true, azimuth true, elevation false
2022-06-16 15:30:10.166 2553-7870/? I/NearbyUWB: UWB Ranging Device start ranging [CONTEXT service_id=49 ]
2022-06-16 15:30:10.168 2553-7870/? I/NearbyUWB: Local UWB address is 0X6C8A [CONTEXT service_id=49 ]
2022-06-16 15:30:10.168 2553-7870/? I/NearbyUWB: Opens UWB session with bundle parameters: [CONTEXT service_id=49 ]
2022-06-16 15:30:10.168 2553-7870/? I/NearbyUWB: UWB parameter: aoa_result_request, value: 1 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.168 2553-7870/? I/NearbyUWB: UWB parameter: range_data_ntf_proximity_near, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.168 2553-7870/? I/NearbyUWB: UWB parameter: is_tx_adaptive_payload_power_enabled, value: false [CONTEXT service_id=49 ]
2022-06-16 15:30:10.168 2553-7870/? I/NearbyUWB: UWB parameter: rframe_config, value: 3 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.168 2553-7870/? I/NearbyUWB: UWB parameter: max_ranging_round_retries, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.169 2553-7870/? I/NearbyUWB: UWB parameter: psdu_data_rate, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.169 2553-7870/? I/NearbyUWB: UWB parameter: fcs_type, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.169 2553-7870/? I/NearbyUWB: UWB parameter: device_role, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: device_type, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: block_stride_length, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: prf_mode, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: slot_duration_rstu, value: 2400 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: protocol_version, value: 1.1 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: slots_per_ranging_round, value: 6 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: vendor_id, value: [7, 8] [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: ranging_interval_ms, value: 240 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: dest_address_list, value: [-281474976710656] [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: sfd_id, value: 2 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: num_of_msrmt_focus_on_range, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: channel_number, value: 5 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: session_priority, value: 50 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: is_key_rotation_enabled, value: false [CONTEXT service_id=49 ]
2022-06-16 15:30:10.170 2553-7870/? I/NearbyUWB: UWB parameter: sts_config, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.171 2553-7870/? I/NearbyUWB: UWB parameter: num_of_msrmt_focus_on_aoa_elevation, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.171 2553-7870/? I/NearbyUWB: UWB parameter: in_band_termination_attempt_count, value: 3 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.171 2553-7870/? I/NearbyUWB: UWB parameter: range_data_ntf_proximity_far, value: 20000 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.171 2553-7870/? I/NearbyUWB: UWB parameter: bprf_phr_data_rate, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.171 2553-7870/? I/NearbyUWB: UWB parameter: sts_length, value: 1 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.171 2553-7870/? I/NearbyUWB: UWB parameter: initiation_time_ms, value: 100 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.172 2553-7870/? I/NearbyUWB: UWB parameter: aoa_type, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.172 2553-7870/? I/NearbyUWB: UWB parameter: has_time_of_flight_report, value: true [CONTEXT service_id=49 ]
2022-06-16 15:30:10.172 2553-7870/? I/NearbyUWB: UWB parameter: has_angle_of_arrival_figure_of_merit_report, value: false [CONTEXT service_id=49 ]
2022-06-16 15:30:10.172 2553-7870/? I/NearbyUWB: UWB parameter: has_angle_of_arrival_azimuth_report, value: false [CONTEXT service_id=49 ]
2022-06-16 15:30:10.173 2553-7870/? I/NearbyUWB: UWB parameter: mac_address_mode, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.173 2553-7870/? I/NearbyUWB: UWB parameter: preamble_duration, value: 1 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.173 2553-7870/? I/NearbyUWB: UWB parameter: key_rotation_rate, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.174 2553-7870/? I/NearbyUWB: UWB parameter: bundle_version, value: 1 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.174 2553-7870/? I/NearbyUWB: UWB parameter: has_angle_of_arrival_elevation_report, value: false [CONTEXT service_id=49 ]
2022-06-16 15:30:10.174 2553-7870/? I/NearbyUWB: UWB parameter: static_sts_iv, value: [1, 2, 3, 4, 5, 6] [CONTEXT service_id=49 ]
2022-06-16 15:30:10.174 2553-7870/? I/NearbyUWB: UWB parameter: range_data_ntf_config, value: 1 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.174 2553-7870/? I/NearbyUWB: UWB parameter: ranging_round_usage, value: 2 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.174 2553-7870/? I/NearbyUWB: UWB parameter: protocol_name, value: fira [CONTEXT service_id=49 ]
2022-06-16 15:30:10.174 2553-7870/? I/NearbyUWB: UWB parameter: has_result_report_phase, value: true [CONTEXT service_id=49 ]
2022-06-16 15:30:10.175 2553-7870/? I/NearbyUWB: UWB parameter: device_address, value: 7821063702882287616 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.175 2553-7870/? I/NearbyUWB: UWB parameter: measurement_report_type, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.175 2553-7870/? I/NearbyUWB: UWB parameter: preamble_code_index, value: 9 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.176 2553-7870/? I/NearbyUWB: UWB parameter: session_id, value: 1832243397 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.176 2553-7870/? I/NearbyUWB: UWB parameter: multi_node_mode, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.176 2553-7870/? I/NearbyUWB: UWB parameter: num_of_msrmt_focus_on_aoa_azimuth, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.176 2553-7870/? I/NearbyUWB: UWB parameter: hopping_mode, value: 0 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.177 2553-7870/? I/NearbyUWB: UWB parameter: sts_segment_count, value: 1 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.177 2553-7870/? I/NearbyUWB: exec UWB operation Open session [CONTEXT service_id=49 ]
2022-06-16 15:30:10.180 3382-31216/? V/UwbService: DefaultSessionManager: Opening fira ranging
2022-06-16 15:30:10.181 775-775/? I/qorvo.uwb.FiraController: initNewTwrSession:FiraTwrSession{id: 1832243397, deviceType: CONTROLEE, deviceRole: RESPONDER, rangingRoundUsage: DS_TWR, multiNodeMode: UNICAST, deviceAddress: UwbAddress{address: [108, 138]}, destAddressList: [UwbAddress{address: [255, 255]}], initiationTimeMs: 100, slotDurationRstu: 2400, slotsPerRangingRound: 6, rangingBlockDurationMs: 240, blockStridingValue: 0, maxRangingRoundRetries: 0, isHoppingEnabled: false, isBlockStridingEnabled: false, sessionPriority: 50, rangingRoundControl: RangingRoundControl{hasResultReportPhase: true, measurementReportType: INITIATOR_TO_RESPONDER, hasDeferredMode: true}, inBandTerminationAttemptCount: 3, channelNumber: 5, preambleCodeIndex: 9, rframeConfig: SP3, prfMode: BPRF, preambleDuration: T64_SYMBOLS, sfdId: 2, stsSegmentCount: 1, psduDataRate: RATE_6M81, bprfPhrDataRate: RATE_850K, fcsType: CRC_16, isTxAdaptivePayloadPowerEnabled: false, aoaType: AZIMUTH, stsConfig: STATIC, subSessionId: 0, vendorId: [7, 8], staticStsIV: [1, 2, 3, 4, 5, 6], isKeyRotationEnabled: false, keyRotationRate: 0, aoaResultRequest: REQ_AOA_RESULTS, resultReportConfig: ResultReportConfig{hasTimeOfFlightReport: true, hasAngleOfArrivalAzimuthReport: false, hasAngleOfArrivalElevationReport: false, hasAngleOfArrivalFigureOfMeritReport: false}}
2022-06-16 15:30:10.181 775-775/? I/qorvo.uwb.FiraController: CheckTwrSessionFields
2022-06-16 15:30:10.181 775-775/? I/qorvo.uwb.IeeeUtils: GetPhyInfo
2022-06-16 15:30:10.182 775-775/? I/qorvo.uwb.NlSocket: SendAndAwaitResponse
2022-06-16 15:30:10.182 775-775/? I/qorvo.uwb.NlSocket: SendAndAwaitResponse: Read message
2022-06-16 15:30:10.182 775-775/? I/qorvo.uwb.IeeeUtils: SetChannel: Set channel to 5
2022-06-16 15:30:10.182 775-775/? I/qorvo.uwb.NlSocket: SendAndAwaitAck: Received ACK
2022-06-16 15:30:10.182 775-775/? I/qorvo.uwb.UwbIface: OnPreSessionOpen fira
2022-06-16 15:30:10.182 775-775/? I/qorvo.uwb.McpsUtils: SetRegion
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.NlSocket: SendAndAwaitAck: Received ACK
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: InitSession
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: CreateSessionStateMsg
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.NlSocket: SendAndAwaitAck: Received ACK
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: ConfigTwrSession
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: PutMainSessionParams
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: PutTimingsParams
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: PutBehaviorParams
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: PutRadioParams
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: PutAntennaParams
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: PutCryptoParams
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.FiraRegionUtils: PutReportParams
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.NlSocket: SendAndAwaitAck: Received ACK
2022-06-16 15:30:10.183 775-775/? I/qorvo.uwb.UwbIface: OnSessionChanged
2022-06-16 15:30:10.184 775-775/? I/qorvo.uwb.FiraController: setSessionCallback
2022-06-16 15:30:10.184 3382-11798/? D/UwbService: UwbRangingSession: Sending ranging opened callback
2022-06-16 15:30:10.186 2553-7872/? I/NearbyUWB: UWB session opened: 1832243397 [CONTEXT service_id=49 ]
2022-06-16 15:30:10.186 2553-7870/? I/NearbyUWB: exec UWB operation Start ranging [CONTEXT service_id=49 ]
2022-06-16 15:30:10.187 3382-31216/? V/UwbService: DefaultSessionManager: Starting session 4
2022-06-16 15:30:10.187 775-775/? I/qorvo.uwb.FiraController: startRangingSession
2022-06-16 15:30:10.187 775-775/? I/qorvo.uwb.UwbIface: OnPreSessionStart
2022-06-16 15:30:10.250 775-775/? I/qorvo.uwb.FiraRegionUtils: SubscribeCallback
2022-06-16 15:30:10.250 775-775/? I/qorvo.uwb.FiraRegionUtils: StartSession
2022-06-16 15:30:10.250 775-775/? I/qorvo.uwb.FiraRegionUtils: CreateSessionStateMsg
2022-06-16 15:30:10.254 775-775/? I/qorvo.uwb.NlSocket: SendAndAwaitAck: Received ACK
2022-06-16 15:30:10.254 775-775/? I/qorvo.uwb.UwbIface: OnSessionChanged
2022-06-16 15:30:10.255 3382-11798/? D/UwbService: UwbRangingSession: Sending ranging started callback
2022-06-16 15:30:10.256 2553-7872/? I/NearbyUWB: UWB ranging started [CONTEXT service_id=49 ]
2022-06-16 15:30:10.257 2553-7872/? I/NearbyUWB: Local UWB address is 0X6C8A [CONTEXT service_id=49 ]
2022-06-16 15:30:10.258 2553-7872/? I/NearbyUWB: Local UWB address is 0X6C8A [CONTEXT service_id=49 ]
2022-06-16 15:30:10.264 8141-8141/com.example.app I/UwbClientSessionScope: Started UWB ranging.
2022-06-16 15:30:10.308 3382-31216/? V/UwbService: FiraSessionsProxy: Fira TwrResult received for session 1832243397
2022-06-16 15:30:10.308 3382-11798/? D/UwbService: UwbRangingSession: Sending ranging result callback
2022-06-16 15:30:10.311 2553-7870/? I/NearbyUWB: UWB Ranging Data from peer 0XFFFF Status -1 [CONTEXT service_id=49 ]

It appears that part of the problem is that the Android side is using “Static STS” which I see referred to on FiRa but as we don’t want to pay $5000 for a spec, then it doesn’t help much:

At minimum, for a device to be FiRa Certified and display the FiRa Certified logo, the device must meet the FiRa-specified MAC and PHY Conformance Test Specifications and the MAC/PHY Interoperability Test Specification, including **static STS** parameters.

So how do we enable Static STS on the DWM3000?

We have also created an issue on the AndroidX Jetpack library asking for more information.

I found that the source code to the Qorvo Apple Nearyby demo from nearly a year ago includes the FiRa params, so it looks like a better bet: “Qorvo_Apple_Nearby_Interaction_Beta_release_1.0.0-1”.
No idea why the latest DWM3000 examples don’t include the FiRa params…

Of course the Apple demo uses “proprietary” NIQ libs, so no source to work out what it needs in terms of UWBConfig.
I got to the same point by ignoring the error from niq_configure_and_start_uwb and passing the full fira_config data from Android which in theory matches the Android FiraController trace of the settings.
Obviously not quite, as I get:

2022-06-23 16:39:15.329 3572-26074/? V/UwbService: FiraSessionsProxy: Fira TwrResult received for session 286331153
2022-06-23 16:39:15.330 3572-25348/? D/UwbService: UwbRangingSession: Sending ranging result callback
2022-06-23 16:39:15.332 2531-19922/? I/NearbyUWB: UWB Ranging Data from peer 0XFFFF Status -1 [CONTEXT service_id=49 ]

On the nRF side I see the error from _reportTask tracing, so at least it’s consistent…ly wrong.

Having worked out most of the structure we can at least get the Dst Addr / channel / preamble from the initial config and generate a packet->payload that matches what the NIQ library expects ( we can set sessionId / preamble / channel / num slots / slot duration / block duration / STS IV / dest addr ).
However even though the fira_config now matches what Android traces in the FiraController (apart from UWB_Init_Time_ms - hard code to 5 in NIQ and Android says 100), we are still seeing the Status -1 error on the Android side when it gets the Tx packet.

2022-06-25 10:27:22.289 3380-9436/? V/UwbService: FiraSessionsProxy: Fira TwrResult received for session 35684
2022-06-25 10:27:22.289 3380-2022/? D/UwbService: UwbRangingSession: Sending ranging result callback
2022-06-25 10:27:22.291 2542-14941/? I/NearbyUWB: UWB Ranging Data from peer 0X5194 Status -1 [CONTEXT service_id=49 ]

So we are out of ideas until someone from Qorvo who actually wrote the Android driver can tell us what Status -1 actually means!

It appears that the iOS has the same initial timeout error that just repeats, but perhaps rather than ignore the bad message it sends a timing response, whereas Android just has an error with no response.
Of course the code that creates the tx_frame is part of the pre-compiled libs, so no easy way of working out what is going wrong, although the packet data looks wrong after the Header IE.
So iOS start up:

Application: Nearby Interaction Beta
Target: DWM3000EVB + nRF52840DK
OS: FreeRTOS
Version: 1.0.0-220625
DW3XXX Device Driver Version 06.00.00
MAC: R8.2.3_E
ACCESSORY_RANGING_ROLE: Initiator
<info> app: Fast advertising.
<info> app: Connected
<info> app: Notification is enabled
<info> app: App requests accessory config data
<info> app: Sending config data len: 19
Tx: len 67 
 flag 1 
 delayed 18cfc1c 
 rx delay -1 
 rx timeout pac 0 
buff: 
49 2b d2 34 26 13 0 ff 18 
5a 8 8 8 8 8 8 8 
8 19 ee 0 0 fc d7 72 
7a 0 3f 93 52 27 ff eb 
38 d0 63 22 29 22 84 2d 
de 33 b9 20 73 74 19 5d 
95 17 57 af 7b 72 43 a7 
55 49 f5 c3 fa 9f 23 a7 

<info> app: Apple Start UWB tasks with address D2:34 with local addr: 5E:AF
Tx: no buff flag 1 
 delayed 198691c 
 rx delay -1 
 rx timeout pac 0 
Tx: len 67 
 flag 1 
 delayed 43a881c 
 rx delay -1 
 rx timeout pac 0 
buff: 
49 2b d2 34 26 13 0 ff 18 
5a 8 8 8 8 8 8 8 
8 19 ee 0 0 38 d8 72 
7a 0 3f 93 52 27 ff eb 
38 d0 63 22 29 22 84 2d 
de 33 b9 20 73 74 19 5d 
95 17 57 af 7b 72 43 a7 
72 bb 54 94 52 1d e8 6f 

{"TWR": {"R":0,"a16":"0x34d2","S":"ERR","D cm":0}}
Tx: no buff flag 1 
 delayed 445f51c 
 rx delay -1 
 rx timeout pac 0 
Rx: len 0 
 flags 202 
 ranging f3 
 pdoa 0 
data: 

Tx: no buff flag 1 
 delayed 45ccf1c 
 rx delay -1 
 rx timeout pac 0 
Tx: len 57 
 flag 1 
 delayed 4683c1c 
 rx delay -1 
 rx timeout pac 0 
buff: 
49 2b d2 34 26 13 0 ff 18 
5a 8 8 8 8 8 8 8 
8 19 ee 0 0 3c d8 72 
7a 0 3f f1 a0 6b 4f af 
a1 21 14 98 61 de 85 a6 
67 57 d3 75 e 36 36 95 
4c 21 f5 88 2c db 

The same TWR ERR, but it also sees an Rx frame.
Looking at the initial 67 byte packet, it looks like this, with the data looking strange after the IE header termination 1:

49 2b // 0010 1011 0100 1001
// 001 frame type = data 
// 1 security = enabled
// 0 frame pending = none
// 0 ack req = none
// 1 PAN id = compress
// 0 reserved
// 1 suppress seq no = true
// 1 IE present
// 10 dest addr mode = 16 bit
// 10 frame version
// 00 src addr mode = no src addr

57 ed // dest addr- 2

26 // security control 0010 0110
// 110 - security level = ENC-MIC-64 / data confidentiality / data auth / MIC len 8
// 00 - key identifier mode = determined implicitly
// 1 - frame counter suppression
// 0 - ASN in nonce
// 0 - Reserved

13 00  // IE header 0000 0000 0001 0011 
// 0010011 length = 19
// 00000000 = Element ID
// 0 Type = 0

ff 18 5a // Vendor OUI 
 8 8 8 8 8 8 8 8 - 11 byte vendor specific header IE
64 8b 0 0 // SessionId - 18

ae af 4f 34 // 32 bit counter? - 22
// end IE header

0 3f // IE header 0011 1111 0000 0000 - 26
// 0000000 length = 0
// 0111 1110 = Element id 0x7e = header termination 1
// 0 Type 0

e8 d4 // Payload IE 1101 0100 1110 1000 - 28  // hack 1000 0000 0010 0011
// 100 1110 1000 = length 1256 ???
// 1010 = Group Id Reserved ???
// Type = 1

a4 e0 3e 1b
65 d8 9d a6 b5 37 e4 c5
58 d5 b8 68 10 6 c8 4a 
a8 74 8e 23 c5 60 25 

2a 76 42 ea 55 db e9 d6 // changing every Tx - 57 

I really hope someone from Qorvo actually reads this forum…

I did not try Qorvo with Google Pixel, but I can confirm I was able to use the Nearby Interaction example from Qorvo to do a manual FiRa ranging in between 2 Qorvo devices :slight_smile:

The trick is to manually fill the “struct fira_device_configure_s” and then manually start the Controller or Controlee.

see “construct_fira_param_from_config()”

  1. working parameters set you can get from debugging with iPhone and pausing the accessory (responder) on the line fira_helper_controllee()…

here you can get the example values of struct fira_param.

  1. what I did next is to configure the accessory manually to start it as a Controller and I was using the “Listener 1” application from XR6.0C to sniff the RCM packets.

@meavydev FiRa Payload IE are encoded.

@meavydev

I think the problem is that using both the Estimote UWB beacons and the Qorvo EVB Apple Nearby demo need to use the super secret initialisation process, which I have mostly worked out the data, but Android needs the Static STS IV and Vendor ID as well as a session Id.
Given the errors on the Android side, it appears that either the STS IV / Session Id or both are wrong, so when the ranging packet arrives on the Android side it gives an error.
However working out what it doesn’t like is not easy given the complete lack of tracing detail from the Qorvo driver and the complete lack of any response from Qorvo. Almost like they don’t care about supporting UWB.

vUpper64 = StaticStsIV followed by vendorID

I do not remember the order, but VUpper64 ia an array of 8;

StaticSTS -array of 6
VendorID array of 2.

For the start Set them to 0 and that is it.

Look to the structure i gave you - you can see SessionID, and the above.

I agree with you that Qorvo should release an example for Android, no questions, but afaik the issue is an initial BLE handshake. Apple defined that pretty well!

I have set them all to zero (including the session Id) and still the error from Android:
2022-07-26 10:17:32.311 768-768/? W/qorvo.uwb.NlSocket: ReceiveMessage: Error reading message: Try again
As far as Apple goes, I have yet to find anything in their documentation that describes the format other than:

|AppleUWBConfigData|Bytes|Variable length|Parameter selection intended to be consumed by the UWB middleware.|
So not exactly well defined.

The Bluetooth incoming data is in this format:
// 0x01, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Fixed data
// 0x13, // configLen - 15

// 0x01, 0x00, 0x00, 0x00, 0x3f, 0xf5, 0x03, 0x00, 0xb8, // Fixed data
// 0x0b, 0x00, // Preamble - 25
// 0x00, 0x01, 0x09, // Fixed Data
// 0x09, 0x00, // Channel - 30
// 0x01,
// 0x7c, 0xd2, // Dest Addr - 33

So we get the Preamble / Channel / Dest Addr from the Bluetooth data.

The outgoing Bluetooth packet data is in this format:
// Android timings
val packetPayload = byteArrayOf(
0x01, 0x00, 0x00, 0x00, 0x17, 0x45, 0x55, // Fixed data
0x11.toByte(), 0x22.toByte(), 0x00, 0x00, // SessionID - 7
0x0b, // preamble - 11
0x09, // channel - 12
0x06, 0x00, // num slots - 13
0x60, 0x09, // slot duration - 15
0xf0.toByte(), 0x00, // block duration - 17
0x03, Fixed Data
0x11.toByte(), 0x22.toByte(), 0x33.toByte(), 0x44.toByte(), 0x55.toByte(), 0x66.toByte(), // STS IV - 20
0x46, 0x59.toByte(), // SRC_ADDR - 26
)
If you have somewhere that documents the AppleUWBConfigData then feel free to point me at it, as we have Apple Developer Accounts as well as Android.