Merge pull request #10666 from ARMmbed/feature-nrf52-sdk15

Nordic SDK v15 Update
pull/10694/head
Martin Kojtal 2019-05-28 09:48:44 +01:00 committed by GitHub
commit 19e762298f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
856 changed files with 127303 additions and 81764 deletions

View File

@ -223,14 +223,9 @@ void CordioHCIDriver::handle_reset_sequence(uint8_t *pMsg)
} break;
case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN:
/* send next command in sequence */
HciReadLocalVerInfoCmd();
break;
case HCI_OPCODE_READ_LOCAL_VER_INFO:
if (hciCoreCb.extResetSeq) {
/* send first extended command */
(*hciCoreCb.extResetSeq)(pMsg, opcode);
HciReadLocalVerInfoCmd();
} else {
/* initialize extended parameters */
hciCoreCb.maxAdvDataLen = 0;
@ -242,6 +237,7 @@ void CordioHCIDriver::handle_reset_sequence(uint8_t *pMsg)
}
break;
case HCI_OPCODE_READ_LOCAL_VER_INFO:
case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN:
case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS:
case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE:

View File

@ -55,7 +55,8 @@ public:
* packet, ACL packet or EVT packet. Depending on the type of transport
* it can prefix the packet itself.
* @param len Number of bytes to transmit.
* @param pData pointer to the data to transmit.
* @param pData Pointer to the data to transmit. This is an WSF buffer
* and if CORDIO_ZERO_COPY_HCI is enabled we receive ownership.
*
* @return The number of bytes which have been transmited.
*/

View File

@ -68,8 +68,12 @@ void hciTrSendAclData(void *pContext, uint8_t *pData)
/* transmit ACL header and data */
if (hciDrvWrite(HCI_ACL_TYPE, len, pData) == len)
{
/* free buffer */
hciCoreTxAclComplete(pContext, pData);
#if CORDIO_ZERO_COPY_HCI
/* pData is not freed as the hciDrvWrite took ownership of the WSF buffer */
#else
/* free buffer */
WsfMsgFree(pData);
#endif // CORDIO_ZERO_COPY_HCI
}
}
@ -80,7 +84,7 @@ void hciTrSendAclData(void *pContext, uint8_t *pData)
*
* \brief Send a complete HCI command to the transport.
*
* \param pData WSF msg buffer containing an HCI command.
* \param pData WSF msg buffer containing an HCI command. WSF buffer ownership is released by this function.
*
* \return None.
*/
@ -98,8 +102,12 @@ void hciTrSendCmd(uint8_t *pData)
/* transmit ACL header and data */
if (hciDrvWrite(HCI_CMD_TYPE, len, pData) == len)
{
/* free buffer */
WsfMsgFree(pData);
#if CORDIO_ZERO_COPY_HCI
/* pData is not freed as the hciDrvWrite took ownership of the WSF buffer */
#else
/* free buffer */
WsfMsgFree(pData);
#endif // CORDIO_ZERO_COPY_HCI
}
}

View File

@ -0,0 +1,55 @@
{
"name": "cordio-ll",
"config": {
"max-advertising-sets": {
"help": "Maximum number of advertising sets.",
"value": 4
},
"max-advertising-reports": {
"help": "Maximum number of pending legacy or extended advertising reports.",
"value": 8
},
"default-extended-advertising-fragmentation-size": {
"help": "Default extended advertising data fragmentation size.",
"value": 64
},
"max-scan-request-events": {
"help": "Maximum scan request received events.",
"value": 4
},
"phy-2m-support": {
"help": "2M PHY supported.",
"value": 1
},
"rx-buffers": {
"help": "Default number of receive buffers.",
"value": 8
},
"phy-coded-support": {
"help": "Coded PHY supported.",
"value": 0
},
"extended-advertising-size": {
"help": "Maximum extended advertising data (and scan data response) size",
"value": 128
},
"max-acl-size": {
"help": "Maximum ACL buffer size",
"value": 256
},
"tx-buffers": {
"help": "Default number of send buffers",
"value": 8
},
"handle-vendor-specific-hci-commands": {
"help": "Handle VS HCI commands. Valid values are 0 (ignore) and 1 (handle).",
"value": 0,
"macro_name": "LHCI_ENABLE_VS"
},
"uart-hci": {
"help": "Does the board have a UART HCI. Valid values are 0 and 1 (must provide UART through PAL).",
"value": 0,
"macro_name": "CHCI_TR_UART"
}
}
}

View File

@ -0,0 +1,543 @@
Cordio Link Release Notes
=========================
Legal
-----
Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved.
Arm Ltd. confidential and proprietary.
Compliance
----------
This release complies with the Bluetooth Core.TCRL.2018-2 definitions using the following test
specification versions:
* LL.TS.5.1.0, Link Layer (LL) Bluetooth Test Specification
* HCI.TS.5.1.0, Host Controller Interface (HCI) Bluetooth Test Specification
Compliance is verified with the Ellisys EBQ compliance tester using the following version:
* EBQ 2017-2.6969
Note : The following test cases will fail because of tester issue : Sync packet offset calculation is wrong in LL_PERIODIC_SYNC_IND PDU when offset_adjust field is 1.
LL/CON/MAS/BV-99-C, LL/CON/MAS/BV-100-C, LL/CON/MAS/BV-101-C, LL/CON/SLA/BV-103-C, LL/CON/SLA/BV-104-C, LL/CON/SLA/BV-105-C
Compliance is verified with the Harmony compliance tester using the following version:
* 19.1.16916.18388
Changes
-------
The following changes were made in r19.02
Enhancements in this release:
WBUSW-2402 MEP16 Allow ADI field to be optional in the AUX_SCAN_RSP
WBUSW-2938 Enable ADI field by default in the AUX_SCAN_RSP after Madrid spec is adopted
WBUSW-3108 Update HCI definition and LL definition to conform Madrid spec
WBUSW-3139 CIS master needs to send additional ack if there is still subevent
WBUSW-3144 PAST implementation update for Madrid version r15
WBUSW-3193 Add support of adjusting CIS offset in the LL_CIS_RSP on the CIS slave
WBUSW-3195 Add support of multiple CIS streams phase I
WBUSW-3203 Add op flag for CIS master to skip sending additional NULL PDU
WBUSW-3208 LE Extended Advertising Enable returns incorrect status when no scan response data provided
WBUSW-3227 MEP9 HCI support for debug keys in LE Secure Connections
WBUSW-3228 Add Opflag to optionally include/exclude advertising address in AUX_ADV_IND PDU
WBUSW-3229 Add opflag to include/exclude the ADI field in AUX_SCAN_RSP
WBUSW-3242 Add test command LE Modify Sleep Clock Accuracy command
WBUSW-3256 Add support of multiple CIS stream phases II
WBUSW-3258 Add test command to change the advertising address in AUX_CONNECT_RSP
WBUSW-3261 Update window widening calculation algorithm
WBUSW-3268 Add support of verifying connection parameter update on the slave when the instance is the current connection event
WBUSW-3279 Add check for HCI_LE_Periodic_Adv_Enable
WBUSW-3281 Add check for HCI_LE_Extended_Create_Connection
WBUSW-3292 Add support of multiple CIS streams phase III
WBUSW-3324 Update LL_CIS_EST_EVT to spec version 18a
WBUSW-3327 Update HCI_SET_CIG_PARAMETER to spec version 18a
WBUSW-3331 Update LL_CIS_REQ PDU to spec version 18a
WBUSW-3333 Add support of checking if random address is initialized for some HCI command
WBUSW-3348 Add interleaved packing scheme for multiple CISs
Resolved defects in this release:
WBUSW-2981 Connection fails to be established with coded phy when connection interval is smaller than 30ms
WBUSW-3080 HCI_LE_Periodic_Advertising_Sync_Established event has wrong info in it
WBUSW-3103 LL_PERIODIC_SYNC_IND PDU has wrong info in it
WBUSW-3119 One variable size definition is incorrect
WBUSW-3120 CIS slave sometime transmits at the incorrect timing
WBUSW-3141 ACL sometimes gets lost when CIS is present
WBUSW-3142 CIS crashes sometimes when doing uni-directional data transfer
WBUSW-3154 Flush scheme sometimes doesn't work correctly on the slave when RX timeout happens
WBUSW-3167 Advertiser cannot handle connection indication with connection interval of 0
WBUSW-3177 Return incorrect error code when creating connection with invalid interval
WBUSW-3199 Sometime CIS bod is incorrectly terminated twice on master or slave
WBUSW-3206 Sometimes there is memory leak for the CIS master Rx operation
WBUSW-3213 HCI_LE_Periodic_Advertising_Sync_Transfer_Received event is sent too early
WBUSW-3216 CIS link drops when CIS bod can't be executed in time
WBUSW-3218 Wrong address type in the LL_PERIODIC_SYNC_IND PDU when address is RPA
WBUSW-3219 Local RPA sometimes is incorrect for the enhanced connection complete event
WBUSW-3222 ADV_SCAN_IND is not using RPA for advertising address when local IRK is provided
WBUSW-3235 Failed to create sync with RPA address
WBUSW-3260 Not enough memory for PCA10040 with large periodic advertising data size
WBUSW-3262 High duty cycle connectable directed advertising shall use fixed sequential channels for primary advertising operation
WBUSW-3280 Wrong address type in LE_PER_ADV_SYNC_TRANS_REC_EVT when RPA address is used
WBUSW-3291 Seeing unexpected periodic advertising sync lost event
WBUSW-3295 HCI_Reset is not completed when periodic sync transfer is pending
WBUSW-3304 Incomplete Periodic Advertising Report event is received
WBUSW-3306 Assertion error when dynamically update extended advertising data
WBUSW-3307 Tx PDU sometimes is not cleaned up correctly after it is being flushed on CIS slave
WBUSW-3314 Failed to disable advertising for multiple advertising sets
WBUSW-3338 Flush scheme doesn't work for the second CIS in sequential packing scheme with multiple CIS.
WBUSW-3363 Buffer is not freed correctly sometimes when restarting advertising
WBUSW-3369 Command complete event for scan disable is received too late in some cases
WBUSW-3376 IUT receives incorrect status for LE_Periodic_Advertising_Sync_Transfer_Received event
WBUSW-3418 Connection update with invalid handle returns incorrect status
WBUSW-3420 HCI_LE_Set_PHY with invalid handle returns invalid status
WBUSW-3423 HCI LE Set Data Length with invalid handle returns incorrect status
WBUSW-3451 CIS slave sometimes fails to receive
WBUSW-3479 There is unused value in the code
WBUSW-3505 Intermittent periodic sync lost when PAST transfer happens back to back
WBUSW-3511 Scheduling conflict between AUX ADV and periodic ADV is not handled correctly
Known limitations in this release:
WBUSW-3183 Scanner fails to receive scan request intermittently when scan interval and scan window are same
WBUSW-3367 Primary scan fails to receive ADV packets intermittently when 6 periodic scan is ongoing with maximum periodic data size
Incomplete features in this release:
None
Change History
--------------
Changes in r18.11
WBUSW-2025 Madrid - Periodic Advertising Sync Transfer
WBUSW-2026 Madrid - Control Length Extension
WBUSW-2401 [MFE] MEP12 Add sleep clock accuracy update machanism
WBUSW-2816 Add functionality to pack ACAD field for TX
WBUSW-2817 Add functionality to parse ACAD field for rx
WBUSW-2818 Add ACAD structure for channel map
WBUSW-2835 Reservation manager enhancement to support common interval
WBUSW-2907 Optimize ACAD skip
WBUSW-2925 Add new test command to set trigger tx mode and invalid CRC init at the same time
WBUSW-2927 [MFE] MEP21 Host channel classification for secondary advertising
WBUSW-2983 Modify BbTesterSetInvalidAccessAddress() to support changes in TSE 10530
WBUSW-3044 Need to add timeout event for CIS LLCP procedure
WBUSW-3054 Update HCI_SET_CIG_PARAM command
WBUSW-3081 Add support of encryption for CIS
WBUSW-3082 Add support of MIC failure in the CIS state machine
WBUSW-3095 PAST commands are updated to swap connection handle and sync handle
WBUSW-3108 Update HCI def and LL def to Madrid spec
WBUSW-2339 [ESR11] Avoid adding duplicate address to the white list
WBUSW-2429 Active extended scanning sometimes delivers incorrect advertising report
WBUSW-2756 Failed to establish connection with the second device in multi-connection role
WBUSW-2796 IUT supporting symmetric PHY responds with incorret error code when UT sends HCI LE SET PHY with asymmetric parameters
WBUSW-2806 Incorrect error code for LE set extended advertising enable command when scannable adv pdu is set
WBUSW-2821 Controller sometimes crashes when enabling periodic advertising
WBUSW-2838 AUX_CHAIN_IND incorrectly includes ADI field if corresponding field in PDU pointed to this PDU is not present
WBUSW-2839 Advertising DID is not updated correctly whenever host provides new scan response data
WBUSW-2863 AUX_ADV_IND doesn't get updated when there is a change for the advertising data
WBUSW-2866 TesterSetTxAuxReqPdu() command is not implemented in the LL
WBUSW-2882 Controller fails to execute connection BOD when connection BOD collides with advertising BOD
WBUSW-2887 No data observed in ae directed or undirected connectable advertisements
WBUSW-2918 Extended advertiser sometimes doesn't include advertising data in the connectable advertising packet
WBUSW-2921 Aborting slave latency doesn't work when ACL data arrives at channel map update instance
WBUSW-2922 Periodic scanner incorrectly updates the anchor point when receiving a packet with CRC error
WBUSW-2926 Reservation manager returns wrong offset when BB_CLK_RATE_HZ is not 1M
WBUSW-3056 LE Set Periodic Adv Sync Transfer Param command returns incorrect status when wrong connection handle is provided
WBUSW-3060 HCI_Periodic_Adv_Terminate_Sync command does not return error when sync handle is invalid
WBUSW-3065 LE_PER_ADV_SYNC_TRANS_REC_EVT sometimes is not received in time
WBUSW-3079 Periodic interval is not correct in periodic advertising sync transfer received event
WBUSW-3085 Incorrect bits received in the channel selection algorithm event
WBUSW-3094 Sometimes the TX power for the extended advertising is too low
WBUSW-3105 Compiler warning when feature bit are more than 32 bits
WBUSW-3106 Tx power on the secondary channel for the 2018 nordic board is too low
WBUSW-3116 Corrupted Advertising reports are received when payload > 251
WBUSW-3147 With 2M, AUX_SCAN_RSP has wrong auxPtr value
WBUSW-3149 ADI field is sometimes 0 after setting periodic advertising data
WBUSW-3155 Failed to create connection with some connection interval when ACL connection is on coded PHY
WBUSW-3171 Incorrect assertion in scheduler when there is no hardware timer
WBUSW-3175 Slave sometimes fails to remove the advertising BOD
WBUSW-3180 Sometimes there is assertion error after cancelling the ACL connection establishment procedure
Changes in r2p4-00rel0.
WBUSW-2340 [ESR11] LL needs to return with error code of unsupported features if the txPhys or rxPhys in the set default PHY and set PHY
WBUSW-2341 [ESR11] LL needs to return unsupported features error code if the phys in the set extended adv parameter are not supported
WBUSW-2343 [ESR11] Scan response data length range
WBUSW-2344 [ESR11] Shall not allow removing adv set or clear adv sets when periodic advertising is enabled
WBUSW-2345 [ESR11] Filter_Duplicates when Duration is zero
WBUSW-2346 [ESR11] Return error code when there is no more resource to create periodic sync
WBUSW-2347 [ESR11] Some extended PDU shall not include Tx power level
WBUSW-2348 [ESR11] LL shall reject the control PDU with incorrect length with LL_UNKNOWN_RSP
WBUSW-2394 [ESR11] LL is recommended to change advertising DID when periodic advertising is enabled on a advertising set
WBUSW-2395 [ESR11] Periodic scanner shall terminate create sync procedure if the periodic event is not received within the first 6 periodic interval
WBUSW-2396 [ESR11] Add LL_FEAT_MIN_NUM_USED_CHAN to LCTR_FEAT_PEER_MASK
WBUSW-2476 [ESR11] LE Set Random Address, not allowed when advertising or scanning is enabled
WBUSW-2494 Advertising scheduling enhancement
WBUSW-2507 Scan BOD scheduling enhancement
WBUSW-2634 Add OpFlag to disable slave latency wakeup upon data pending.
WBUSW-2696 Core paring update - Validate the public key in LL
WBUSW-2732 Added runtime config to ignore timestamp with CRC-error packet
WBUSW-2223 HCI resets doesn't complete sometimes
WBUSW-2376 Connection complete event is missing when reservation manager is full
WBUSW-2383 Adjusted min duration for the scan operation to support simultaneous scanning for multiple phy
WBUSW-2413 Connection Interval is not a multiple of preferred periodicity
WBUSW-2414 [UPF59] Channel selection bit is not set to reserved in the aux_conn_req
WBUSW-2415 [UPF59] The scanA in the aux_scan_req is not the same as the targetA in the extended advertising packet
WBUSW-2418 [UPF59] Slave is not handling the extended reject indication after connection parameter response is sent.
WBUSW-2419 Slave abort slave latency incorrectly between the last CE with old connection parameter and the first instant with the connection parameter
WBUSW-2431 Disconnection happens when advertising event conflicts with connection event.
WBUSW-2435 Connection drops when ADV BOD runs over connection bod
WBUSW-2448 Channel selection method is not correct in the LL_CONNECT_IND when extended API is used
WBUSW-2449 Rx window opens too late for coded packets
WBUSW-2454 Delay in receiving HCI_ADV_REPORT_EVENT for multiple adv sets.
WBUSW-2460 Each extended advertising command is not returning "Command Disallowed" with no scan response data.
WBUSW-2461 Initiating LL_CONN_PARAM_REQ - Unsupported Without Feature exchange
WBUSW-2462 Initiate LL_CONN_PARAM_REQ when the feature is not supported
WBUSW-2480 Periodic scanner uses incorrect filter policy
WBUSW-2481 Incorrect values in HCI_LE_Data_Length_Change event
WBUSW-2496 Sync established event with status ERR_OP_CANCELLED_BY_HOST is not received when sync is cancelled
WBUSW-2512 HCI_LE_Set_PHY return status depends on connection established state
WBUSW-2517 Sending LL_AUX_CHAIN_IND earlier than the time indicated by the aux pointer offset
WBUSW-2522 order of receiving adv report event (with bit 1 and 2) and adv report event (with bit 3) is incorrect
WBUSW-2533 Scan on multiple PHYs sometimes is not working
WBUSW-2537 Cannot start three advertising sets with interval of 20ms.
WBUSW-2546 Periodic Interval calculation is not correct.
WBUSW-2547 [qual] Incorrect error code for invalid set phy command.
WBUSW-2556 Periodic advertising interval is calculated incorrectly when min_int equals max_int.
WBUSW-2629 Periodic scan minimum duration is too long.
WBUSW-2636 Missing ADV_EXT_IND packets when advertising interval is small (Ex. 20 ms)
WBUSW-2643 No data transmit when slave latency is applied during channel map update procedure
WBUSW-2700 Extended advertising state is incorrect when restarts
WBUSW-2705 Connectable extended adv is sending the truncated data.
WBUSW-2707 Assertion failures when simultaneous connection and scanning state
WBUSW-2711 Missing sync established event for the third periodic advertising set.
WBUSW-2718 Slave sometimes allows connection from the device with un-resolvable RPA.
WBUSW-2721 Coverity issues
WBUSW-2741 Sometimes extended scan on multiple PHY does not work
WBUSW-2756 Failed to establish connection with the second device in multi-connection role
WBUSW-2779 Sometimes miss advertising report events for multi-set and mixed role
Changes in r2p3-03rel0.
WBUSW-1820 LL frees the connect context incorrectly
WBUSW-2113 [EBQ] ADV Data ID should be different from the previous round
WBUSW-2126 Adjust scheduling priority for Periodic Advertising and Scanning
WBUSW-2128 Aux scan operation uses incorrect minimum and maximum scan duration
WBUSW-2185 [EBQ] Symmetric phys are not set correctly OTA
WBUSW-2199 Extended ADV report sometimes contains more than 1650
WBUSW-2216 [feat] Address is not refreshed when advertising with non-connectable events using RPA
WBUSW-2232 LLCP with instance should honor slave latency
WBUSW-2262 Wrong LE extended advertising report when RX error happens with AUX_CHAIN_IND
WBUSW-2283 llValidatePhyPreferences parameter size incorrect
WBUSW-2284 [EBQ] IUT should respond with Command Disallowed to an LE Set Random Address command when advertising or scanning is enabled
WBUSW-2287 Return incorrect status for the extended adv set termination event when extended API is used for the legacy high duty cycle connectable adv
WBUSW-2298 Multi-slave connection case, BOD due time is wrong when rescheduled because of conflict
WBUSW-2299 Slave doesn't wake up to Rx when slave latency is used and event counter wraps around
WBUSW-2311 AccessAddress should be unique in each connection for different device.
WBUSW-2316 [Qual] AdvA in AUX_ADV_IND on coded phy should be reserved with event type 0x0000
WBUSW-2318 [Qual] "Unused" parameter is incorrect from LE Periodic Advertising Report Event
WBUSW-2333 doxigen fixes for LL
WBUSW-2362 Check extended adv data length shall be done when extended adv is enabled
WBUSW-2367 Add support of extended scan on mulitple PHYs at the same time.
WBUSW-2370 Change the ceJitterDelay from 32us to 0us
WBUSW-2374 [FEAT] Connection dropped while connection update with multiple testers
WBUSW-2377 Add maximum connection event deviation to the calculation of CE window widening
WBUSW-2383 Adjust min duration for the scan operation to improve schedule for simultaneous operation at the same time.
WBUSW-2389 Change LL_MAX_PER_SCAN from 4 to 6 to pass qualification test
Changes in r2p3-02eac0.
WBUSW-1626 Reading Tx power levels should return actual power used
WBUSW-1709 AUX Offset field in AuxPtr sometimes violates MAFS (300-us)
WBUSW-1932 LE_EXT_ADV_REPORT_EVT event sometimes contains extra AdvData
WBUSW-1933 Establish connection may fail with status CONN_FAILED_TO_ESTABLISH (0x3e)
WBUSW-2019 LE_[Read|Write]_RF_Path_Compensation commands should use transceiver as reference
WBUSW-2035 Missing LE Advertising Set Terminated Event when AdvSet duration expires
WBUSW-2046 Fail to establish connection when PHY Options are different between two devices
WBUSW-2050 [EBQ] No LL_FEATURE_RSP when established connection as master with slave latency 5
WBUSW-2098 [EBQ] Disconnection Complete Event is received before supervision timeout
WBUSW-2127 Large gaps while scanning reduces opportunities to receive advertising packets
WBUSW-2140 Data Length Exchange should limit MaxRxTime and MaxTxTime with unsupported LE Coded PHY peers
WBUSW-2143 UPF58 vendor compatibility fixes
WBUSW-2147 Incorrect padding when aligning uint64_t on 8-byte boundary
WBUSW-2172 Fix the inaccuracy of the fast divisions
WBUSW-2173 Fixed unit test errors
WBUSW-2174 Use the fast division function when calculating the aux pointer offset
WBUSW-2175 Coded operation cannot sustain
WBUSW-2179 Fix ADV_BV_30 and ADV_BV_31
WBUSW-2181 Prevent multiplication overflow issue.
WBUSW-2186 Window Widening too small when there is unsync'ed time before a connection update
WBUSW-2197 Double TX done IRQ from PPL
WBUSW-2198 IUT as initiator should connect to devices using RPA when the address is resolvable
WBUSW-2202 Collision resolution sometimes fails with simultaneous PHY updates
WBUSW-2248 [nRF52] maxAdvReports adjusted based on RAM availability
Changes in r2p3-01eac0.
WBUSW-1289 Pended host connection or PHY update receives no update completion if parameters unchanged
WBUSW-1421 Slave may not complete HCI_LE_Connection_Update
WBUSW-1534 AdvData length limited to 31 bytes for Extended Connectable Advertising
WBUSW-1751 HCI_LE_Extended_Create_Connection with Coded PHY fails to establish with small CI
WBUSW-1937 Scanner sometimes sends incorrect LE_Extended_Advertising_Report
WBUSW-1953 Extended create connection sometimes connect to the incorrect peer device
WBUSW-1955 Scanner ignores SCAN_RSP/AUX_SCAN_RSP when the AdvA does not match SCAN_REQ/AUX_SCAN_REQ
WBUSW-1967 Extended scanner fails to filter anonymous advertising
WBUSW-1970 PDU filtering enables local address resolution when local address is public
WBUSW-1972 Scanner ignores SCAN_RSP and AUX_SCAN_RSP when the AdvA does not match SCAN_REQ/AUX_SCAN_REQ
WBUSW-1996 Incorrect Peer_Address when High Duty Cycle Directed Advertising times out
WBUSW-2041 TesterSendConnUpdInd command does not set ConnInterval
WBUSW-2053 MediaTek interoperability with Connection Parameter Update Procedure
WBUSW-2089 Incorrect timing for AUX_CHAIN_IND packet with Coded PHY
WBUSW-2096 Extended advertiser sends incorrect AuxPtrOffset in AUX_SCAN_RSP
WBUSW-2112 [EBQ] Should not send Command Disallowed when disabling an advertising set which is already disabled
WBUSW-2125 Incorrect initialization of Channel Selection 1 with master role only
Changes in r2p3-00eac0.
WBUSW-456 Slave with latency should transmit queued data in next CE
WBUSW-1717 LE_Extended_Advertising_Report may not send complete periodic reports
WBUSW-1762 Disconnect_Complete with reason connection timeout while updating PHY
WBUSW-1835 LE_Enhanced_Connection_Complete may incorrectly report Peer_Address as 0
WBUSW-1841 Periodic advertising report should send in task context
WBUSW-1850 Periodic advertising sometimes starts long time later
WBUSW-1854 Extended Advertising Set sometimes not terminated with Coded PHY
WBUSW-1856 Scanner cannot receive anonymous non-connectable non-scannable adv packet with auxiliary packet
Changes in r2p2-00bet0.
WBUSW-1283 Extended advertising and scanning resolves private addresses
WBUSW-1489 BLE5 - Synchronized scanning
WBUSW-1591 Improve device interoperability with LENGTH_REQ startup collisions
WBUSW-1602 Do not send extended advertising reports in ISR
WBUSW-1641 Coordinate Periodic Advertising operations with Reservation Manager
WBUSW-1662 LE_Extended_Advertising_Report reassembles data fragments
WBUSW-1663 SCH_CHECK_LIST_INTEGRITY option for all scheduler insertions
WBUSW-1677 Reduce execution time of LctrRxAcl()
WBUSW-1678 Cannot update the DID when advertising
WBUSW-1682 Architecture-based folder organization
WBUSW-1685 LE_Set_PHY while length procedure in progress may not complete
WBUSW-1695 Add support of simultaneous scan and initiate using the extended API
WBUSW-1724 UPF57 vendor compatibility fixes
WBUSW-1750 Optimize calculation of advertising operation duration
WBUSW-1754 Allow handling the chain packet if scan is not disabled
WBUSW-1773 Cross-Protocol project interface for all platform components
WBUSW-1792 Controller projects uses maximum AdvData size of 1650
WBUSW-1844 Dedicated extended and periodic advertising data
WBUSW-1329 LE_Read_Tx_Power handled in AE slave command handler
WBUSW-1407 LLCP procedure does not reject already pended or active procedures
WBUSW-1511 HCI_Reset timeouts in extended scanning state
WBUSW-1532 Extended ADVB PDUs use incorrect RxAdd
WBUSW-1537 HCI_Reset sometimes does not respond with command completion after disconnect
WBUSW-1545 Extended advertising should allow legacy high duty cycle connectable direct advertising
WBUSW-1567 LE_Extended_Advertising_Report sometimes sends duplicate events when filter is enabled
WBUSW-1577 WSF_MIN() / WSF_MAX() multiple evaluation
WBUSW-1599 HCI_Reset timeouts in extended initiating state
WBUSW-1600 An unknown private device should not be filtered
WBUSW-1601 LL should not modify Suggested Default Data Length value
WBUSW-1623 BB should not specify an invalid BbBleDrvTxBufDesc_t::pBuf
WBUSW-1629 bbGetTxData() use in example code may corrupt memory
WBUSW-1630 LE_Extended_Advertising_Report truncate AdvData with 2M_PHY
WBUSW-1631 AuxPtr::offset contains invalid value in first EXT_ADV_IND packet
WBUSW-1634 Invalid BB state when BB driver calls callback with failure
WBUSW-1638 HCI_LE_Extended_Create_Connection should allow initiating with 2M PHY
WBUSW-1640 LE_Extended_Advertising_Report sometimes corrupted when receiving AUX_CHAIN_IND
WBUSW-1645 HCI_LE_Extended_Create_Connection cannot establish connection with large Auxiliary Frame Spacing
WBUSW-1649 Failed HCI_LE_Set_Random_Address should not modify state
WBUSW-1650 HCI_LE_Extended_Create_Connection should be rejected if already in progress
WBUSW-1657 Extended advertiser sometimes allows connections with non-matching AdvA
WBUSW-1659 Address resolution sometimes fails to resolve
WBUSW-1660 Extended connection sometimes established with wrong PHY
WBUSW-1661 Master uses incorrect fast termination timeout with Extended Create Connection
WBUSW-1664 Paring fails with legacy advertisers using directed advertising
WBUSW-1665 Initialization sequence should initialize handlers before using them
WBUSW-1666 Extended scanner does not update parameters when already in progress
WBUSW-1668 HCI_LE_Set_Extended_Advertising_Parameters returns incorrect error code when memory is exceeded
WBUSW-1672 LE_Extended_Advertising_Report may use incorrect Data_Length
WBUSW-1687 HCI_LE_Set_Extended_Scan_Enable sometimes does not complete
WBUSW-1688 Some LLCP collision cases fail to complete
WBUSW-1689 LE_Set_Extended_Advertising_Enable does not adhere to duration limits for high duty cycle directed advertising
WBUSW-1711 LE_Extended_Advertising_Report may use incorrect values in truncated report
WBUSW-1716 Maximum data PDU length doesn't support 251 bytes in Coded PHY
WBUSW-1729 HCI_Reset fails after LE_Extended_Create_Connection command is canceled
WBUSW-1740 Periodic scanner sometimes loses sync with the periodic advertiser
WBUSW-1745 Improve diversity with auxiliary channel selection
WBUSW-1747 HCI_LE_Set_Extended_Advertising_Parameters uses incorrect error code with invalid Primary_Advertising_Interval
WBUSW-1753 Coded PHY connections may disconnect
WBUSW-1766 Failed to enable extended advertising on multiple sets
WBUSW-1774 Connection may not establish due to PDU filtering
WBUSW-1802 Extended advertiser sometimes incorrectly filters AUX_SCAN_REQ
WBUSW-1803 LT does not modify AUX_CONN_REQ
WBUSW-1805 Extended initiator cannot establish with Coded PHY
WBUSW-1810 Periodic scanner may lose sync with the periodic advertiser
Changes in r2p1-00eac0.
WBUSW-840 Simultaneous initiate and scan state
WBUSW-1077 Validate static random address from host
WBUSW-1135 Extended scanning on multiple PHYs
WBUSW-1391 Improve compatibility when peer incorrectly responds to unknown packets during encryption procedure
WBUSW-1408 Separate auto-start feature exchange Op Mode flag
WBUSW-1422 Improve interoperability with masters that send initial LLCP
WBUSW-1432 [nRF52] Driver supports BB_PHY_BLE_CODED PHY type
WBUSW-1433 [nRF5x] Update platform to nRF5 SDK revision 13.0.0 alpha
WBUSW-1447 Add extended advertising statistics
WBUSW-1488 BLE5 - Periodic Advertising
WBUSW-1490 BLE5 - Stable modulation index
WBUSW-1519 Compute packet duration for all extended BOD operations
WBUSW-1541 Allow ADV_DIRECT_IND high duty cycle with extended advertising API
WBUSW-1558 UPF56 vendor compatibility fixes
WBUSW-1561 Use runtime configuration to configure PHY features
WBUSW-1562 Improve interoperability by defaulting length extension to minimum
WBUSW-733 Enabling scan while scan enabled does not change filter duplicates
WBUSW-1180 Feature exchange only valid controller to controller bits
WBUSW-1366 [nRF52] RF Compensation does not dynamically adjust
WBUSW-1387 [nRF5x] BbBleRfGetSupTxPower() should report power referenced at the antenna
WBUSW-1405 Minimum advertising interval is BT version dependent
WBUSW-1409 Connection sometimes fails with 32KHz BB clock
WBUSW-1416 LT cannot start auxiliary channel exactly at MAFS
WBUSW-1445 Reset may not complete after HCI_Clear_Advertising_Sets
WBUSW-1485 Failed to receive the CONNECT_IND with the random address and extended advertising
WBUSW-1495 IUT in extended legacy advertising mode does not respond to SCAN_REQ
WBUSW-1502 LE_Enhanced_Connection_Complete event may contain incorrect peer address
WBUSW-1508 [nRF52] Long range operation is sometimes unstable
WBUSW-1509 Extended advertiser does not report legacy SCAN_REQ with Scan_Request_Notification_Enable
WBUSW-1517 Remove lhciPackEvtHdr() redundant definition
WBUSW-1518 Path compensation API organized with device management
WBUSW-1538 Master may fail to establish connection with short connInterval
WBUSW-1543 Fail to locate the correct resolving list entry when local IRK is the same for the entries
WBUSW-1560 Example LL initialization does not set extended feature bits
WBUSW-1563 Incorrect Adv filtering when AdvA is not resolved and white list filtering is enabled
WBUSW-1564 Connection sometimes fails if CONNECT_IND does not match ADV_DIRECT_IND's InitA
WBUSW-1582 RF Path Compensation example code incorrectly stores values
WBUSW-1585 AUX Offset is incorrect between AUX_SCAN_RSP and AUX_CHAIN_IND in 2M and Coded PHY
WBUSW-1587 Incorrect TxWindowDelay with 2M or Coded PHY
WBUSW-1628 Extended advertiser sometimes does not respond to SCAN_REQ
Changes in r2p0-10eac0.
WBUSW-438 BLE5 - LE Coded PHY
WBUSW-841 Simultaneous initiate and connectable advertising
WBUSW-1057 BLE5 - Minimum Used Channels
WBUSW-1058 BLE5 - LE Privacy 1.2.1
WBUSW-1103 BLE5 - White list anonymous advertisers
WBUSW-1128 BLE5 - Extended Scanning
WBUSW-1130 BLE5 - RF Path Compensation
WBUSW-1147 Extended Advertising should limit maximum interval
WBUSW-1148 Centralized reset logic
WBUSW-1150 BLE5 - Read Transmit Power
WBUSW-1187 Core IOP fixes - San Diego
WBUSW-1196 Add BSP_DIR command line override option for Nordic platform builds
WBUSW-1197 Allow Makefile command line override BAUD value for Nordic platform
WBUSW-1199 Consistent logic for validating connection parameters
WBUSW-1238 Extended advertising LT VS commands
WBUSW-1273 Add maximum request length to pool statistics
WBUSW-1292 Set local default maxTx to be the largest (251)
WBUSW-1312 BLE5 - LE Extended Create Connection
WBUSW-1323 BLE5 - Shanghai r10 HCI commands and events
WBUSW-1324 Return error if random address required but not initialized
WBUSW-1351 Nordic PCA10040 LEDs displays Tx PHY state
WBUSW-1385 LL_OP_MODE_FLAG_ENA_LLCP_STARTUP includes slave initiated feature request
WBUSW-1392 Do not allow mixed use of legacy and extended advertising, scan or initiate commands
WBUSW-790 Distinguish pseudo random from crytographic random generation
WBUSW-867 [ll-tester] does not adjust TIFS down to +/-0.5us
WBUSW-962 Initiator with white list connects to other RPAs
WBUSW-975 Scheduler should not allow overlapped BODs
WBUSW-998 Indicate completed packets only for active connections
WBUSW-1040 Validate parameters in the LL_CHANNEL_MAP_IND
WBUSW-1044 Valid parameter for the connection update indication
WBUSW-1117 Improve collision resolution between different LLCP
WBUSW-1185 Disconnect when receiving unknown or invalid PDU during encryption start procedure
WBUSW-1194 Resolve peer addresses without specifying own identity address
WBUSW-1250 Disallow supervision timeout exactly twice connection interval
WBUSW-1261 Version exchange procedure collision with procedure with instant
WBUSW-1276 Initiator's RPA does not change after expected time.
WBUSW-1286 UPF55 vendor compatibility fixes
WBUSW-1290 Advertising data corrupted with undirected advertisement and peer IRK
WBUSW-1303 LL will connect to peer identity address even with peer IRK
WBUSW-1305 LL requires peer match even for undirected advertising
WBUSW-1335 Resolve peer addresses even if peer is not in resolving list
WBUSW-1336 Initiator will not respond to the previous local RPA associated with a peer
WBUSW-1340 Resolve local address without transmitting local RPAs
WBUSW-1342 Nordic BB receives with Access Address bit errors
WBUSW-1394 [nRF52] VS_GET_SYS_STATS does not report CS watermark
Changes in r2p0-00bet0.
WBUSW-431 BLE5 - 2Mbps LE PHY
WBUSW-432 BLE5 - Extended Advertising (see note in Limitations)
WBUSW-507 Remove lctrMaxConsCrc variable (use constant LCTR_MAX_CONS_CRC)
WBUSW-754 BLE5 - LE Channel Selection #2
WBUSW-822 Broadcaster build should not require connection sources
WBUSW-915 LL should reject PDUs with invalid length
WBUSW-1005 Improve the diversity of Access Address
WBUSW-1009 Missing and incorrect documentation parameters
WBUSW-1011 Obsolete ISR scheduler execution
WBUSW-1013 Remove duplicate symbols between hci_defs.h and lhci_int.h
WBUSW-1021 HCI reset should not reset scheduler
WBUSW-1037 LL shall mask out the feature bits that should not be sent over the air
WBUSW-1038 Align tester advertising PDU buffers
WBUSW-1055 Avoid double decoding of PDUs
WBUSW-1056 BLE5 - High Duty Cycle Non-Connectable Advertising
WBUSW-1073 Move LL PDU defines to ll_defs.h
WBUSW-1081 [ESR10] #6672 rename some PDUs
WBUSW-1106 Suppress length exchange at startup with operation mode
WBUSW-1125 Unaligned scan response buffer
WBUSW-1127 Clear LL Tester transmit packet trigger on HCI reset
WBUSW-1134 Advertising not terminated immediately with CONNECT_IND
WBUSW-1149 Legacy and extended advertising commands are mutually exclusive
WBUSW-1159 Legacy advertising does not allow dynamic data updates
WBUSW-1188 Length excluded from advertising packet length calculation
WBUSW-736 LHCI transport for multi-protocol operation
WBUSW-959 Multi-protocol BB initialization
WBUSW-965 Relocate BLE-specific scheduler functionality
WBUSW-1006 Controller sources reorganization
WBUSW-1060 Remove the redundant local feature flag and fix the script issue
WBUSW-1061 [Coverity] Fix Coverity issue under mac-ble/sw
WBUSW-1072 Corrections to source reorganization
WBUSW-1115 Update documentation to ARM format
WBUSW-1039 System and diagnostic WSF_ASSERT interface
Changes in LL_16.06.
[#681] LL ACL test statistics
[#762] Enter termination state after ACK is transmitted following LL_TERMINATE_IND
[#830] Master sometimes starts CE outside Tx Window
[#854] Reset should clear state variables
[#859] Receive PDU buffer should limit to buffer allocation size
[#880] Slave receiving LL_TERMINATE_IND with pending data does not terminate
[#881] Connection that receives any packet, even with CRC failure, is established
[#892] Scan BOD may be scheduled very far in the future
[#893] Master connection may corrupt advertising report filter
[#905] Calculate scan due time after TIFS cancel
[#908] LL connection parameter events do not match "thin HCI" fields
[#943] Return peer device address in LE_Connection_Complete event with privacy
[#946] Improve LL test mode
[#951] Connection initiation requires additional scheduler setup
[#956] LL_CONNECTION_PARAM_REQ is not reject with invalid parameters
[#961] Cannot create high density connections
[#963] Reservation manager should avoid overlapping connection events
Changes in LL_16.03.
[#568] Master selects connection parameters with least conflicts
[#610] Inform BBP about TIFS setup requirement
[#727] Handler performance metrics
[#728] UPF53 vendor compatibility fixes
[#730] Reject connection parameter request with REJECT_IND_EXT
[#732] PRBS9 test packets calculated wrong
[#734] InitA not refreshed in directed advertisements
[#748] LL API to get connection context size
[#755] VS command to set private key for LE SC
[#759] Incorrect us-to-BB ticks conversion for 32k BB clock
[#780] LE Secure Connections parameters should be little-endian
[#787] VS event mask to disable trace events
[#788] Maximum entries cannot be added to resolving list
[#791] upperLimit in scan backoff algorithm changes after pairs of failures or successes
[#831] Allow LlSetOpFlags() to set Connection Parameter operation flags

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief BLE baseband interface file.
* \file
* \brief BLE baseband interface file.
*/
/*************************************************************************************************/
@ -312,33 +313,6 @@ uint16_t BbBleInitResolvingList(uint8_t numEntries, uint8_t *pFreeMem, uint32_t
/*************************************************************************************************/
uint16_t BbBleInitPeriodicList(uint8_t numEntries, uint8_t *pFreeMem, uint32_t freeMemSize);
/*************************************************************************************************/
/*!
* \brief Get transmit RF path compensation.
*
* \return Transmit RF path compensation (in 1-dBm units).
*/
/*************************************************************************************************/
int8_t BbBleRfGetTxRfPathComp(void);
/*************************************************************************************************/
/*!
* \brief Get receive RF path compensation.
*
* \return Transmit RF path compensation (in 1-dBm units).
*/
/*************************************************************************************************/
int8_t BbBleRfGetRxRfPathComp(void);
/*************************************************************************************************/
/*!
* \brief Initialize RF path compensation.
*
* \return None.
*/
/*************************************************************************************************/
void BbBleInitRfPathComp(void);
/*************************************************************************************************/
/*!
* \brief Get advertising packet statistics.
@ -429,54 +403,36 @@ void BbBleGetPduFiltStats(BbBlePduFiltStats_t *pStats);
/*************************************************************************************************/
/*!
* \brief Get supported transmit power.
* \brief Initialize for connected isochronous stream master operations.
*
* \param pMinTxPwr Return buffer for minimum transmit power (expressed in 1dBm units).
* \param pMaxTxPwr Return buffer for maximum transmit power (expressed in 1dBm units).
* \return None.
*
* Update the operation table with CIS master operations routines.
*/
/*************************************************************************************************/
void BbBleCisMasterInit(void);
/*************************************************************************************************/
/*!
* \brief Initialize for connected isochronous stream slave operations.
*
* \return None.
*
* Update the operation table with CIS slave operations routines.
*/
/*************************************************************************************************/
void BbBleCisSlaveInit(void);
/*************************************************************************************************/
/*!
* \brief Get CIS packet statistics.
*
* \param pStats CIS data statistics.
*
* \return None.
*/
/*************************************************************************************************/
void BbBleRfGetSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr);
/*************************************************************************************************/
/*!
* \brief Read RF path compensation.
*
* \param pTxPathComp Return buffer for RF transmit path compensation value (expressed in 0.1dBm units).
* \param pRxPathComp Return buffer for RF receive path compensation value (expressed in 0.1dBm units).
*
* \return None.
*/
/*************************************************************************************************/
void BbBleRfReadRfPathComp(int16_t *pTxPathComp, int16_t *pRxPathComp);
/*************************************************************************************************/
/*!
* \brief Set RF path compensation.
*
* \param txPathComp RF transmit path compensation value (expressed in 0.1dBm units).
* \param rxPathComp RF receive path compensation value (expressed in 0.1dBm units).
*
* \return TRUE if successful, FALSE otherwise.
*/
/*************************************************************************************************/
bool_t BbBleRfWriteRfPathComp(int16_t txPathComp, int16_t rxPathComp);
/*************************************************************************************************/
/*!
* \brief Get the actual Tx power at the antenna (expressed in 1dBm units).
*
* \param txPwr Tx power provided by the host (expressed in 1dBm units).
* \param compFlag Flag to apply Tx path compensation or not.
*
* \return Actual Tx power at the antenna (expressed in 1dBm units).
*
* Tx path compensation is only used for extended ADV header.
* Compensation is not considered when filling in HCI events.
*/
/*************************************************************************************************/
int8_t BbBleRfGetActualTxPower(int8_t txPwr, bool_t compFlag);
void BbBleGetCisStats(BbBleDataPktStats_t *pStats);
/*! \} */ /* BB_API_BLE */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief BLE baseband interface file.
* \file
* \brief BLE baseband interface file.
*/
/*************************************************************************************************/
@ -24,7 +25,7 @@
#define BB_BLE_API_OP_H
#include "bb_api.h"
#include "bb_ble_drv.h"
#include "pal_bb_ble.h"
#include "bb_ble_api_pdufilt.h"
#include "ll_defs.h"
@ -62,12 +63,20 @@ enum
BB_BLE_OP_SLV_AUX_ADV_EVENT, /*!< Slave auxiliary advertising event. */
BB_BLE_OP_SLV_PER_ADV_EVENT, /*!< Slave periodic advertising event. */
BB_BLE_OP_MST_PER_SCAN_EVENT, /*!< Master periodic scanning event. */
BB_BLE_OP_MST_CIS_EVENT, /*!< Master CIS event. */
BB_BLE_OP_SLV_CIS_EVENT, /*!< Slave CIS event. */
BB_BLE_OP_NUM /*!< Total number of operations. */
};
/*! \brief Maximum request PDU length (MAX(LL_SCAN_REQ_PDU_LEN, LL_CONN_IND_PDU_LEN)). */
#define BB_REQ_PDU_MAX_LEN (LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN)
/*! \brief Guard time at the end of a scan window to the next BOD. Backoff one advertise data exchange. */
#define BB_SCAN_GUARD_US (LL_ADV_PKT_MAX_USEC + LL_BLE_TIFS_US + \
LL_SCAN_REQ_MAX_USEC + LL_BLE_TIFS_US + \
LL_SCAN_RSP_MAX_USEC + \
BbGetSchSetupDelayUs())
/**************************************************************************************************
Data Types
**************************************************************************************************/
@ -105,6 +114,15 @@ typedef void (*BbBleTxDataComp_t)(BbOpDesc_t *pBod, uint8_t status);
/*! \brief Data receive completion callback signature. */
typedef void (*BbBleRxDataComp_t)(BbOpDesc_t *pBod, uint8_t *pBuf, uint8_t status);
/*! \brief CIS check whether to continue current operation call signature. */
typedef uint32_t (*BbBleCisCheckContOp_t)(BbOpDesc_t *pBod, bool_t *pNewCisCtx);
/*! \brief CIS post execute callback signature. */
typedef void (*BbBleCisPostExec_t)(BbOpDesc_t *pBod, uint8_t status);
/*! \brief CIS data receive completion callback signature. */
typedef void (*BbBleCisRxDataComp_t)(BbOpDesc_t *pBod, uint8_t *pBuf, uint8_t status);
/*! \brief Test completion callback signature. */
typedef bool_t (*BbBleTestComp_t)(BbOpDesc_t *pBod, uint8_t status);
@ -164,6 +182,8 @@ typedef struct
uint8_t txAdvLen; /*!< Advertising buffer length. */
uint8_t txRspLen; /*!< Scan response buffer length. */
uint8_t firstAdvChIdx; /*!< first advertising channel index. */
uint8_t advChMap; /*!< Advertising channel map. */
/* Return parameters. */
@ -219,10 +239,10 @@ typedef struct
typedef struct
{
/* TODO BbBleSlvAuxAdvEvent_t hide buffer descriptors in BB layer. */
BbBleDrvTxBufDesc_t txAuxAdvPdu[2]; /*!< Advertising PDU descriptor. */
PalBbBleTxBufDesc_t txAuxAdvPdu[2]; /*!< Advertising PDU descriptor. */
uint8_t *pRxAuxReqBuf; /*!< Auxiliary request buffer (must be size of BB_REQ_PDU_MAX_LEN). */
BbBleDrvTxBufDesc_t txAuxRspPdu[2]; /*!< Response PDU descriptor. */
BbBleDrvTxBufDesc_t txAuxChainPdu[2]; /*!< Auxiliary chain PDU descriptor. */
PalBbBleTxBufDesc_t txAuxRspPdu[2]; /*!< Response PDU descriptor. */
PalBbBleTxBufDesc_t txAuxChainPdu[2]; /*!< Auxiliary chain PDU descriptor. */
BbBleAdvComp_t rxAuxReqCback; /*!< Auxiliary request receive completion callback. */
BbBleAdvPost_t rxAuxReqPostCback; /*!< Auxiliary scan/connect request receive post processing callback. */
@ -266,6 +286,39 @@ typedef struct
uint8_t rxPhyOptions; /*!< Rx PHY options. */
} BbBleSlvConnEvent_t;
/*! \brief CIS master event operation data (\ref BB_BLE_OP_MST_CIS_EVENT). */
typedef struct
{
BbBleCisCheckContOp_t checkContOpCback; /*!< Check whether to continue current operation callback. */
BbBleExec_t execCback; /*!< Execute callback. */
BbBleExec_t contExecCback; /*!< Continue execute callback. */
BbBleCisPostExec_t postSubEvtCback; /*!< Post subevent callback. */
BbBleCancel_t cancelCback; /*!< Cancel callback. */
BbBleTxDataComp_t txDataCback; /*!< Transmit completion callback. */
BbBleCisRxDataComp_t rxDataCback; /*!< Receive completion callback. */
/* Return parameters. */
int8_t rssi; /*!< RSSI of the last received packet. */
uint8_t rxPhyOptions; /*!< Rx PHY options. */
} BbBleMstCisEvent_t;
/*! \brief CIS slave event operation data (\ref BB_BLE_OP_SLV_CIS_EVENT). */
typedef struct
{
BbBleCisCheckContOp_t checkContOpCback; /*!< Check whether to continue current operation callback. */
BbBleExec_t execCback; /*!< Execute callback. */
BbBleExec_t contExecCback; /*!< Continue execute callback. */
BbBleCisPostExec_t postSubEvtCback; /*!< Post subevent callback. */
BbBleCancel_t cancelCback; /*!< Cancel callback. */
BbBleTxDataComp_t txDataCback; /*!< Transmit completion callback. */
BbBleRxDataComp_t rxDataCback; /*!< Receive completion callback. */
/* Return parameters. */
uint32_t startTs; /*!< Start timestamp of the first received packet. */
int8_t rssi; /*!< RSSI of the last received packet. */
uint8_t rxPhyOptions; /*!< Rx PHY options. */
uint32_t rxSyncDelayUsec; /*!< Receive timeout in microseconds. */
} BbBleSlvCisEvent_t;
/*! \brief Continuous transmit operation data (\ref BB_BLE_OP_TEST_TX). */
typedef struct
{
@ -289,7 +342,7 @@ typedef struct
/*! \brief Bluetooth Low Energy protocol specific operation parameters. */
typedef struct BbBleData_tag
{
BbBleDrvChan_t chan; /*!< Channelization parameters. */
PalBbBleChan_t chan; /*!< Channelization parameters. */
bbBlePduFiltParams_t pduFilt; /*!< PDU filter parameters. */
union
@ -300,8 +353,10 @@ typedef struct BbBleData_tag
BbBleSlvAuxAdvEvent_t slvAuxAdv; /*!< Slave auxiliary advertising event data. */
BbBleSlvAuxAdvEvent_t slvPerAdv; /*!< Slave periodic advertising event data. */
BbBleMstConnEvent_t mstConn; /*!< Master connection event data. */
BbBleMstPerScanEvent_t mstPerScan; /*!< Master periodic scanning event data. */
BbBleSlvConnEvent_t slvConn; /*!< Slave connection event data. */
BbBleMstPerScanEvent_t mstPerScan; /*!< Master periodic scanning event data. */
BbBleMstCisEvent_t mstCis; /*!< Master CIS event data. */
BbBleSlvCisEvent_t slvCis; /*!< Slave CIS event data. */
BbBleTestTx_t testTx; /*!< Transmit test data. */
BbBleTestRx_t testRx; /*!< Receive test data. */
} op; /*!< Operation specific data. */
@ -324,7 +379,7 @@ typedef struct BbBleData_tag
* \ref BbBleSlvConnEvent_t::rxDataCback callback routine.
*/
/*************************************************************************************************/
void BbBleTxData(BbBleDrvTxBufDesc_t descs[], uint8_t cnt);
void BbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt);
/*************************************************************************************************/
/*!
@ -344,6 +399,39 @@ void BbBleTxData(BbBleDrvTxBufDesc_t descs[], uint8_t cnt);
/*************************************************************************************************/
void BbBleRxData(uint8_t *pBuf, uint16_t len);
/*************************************************************************************************/
/*!
* \brief Transmit CIS PDU at next transmit slot.
*
* \param descs Array of transmit buffer descriptor.
* \param cnt Number of descriptors.
*
* \return None.
*
* \note This function is expected to be called during the call context of
* \ref BbBleMstCisEvent_t::rxDataCback or \ref BbBleSlvCisEvent_t::rxDataCback
* callback routine.
*/
/*************************************************************************************************/
void BbBleCisTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt);
/*************************************************************************************************/
/*!
* \brief Set receive data buffer for next receive slot.
*
* \param pBuf Receive data buffer.
* \param len Maximum length of data buffer.
*
* \return None.
*
* \note This function is expected to be called during the call context of
* \ref BbBleSlvCisEvent_t::rxDataCback callback routine.
*
* \note BB must always call the BbBleSlvCisEvent_t::rxDataCback callback routine of the
* currently executing BOD with the given buffer.
*/
/*************************************************************************************************/
void BbBleCisRxData(uint8_t *pBuf, uint16_t len);
/*! \} */ /* BB_API_BLE */
#ifdef __cplusplus

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief BLE baseband PDU filtering interface file.
* \file
* \brief BLE baseband PDU filtering interface file.
*/
/*************************************************************************************************/
@ -39,7 +40,7 @@ extern "C" {
/*! \brief Check whether a flag is set. */
#define BB_BLE_PDU_FILT_FLAG_IS_SET(pFilt, flag) (((pFilt)->flags & BB_BLE_PDU_FILT_FLAG_##flag) != 0)
/*! \brief Check whether a flag is clear. */
/*! \brief Set a flag. */
#define BB_BLE_PDU_FILT_SET_FLAG(pFilt, flag) (pFilt)->flags |= BB_BLE_PDU_FILT_FLAG_##flag;
/*! \brief PDU filtering flags. */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief BLE baseband periodiclist interface file.
* \file
* \brief BLE baseband periodiclist interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief BLE baseband resolving list interface file.
* \file
* \brief BLE baseband resolving list interface file.
*/
/*************************************************************************************************/
@ -337,6 +338,32 @@ uint8_t BbBleResListLocalStatus(bool_t peerAddrRand, uint64_t peerIdentityAddr);
/*************************************************************************************************/
void BbBleResListHandleTimeout(void);
/*************************************************************************************************/
/*!
* \brief Check if either local RPA or peer RPA is updated.
*
* \param peerAddrType Peer identity address type.
* \param peerIdentityAddr Peer identity address.
*
* \return TRUE if either local RPA or peer RPA is updated.
*
*/
/*************************************************************************************************/
bool_t BbBleResListIsRpaUpd(uint8_t peerAddrType, uint64_t peerIdentityAddr);
/*************************************************************************************************/
/*!
* \brief Check if peer identity is in the resolving list.
*
* \param peerAddrType Peer identity address type.
* \param peerIdentityAddr Peer identity address.
*
* \return TRUE if peer addr is in the resolving list.
*
*/
/*************************************************************************************************/
bool_t bbBleIsPeerInResList(uint8_t peerAddrType, uint64_t peerIdentityAddr);
/*! \} */ /* BB_API_BLE_RL */
#ifdef __cplusplus

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief BLE baseband whitelist interface file.
* \file
* \brief BLE baseband whitelist interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer HCI subsystem API.
* \file
* \brief Link layer HCI subsystem API.
*/
/*************************************************************************************************/
@ -63,10 +64,17 @@ void LhciConnMasterInit(void);
void LhciExtConnMasterInit(void);
void LhciScInit(void);
void LhciPhyInit(void);
void LhciPastInit(void);
void LhciChannelSelection2Init(void);
void LhciCisMasterInit(void);
void LhciCisSlaveInit(void);
void LhciIsoInit(void);
void LhciVsExtInit(lhciCmdHandler_t decodeCmd);
void LhciHandlerInit(wsfHandlerId_t handlerId);
void LhciHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
void LhciIsoHandlerInit(wsfHandlerId_t handlerId);
void LhciIsoHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
void LhciSetDefaultHciSupCmd(uint8_t *pBuf);
#if (LL_ENABLE_TESTER)
void LhciTesterInit(void);
#endif
@ -81,7 +89,7 @@ bool_t LhciIsEventPending(void);
uint8_t LhciPackEvtHdr(uint8_t *pBuf, uint8_t evtCode, uint8_t paramLen);
/* Event processing */
void LhciVsEncodeTraceMsgEvtPkt(uint8_t *pBuf, uint8_t len);
bool_t LhciVsEncodeTraceMsgEvtPkt(const uint8_t *pBuf, uint32_t len);
#ifdef __cplusplus
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer constant definitions.
* \file
* \brief Link layer constant definitions.
*/
/*************************************************************************************************/
@ -39,6 +40,9 @@ extern "C" {
#define LL_VER_BT_CORE_SPEC_4_1 0x07 /*!< Bluetooth core specification 4.1 */
#define LL_VER_BT_CORE_SPEC_4_2 0x08 /*!< Bluetooth core specification 4.2 */
#define LL_VER_BT_CORE_SPEC_5_0 0x09 /*!< Bluetooth core specification 5.0 */
#define LL_VER_BT_CORE_SPEC_5_1 0x0A /*!< Bluetooth core specification 5.1 */
#define LL_VER_BT_CORE_SPEC_MILAN 0x0B /*!< Bluetooth core specification Milan */
#define LL_VER_BT_CORE_SPEC_SYDNEY 0x0C /*!< Bluetooth core specification Sydney */
#define LL_COMP_ID_ARM 0x005F /*!< ARM Ltd. company ID. */
@ -131,7 +135,7 @@ enum
{
LL_EXT_HDR_ADV_ADDR_BIT = (1 << 0), /*!< Extended header AdvA bit. */
LL_EXT_HDR_TGT_ADDR_BIT = (1 << 1), /*!< Extended header TargetA bit. */
LL_EXT_HDR_SUPP_INFO_BIT = (1 << 2), /*!< Extended header SuppInfo bit. */
LL_EXT_HDR_CTE_INFO_BIT = (1 << 2), /*!< Extended header CTEInfo bit. */
LL_EXT_HDR_ADI_BIT = (1 << 3), /*!< Extended header AdvDataInfo bit. */
LL_EXT_HDR_AUX_PTR_BIT = (1 << 4), /*!< Extended header AuxPtr bit. */
LL_EXT_HDR_SYNC_INFO_BIT = (1 << 5), /*!< Extended header SyncInfo bit. */
@ -141,10 +145,14 @@ enum
#define LL_MAX_ADV_HANDLE 0xEF /*!< Maximum advertising handle. */
#define LL_MAX_ADV_SID 0x0F /*!< Maximum advertising SID */
#define LL_EXT_ADV_HDR_MIN_LEN 1 /*!< Minimum extended advertising header length (ExtHdrLen and AdvMode fields). */
#define LL_EXT_ADV_HDR_MAX_LEN 64 /*!< Maximum extended advertising header length (ExtHdrLen, AdvMode fields and Extended header). */
#define LL_EXT_ADVBU_MAX_LEN 251 /*!< Maximum extended advertising channel PDU host data length. */
#define LL_EXT_ADVB_MAX_LEN 257 /*!< Maximum extended advertising channel PDU length. */
#define LL_EXT_ADV_HDR_MIN_LEN 1 /*!< Minimum extended advertising header length (ExtHdrLen and AdvMode fields). */
#define LL_EXT_ADV_HDR_MAX_LEN 64 /*!< Maximum extended advertising header length (ExtHdrLen, AdvMode fields and Extended header). */
#define LL_EXT_HDR_FLAG_LEN 1 /*!< Length of extended header flag field */
#define LL_EXT_ADVBU_MAX_LEN 251 /*!< Maximum extended advertising channel PDU host data length. */
#define LL_EXT_ADVB_MAX_LEN 257 /*!< Maximum extended advertising channel PDU length. */
#define LL_EXT_ADVB_NORMAL_LEN 50 /*!< Normal extended advertising channel PDU length. */
#define LL_EXT_HDR_ACAD_MAX_LEN LL_EXT_ADV_HDR_MAX_LEN - LL_EXT_ADV_HDR_MIN_LEN - LL_EXT_HDR_FLAG_LEN /*!< Maximum possible ACAD length (Max extended header minus ExtHdrLen, AdvMode, and extended header flag field. */
#define LL_EXT_ADVB_MAX_TIME_1M ((LL_BLE_US_PER_BYTE_1M * (LL_EXT_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_1M)
/*!< Maximum time for a 1M advertising channel PDU. */
@ -154,6 +162,8 @@ enum
/*!< Maximum time for a Coded S2 advertising channel PDU. */
#define LL_EXT_ADVB_MAX_TIME_S8 ((LL_BLE_US_PER_BYTE_CODED_S8 * (LL_EXT_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_CODED_S8)
/*!< Maximum time for a Coded S8 advertising channel PDU. */
#define LL_EXT_ADVB_NORMAL_TIME_S8 ((LL_BLE_US_PER_BYTE_CODED_S8 * (LL_EXT_ADVB_NORMAL_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_CODED_S8)
/*!< Time for a Coded S8 advertising channel PDU with normal length. */
#define LL_AUX_PTR_MAX_USEC 2457600 /*!< Maximum AuxPtr offset value in microseconds. */
@ -164,6 +174,17 @@ enum
#define LL_PER_ADV_INT_MIN 0x0006 /*!< Minimum periodic advertising interval. */
#define LL_SYNC_OFFS_ADJUST_USEC LL_AUX_PTR_MAX_USEC /*!< Sync offset adjust of 2.4576 seconds. */
#define LL_SYNC_INFO_LEN 18 /*!< Size of SyncInfo field. */
/*! \brief Periodic sync transfer receive mode. */
enum
{
LL_SYNC_TRSF_MODE_OFF = 0, /*!< Periodic sync transfer receive is disabled. */
LL_SYNC_TRSF_MODE_REP_DISABLED = 1, /*!< Periodic sync transfer receive is enabled, report event is disabled. */
LL_SYNC_TRSF_MODE_REP_ENABLED = 2, /*!< Periodic sync transfer receive is enabled, report event is enabled. */
LL_SYNC_TRSF_MAX_MODE = LL_SYNC_TRSF_MODE_REP_ENABLED
};
/*** Data PDU ***/
@ -199,6 +220,17 @@ enum
LL_PDU_PHY_RSP = 0x17, /*!< PHY response PDU. */
LL_PDU_PHY_UPDATE_IND = 0x18, /*!< PHY update indication PDU. */
LL_PDU_MIN_USED_CHAN_IND = 0x19, /*!< Minimum used channels indication PDU. */
/* --- Core Spec 5.1 --- */
// 0x1A 0x1B for AOA AOD, 0x1C for PAST 0x20 RFU
LL_PDU_PERIODIC_SYNC_IND = 0x1C, /*!< Periodic sync indication PDU. */
/* --- Core Spec Milan --- */
LL_PDU_PEER_SCA_REQ = 0x1D, /*!< Peer SCA request PDU. */
LL_PDU_PEER_SCA_RSP = 0x1E, /*!< Peer SCA response PDU. */
LL_PDU_CIS_REQ = 0x1F, /*!< CIS request PDU. */
LL_PDU_CIS_RSP = 0x21, /*!< CIS response PDU. */
LL_PDU_CIS_IND = 0x22, /*!< CIS indication PDU. */
LL_PDU_CIS_TERM_IND = 0x23, /*!< CIS terminate indication PDU. */
LL_PDU_UNSPECIFIED = 0xFF /*!< Unspecified PDU. */
};
@ -224,6 +256,17 @@ enum
#define LL_PHY_PDU_LEN 3 /*!< PHY request/response PDU length. */
#define LL_PHY_UPD_IND_PDU_LEN 5 /*!< PHY update indication PDU length. */
#define LL_MIN_USED_CHAN_PDU_LEN 3 /*!< Minimum used channels indication PDU length. */
/* --- Core Spec 5.1 --- */
#define LL_PERIODIC_SYNC_PDU_LEN 35 /*!< Periodic sync indication PDU length. */
/* --- Core Spec Milan --- */
#define LL_PEER_SCA_REQ_LEN 2 /*!< Peer SCA request PDU length. */
#define LL_PEER_SCA_RSP_LEN 2 /*!< Peer SCA response PDU length. */
#define LL_CIS_REQ_LEN 34 /*!< CIS request PDU length. */
#define LL_CIS_RSP_LEN 9 /*!< CIS response PDU length. */
#define LL_CIS_IND_LEN 16 /*!< CIS indication PDU length. */
#define LL_CIS_TERM_LEN 4 /*!< CIS termination PDU length. */
#define LL_CIS_SDU_CONFIG_REQ_LEN 13 /*!< CIS SDU config request PDU length. */
#define LL_CIS_SDU_CONFIG_RSP_LEN 4 /*!< CIS SDU config response PDU length. */
#define LL_EMPTY_PDU_LEN 2 /*!< Length of an empty data PDU. */
@ -236,6 +279,12 @@ enum
#define LL_MAX_NUM_CHAN_DATA 37 /*!< Maximum number of used data channels. */
#define LL_MIN_NUM_CHAN_DATA 2 /*!< Minimum number of used data channels. */
#define LL_ISO_DATA_HDR_LEN 2 /*!< ISO data PDU header length. */
#define LL_ISO_DATA_MIC_LEN 4 /*!< ISO data PDU MIC length. */
#define LL_ISO_DATA_HDR_LLID_MSK 0x03 /*!< ISO data PDU LLID mask. */
#define LL_ISO_DATA_HDR_LEN_MSK 0xFF /*!< ISO Data header length mask. */
/*! \brief Data PDU LLID types. */
enum
{
@ -281,6 +330,7 @@ enum
#define LL_MAX_DATA_TIME_MIN 328 /*!< Minimum value for maximum Data PDU time */
#define LL_MAX_DATA_TIME_ABS_MAX 17040 /*!< Absolute maximum limit for maximum Data PDU time */
#define LL_MAX_DATA_TIME_ABS_MAX_1M 2120 /*!< Absolute maximum limit for maximum Data PDU time (LE 1M PHY) */
#define LL_MAX_DATA_TIME_ABS_MIN_CODED 2704 /*!< Absolute minimum limit for maximum Data PDU time (CODED PHY) */
#define LL_T_PRT_SEC 40 /*!< LLCP procedure response timeout in seconds. */
@ -303,6 +353,67 @@ enum
#define LL_MAX_PHYS 3 /*!< Number of LE PHYs. */
#define LL_ALL_PHYS_MSK 0x7 /*!< All supported LE PHYs mask. */
/*** ISO ***/
#define LL_MAX_ISO_DATA_LEN_ABS_MAX 251 /*!< Absolute maximum limit for maximum ISO Data PDU length */
#define LL_MAX_CIS_COUNT 0x10 /*!< Maximum count for CIS. */
#define LL_MIN_CIG_ID 0x00 /*!< Minimum value for CIG ID. */
#define LL_MAX_CIG_ID 0xEF /*!< Maximum value for CIG ID. */
#define LL_MIN_CIS_ID 0x00 /*!< Minimum value for CIS ID. */
#define LL_MAX_CIS_ID 0xEF /*!< Maximum value for CIS ID. */
#define LL_MIN_ISO_INTERV 0x0004 /*!< Minimum value for ISO interval. */
#define LL_MAX_ISO_INTERV 0x0C80 /*!< Maximum value for ISO interval. */
#define LL_MIN_ISOAL_PDU_TYPE 0x00 /*!< Minimum value for ISOAL PDU type. */
#define LL_MAX_ISOAL_PDU_TYPE 0x01 /*!< Maximum value for ISOAL PDU type. */
#define LL_MIN_SDU_SIZE 0x000 /*!< Minimum value for SDU size. */
#define LL_MAX_SDU_SIZE 0xFFF /*!< Maximum value for SDU size. */
#define LL_MIN_SDU_INTERV 0x000FF /*!< Minimum value for SDU interval. */
#define LL_MAX_SDU_INTERV 0xFFFFF /*!< Maximum value for SDU interval. */
#define LL_MIN_CIS_NSE 0x00 /*!< Minimum value for CIS number of subevent. */
#define LL_MAX_CIS_NSE 0x1F /*!< Maximum value for CIS number of subevent. */
#define LL_MIN_CIS_PL 0x00 /*!< Minimum value for CIS payload. */
#define LL_MAX_CIS_PL 0xFB /*!< Maximum value for CIS payload. */
#define LL_MIN_CIS_PHY_BIT 0x00 /*!< Minimum value for CIS PHY bit. */
#define LL_MAX_CIS_PHY_BIT 0x02 /*!< Maximum value for CIS PHY bit. */
#define LL_MIN_CIS_FT 0x01 /*!< Minimum value for CIS flush time. */
#define LL_MAX_CIS_FT 0x1F /*!< Maximum value for CIS flush time. */
#define LL_MIN_CIS_BN 0x00 /*!< Minimum value for CIS burst number. */
#define LL_MAX_CIS_BN 0x10 /*!< Maximum value for CIS burst number. */
/*! \brief ISO PDU LLID types. */
enum
{
LL_ISO_LLID_CIS_DATA_PDU = 0x00, /*!< CIS data PDU. */
LL_ISO_LLID_BIS_DATA_PDU = 0x00, /*!< BIS data PDU. */
LL_ISO_LLID_BIS_CTRL_PDU = 0x03, /*!< BIS control PDU. */
};
/*! \brief ISO PDU types. */
enum
{
LL_ISO_PDU_TYPE_UNFRAMED = 0x00, /*!< Unframed PDU type. */
LL_ISO_PDU_TYPE_FRAMED = 0x01, /*!< framed PDU type. */
};
/*! \brief ISO PDU types. */
enum
{
LL_ISO_TEST_PL_LEN_MAX = 0x00, /*!< \brief Maximum length test payload */
LL_ISO_TEST_PL_LEN_VAR = 0x01, /*!< \brief Maximum length test payload */
LL_ISO_TEST_PL_LEN_ZERO = 0x02, /*!< \brief Maximum length test payload */
};
/*** DTM ***/
#define LL_DTM_HDR_LEN 2 /*!< Direct Test Mode PDU header length. */
@ -328,6 +439,7 @@ enum
#define LL_BLE_TIFS_US 150 /*!< BLE inter-frame space. */
#define LL_BLE_MAFS_US 300 /*!< BLE minimum AUX frame space. */
#define LL_BLE_US_PER_TICK 625 /*!< Microseconds per BLE tick. */
#define LL_BLE_TMSS_US 150 /*!< BLE minimum subevent space. */
#define LL_MIN_PKT_TIME_US_1M 80 /*!< Minimum packet time (i.e. empty PDU) on LE 1M PHY. */
#define LL_MIN_PKT_TIME_US_2M 44 /*!< Minimum packet time (i.e. empty PDU) on LE 2M PHY. */
@ -342,7 +454,36 @@ enum
#define LL_MAX_TIFS_DEVIATION 2 /*!< Maximum TIFS deviation in microseconds. */
#define LL_MAX_CE_DEVIATION_USEC 16 /*!< Maximum connection event deviation in microseconds. */
#define LL_WW_RX_DEVIATION_USEC 16 /*!< RX deviation in microseconds for window widening. */
#define LL_30_USEC_OFFS_MAX_USEC 245730 /*!< Maximum value for 30 microseconds offset unit in microseconds. */
/*** ACAD ***/
/*! \brief ACAD opcodes. */
enum
{
LL_ACAD_OPCODE_CHANNEL_MAP_UPDATE = 0x28 /*!< Opcode for acad update periodic channel map ind. */
};
#define LL_ACAD_OPCODE_LEN 1 /*!< Length of a single Acad opcode. */
#define LL_INSTANT_LEN 2 /*!< Length of instant field (event counter). */
#define LL_ACAD_LEN_FIELD_LEN 1 /*!< Length of Acad length field */
#define LL_ACAD_CHAN_MAP_LEN 5 /*!< Length of channel map rounded to nearest byte */
#define LL_ACAD_DATA_FIELD_MAX_LEN LL_EXT_HDR_ACAD_MAX_LEN - LL_ACAD_OPCODE_LEN - LL_ACAD_LEN_FIELD_LEN /*!< Length of max ACAD field length without opcode and length field */
#define LL_ACAD_UPDATE_CHANNEL_MAP_LEN LL_ACAD_OPCODE_LEN + LL_ACAD_CHAN_MAP_LEN + LL_INSTANT_LEN /*!< Length of acad update periodic channel map data field. */
/*** Modify Sleep Clock Accuracy ***/
/*! \brief Action parameter. */
enum
{
LL_MODIFY_SCA_MORE_ACCURATE = 0x00, /*!< Modify to more accurate clock accuracy. */
LL_MODIFY_SCA_LESS_ACCURATE = 0x01, /*!< Modify to less accurate clock accuracy. */
LL_MODIFY_SCA_NO_ACTION /*!< No action (Used for request sca tester command). */
};
#define LL_SCA_MIN_INDEX 0 /*!< Index for lowest accuracy clock. */
#define LL_SCA_MAX_INDEX 7 /*!< Index for highest accuracy clock. */
#ifdef __cplusplus
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,20 @@
/*************************************************************************************************/
/*!
* \brief LL initialization implementation file.
* \file
* \brief LL initialization implementation file.
*
* Initialization conditional compilation are used to control LL initialization options.
* Define one or more of the following to enable roles and features.
*
* - INIT_BROADCASTER (default)
* - INIT_OBSERVER
* - INIT_PERIPHERAL
* - INIT_CENTRAL
* - INIT_ENCRYPTED
* - BT_VER
*
* \note Each feature may require additional \ref LlRtCfg_t requirements.
*/
/*************************************************************************************************/
@ -45,6 +58,11 @@ extern "C" {
#define INIT_BROADCASTER
#endif
#ifndef BT_VER
/*! \brief Initialize default BT version. */
#define BT_VER LL_VER_BT_CORE_SPEC_5_1
#endif
/**************************************************************************************************
Data Types
**************************************************************************************************/
@ -66,22 +84,20 @@ typedef struct
**************************************************************************************************/
/* System initializers. */
uint32_t LlInitStdInit(LlInitRtCfg_t *pCfg);
uint32_t LlInitExtInit(LlInitRtCfg_t *pCfg);
uint32_t LlInit(LlInitRtCfg_t *pCfg);
uint32_t LlInitControllerInit(LlInitRtCfg_t *pCfg);
uint32_t LlInitControllerExtInit(LlInitRtCfg_t *pCfg);
/* Intermediate initializers. */
uint32_t LlInitSetBbRtCfg(const BbRtCfg_t *pBbRtCfg, const uint8_t wlSizeCfg, const uint8_t rlSizeCfg,
const uint8_t plSizeCfg, uint8_t *pFreeMem, uint32_t freeMemAvail);
uint32_t LlInitSetLlRtCfg(const LlRtCfg_t *pLlRtCfg, uint8_t *pFreeMem, uint32_t freeMemAvail);
void LlInitBbInit(void);
void LlInitBbAuxInit(void);
void LlInitSchInit(void);
void LlInitLlInit(bool_t initHandler);
void LlInitLlInit(void);
void LlInitChciTrInit(void);
void LlInitLhciInit(void);
void LlMathSetSeed(const uint32_t *pSeed);
void LlInitLhciHandler(void);
/*! \} */ /* LL_INIT_API */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link Layer math utilities.
* \file
* \brief Link Layer math utilities.
*/
/*************************************************************************************************/
#ifndef LL_MATH_H
@ -89,103 +90,6 @@ enum
/*************************************************************************************************/
uint32_t LlMathRandNum(void);
/*************************************************************************************************/
/*!
* \brief Calculate AES ECB.
*
* \param pKey Encryption key.
* \param pOut Output data.
* \param pIn Input data.
*
* \return None.
*/
/*************************************************************************************************/
void LlMathAesEcb(const uint8_t *pKey, uint8_t *pOut, const uint8_t *pIn);
/*************************************************************************************************/
/*!
* \brief Set service callback for ECC generation.
*
* \param cback Callback to invoke when driver needs servicing.
*
* \return None.
*/
/*************************************************************************************************/
void LlMathEccSetServiceCback(LlMathEccServiceCback_t cback);
/*************************************************************************************************/
/*!
* \brief Start generating P-256 key pair.
*
* \return None.
*/
/*************************************************************************************************/
void LlMathEccGenerateP256KeyPairStart(void);
/*************************************************************************************************/
/*!
* \brief Start generating P-256 public key with a specified private key.
*
* \param pPrivKey Private key.
*
* \return None.
*/
/*************************************************************************************************/
void LlMathEccGenerateP256PublicKeyStart(const uint8_t *pPrivKey);
/*************************************************************************************************/
/*!
* \brief Continue generating P-256 key pair.
*
* \return TRUE if key generation complete.
*/
/*************************************************************************************************/
bool_t LlMathEccGenerateP256KeyPairContinue(void);
/*************************************************************************************************/
/*!
* \brief Get results from generating P-256 key pair.
*
* \param pPubKey Storage for public key.
* \param pPrivKey Storage for private key.
*
* \return None.
*/
/*************************************************************************************************/
void LlMathEccGenerateP256KeyPairComplete(uint8_t *pPubKey, uint8_t *pPrivKey);
/*************************************************************************************************/
/*!
* \brief Start generating Diffie-Hellman key.
*
* \param pPubKey Public key.
* \param pPrivKey Private key.
*
* \return None.
*/
/*************************************************************************************************/
void LlMathEccGenerateDhKeyStart(const uint8_t *pPubKey, const uint8_t *pPrivKey);
/*************************************************************************************************/
/*!
* \brief Continue generating Diffie-Hellman key.
*
* \return TRUE if Diffie-Hellman key generation complete.
*/
/*************************************************************************************************/
bool_t LlMathEccGenerateDhKeyContinue(void);
/*************************************************************************************************/
/*!
* \brief Get results from generating Diffie-Hellman key.
*
* \param pDhKey Storage for Diffie-Hellman key.
*
* \return None.
*/
/*************************************************************************************************/
void LlMathEccGenerateDhKeyComplete(uint8_t *pDhKey);
/*************************************************************************************************/
/*!
* \brief Return the number of bits which are set.

View File

@ -1,320 +0,0 @@
/* Copyright (c) 2009-2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*************************************************************************************************/
/*!
* \brief Link layer tester interface file.
*/
/*************************************************************************************************/
#ifndef LL_TESTER_API_H
#define LL_TESTER_API_H
#include "wsf_types.h"
#include "ll_api.h"
#include "lctr_api.h"
/* Access internal definitions. */
#include "../../sources/ble/lctr/lctr_pdu_conn.h"
/* Require compile time directive. */
#if (LL_ENABLE_TESTER != TRUE)
#error "LL_ENABLE_TESTER compilation directive must be set to 1."
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Constants
**************************************************************************************************/
/*! \brief Tester acknowledgement mode. */
enum
{
LL_TESTER_ACK_MODE_NORMAL = 0, /*!< Ack packets according to normal acknowledgement/flow control scheme. */
LL_TESTER_ACK_MODE_NO_RX_ACK = 1, /*!< Do not acknowledge Rx packets. */
LL_TESTER_ACK_MODE_IGNORE_TX_ACK = 2 /*!< Ignore acknowledgements of Tx packets. */
};
#define LL_TESTER_TRIGGER_NONEMPTY 0xFE /*!< Trigger only on non-empty packets. */
#define LL_TESTER_TRIGGER_ALWAYS 0xFF /*!< Always trigger. */
#define LL_TESTER_ADVB_MAX_LEN LL_ADVB_MAX_LEN + 4 /*!< Maximum allowed ADVB length. */
/**************************************************************************************************
Data Types
**************************************************************************************************/
/*! \brief Link layer tester control block */
typedef struct
{
/* Advertising channel override values. */
/* Place here to 32-bit align. */
uint8_t txAdvPdu[LL_TESTER_ADVB_MAX_LEN]; /*!< Advertising PDU override buffer. */
uint32_t advAccessAddrRx; /*!< Advertising access address override (Rx). */
uint32_t advAccessAddrTx; /*!< Advertising access address override (Tx). */
/* Place here to 32-bit align. */
uint8_t txScanReqPdu[LL_TESTER_ADVB_MAX_LEN]; /*!< Scan request PDU override buffer. */
uint32_t advCrcInitRx; /*!< Advertising CRC value override (Rx). */
uint32_t advCrcInitTx; /*!< Advertising CRC value override (Tx). */
/* Place here to 32-bit align. */
uint8_t txScanRspPdu[LL_TESTER_ADVB_MAX_LEN]; /*!< Scan response PDU override buffer. */
bool_t txAdvPduLen; /*!< Advertising PDU override buffer length, 0 to disable. */
bool_t txScanReqPduLen; /*!< Scan request PDU override buffer length, 0 to disable. */
bool_t txScanRspPduLen; /*!< Scan response PDU override buffer length, 0 to disable. */
/* Extended advertising channel override values. */
uint32_t auxAccessAddrRx; /*!< Auxiliary advertising access address override (Rx). */
uint32_t auxAccessAddrTx; /*!< Auxiliary advertising access address override (Tx). */
uint32_t auxCrcInitRx; /*!< Advertising CRC value override (Rx). */
uint32_t auxCrcInitTx; /*!< Advertising CRC value override (Tx). */
struct
{
uint8_t pduMatch; /*!< PDU type to override. */
uint8_t len; /*!< Length of override buffer. */
uint8_t buf[LL_CONN_IND_PDU_LEN];
/*!< Override request buffer. */
} auxReq; /*!< Auxiliary request buffer override parameters. */
struct
{
uint16_t pduMatchMask; /*!< Enable override bitmask of PDU types. */
uint8_t modifyMask; /*!< Enable extended header field override bitmask. */
uint64_t AdvA; /*!< AdvA override value. */
uint64_t TargetA; /*!< TargetA override value. */
uint8_t SuppInfo; /*!< SuppInfo override value. */
uint16_t ADI; /*!< ADI override value. */
int8_t TxPower; /*!< TxPower override value. */
} extHdr; /*!< Extended header override values. */
/* Data channel override values. */
uint32_t dataAccessAddrRx; /*!< Data channel access address override (Rx). */
uint32_t dataAccessAddrTx; /*!< Data channel access address override (Tx). */
uint32_t dataCrcInitRx; /*!< Data channel CRC value override (Rx). */
uint32_t dataCrcInitTx; /*!< Data channel CRC value override (Tx). */
/* Connection parameter override values. */
bool_t connIndEnabled; /*!< Connection indication override packet enabled. */
lctrConnInd_t connInd; /*!< Connection indication override packet. */
bool_t connUpdIndEnabled; /*!< Connection update indication override packet enabled. */
lctrConnUpdInd_t connUpdInd; /*!< Connection update indication override packet. */
bool_t connParamReqEnabled;/*!< Connection parameter request override packet enabled. */
lctrConnParam_t connParamReq; /*!< Connection parameter request override packet. */
/* Data length override values. */
bool_t dataLenReqEnabled; /*!< Local Data PDU parameters enabled. */
lctrDataLen_t dataLenReq; /*!< Local Data PDU parameters. */
uint32_t connIntervalUs; /*!< Connection interval override. */
uint16_t eventCounterOffset; /*!< Event counter offset value. */
uint32_t txLlcpFilter; /*!< Filter for LLCP Tx. */
uint32_t rxLlcpFilter; /*!< Filter for LLCP Rx. */
bool_t dataTriggerEnabled; /*!< Trigger is enabled. */
uint8_t dataTriggerPdu; /*!< PDU on which to trigger data. */
bool_t dataTriggerAfter; /*!< Data sent after PDU. */
/* Packet override values. */
uint32_t pktMic; /*!< Packet MIC override XOR value. */
uint8_t pktLlId; /*!< Packet LLID override XOR value. */
/* LLCP handling. */
bool_t llcpForwardEnabled; /*!< LLCP packet to host enable. */
bool_t llcpLlcpIntercept; /*!< LLCP intercept enable. */
/* Acknowledgement/flow control. */
uint8_t ackMode; /*!< Acknowledgement mode. */
uint8_t ackTrigger; /*!< Rx datum or condition on which to trigger special ack handling. */
} llTesterCtrlBlock_t;
/**************************************************************************************************
Global Variables
**************************************************************************************************/
extern llTesterCtrlBlock_t llTesterCb;
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*! \addtogroup LL_TESTER_API_INIT
* \{ */
void LlTesterInit(void);
/* \} */
/*! \addtogroup LL_TESTER_API_ADV_CHAN
* \{ */
/* Advertising channel override */
void LlTesterSetAdvAccessAddr(uint32_t accessAddr, bool_t forRx);
void LlTesterSetAdvCrcInit(uint32_t crcInit, bool_t forRx);
/* Advertising data exchange */
uint8_t LlTesterSetTxAdvPdu(uint8_t *pBuf, uint8_t len);
uint8_t LlTesterSetTxScanReqPdu(uint8_t *pBuf, uint8_t len);
uint8_t LlTesterSetTxScanRspPdu(uint8_t *pBuf, uint8_t len);
/* Extended advertising override */
void LlTesterSetAuxAccessAddr(uint32_t accessAddr, bool_t forRx);
void LlTesterSetAuxCrcInit(uint32_t crcInit, bool_t forRx);
void LlTesterSetTxAuxReqPdu(uint8_t pduMatch, uint8_t *pBuf, uint8_t len);
void LlTesterSetExtAdvHdrFields(uint16_t pduMatchMask, uint8_t modifyMask,
uint8_t *pAdvA, uint8_t *pTargetA, uint8_t SuppInfo, uint16_t ADI, int8_t TxPower);
/* \} */
/*! \addtogroup LL_TESTER_API_DATA_CHAN
* \{ */
/* Data channel override */
void LlTesterSetDataAccessAddr(uint32_t accessAddr, bool_t forRx);
uint8_t LlTesterGetDataAccessAddr(uint16_t handle, uint32_t *pAccessAddr);
void LlTesterSetDataCrcInit(uint32_t crcInit, bool_t forRx);
uint8_t LlTesterGetDataCrcInit(uint16_t handle, uint32_t *pCrcInit);
/* Data control override */
void LlTesterSetConnInd(uint32_t accessAddr, uint32_t crcInit, uint8_t txWinSize, uint16_t txWinOffset,
uint16_t interval, uint16_t latency, uint16_t timeout, uint64_t chanMask,
uint8_t hopInc, uint8_t masterSca);
void LlTesterAdjConnInterval(uint32_t intervalUs);
/* Data packet override */
void LlTesterSetPktLlId(uint8_t id);
void LlTesterSetPktMic(uint32_t mic);
/* Acknowledgement/flow control override */
void LlTesterSetAckMode(uint8_t ackMode, uint8_t ackTrigger);
/* Data exchange */
uint8_t LlTesterTxDataPdu(uint16_t handle, uint8_t *pBuf, uint8_t len);
/* \} */
/*! \addtogroup LL_TESTER_API_LLCP
* \{ */
void LlTesterForwardLlcpToHost(bool_t enable, bool_t intercept);
void LlTesterSetEventCounterOffset(uint16_t offset);
uint8_t LlTesterSendConnUpdInd(uint16_t handle,
uint8_t txWinSize, uint16_t txWinOffset,
uint16_t interval, uint16_t latency, uint16_t timeout);
uint8_t LlTesterSendConnParamReq(uint16_t handle,
uint16_t connIntervalMin, uint16_t connIntervalMax,
uint16_t connLatency, uint16_t supTimeout, uint8_t prefPeriod,
uint16_t refConnEvtCnt, uint16_t *pOffset);
uint8_t LlTesterSendDataLen(uint16_t handle,
uint16_t rxLen, uint16_t rxTime,
uint16_t txLen, uint16_t txTime);
uint8_t LlTesterSendPhyReq(uint16_t handle, uint8_t txPhys, uint8_t rxPhys);
uint8_t LlTesterSendPhyUpdateInd(uint16_t handle, uint8_t mToSPhy, uint8_t sToMPhy);
void LlTesterEnableRxFlowControl(bool_t enable);
void LlTesterSetTxLlcpFilter(uint32_t filter);
void LlTesterSetRxLlcpFilter(uint32_t filter);
void LlTesterSetDataTrigger(uint8_t pdu, bool_t enable, bool_t after);
/* \} */
/*! \addtogroup LL_TESTER_API_BB
* \{ */
/*************************************************************************************************/
/*!
* \brief Adjust Tx TIFS timing value.
*
* \param adjNs Adjustment value in nanoseconds.
*
* \return None.
*
* Adjust the TIFS timing of transmit by the given signed value of timer ticks.
* If adjustment value is out of range, maximum allowed value is used.
*/
/*************************************************************************************************/
void BbTesterAdjTxTifsNs(int16_t adjNs);
/*************************************************************************************************/
/*!
* \brief Trigger channel modifications on matching Tx packet header.
*
* \param hdrMask Header mask.
* \param hdrValue Match value.
*
* \return None.
*
* Modify the transmit channel parameters of a packet only when the Tx packet header matches
* the given parameters. This applies to the modification parameter provided by the following
* routines:
*
* - \ref BbTesterSetInvalidCrcInit()
* - \ref BbTesterSetInvalidAccessAddress()
*/
/*************************************************************************************************/
void BbTesterSetModifyTxPktTrigger(uint16_t hdrMask, uint16_t hdrValue);
/*************************************************************************************************/
/*!
* \brief Invalidate CRC initialization value.
*
* \param chanMask Invalidate channel mask.
* \param adjMask Number of adjustments (0 to disable).
* \param forRx TRUE for Rx, FALSE for Tx.
*
* \return None.
*
* Force the receiver to receive a packet with CRC error if the receive channel is in
* \b chanMask while stepping through the invalid pattern in \b invalidMask.
*/
/*************************************************************************************************/
void BbTesterSetInvalidCrcInit(uint64_t chanMask, uint32_t adjMask, bool_t forRx);
/*************************************************************************************************/
/*!
* \brief Invalidate access address value.
*
* \param chanMask Invalidate channel mask.
* \param invalidMask Enable mask for invalidating access address (0 to disable).
* \param forRx TRUE for Rx, FALSE for Tx.
*
* \return None.
*
* Force the receiver to receive a miss a packet if the receive channel is in
* \b chanMask while stepping through the invalid pattern in \b invalidMask.
*/
/*************************************************************************************************/
void BbTesterSetInvalidAccessAddress(uint64_t chanMask, uint32_t invalidMask, bool_t forRx);
/*************************************************************************************************/
/*!
* \brief Enable bypassing PDU filtering.
*
* \param enable If TRUE enable bypass PDU filtering, FALSE otherwise.
*
* \return None.
*
* Enable bypassing PDU filtering.
*/
/*************************************************************************************************/
void BbTesterEnablePduFilterBypass(bool_t enable);
/* \} */
#ifdef __cplusplus
};
#endif
#endif /* LL_TESTER_API_H */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer scheduler interface file.
* \file
* \brief Link layer scheduler interface file.
*/
/*************************************************************************************************/
@ -30,6 +31,37 @@
extern "C" {
#endif
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! \brief Preferred periodicity. */
#define SCH_RM_PREF_PER_USEC 10000
/*! \brief Preferred periodicity for connections. */
#define SCH_RM_PREF_PER_CONN_USEC (SCH_RM_PREF_PER_USEC)
/*! \brief Preferred periodicity for periodic sync. */
#define SCH_RM_PREF_PER_SYNC_USEC (SCH_RM_PREF_PER_USEC * 4)
/**************************************************************************************************
Constants
**************************************************************************************************/
/*! \brief Resource manager preference for setting interval. */
enum
{
SCH_RM_PREF_PERFORMANCE, /*!< Performance is preferred, search from minimum interval. */
SCH_RM_PREF_CAPACITY /*!< Capacity is preferred, search from maximum interval. */
};
/**************************************************************************************************
Data Types
**************************************************************************************************/
/*! \brief Get reference time callback signature. */
typedef uint32_t (*GetRefTimeCb_t)(uint8_t handle, uint32_t *pDurUsec);
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
@ -37,19 +69,22 @@ extern "C" {
/* Resource manager */
void SchRmInit(void);
uint32_t SchRmPreferredPeriodUsec(void);
bool_t SchRmAdd(uint8_t handle, uint32_t minUsec, uint32_t maxUsec, uint32_t durUsec, uint32_t *pInterUsec);
bool_t SchRmStartUpdate(uint8_t handle, uint32_t minUsec, uint32_t maxUsec, uint32_t durUsec, uint32_t *pInterUsec);
uint32_t SchRmCalcCommonPeriodicityUsec(uint32_t peerPerUsec);
bool_t SchRmAdd(uint8_t handle, uint8_t pref, uint32_t minUsec, uint32_t maxUsec, uint32_t durUsec, uint32_t *pInterUsec, GetRefTimeCb_t refTimeCb);
bool_t SchRmStartUpdate(uint8_t handle, uint32_t minUsec, uint32_t maxUsec, uint32_t perfPerUsec, uint32_t durUsec, uint32_t *pInterUsec);
void SchRmCommitUpdate(uint8_t handle);
void SchRmRemove(uint8_t handle);
void SchRmSetReference(uint8_t handle);
uint32_t SchRmGetOffsetUsec(uint32_t rsvnOffs[], uint32_t maxOffsUsec, uint8_t handle);
uint32_t SchRmGetOffsetUsec(uint32_t maxOffsUsec, uint8_t handle, uint32_t refTime);
/* BLE time utilities */
uint32_t SchBleCalcDataPktDurationUsec(uint8_t phy, uint16_t len);
uint32_t SchBleCalcAdvPktDurationUsec(uint8_t phy, uint8_t phyOptions, uint16_t len);
uint32_t SchBleCalcPerAdvDurationUsec(uint8_t txPhy, uint8_t fragLen, uint16_t addMafDelay, uint16_t len, bool_t worstCase, uint8_t phyOptions);
uint32_t SchBleCalcAuxPktDurationUsec(uint8_t phy, uint8_t phyOptions, uint16_t len);
void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod);
void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen);
bool_t SchBleGetNextMstConnDueTime(uint32_t *pDueTime);
uint32_t SchBleGetAlignedAuxOffsUsec(uint32_t auxOffsUsec);
#ifdef __cplusplus
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,10 +16,17 @@
/*************************************************************************************************/
/*!
* \brief Baseband interface file.
* \file
* \brief Baseband interface file.
*
* \addtogroup BB_API Baseband (BB) API
* \{
*
* The baseband porting layer is a protocol independent BB + radio abstraction layer. It allows
* the simultaneous operation of protocol specific schedulers to transport packets across each
* medium via a single multi-protocol baseband. This interface describes operations for the
* following protocols:
*
* - Bluetooth low energy: advertising and connections
* - ZigBee/802.15.4 (TBD)
* - BAN/802.15.6 (TBD)
@ -73,86 +80,8 @@ extern "C" {
/*! \addtogroup BB_API_BOD
* \{ */
/*! \brief Protocol types */
enum
{
BB_PROT_NONE, /*!< Non-protocol specific operation. */
BB_PROT_BLE, /*!< Bluetooth Low Energy normal mode. */
BB_PROT_BLE_DTM, /*!< Bluetooth Low Energy direct test mode. */
BB_PROT_PRBS15, /*!< Enable the continuous PRBS15 transmit sequence. */
BB_PROT_15P4, /*!< 802.15.4. */
BB_PROT_NUM /*!< Number of protocols. */
};
/*! \brief Status codes */
enum
{
BB_STATUS_SUCCESS, /*!< Operation successful. */
BB_STATUS_FAILED, /*!< General failure. */
BB_STATUS_CANCELED, /*!< Receive canceled. */
BB_STATUS_RX_TIMEOUT, /*!< Receive packet timeout. */
BB_STATUS_CRC_FAILED, /*!< Receive packet with CRC verification failed. */
BB_STATUS_FRAME_FAILED, /*!< Receive packet with frame verification failed. */
BB_STATUS_ACK_FAILED, /*!< ACK packet failure. */
BB_STATUS_ACK_TIMEOUT, /*!< ACK packet timeout. */
BB_STATUS_TX_CCA_FAILED, /*!< Transmit CCA failure. */
BB_STATUS_TX_FAILED /*!< Transmit failure. */
};
/*! \brief PHY types. */
enum
{
BB_PHY_BLE_1M = 1, /*!< Bluetooth Low Energy 1Mbps PHY. */
BB_PHY_BLE_2M = 2, /*!< Bluetooth Low Energy 2Mbps PHY. */
BB_PHY_BLE_CODED = 3, /*!< Bluetooth Low Energy Coded PHY (data coding unspecified). */
BB_PHY_15P4 = 4, /*!< 802.15.4 PHY. */
};
/*! \brief PHY options. */
enum
{
BB_PHY_OPTIONS_DEFAULT = 0, /*!< BB defined PHY Options behavior. */
BB_PHY_OPTIONS_BLE_S2 = 1, /*!< Always use S=2 coding when transmitting on LE Coded PHY. */
BB_PHY_OPTIONS_BLE_S8 = 2 /*!< Always use S=8 coding when transmitting on LE Coded PHY. */
};
/*! \} */ /* BB_API_BOD */
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! \brief Binary divide with 1,000,000 divisor (n[max]=0xFFFFFFFF). */
#define BB_MATH_DIV_10E6(n) ((uint32_t)(((uint64_t)(n) * UINT64_C(4295)) >> 32))
#if (BB_CLK_RATE_HZ == 1000000)
/*! \brief Return microseconds (no conversion required). */
#define BB_US_TO_BB_TICKS(us) (us)
#elif (BB_CLK_RATE_HZ == 8000000)
/*! \brief Compute BB ticks from given time in microseconds (max time is interval=1,996s). */
#define BB_US_TO_BB_TICKS(us) ((uint32_t)((us) << 3))
#elif (BB_CLK_RATE_HZ == 32768)
/*! \brief Compute BB ticks from given time in microseconds (max time is interval=1,996s). */
#define BB_US_TO_BB_TICKS(us) ((uint32_t)(((uint64_t)(us) * UINT64_C(549755)) >> 24)) /* calculated value may be one tick low */
#else
/*! \brief Compute BB ticks from given time in microseconds (max time is interval=1,996s). */
#define BB_US_TO_BB_TICKS(us) BB_MATH_DIV_10E6((uint64_t)(us) * (uint64_t)(BB_CLK_RATE_HZ))
#endif
#if (BB_CLK_RATE_HZ == 1000000)
/*! \brief BB ticks to microseconds (no conversion required). */
#define BB_TICKS_TO_US(n) (n)
#elif (BB_CLK_RATE_HZ == 8000000)
/*! \brief BB ticks to microseconds (8MHz). */
#define BB_TICKS_TO_US(n) ((n) >> 3)
#elif (BB_CLK_RATE_HZ == 32768)
/*! \brief BB ticks to microseconds (32768 Hz). */
#define BB_TICKS_TO_US(n) (uint32_t)(((uint64_t)(n) * 15625) >> 9)
#else
/*! \brief BB ticks to microseconds. */
#define BB_TICKS_TO_US(n) (uint32_t)((uint64_t)(n) * 1000000 / BB_CLK_RATE_HZ)
#endif
/**************************************************************************************************
Data Types
**************************************************************************************************/
@ -160,16 +89,6 @@ enum
/*! \addtogroup BB_API_INIT
* \{ */
/*! \brief Typical maximum duration to scan in a scan interval (BbRtCfg_t::maxScanPeriodMs). */
#define BB_MAX_SCAN_PERIOD_MS 1000
/*! \brief Typical RF setup delay (BbRtCfg_t::rfSetupDelayUs). */
#define BB_RF_SETUP_DELAY_US 150
/*! \brief Typical operation setup delay in microseconds (BbRtCfg_t::schSetupDelayUs). */
#define BB_SCH_SETUP_DELAY_US 500
/*! \brief BB runtime configuration parameters. */
typedef struct
{
@ -240,6 +159,7 @@ typedef struct BbOpDesc_tag
BbBodCback_t abortCback; /*!< Abort BOD callback (when BOD is removed before beginning). */
void *pCtx; /*!< Client defined context. */
uint16_t *pDataLen; /*!< Pointer to client data length. */
union
{
@ -379,12 +299,13 @@ BbOpDesc_t *BbGetCurrentBod(void);
/*************************************************************************************************/
/*!
* \brief Cancel current executing BOD.
* \brief Set termination flag of current executing BOD.
*
* \return None.
*
* \note This function is expected to be called during the execution context of the
* current executing BOD, typically in the related ISRs.
* current executing BOD, typically in the related ISRs. In the end, termination
* flag will help to decide if BbTerminateBod() should be called.
*/
/*************************************************************************************************/
void BbSetBodTerminateFlag(void);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief MAC system configuration.
* \file
* \brief MAC system configuration.
*/
/*************************************************************************************************/
@ -43,6 +44,11 @@ extern "C" {
#define CHCI_BUF_TAILROOM 4 /*!< Extra byte allocation required for buffer (e.g., for MIC). */
#endif
/*** Scheduler ***/
#ifndef SCH_TIMER_REQUIRED
#define SCH_TIMER_REQUIRED TRUE /*!< If hardware timer is required for radio access scheduler.*/
#endif
#ifdef __cplusplus
};
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief BLE MAC system configuration.
* \file
* \brief BLE MAC system configuration.
*/
/*************************************************************************************************/
@ -49,6 +50,10 @@ extern "C" {
#define LL_MAX_ADV_SETS 6 /*!< Absolute maximum number of advertising sets. */
#endif
#ifndef LL_MAX_PHYS
#define LL_MAX_PHYS 3 /*!< Absolute maximum number of PHYs supported. */
#endif
#ifndef LL_MAX_PER_SCAN
#define LL_MAX_PER_SCAN 6 /*!< Absolute maximum number of periodic scanners (maximum is 32). */
#endif
@ -57,6 +62,18 @@ extern "C" {
#define LL_ENABLE_TESTER 0 /*!< Enable LL tester extensions. */
#endif
#ifndef LL_ENABLE_CALIBRATION
#define LL_ENABLE_CALIBRATION 0 /*!< Enable LL calibration extensions. */
#endif
#ifndef LL_MAX_CIG
#define LL_MAX_CIG 2 /*!< Absolute maximum number of connected isochronous groups. */
#endif
#ifndef LL_MAX_CIS
#define LL_MAX_CIS 2 /*!< Absolute maximum number of connected isochronous streams per CIG. */
#endif
#ifndef LHCI_ENABLE_VS
#define LHCI_ENABLE_VS 1 /*!< Enable vendor specific command processing. */
#endif
@ -64,7 +81,7 @@ extern "C" {
/*** Scheduler ***/
#ifndef SCH_RM_MAX_RSVN
#define SCH_RM_MAX_RSVN (LL_MAX_CONN + LL_MAX_ADV_SETS) /*!< Maximum number of reservations (maximum is 32). */
#define SCH_RM_MAX_RSVN (LL_MAX_CONN + LL_MAX_ADV_SETS + LL_MAX_CIG) /*!< Maximum number of reservations (maximum is 32). */
#endif
/*** Baseband ***/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Controller HCI transport API.
* \file
* \brief Controller HCI transport API.
*/
/*************************************************************************************************/
@ -37,6 +38,7 @@ enum
CHCI_TR_PROT_BLE = 0, /*!< BLE protocol. */
CHCI_TR_PROT_BOOT = 1, /*!< Boot protocol. */
CHCI_TR_PROT_15P4 = 2, /*!< 802.15.4 protocol */
CHCI_TR_PROT_CAL = 3, /*!< Radio Calibration protocol */
CHCI_TR_PROT_NUM /*!< Number of protocols. */
};
@ -44,8 +46,9 @@ enum
enum
{
CHCI_TR_TYPE_CMD = 0, /*!< Command message (receive only). */
CHCI_TR_TYPE_DATA, /*!< Data message (send or receive). */
CHCI_TR_TYPE_DATA, /*!< ACL data message (send or receive). */
CHCI_TR_TYPE_EVT, /*!< Event message (send only). */
CHCI_TR_TYPE_ISO, /*!< ISO data message (send or receive). */
CHCI_TR_TYPE_NUM /*!< Number of types. */
};
@ -62,9 +65,21 @@ enum
/*! \brief 802.15.4 protocol data type. */
#define CHCI_15P4_DATA_TYPE 0x81
/*! \brief Radio calibration command type. */
#define CHCI_CAL_CMD_TYPE 0xF1
/*! \brief Radio calibration signal type. */
#define CHCI_CAL_SIG_TYPE 0xF2
/*! \brief Radio calibration event type. */
#define CHCI_CAL_EVT_TYPE 0xF4
/*! \brief 802.15.4 protocol header length. */
#define CHCI_15P4_HDR_LEN 3
/*! \brief Radio calibration header length. */
#define CHCI_CAL_HDR_LEN 3
/*! \brief Message received callback. */
typedef void (*ChciTrRecvCback_t)(uint8_t type, uint8_t *pBuf);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Controller HCI transport interface file.
* \file
* \brief Controller HCI transport interface file.
*/
/*************************************************************************************************/
@ -31,20 +32,22 @@ extern "C" {
#endif
/**************************************************************************************************
Function Declarations
Macros
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \brief Signal the completion of a message write.
*
* \return None.
*
* This routine is used for asynchronous write operations. When the driver has completed the
* use of the write buffer, this routine is called to free the buffer and release flow control.
*/
/*************************************************************************************************/
void chciTrSendComplete(void);
#ifndef UART_BAUD
/*! \brief Default UART baud rate. */
#define UART_BAUD 1000000
#endif
#ifndef UART_DEFAULT_CONFIG_HWFC
/*! \brief Default Hardware Flow Control. */
#define UART_DEFAULT_CONFIG_HWFC 1
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
@ -61,14 +64,12 @@ void chciTrRecv(uint8_t prot, uint8_t type, uint8_t *pBuf);
/*************************************************************************************************/
/*!
* \brief Signal a hardware error.
* \brief Service the transport device.
*
* \param code Error code.
*
* \return None.
* \return TRUE if work pending, FALSE if no work is pending.
*/
/*************************************************************************************************/
void chciTrHwError(uint8_t code);
bool_t ChciTrService(void);
#ifdef __cplusplus
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Multi-protocol scheduler interface file.
* \file
* \brief Multi-protocol scheduler interface file.
*/
/*************************************************************************************************/
@ -50,6 +51,7 @@ uint16_t SchStatsGetHandlerWatermarkUsec(void);
/* Control */
void SchHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
void SchLoadHandler(void);
/* List maintenance */
void SchInsertNextAvailable(BbOpDesc_t *pBod);
@ -58,9 +60,7 @@ bool_t SchInsertEarlyAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max);
bool_t SchInsertLateAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max);
bool_t SchRemove(BbOpDesc_t *pBod);
void SchReload(BbOpDesc_t *pBod);
void SchRemoveBackground(void);
void SchInsertBackground(BbOpDesc_t *pBod);
void SchTerminateBackground(void);
bool_t SchIsBodCancellable(BbOpDesc_t *pBod);
#ifdef __cplusplus
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,12 +16,13 @@
/*************************************************************************************************/
/*!
* \brief Scanning master BLE baseband porting implementation file.
* \file
* \brief Scanning master BLE baseband porting implementation file.
*/
/*************************************************************************************************/
#include "bb_api.h"
#include "bb_drv.h"
#include "pal_bb.h"
#include "bb_ble_int.h"
#include "sch_api.h"
#include "wsf_math.h"
@ -31,12 +32,6 @@
Macros
**************************************************************************************************/
/*! \brief Guard time at the end of a scan window to the next BOD. Backoff one advertise data exchange. */
#define BB_SCAN_GUARD_US (LL_ADV_PKT_MAX_USEC + LL_BLE_TIFS_US + \
LL_SCAN_REQ_MAX_USEC + LL_BLE_TIFS_US + \
LL_SCAN_RSP_MAX_USEC + \
BbGetSchSetupDelayUs())
/*! \brief Event states for scan operations. */
enum
{
@ -128,7 +123,7 @@ static bool_t bbContScanOp(BbOpDesc_t *pBod, BbBleMstAdvEvent_t *pScan)
return TRUE;
}
uint32_t curTime = BbDrvGetCurrentTime();
uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK);
pScan->elapsedUsec += BB_TICKS_TO_US(curTime - bbBleCb.lastScanStart);
bbBleCb.lastScanStart = curTime;
@ -142,7 +137,7 @@ static bool_t bbContScanOp(BbOpDesc_t *pBod, BbBleMstAdvEvent_t *pScan)
bbBleCb.bbParam.due = bbBleCb.lastScanStart + BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs());
bbBleCb.bbParam.dueOffsetUsec = 0;
bbBleCb.bbParam.rxTimeoutUsec = scanDurUsec;
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleCb.evtState = BB_EVT_STATE_RX_ADV_IND;
@ -154,7 +149,7 @@ static bool_t bbContScanOp(BbOpDesc_t *pBod, BbBleMstAdvEvent_t *pScan)
{
bbBleClrIfs(); /* passive scan */
}
BbBleDrvRxData(pScan->pRxAdvBuf, BB_ADVB_MAX_LEN);
PalBbBleRxData(pScan->pRxAdvBuf, BB_ADVB_MAX_LEN);
return FALSE;
}
@ -200,7 +195,7 @@ static void bbMstScanTxCompCback(uint8_t status)
BB_ISR_MARK(bbScanStats.rxSetupUsec);
bbBleClrIfs(); /* last operation in event */
BbBleDrvRxTifsData(pScan->pRxRspBuf, BB_ADVB_MAX_LEN);
PalBbBleRxTifsData(pScan->pRxRspBuf, BB_ADVB_MAX_LEN);
/* Rx may fail; no more important statements in the !bodComplete code path */
}
@ -240,10 +235,11 @@ static void bbMstScanTxCompCback(uint8_t status)
if (bodCont)
{
/* Cancel TIFS timer if active. */
/* coverity[dead_error_condition] */
switch (status)
{
case BB_STATUS_SUCCESS:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
/* coverity[dead_error_begin] */
@ -313,10 +309,10 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint
BB_ISR_MARK(bbScanStats.txSetupUsec);
BbBleDrvTxBufDesc_t desc = {.pBuf = pScan->pTxReqBuf, .len = pScan->txReqLen};
PalBbBleTxBufDesc_t desc = {.pBuf = pScan->pTxReqBuf, .len = pScan->txReqLen};
bbBleSetIfs();
BbBleDrvTxTifsData(&desc, 1);
PalBbBleTxTifsData(&desc, 1);
/* Tx may fail; no more important statements in the !bodComplete code path */
}
@ -425,7 +421,7 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint
{
case BB_STATUS_SUCCESS:
case BB_STATUS_CRC_FAILED:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -471,14 +467,14 @@ static void bbMstExecuteScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
bbBleCb.lastScanStart = pBod->due;
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.txCback = bbMstScanTxCompCback;
bbBleCb.bbParam.rxCback = bbMstScanRxCompCback;
bbBleCb.bbParam.rxTimeoutUsec = scanDurUsec;
bbBleCb.bbParam.due = pBod->due;
bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec;
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleCb.evtState = 0;
@ -490,7 +486,7 @@ static void bbMstExecuteScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
bbBleClrIfs(); /* passive scan */
}
BbBleDrvRxData(pScan->pRxAdvBuf, BB_ADVB_MAX_LEN);
PalBbBleRxData(pScan->pRxAdvBuf, BB_ADVB_MAX_LEN);
/* Rx may fail; no more important statements in the !bodComplete code path */
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Extended scanning master BLE baseband porting implementation file.
* \file
* \brief Extended scanning master BLE baseband porting implementation file.
*/
/*************************************************************************************************/
@ -83,7 +84,7 @@ static void bbMstAuxScanTxCompCback(uint8_t status)
BB_ISR_MARK(bbAuxScanStats.rxSetupUsec);
bbBleClrIfs(); /* Prepare for SCAN_OR_CONN_RSP */
BbBleDrvRxTifsData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
PalBbBleRxTifsData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
break;
}
@ -175,10 +176,10 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u
BB_ISR_MARK(bbAuxScanStats.txSetupUsec);
BbBleDrvTxBufDesc_t desc = {.pBuf = pAuxScan->pTxAuxReqBuf, .len = pAuxScan->txAuxReqLen};
PalBbBleTxBufDesc_t desc = {.pBuf = pAuxScan->pTxAuxReqBuf, .len = pAuxScan->txAuxReqLen};
bbBleSetIfs();
BbBleDrvTxTifsData(&desc, 1);
PalBbBleTxTifsData(&desc, 1);
}
}
else if ((pAuxScan->rxAuxChainCback) &&
@ -189,16 +190,16 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u
bbBleCb.evtState = BB_EVT_STATE_RX_CHAIN_IND;
/* Cancel Tifs operation is needed for passive scan and non connectable/scannable adv with chain. */
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
BB_ISR_MARK(bbAuxScanStats.rxSetupUsec);
bbBleClrIfs(); /* CHAIN_IND does not use TIFS. */
BbBleDrvRxData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
PalBbBleRxData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
WSF_ASSERT(pAuxScan->rxAuxChainPostCback);
if (pAuxScan->rxAuxChainPostCback(pCur, bbAuxAdvBuf) == FALSE)
@ -269,14 +270,14 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u
if ((pAuxScan->rxAuxChainCback) &&
((auxOffsetUsec = pAuxScan->rxAuxChainCback(pCur, bbAuxAdvBuf)) > 0))
{
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
BB_ISR_MARK(bbAuxScanStats.rxSetupUsec);
bbBleClrIfs(); /* CHAIN_IND does not use TIFS. */
BbBleDrvRxData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
PalBbBleRxData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
WSF_ASSERT(pAuxScan->rxAuxChainPostCback);
if (pAuxScan->rxAuxChainPostCback(pCur, bbAuxAdvBuf) == FALSE)
@ -342,14 +343,14 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u
uint32_t auxOffsetUsec;
if ((auxOffsetUsec = pAuxScan->rxAuxChainCback(pCur, bbAuxAdvBuf)) > 0)
{
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
BB_ISR_MARK(bbAuxScanStats.rxSetupUsec);
bbBleClrIfs(); /* CHAIN_IND does not use TIFS. */
BbBleDrvRxData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
PalBbBleRxData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
WSF_ASSERT(pAuxScan->rxAuxChainPostCback);
if (pAuxScan->rxAuxChainPostCback(pCur, bbAuxAdvBuf) == FALSE)
@ -421,7 +422,7 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u
{
case BB_STATUS_SUCCESS:
case BB_STATUS_CRC_FAILED:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -452,14 +453,14 @@ static void bbMstExecuteAuxScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
BbBleMstAuxAdvEvent_t * const pAuxScan = &pBod->prot.pBle->op.mstAuxAdv;
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.txCback = bbMstAuxScanTxCompCback;
bbBleCb.bbParam.rxCback = bbMstAuxScanRxCompCback;
bbBleCb.bbParam.rxTimeoutUsec = pAuxScan->rxSyncDelayUsec;
bbBleCb.bbParam.due = pBod->due;
bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec;
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleCb.evtState = 0;
@ -471,7 +472,7 @@ static void bbMstExecuteAuxScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
bbBleClrIfs(); /* passive scan */
}
BbBleDrvRxData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
PalBbBleRxData(bbAuxAdvBuf, sizeof(bbAuxAdvBuf));
}
/*************************************************************************************************/
@ -524,13 +525,13 @@ static void bbMstPerScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u
if ((auxOffsetUsec = pPerScan->rxPerAdvCback(pCur, bbPerScanBuf, status)) > 0)
{
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
BB_ISR_MARK(bbPerScanStats.rxSetupUsec);
bbBleClrIfs(); /* SYNC_IND does not use TIFS. */
BbBleDrvRxData(bbPerScanBuf, sizeof(bbPerScanBuf));
PalBbBleRxData(bbPerScanBuf, sizeof(bbPerScanBuf));
if (pPerScan->rxPerAdvPostCback(pCur, bbAuxAdvBuf) == FALSE)
{
@ -594,14 +595,14 @@ static void bbMstPerScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u
if ((auxOffsetUsec = pPerScan->rxPerAdvCback(pCur, bbPerScanBuf, status)) > 0)
{
/* Continue BOD with the CHAIN_IND and adjust the channel parameters. */
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
BB_ISR_MARK(bbPerScanStats.rxSetupUsec);
bbBleClrIfs(); /* SYNC_IND does not use TIFS. */
BbBleDrvRxData(bbPerScanBuf, sizeof(bbPerScanBuf));
PalBbBleRxData(bbPerScanBuf, sizeof(bbPerScanBuf));
if (pPerScan->rxPerAdvPostCback(pCur, bbAuxAdvBuf) == FALSE)
{
@ -665,7 +666,7 @@ static void bbMstPerScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u
{
case BB_STATUS_SUCCESS:
case BB_STATUS_CRC_FAILED:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -696,19 +697,19 @@ static void bbMstExecutePerScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
BbBleMstPerScanEvent_t * const pPerScan = &pBod->prot.pBle->op.mstPerScan;
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.rxCback = bbMstPerScanRxCompCback;
bbBleCb.bbParam.rxTimeoutUsec = pPerScan->rxSyncDelayUsec;
bbBleCb.bbParam.due = pBod->due;
bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec;
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleCb.evtState = 0;
bbBleClrIfs(); /* passive scan */
BbBleDrvRxData(bbPerScanBuf, sizeof(bbPerScanBuf));
PalBbBleRxData(bbPerScanBuf, sizeof(bbPerScanBuf));
}
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,20 +16,23 @@
/*************************************************************************************************/
/*!
* \brief Advertising slave BLE baseband porting implementation file.
* \file
* \brief Advertising slave BLE baseband porting implementation file.
*/
/*************************************************************************************************/
#include "bb_drv.h"
#include "pal_bb.h"
#include "bb_ble_int.h"
#include "sch_api.h"
#include "sch_api_ble.h"
#include "ll_math.h"
#include "ll_api.h"
#include "lmgr_api_adv_slave.h"
#include <string.h>
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! \brief Event states for advertising operations. */
enum
{
@ -73,13 +76,15 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s
/* Compute next channel. */
do
{
if (bbBleCb.advChIdx >= LL_NUM_CHAN_ADV)
if (bbBleCb.numChUsed == LL_NUM_CHAN_ADV)
{
/* BOD completed. */
return TRUE;
}
bbBleCb.advChIdx = bbBleCb.advChIdx % LL_NUM_CHAN_ADV;
pBle->chan.chanIdx = LL_CHAN_ADV_MIN_IDX + bbBleCb.advChIdx;
bbBleCb.numChUsed++;
/* Selected channel in channel map; use this channel. */
} while (!((1 << bbBleCb.advChIdx++) & pAdv->advChMap));
@ -91,14 +96,14 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s
{
case BB_STATUS_SUCCESS:
case BB_STATUS_CRC_FAILED:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
}
}
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
if (firstOpInSet)
{
@ -108,14 +113,16 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s
{
if (pAdv->pRxReqBuf)
{
/* Schedule with relative framge gap. */
bbBleCb.bbParam.due = BbDrvGetCurrentTime() + BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs());
/* Schedule with relative frame gap. */
bbBleCb.bbParam.due = PalBbGetCurrentTime(USE_RTC_BB_CLK) + BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs());
}
else
{
/* Schedule with absolute frame gap. */
bbBleCb.bbParam.due += (BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, pAdv->txAdvLen)) +
BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs()));
uint32_t advGap = (BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, pAdv->txAdvLen)) +
BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs()));
bbBleCb.bbParam.due += SchBleGetAlignedAuxOffsUsec(advGap);
}
}
@ -126,7 +133,7 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s
pAdv->txAdvSetupCback(pBod, bbBleCb.bbParam.due);
}
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
if (pAdv->pRxReqBuf)
{
@ -136,8 +143,8 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s
{
bbBleClrIfs(); /* non-connectable advertising */
}
BbBleDrvTxBufDesc_t desc = {.pBuf = pAdv->pTxAdvBuf, .len = pAdv->txAdvLen};
BbBleDrvTxData(&desc, 1);
PalBbBleTxBufDesc_t desc = {.pBuf = pAdv->pTxAdvBuf, .len = pAdv->txAdvLen};
PalBbBleTxData(&desc, 1);
/* Tx may fail; no more important statements in the FALSE code path */
@ -181,7 +188,7 @@ static void bbSlvAdvTxCompCback(uint8_t status)
BB_ISR_MARK(bbAdvStats.rxSetupUsec);
bbBleSetIfs(); /* set up for Tx SCAN_RSP */
BbBleDrvRxTifsData(pAdv->pRxReqBuf, BB_REQ_PDU_MAX_LEN); /* reduce max length requirement */
PalBbBleRxTifsData(pAdv->pRxReqBuf, BB_REQ_PDU_MAX_LEN); /* reduce max length requirement */
}
else
{
@ -213,7 +220,7 @@ Cleanup:
switch (status)
{
case BB_STATUS_SUCCESS:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -270,8 +277,8 @@ static void bbSlvAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint3
BB_ISR_MARK(bbAdvStats.txSetupUsec);
bbBleClrIfs(); /* last operation in event */
BbBleDrvTxBufDesc_t desc = {.pBuf = pAdv->pTxRspBuf, .len = pAdv->txRspLen};
BbBleDrvTxTifsData(&desc, 1);
PalBbBleTxBufDesc_t desc = {.pBuf = pAdv->pTxRspBuf, .len = pAdv->txRspLen};
PalBbBleTxTifsData(&desc, 1);
}
else
{
@ -330,7 +337,7 @@ static void bbSlvAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint3
{
case BB_STATUS_SUCCESS:
case BB_STATUS_CRC_FAILED:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -360,9 +367,9 @@ static void bbSlvExecuteAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
bbBleCb.bbParam.rxCback = bbSlvAdvRxCompCback;
bbBleCb.bbParam.rxTimeoutUsec = 2 * LL_MAX_TIFS_DEVIATION;
bbBleCb.bbParam.dueOffsetUsec = 0;
bbBleCb.advChIdx = 0;
bbBleCb.evtState = 0;
bbBleCb.numChUsed = 0;
bbBleCb.advChIdx = pAdv->firstAdvChIdx;
if (bbSetupAdvOp(pBod, pAdv, BB_STATUS_SUCCESS, TRUE))
{
@ -382,7 +389,7 @@ static void bbSlvExecuteAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
/*************************************************************************************************/
static void bbSlvCancelAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
BbBleDrvCancelData();
PalBbBleCancelData();
}
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Extended advertising slave BLE baseband porting implementation file.
* \file
* \brief Extended advertising slave BLE baseband porting implementation file.
*/
/*************************************************************************************************/
@ -71,15 +72,15 @@ static bool_t bbSlvAdvSetupTxAuxChainInd(BbOpDesc_t *pCur, BbBleSlvAuxAdvEvent_t
}
/* Set updated auxiliary channel. */
BbBleDrvSetChannelParam(&pCur->prot.pBle->chan);
PalBbBleSetChannelParam(&pCur->prot.pBle->chan);
/* Offset may be up to 1 unit earlier than actual transmission. */
bbBleCb.bbParam.due += BB_US_TO_BB_TICKS(auxOffsUsec);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
BB_ISR_MARK(bbAuxAdvStats.rxSetupUsec);
bbBleClrIfs(); /* CHAIN_IND does not use TIFS. */
BbBleDrvTxData(pAuxAdv->txAuxChainPdu, 2);
PalBbBleTxData(pAuxAdv->txAuxChainPdu, 2);
/* Operation continues. */
return FALSE;
@ -130,7 +131,7 @@ static void bbSlvAuxAdvTxCompCback(uint8_t status)
bbBleCb.evtState = BB_EVT_STATE_RX_SCAN_OR_CONN_REQ;
BB_ISR_MARK(bbAuxAdvStats.rxSetupUsec);
bbBleSetIfs(); /* set up for Tx SCAN_RSP */
BbBleDrvRxTifsData(pAuxAdv->pRxAuxReqBuf, BB_REQ_PDU_MAX_LEN); /* reduce max length requirement */
PalBbBleRxTifsData(pAuxAdv->pRxAuxReqBuf, BB_REQ_PDU_MAX_LEN); /* reduce max length requirement */
}
BB_INC_STAT(bbAuxAdvStats.txAdv);
break;
@ -138,7 +139,7 @@ static void bbSlvAuxAdvTxCompCback(uint8_t status)
case BB_EVT_STATE_TX_SCAN_RSP:
bbBleCb.evtState = BB_EVT_STATE_TX_CHAIN_IND;
bbBleCb.bbParam.due = pAuxAdv->auxReqStartTs +
BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxAdv->auxRxPhyOptions, LL_ADV_HDR_LEN + LL_SCAN_REQ_PDU_LEN )) +
BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxAdv->auxRxPhyOptions, LL_ADV_HDR_LEN + LL_SCAN_REQ_PDU_LEN)) +
BB_US_TO_BB_TICKS(LL_BLE_TIFS_US);
bodComplete = bbSlvAdvSetupTxAuxChainInd(pCur, pAuxAdv);
BB_INC_STAT(bbAuxAdvStats.txRsp);
@ -165,7 +166,7 @@ Cleanup:
switch (status)
{
case BB_STATUS_SUCCESS:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -220,7 +221,7 @@ static void bbSlvAuxAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, ui
BB_ISR_MARK(bbAuxAdvStats.txSetupUsec);
bbBleClrIfs(); /* last operation in event */
BbBleDrvTxTifsData(pAuxAdv->txAuxRspPdu, 2);
PalBbBleTxTifsData(pAuxAdv->txAuxRspPdu, 2);
if (pAuxAdv->rxAuxReqPostCback)
{
@ -276,7 +277,7 @@ static void bbSlvAuxAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, ui
{
case BB_STATUS_SUCCESS:
case BB_STATUS_CRC_FAILED:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -322,11 +323,11 @@ static void bbSlvExecuteAuxAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
pAuxAdv->txAuxSetupCback(pBod, FALSE);
}
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.due = pBod->due;
bbBleCb.evtState = BB_EVT_STATE_TX_ADV_IND;
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
if (pAuxAdv->pRxAuxReqBuf)
{
@ -339,7 +340,7 @@ static void bbSlvExecuteAuxAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
bbBleClrIfs();
}
BbBleDrvTxData(pAuxAdv->txAuxAdvPdu, 2);
PalBbBleTxData(pAuxAdv->txAuxAdvPdu, 2);
}
/*************************************************************************************************/
@ -376,11 +377,11 @@ static void bbSlvExecutePerAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
pAuxAdv->txAuxSetupCback(pBod, FALSE);
}
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.due = pBod->due;
bbBleCb.evtState = BB_EVT_STATE_TX_ADV_IND;
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
if (pAuxAdv->pRxAuxReqBuf)
{
@ -393,7 +394,7 @@ static void bbSlvExecutePerAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
bbBleClrIfs();
}
BbBleDrvTxData(pAuxAdv->txAuxAdvPdu, 2);
PalBbBleTxData(pAuxAdv->txAuxAdvPdu, 2);
}
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,12 +16,13 @@
/*************************************************************************************************/
/*!
* \brief Connectable BLE baseband porting implementation file.
* \file
* \brief Connectable BLE baseband porting implementation file.
*/
/*************************************************************************************************/
#include "bb_api.h"
#include "bb_drv.h"
#include "pal_bb.h"
#include "bb_ble_int.h"
#if BB_DATA_PLD_MAX_LEN < LL_MAX_DATA_LEN_MIN
@ -52,13 +53,13 @@ BbBleDataPktStats_t bbConnStats; /*!< Connection packet statistics. */
* callback routine.
*/
/*************************************************************************************************/
void BbBleTxData(BbBleDrvTxBufDesc_t descs[], uint8_t cnt)
void BbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt)
{
if ((BbGetCurrentBod()->prot.pBle->chan.opType == BB_BLE_OP_MST_CONN_EVENT) &&
(bbBleCb.evtState == 0))
{
bbBleSetIfs(); /* master always Rx's after Tx */
BbBleDrvTxData(descs, cnt);
PalBbBleTxData(descs, cnt);
}
else
{
@ -66,7 +67,7 @@ void BbBleTxData(BbBleDrvTxBufDesc_t descs[], uint8_t cnt)
/* TODO set only if master or if slave and Rx may follow in CE. */
bbBleSetIfs();
BbBleDrvTxTifsData(descs, cnt);
PalBbBleTxTifsData(descs, cnt);
}
}
@ -99,7 +100,7 @@ void BbBleRxData(uint8_t *pBuf, uint16_t len)
(bbBleCb.evtState == 0))
{
bbBleSetIfs(); /* slave always Tx's after Rx */
BbBleDrvRxData(pBuf, len);
PalBbBleRxData(pBuf, len);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,12 +16,13 @@
/*************************************************************************************************/
/*!
* \brief Connectable master BLE baseband porting implementation file.
* \file
* \brief Connectable master BLE baseband porting implementation file.
*/
/*************************************************************************************************/
#include "bb_api.h"
#include "bb_drv.h"
#include "pal_bb.h"
#include "bb_ble_int.h"
#include <string.h>
@ -51,6 +52,8 @@ static void bbMstConnTxCompCback(uint8_t status)
BbOpDesc_t * const pCur = BbGetCurrentBod();
BbBleMstConnEvent_t * const pConn = &pCur->prot.pBle->op.mstConn;
WSF_ASSERT(pCur);
pConn->txDataCback(pCur, status);
if (bbBleCb.pRxDataBuf &&
@ -59,7 +62,7 @@ static void bbMstConnTxCompCback(uint8_t status)
BB_ISR_MARK(bbConnStats.rxSetupUsec);
bbBleSetIfs(); /* TODO set only if Tx may follow in CE */
BbBleDrvRxTifsData(bbBleCb.pRxDataBuf, bbBleCb.rxDataLen);
PalBbBleRxTifsData(bbBleCb.pRxDataBuf, bbBleCb.rxDataLen);
}
else
{
@ -67,7 +70,7 @@ static void bbMstConnTxCompCback(uint8_t status)
switch (status)
{
case BB_STATUS_SUCCESS:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
case BB_STATUS_FAILED:
default:
@ -147,7 +150,7 @@ static void bbMstConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint
{
case BB_STATUS_SUCCESS:
case BB_STATUS_CRC_FAILED:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -189,7 +192,7 @@ static void bbMstConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint
/*************************************************************************************************/
static void bbMstExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
WSF_ASSERT(pBle->op.mstConn.txDataCback);
WSF_ASSERT(pBle->op.mstConn.rxDataCback);
@ -200,7 +203,7 @@ static void bbMstExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec;
bbBleCb.bbParam.rxTimeoutUsec = 2 * LL_MAX_TIFS_DEVIATION;
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleCb.evtState = 0;
@ -219,10 +222,11 @@ static void bbMstExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
/*************************************************************************************************/
static void bbMstCancelConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
WSF_ASSERT(pBod && pBle);
WSF_ASSERT(pBod);
WSF_ASSERT(pBle);
WSF_ASSERT(pBle->op.mstConn.rxDataCback);
BbBleDrvCancelData();
PalBbBleCancelData();
if (bbBleCb.pRxDataBuf)
{

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,12 +16,13 @@
/*************************************************************************************************/
/*!
* \brief Connectable slave BLE baseband porting implementation file.
* \file
* \brief Connectable slave BLE baseband porting implementation file.
*/
/*************************************************************************************************/
#include "bb_api.h"
#include "bb_drv.h"
#include "pal_bb.h"
#include "bb_ble_int.h"
#include <string.h>
@ -60,12 +61,12 @@ static void bbSlvConnTxCompCback(uint8_t status)
BB_ISR_MARK(bbConnStats.rxSetupUsec);
bbBleSetIfs(); /* slave always Tx's after Rx */
BbBleDrvRxTifsData(bbBleCb.pRxDataBuf, bbBleCb.rxDataLen);
PalBbBleRxTifsData(bbBleCb.pRxDataBuf, bbBleCb.rxDataLen);
}
else
{
/* Cancel TIFS timer if active. */
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
/* Tx completion is end of BOD. */
BbTerminateBod();
@ -131,8 +132,6 @@ static void bbSlvConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint
bbBleCb.evtState = 1;
pConn->startTs = timestamp;
bbBleCb.bbParam.rxTimeoutUsec = 2 * LL_MAX_TIFS_DEVIATION;
}
WSF_ASSERT(bbBleCb.pRxDataBuf);
@ -152,7 +151,7 @@ static void bbSlvConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint
{
case BB_STATUS_SUCCESS:
case BB_STATUS_CRC_FAILED:
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
break;
default:
break;
@ -199,7 +198,7 @@ static void bbSlvExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
WSF_ASSERT(pConn->txDataCback);
WSF_ASSERT(pConn->rxDataCback);
BbBleDrvSetChannelParam(&pBle->chan);
PalBbBleSetChannelParam(&pBle->chan);
bbBleCb.bbParam.txCback = bbSlvConnTxCompCback;
bbBleCb.bbParam.rxCback = bbSlvConnRxCompCback;
@ -207,7 +206,7 @@ static void bbSlvExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec;
bbBleCb.bbParam.rxTimeoutUsec = pConn->rxSyncDelayUsec;
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleCb.evtState = 0;
@ -226,10 +225,11 @@ static void bbSlvExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
/*************************************************************************************************/
static void bbSlvCancelConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
WSF_ASSERT(pBod && pBle);
WSF_ASSERT(pBod);
WSF_ASSERT(pBle);
WSF_ASSERT(pBle->op.slvConn.rxDataCback);
BbBleDrvCancelData();
PalBbBleCancelData();
if (bbBleCb.pRxDataBuf)
{

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal BLE baseband interface file.
* \file
* \brief Internal BLE baseband interface file.
*/
/*************************************************************************************************/
@ -25,8 +26,8 @@
#include "bb_ble_api.h"
#include "bb_ble_api_op.h"
#include "bb_ble_drv.h"
#include "bb_drv.h"
#include "pal_bb_ble.h"
#include "pal_bb.h"
#include "ll_defs.h"
#include "wsf_assert.h"
#include "wsf_math.h"
@ -44,10 +45,10 @@ extern "C" {
#define BB_ADVB_MAX_LEN WSF_MAX(BB_FIXED_ADVB_PKT_LEN, LL_ADVB_MAX_LEN)
/*! \brief Mark the start of an ISR. */
#define BB_ISR_START() bbIsrStartTime = BbDrvGetCurrentTime()
#define BB_ISR_START() bbIsrStartTime = PalBbGetCurrentTime(USE_RTC_BB_CLK)
/*! \brief Mark the ISR duration, recording the high watermark. */
#define BB_ISR_MARK(x) x = WSF_MAX(x, BB_TICKS_TO_US(BbDrvGetCurrentTime() - bbIsrStartTime))
#define BB_ISR_MARK(x) x = WSF_MAX(x, BB_TICKS_TO_US(PalBbGetCurrentTime(USE_RTC_BB_CLK) - bbIsrStartTime))
/**************************************************************************************************
Data Types
@ -67,18 +68,23 @@ typedef struct
uint8_t evtState; /*!< Action state of the currently operating BOD. */
uint8_t advChIdx; /*!< Current advertising channel index. */
uint8_t numChUsed; /*!< Total number of channels visited. */
uint32_t lastScanStart; /*!< Last scan start time. */
BbBleDrvDataParam_t bbParam; /*!< Baseband data parameters. */
PalBbBleDataParam_t bbParam; /*!< Baseband data parameters. */
uint16_t rxDataLen; /*!< Receive data buffer length. */
uint8_t *pRxDataBuf; /*!< Current Rx data buffer. */
uint16_t rxCisDataLen; /*!< Receive CIS data buffer length. */
uint8_t *pRxCisDataBuf; /*!< Current Rx CIS data buffer. */
} bbBleCtrlBlk_t;
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/* BB BLE Control Block. */
extern bbBleCtrlBlk_t bbBleCb;
/* ISR start time. */
@ -112,8 +118,8 @@ void bbBleRegisterOp(uint8_t opType, bbBleExecOpFn_t execOpCback, bbBleExecOpFn_
/*************************************************************************************************/
static inline void bbBleClrIfs(void)
{
BbBleDrvOpParam_t opParams = { .ifsSetup = FALSE, .ifsUsec = 0 };
BbBleDrvSetOpParams(&opParams);
PalBbBleOpParam_t opParams = { .ifsSetup = FALSE, .ifsUsec = 0 };
PalBbBleSetOpParams(&opParams);
}
/*************************************************************************************************/
@ -127,8 +133,8 @@ static inline void bbBleClrIfs(void)
/*************************************************************************************************/
static inline void bbBleSetIfs(void)
{
BbBleDrvOpParam_t opParams = { .ifsSetup = TRUE, .ifsUsec = LL_BLE_TIFS_US };
BbBleDrvSetOpParams(&opParams);
PalBbBleOpParam_t opParams = { .ifsSetup = TRUE, .ifsUsec = LL_BLE_TIFS_US };
PalBbBleSetOpParams(&opParams);
}
#endif /* BB_BLE_INT_H */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,13 +16,14 @@
/*************************************************************************************************/
/*!
* \brief Generic BLE baseband driver implementation file.
* \file
* \brief Generic BLE baseband driver implementation file.
*/
/*************************************************************************************************/
#include "bb_api.h"
#include "bb_ble_int.h"
#include "bb_ble_drv.h"
#include "pal_bb_ble.h"
#include <string.h>
/**************************************************************************************************
@ -44,8 +45,8 @@ bbBleCtrlBlk_t bbBleCb; /*!< BB BLE control block. */
/*************************************************************************************************/
static void bbBleStartBle(void)
{
BbBleDrvEnable();
BbBleDrvEnableDataWhitening(TRUE);
PalBbBleEnable();
PalBbBleEnableDataWhitening(TRUE);
}
/*************************************************************************************************/
@ -57,7 +58,7 @@ static void bbBleStartBle(void)
/*************************************************************************************************/
static void bbBleStopBle(void)
{
BbBleDrvDisable();
PalBbBleDisable();
}
/*************************************************************************************************/
@ -69,8 +70,8 @@ static void bbBleStopBle(void)
/*************************************************************************************************/
static void bbBleStartBleDtm(void)
{
BbBleDrvEnable();
BbBleDrvEnableDataWhitening(FALSE);
PalBbBleEnable();
PalBbBleEnableDataWhitening(FALSE);
}
/*************************************************************************************************/
@ -82,9 +83,9 @@ static void bbBleStartBleDtm(void)
/*************************************************************************************************/
static void bbBleStartPrbs15(void)
{
BbBleDrvEnable();
BbBleDrvEnableDataWhitening(FALSE);
BbBleDrvEnablePrbs15(TRUE);
PalBbBleEnable();
PalBbBleEnableDataWhitening(FALSE);
PalBbBleEnablePrbs15(TRUE);
}
/*************************************************************************************************/
@ -96,8 +97,8 @@ static void bbBleStartPrbs15(void)
/*************************************************************************************************/
static void bbBleStopPrbs15(void)
{
BbBleDrvDisable();
BbBleDrvEnablePrbs15(FALSE);
PalBbBleDisable();
PalBbBleEnablePrbs15(FALSE);
}
/*************************************************************************************************/
@ -152,7 +153,7 @@ static void bbBleCancelOp(BbOpDesc_t *pBod)
/*************************************************************************************************/
void BbBleInit(void)
{
BbBleDrvInit();
PalBbBleInit();
BbRegisterProt(BB_PROT_BLE, bbBleExecOp, bbBleCancelOp, bbBleStartBle, bbBleStopBle);
BbRegisterProt(BB_PROT_BLE_DTM, bbBleExecOp, bbBleCancelOp, bbBleStartBleDtm, bbBleStopBle);
BbRegisterProt(BB_PROT_PRBS15, NULL, bbBleCancelOp, bbBleStartPrbs15, bbBleStopPrbs15);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Generic BLE device filtering implementation file.
* \file
* \brief Generic BLE device filtering implementation file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Generic BLE whitelist implementation file.
* \file
* \brief Generic BLE whitelist implementation file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Generic BLE resolving list implementation file.
* \file
* \brief Generic BLE resolving list implementation file.
*/
/*************************************************************************************************/
@ -24,7 +25,8 @@
#include "bb_ble_api.h"
#include "bb_ble_api_reslist.h"
#include "bb_ble_api_pdufilt.h"
#include "bb_ble_drv.h"
#include "pal_bb_ble.h"
#include "pal_crypto.h"
#include "wsf_assert.h"
#include "ll_math.h"
#include "util/bda.h"
@ -59,6 +61,7 @@ typedef struct
bool_t localIrkZero; /*!< Indicates that local IRK is zero. */
bool_t peerRpaGenerated; /*!< Indicates that peer RPA was locally generated. */
uint8_t privMode; /*!< Privacy mode. */
bool_t isRpaUpd; /*!< TRUE if either lcaol RPA or peer RPA is updated. */
} bbBleResListEntry_t;
/**************************************************************************************************
@ -184,7 +187,7 @@ static uint32_t bbGenerateHash(const uint8_t *pIrk, uint32_t r)
rprime[2] = ((r >> 16) & 0xFF);
/* r' = e(k, r') */
LlMathAesEcb(pIrk, rprime, rprime);
PalCryptoAesEcb(pIrk, rprime, rprime);
/* ah(k, r) = e(k, r') mod 2^24 */
hash = (rprime[0] << 0) |
@ -210,7 +213,7 @@ static uint64_t bbGenerateRpa(const uint8_t *pIrk)
uint32_t hash;
uint64_t rpa;
BbBleDrvRand((uint8_t *)&prand, (sizeof(uint32_t) / sizeof(uint8_t)));
PalCryptoGenerateRandomNumber((uint8_t *)&prand, (sizeof(uint32_t) / sizeof(uint8_t)));
prand = (prand & 0x003FFFFF) | 0x00400000;
hash = bbGenerateHash(pIrk, prand);
@ -870,5 +873,50 @@ void BbBleResListHandleTimeout(void)
{
pEntry->peerRpa = bbGenerateRpa(pEntry->peerIrk);
}
pEntry->isRpaUpd = TRUE;
}
}
/*************************************************************************************************/
/*!
* \brief Check if either local RPA or peer RPA is updated.
*
* \param peerAddrType Peer identity address type.
* \param peerIdentityAddr Peer identity address.
*
* \return TRUE if either local RPA or peer RPA is updated.
*
*/
/*************************************************************************************************/
bool_t BbBleResListIsRpaUpd(uint8_t peerAddrType, uint64_t peerIdentityAddr)
{
bbBleResListEntry_t *pEntry;
bool_t result;
pEntry = bbBleFindResolvingListEntry(peerAddrType, peerIdentityAddr);
if (pEntry != NULL)
{
result = pEntry->isRpaUpd;
pEntry->isRpaUpd = FALSE;
return result;
}
return FALSE;
}
/*************************************************************************************************/
/*!
* \brief Check if peer identity is in the resolving list.
*
* \param peerAddrType Peer identity address type.
* \param peerIdentityAddr Peer identity address.
*
* \return TRUE if peer addr is in the resolving list.
*
*/
/*************************************************************************************************/
bool_t bbBleIsPeerInResList(uint8_t peerAddrType, uint64_t peerIdentityAddr)
{
return (bbBleFindResolvingListEntry(peerAddrType, peerIdentityAddr) != NULL) ? TRUE : FALSE;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Generic BLE baseband driver implementation file.
* \file
* \brief Generic BLE baseband driver implementation file.
*/
/*************************************************************************************************/
@ -76,16 +77,16 @@ static void bbTestTxCompCback(uint8_t status)
const uint32_t pktInter = BB_US_TO_BB_TICKS(pktInterUsec);
int16_t dueOffsetUsec = pktInterUsec - BB_TICKS_TO_US(pktInter);
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
bbBleCb.bbParam.due = bbBleCb.bbParam.due + pktInter;
bbBleCb.bbParam.dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0);
BbBleDrvSetChannelParam(&pBle->chan);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetChannelParam(&pBle->chan);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleClrIfs(); /* never setup for TIFS */
BbBleDrvTxBufDesc_t desc = {.pBuf = pTx->pTxBuf, .len = pTx->txLen};
BbBleDrvTxData(&desc, 1);
PalBbBleTxBufDesc_t desc = {.pBuf = pTx->pTxBuf, .len = pTx->txLen};
PalBbBleTxData(&desc, 1);
}
switch (status)
@ -146,20 +147,20 @@ static void bbTestRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint32_
}
else
{
BbBleDrvCancelTifs();
PalBbBleCancelTifs();
const uint32_t pktInterUsec = pBbRtCfg->rfSetupDelayUs;
const uint32_t pktInter = BB_US_TO_BB_TICKS(pktInterUsec);
int16_t dueOffsetUsec = pktInterUsec - BB_TICKS_TO_US(pktInter);
bbBleCb.bbParam.due = BbDrvGetCurrentTime() + pktInter;
bbBleCb.bbParam.due = PalBbGetCurrentTime(USE_RTC_BB_CLK) + pktInter;
bbBleCb.bbParam.dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0);
bbBleCb.bbParam.rxTimeoutUsec = pRx->rxSyncDelayUsec;
BbBleDrvSetChannelParam(&pBle->chan);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetChannelParam(&pBle->chan);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleClrIfs(); /* never setup for TIFS */
BbBleDrvRxData(pRx->pRxBuf, pRx->rxLen);
PalBbBleRxData(pRx->pRxBuf, pRx->rxLen);
}
switch (status)
@ -192,7 +193,7 @@ static void bbTestRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint32_
/*************************************************************************************************/
static void bbTestCleanupOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
{
BbBleDrvCancelData();
PalBbBleCancelData();
BbTerminateBod();
}
@ -215,12 +216,12 @@ static void bbSlvExecuteTestTxOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
bbBleCb.bbParam.due = pBod->due;
bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec;
BbBleDrvSetChannelParam(&pBle->chan);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetChannelParam(&pBle->chan);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleClrIfs(); /* never setup for TIFS */
BbBleDrvTxBufDesc_t desc = {.pBuf = pTx->pTxBuf, .len = pTx->txLen};
BbBleDrvTxData(&desc, 1);
PalBbBleTxBufDesc_t desc = {.pBuf = pTx->pTxBuf, .len = pTx->txLen};
PalBbBleTxData(&desc, 1);
}
/*************************************************************************************************/
@ -243,11 +244,11 @@ static void bbSlvExecuteTestRxOp(BbOpDesc_t *pBod, BbBleData_t *pBle)
bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec;
bbBleCb.bbParam.rxTimeoutUsec = pRx->rxSyncDelayUsec;
BbBleDrvSetChannelParam(&pBle->chan);
BbBleDrvSetDataParams(&bbBleCb.bbParam);
PalBbBleSetChannelParam(&pBle->chan);
PalBbBleSetDataParams(&bbBleCb.bbParam);
bbBleClrIfs(); /* never setup for TIFS */
BbBleDrvRxData(pRx->pRxBuf, pRx->rxLen);
PalBbBleRxData(pRx->pRxBuf, pRx->rxLen);
}
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Generic BLE whitelist implementation file.
* \file
* \brief Generic BLE whitelist implementation file.
*/
/*************************************************************************************************/
@ -165,6 +166,12 @@ void BbBleWhiteListClear(void)
/*************************************************************************************************/
bool_t BbBleWhiteListAdd(bool_t randAddr, uint64_t addr)
{
if (BbBleWhiteListCheckAddr(randAddr, addr))
{
/* Return TRUE if the address is already in the list. */
return TRUE;
}
if (bbBleWhiteListNumEntries < bbBleWhiteListNumEntriesMax)
{
addr |= (uint64_t)randAddr << 48;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller common interface file.
* \file
* \brief Link layer controller common interface file.
*/
/*************************************************************************************************/
@ -55,7 +56,10 @@ enum
LCTR_DISP_EXT_INIT, /*!< Extended Initiate message dispatch handler type. */
LCTR_DISP_PER_ADV, /*!< Periodic Advertising message dispatch handler type. */
LCTR_DISP_PER_CREATE_SYNC, /*!< Periodic Create Sync message dispatch handler type. */
LCTR_DISP_TRANFER_SYNC, /*!< Periodic Sync Transfer message dispatch handler type. */
LCTR_DISP_PER_SCAN, /*!< Periodic Scanning message dispatch handler type. */
LCTR_DISP_ACAD, /*!< ACAD message dispatch handler type (currently only used by slave). */
LCTR_DISP_CIS, /*!< Connected isochronous stream dispatch handler type. */
LCTR_DISP_TOTAL, /*!< Total number of dispatch handlers. */
/* Special IDs */
LCTR_DISP_FIRST_SM = LCTR_DISP_CONN_IND+1, /*!< First state machine. */
@ -75,6 +79,9 @@ enum
LCTR_EVENT_RX_PENDING, /*!< Receive data PDU pending. */
LCTR_EVENT_TX_PENDING, /*!< Transmit data PDU pending. */
LCTR_EVENT_TX_COMPLETE, /*!< Transmit data PDU completed. */
LCTR_EVENT_CIS_TX_PENDING, /*!< Transmit data PDU pending. */
LCTR_EVENT_CIS_RX_PENDING, /*!< Receive data PDU pending. */
LCTR_EVENT_CIS_TX_COMPLETE, /*!< Transmit data PDU completed. */
LCTR_EVENT_RX_ADVB, /*!< Receive AdvB PDU completed. */
LCTR_EVENT_RX_DIRECT_ADVB, /*!< Receive direct AdvB PDU completed. */
LCTR_EVENT_RX_SCAN_REQ, /*!< Receive scan request PDU completed. */
@ -88,6 +95,7 @@ enum
{
LCTR_HOST_REPLY_CONN_PARAM_REQ = (1 << 0), /*!< Waiting for host to submit a connection parameter request reply. */
LCTR_HOST_REPLY_LTK_REQ = (1 << 1), /*!< Waiting for host to submit a LTK request reply. */
LCTR_HOST_REPLY_CIS_REQ = (1 << 2), /*!< Waiting for host to submit a CIS request reply. */
};
/**************************************************************************************************
@ -102,6 +110,13 @@ typedef struct
uint8_t event; /*!< PDU ID. */
} lctrMsgHdr_t;
/*! \brief Channel map update message. */
typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
uint64_t chanMap; /*!< Channel map. */
} lctrChanMapUpdate_t;
/*! \brief Connect request PDU. */
typedef struct
{
@ -141,6 +156,21 @@ typedef struct
Global Variables
**************************************************************************************************/
/* \brief Call signature for periodic enabled check function */
typedef bool_t (*LctrIsPerAdvEnabledFn_t)(uint8_t handle);
/* Function pointer for periodic advertising enable check */
extern LctrIsPerAdvEnabledFn_t LctrPerAdvEnabled;
/* \brief Call signature for extended scan enabled check function. */
typedef bool_t (*LctrExtCheckFn_t)(uint8_t scanPhy);
/* Function pointer for extended scan enable check. */
extern LctrExtCheckFn_t LctrMstExtScanEnabled;
/* Function pointer for extended advertising init enable check. */
extern LctrExtCheckFn_t LctrMstExtInitEnabled;
/* Runtime configuration. */
extern const LlRtCfg_t *pLctrRtCfg;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller scanning master interface file.
* \file
* \brief Link layer controller scanning master interface file.
*/
/*************************************************************************************************/
@ -100,6 +101,10 @@ void LctrMstScanDefaults(void);
void lctrAdvReportsInc(void);
void lctrAdvReportsDec(void);
/* Utility */
bool_t LctrMstScanIsEnabled(void);
bool_t LctrMstScanIsPrivAddr(void);
/*! \} */ /* LL_LCTR_API_ADV_MST */
#ifdef __cplusplus

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller extended scanning master interface file.
* \file
* \brief Link layer controller extended scanning master interface file.
*/
/*************************************************************************************************/
@ -52,13 +53,25 @@ enum
{
/* Broadcast events */
LCTR_CREATE_SYNC_MSG_RESET = LCTR_MSG_RESET, /*!< Reset API message. */
/* Advertising events */
LCTR_CREATE_SYNC_MSG_CREATE, /*!< Create sync create API event. */
LCTR_CREATE_SYNC_MSG_CANCEL, /*!< Create sync cancel sync API event. */
LCTR_CREATE_SYNC_MSG_FAILED, /*!< Create sync failed event. */
LCTR_CREATE_SYNC_MSG_DONE, /*!< Create sync done event. */
LCTR_CREATE_SYNC_MSG_TERMINATE, /*!< Create sync scanning BOD terminate event. */
LCTR_CREATE_SYNC_MSG_TOTAL /*!< Total number of Create sync events. */
};
/*! \brief Scanner transfer sync task messages for \a LCTR_DISP_TRANFER_SYNC dispatcher. */
enum
{
/* Broadcast events */
LCTR_TRANSFER_SYNC_MSG_RESET = LCTR_MSG_RESET, /*!< Reset API message. */
LCTR_TRANSFER_SYNC_MSG_START = LCTR_CREATE_SYNC_MSG_CREATE, /*!< Transfer sync start event. */
LCTR_TRANSFER_SYNC_MSG_CANCEL = LCTR_CREATE_SYNC_MSG_CANCEL, /*!< Transfer sync cancel sync API event. */
LCTR_TRANSFER_SYNC_MSG_FAILED = LCTR_CREATE_SYNC_MSG_FAILED, /*!< Transfer sync failed event. */
LCTR_TRANSFER_SYNC_MSG_DONE = LCTR_CREATE_SYNC_MSG_DONE, /*!< Transfer sync done event. */
LCTR_TRANSFER_SYNC_MSG_TERMINATE = LCTR_CREATE_SYNC_MSG_TERMINATE, /*!< Transfer sync scanning BOD terminate event. */
LCTR_TRANSFER_SYNC_MSG_TOTAL = LCTR_CREATE_SYNC_MSG_TOTAL /*!< Total number of Transfer sync events. */
};
/*! \brief Scanner periodic synchronous task messages for \a LCTR_DISP_PER_SCAN dispatcher. */
@ -122,6 +135,7 @@ typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
uint8_t filterPolicy; /*!< Filter Policy. */
uint8_t repDisabled; /*!< Reporting disabled. */
uint8_t advSID; /*!< Advertising SID. */
uint8_t advAddrType; /*!< Advertiser Address Type. */
uint64_t advAddr; /*!< Advertiser Address. */
@ -129,11 +143,30 @@ typedef struct
uint16_t syncTimeOut; /*!< Synchronization Timeout. */
} lctrPerCreateSyncMsg_t;
/*! \brief Periodic transfer sync message. */
typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
uint16_t id; /*!< ID. */
uint8_t bSyncInfo[LL_SYNC_INFO_LEN]; /*!< SyncInfo bytes. */
uint16_t connHandle; /*!< Connection handle. */
uint16_t ceRef; /*!< Reference connection event counter. */
uint16_t ceRcvd; /*!< Connection event counter when LL_PERIODIC_SYNC_IND was received. */
uint16_t lastPECounter; /*!< Last PA event counter. */
uint8_t advSID; /*!< Advertising SID. */
uint8_t advAddrType; /*!< Advertiser Address Type. */
uint8_t scaB; /*!< Sleep clock accuracy of the device sending LL_PERIODIC_SYNC_IND. */
uint8_t rxPhy; /*!< PHY used for periodic advertising scan. */
uint64_t advAddr; /*!< Advertiser Address. */
uint16_t syncConnEvtCounter; /*!< Connection event counter when the contents of the PDU is determined. */
} lctrPerTransferSyncMsg_t;
/*! \brief Periodic Advertising message data. */
typedef union
{
lctrMsgHdr_t hdr; /*!< Message header. */
lctrPerCreateSyncMsg_t createSync; /*!< Periodic create sync message data. */
lctrPerTransferSyncMsg_t transferSync; /*!< Periodic transfer sync message data. */
} LctrPerScanMsg_t;
/**************************************************************************************************
@ -151,6 +184,7 @@ extern LctrPerScanMsg_t *pLctrMstPerScanMsg;
void LctrMstExtScanInit(void);
void LctrMstExtScanDefaults(void);
void LctrMstPerCreateSyncInit(void);
void LctrMstPerTransferSyncInit(void);
void LctrMstPerScanInit(void);
/* Status */
@ -160,9 +194,17 @@ bool_t LctrMstExtScanValidateParam(void);
void LctrMstExtScanSetScanPhy(uint8_t scanPhy);
void LctrMstExtScanClearScanPhy(uint8_t scanPhy);
void LctrMstExtScanSetParam(uint8_t scanPhy, uint8_t ownAddrType, uint8_t scanFiltPolicy, const LlExtScanParam_t *pParam);
bool_t LctrMstExtScanIsEnabled(uint8_t scanPhy);
bool_t LctrMstExtScanIsPrivAddr(uint8_t scanPhy);
bool_t LctrMstPerIsSyncPending(void);
bool_t LctrMstPerIsSyncDisabled(void);
bool_t LctrMstPerIsSync(uint8_t advSID, uint8_t advAddrType, uint64_t advAddr);
uint8_t lctrMstPerGetNumPerScanCtx(void);
uint64_t LctrGetPerScanChanMap(uint16_t handle);
bool_t lctrMstPerIsSyncHandleValid(uint16_t syncHandle);
void LctrPastInit(void);
uint8_t LctrPeriodicAdvSyncTransfer(uint16_t connHandle, uint16_t serviceData, uint16_t syncHandle);
void LctrMstPerSetRcvEnable(uint16_t syncHandle, bool_t enable);
#ifdef __cplusplus
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller advertising slave interface file.
* \file
* \brief Link layer controller advertising slave interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller extended advertising slave interface file.
* \file
* \brief Link layer controller extended advertising slave interface file.
*/
/*************************************************************************************************/
@ -61,6 +62,14 @@ enum
LCTR_PER_ADV_MSG_TOTAL /*!< Total number of periodic advertising events. */
};
/*! \brief Acad dispatcher messages */
enum
{
LCTR_ACAD_MSG_CHAN_UPDATE, /* Start a channel map update */
LCTR_ACAD_MSG_CHAN_UPDATE_FINISH, /* Finish a channel map update */
LCTR_ACAD_MSG_TOTAL
};
/**************************************************************************************************
Data Types
**************************************************************************************************/
@ -91,6 +100,7 @@ typedef union
{
lctrMsgHdr_t hdr; /*!< Message header. */
LctrPerAdvEnableMsg_t perEnable; /*!< Periodic enable message data. */
lctrChanMapUpdate_t chanUpdate; /*!< Channel map update data. */
} LctrPerAdvMsg_t;
/**************************************************************************************************
@ -107,6 +117,7 @@ uint8_t LctrIsExtAdvEnableParamValid(uint8_t enable, LlExtAdvEnableParam_t *pEna
uint8_t LctrIsExtAdvEnableReady(uint8_t handle);
bool_t LctrIsAdvHandleValid(uint8_t handle);
uint8_t LctrGetExtAdvTxPowerLevel(uint16_t handle, int8_t *pLevel);
bool_t LctrIsPerAdvEnabled(uint8_t handle);
/* Control */
uint8_t LctrGetAdvHandles(uint8_t pHandles[LL_MAX_ADV_SETS]);
@ -114,6 +125,7 @@ uint8_t LctrSetExtAdvSetRandAddr(uint8_t handle, const uint8_t *pAddr);
uint8_t LctrGetExtAdvSetRandAddr(uint8_t handle, uint8_t *pAddr);
uint8_t LctrSetExtAdvParam(uint8_t handle, LlExtAdvParam_t *pExtAdvParam);
uint8_t LctrSetExtAdvData(uint8_t handle, uint8_t op, uint8_t fragPref, uint8_t len, const uint8_t *pData);
uint64_t LctrGetPerAdvChanMap(uint8_t handle);
uint8_t LctrSetExtScanRespData(uint8_t handle, uint8_t op, uint8_t fragPref, uint8_t len, const uint8_t *pData);
uint8_t LctrRemoveAdvSet(uint8_t handle);
uint8_t LctrClearAdvSets(void);
@ -121,6 +133,8 @@ uint8_t LctrSetAuxOffsetDelay(uint8_t handle, uint32_t delayUsec);
uint8_t LctrSetExtAdvDataFragLen(uint8_t handle, uint8_t fragLen);
uint8_t LctrSetExtAdvTxPhyOptions(uint8_t handle, uint8_t priPhyOpts, uint8_t secPhyOpts);
uint8_t LctrSetPeriodicAdvParam(uint8_t handle, LlPerAdvParam_t *pPerAdvParam);
uint8_t LctrPeriodicAdvSetInfoTransfer(uint16_t connHandle, uint16_t serviceData, uint8_t advHandle);
uint8_t LctrSetPeriodicAdvSyncTransParams(uint16_t connHandle, uint8_t mode, uint16_t skip, uint16_t syncTimeout, uint8_t cteType);
void LctrSetPeriodicAdvEnable(uint8_t handle, bool_t enable);
uint8_t LctrSetPeriodicAdvData(uint8_t handle, uint8_t op, uint8_t len, const uint8_t *pData);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller connection interface file.
* \file
* \brief Link layer controller connection interface file.
*/
/*************************************************************************************************/
@ -77,6 +78,12 @@ enum
LCTR_CONN_MSG_API_DATA_LEN_CHANGE, /*!< Data length change API event. */
LCTR_CONN_MSG_API_PHY_UPDATE, /*!< PHY update API event. */
LCTR_CONN_MSG_API_SET_MIN_USED_CHAN, /*!< Set minimum number of used channels API event. */
LCTR_CONN_MSG_API_PER_ADV_SYNC_TRSF, /*!< Periodic advertising sync transfer API event. */
LCTR_CONN_MSG_API_REQ_PEER_SCA, /*!< Request peer SCA. */
LCTR_CONN_MSG_API_CIS_REQ, /*!< CIS request API event. */
LCTR_CONN_MSG_API_CIS_REQ_ACCEPT, /*!< Peer CIS request accept API event. */
LCTR_CONN_MSG_API_CIS_REQ_REJECT, /*!< Peer CIS request accept API event. */
/* Internal events */
_LCTR_CONN_INT_EVENTS = 40,
LCTR_CONN_DATA_PENDING, /*!< New data pending. */
@ -93,13 +100,15 @@ enum
LCTR_CONN_LLCP_START_PENDING, /*!< Start pending LLCP procedure. */
LCTR_CONN_LLCP_SKIP_CONN_PARAM, /*!< Skip connection parameter exchange. */
LCTR_CONN_LLCP_REJECT_CONN_UPD, /*!< Reject a connection update. */
_LCTR_CONN_TERM_EVENTS = 60,
_LCTR_CONN_TERM_EVENTS = 70,
LCTR_CONN_TERM_SUP_TIMEOUT, /*!< Terminate connection due to supervision timeout. */
LCTR_CONN_TERM_MIC_FAILED, /*!< Terminate connection due to MIC failure. */
LCTR_CONN_TERM_INST_PASSED, /*!< Terminate connection due to instant passed. */
LCTR_CONN_TERM_CIS_LOCAL_RESOURCE, /*!< Terminate CIS connection due to local resource limitation. */
LCTR_CONN_TERMINATED, /*!< Connection event terminated. */
_LCTR_CONN_TMR_EVENTS = 70,
_LCTR_CONN_TMR_EVENTS = 80,
LCTR_CONN_TMR_LLCP_RSP_EXP, /*!< LLCP response timer expired. */
LCTR_CONN_TMR_CIS_LLCP_RSP_EXP, /*!< CIS LLCP response timer expired. */
LCTR_CONN_TMR_PING_PERIOD_EXP, /*!< LE Ping period timer expired. */
LCTR_CONN_TMR_AUTH_PAYLOAD_EXP /*!< Authentication payload timer expired. */
};
@ -115,13 +124,6 @@ typedef struct
LlConnSpec_t connSpec; /*!< Updated connection specification. */
} lctrConnUpdate_t;
/*! \brief Channel map update message. */
typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
uint64_t chanMap; /*!< Channel map. */
} lctrChanMapUpdate_t;
/*! \brief Disconnect message. */
typedef struct
{
@ -185,6 +187,45 @@ typedef struct
uint8_t minUsedChan; /*!< Minimum number of used channels. */
} lctrSetMinUsedChan_t;
/*! \brief Periodic advertising sync transfer message. */
typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
uint16_t syncSource; /*!< Periodic sync source. */
uint16_t syncHandle; /*!< Periodic sync handle. */
uint16_t serviceData; /*!< Service data provided by the host. */
} lctrPerAdvSyncTrsf_t;
/*! \brief Set minimum number of used channels message. */
typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
uint8_t action; /*!< Action. */
} lctrScaReq_t;
/*! \brief CIS set CIG test CIS parameters. */
typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
uint16_t cisHandle; /*!< CIS handle. */
} lctrCreateCis_t;
/*! \brief Internal reject CIS request message. */
typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
// uint16_t cisHandle; /*!< CIS handle. */
uint8_t reason; /*!< Reject reason. */
} lctrRejCisReq_t;
/*! \brief Disconnect message. */
typedef struct
{
lctrMsgHdr_t hdr; /*!< Message header. */
uint8_t reason; /*!< Disconnect reason. */
uint16_t cisHandle; /*!< CIS handle. */
} lctrCisDisc_t;
/*! \brief Link layer controller message data. */
typedef union
{
@ -200,6 +241,13 @@ typedef union
lctrDataLengthChange_t dataLenChange; /*!< Data length change message data. */
lctrPhyUpdate_t phyUpd; /*!< PHY update message data. */
lctrSetMinUsedChan_t setMinUsedChan; /*!< Set minimum number of used channels message data. */
lctrPerAdvSyncTrsf_t perAdvSyncTrsf; /*!< Periodic advertising sync transfer data. */
lctrScaReq_t scaReq; /*!< Sleep clock accuracy request. */
/* CIS */
lctrCreateCis_t createCis; /*!< Create CIS message data. */
lctrRejCisReq_t rejCisReq; /*!< Reject CIS request message data. */
lctrCisDisc_t cisDisc; /*!< CIS disconnect message data. */
} lctrConnMsg_t;
/*! \brief Initialize connection context. */
@ -249,19 +297,22 @@ void LctrVsConnInit(const LctrVsHandlers_t *pHdlrs);
/* Helpers */
uint8_t LctrValidateConnSpec(const LlConnSpec_t *pConnSpec);
uint8_t LctrValidateModifyScaParam(uint8_t action);
bool_t LctrIsProcActPended(uint16_t handle, uint8_t event);
/* Status */
bool_t LctrIsConnHandleEnabled(uint16_t handle);
bool_t LctrIsCisConnHandleEnabled(uint16_t handle);
uint8_t LctrGetRole(uint16_t handle);
int8_t LctrGetRssi(uint16_t handle);
int8_t LctrGetTxPowerLevel(uint16_t handle);
uint64_t LctrGetChannelMap(uint16_t handle);
uint8_t LctrGetUsedFeatures(uint16_t handle);
uint64_t LctrGetUsedFeatures(uint16_t handle);
uint8_t LctrGetTxPhy(uint16_t handle);
uint8_t LctrGetRxPhy(uint16_t handle);
void LctrGetPeerMinUsedChan(uint16_t handle, uint8_t *pPeerMinUsedChan);
bool_t LctrIsWaitingForReply(uint16_t handle, uint8_t reply);
bool_t LctrIsCisEnabled(uint16_t handle);
/* Control */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller channel selection interface file.
* \file
* \brief Link layer controller channel selection interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller initiating master interface file.
* \file
* \brief Link layer controller initiating master interface file.
*/
/*************************************************************************************************/
@ -63,6 +64,10 @@ enum
void LctrMstInitInit(void);
void LctrMstInitDefaults(void);
/* Utility */
bool_t LctrMstInitIsEnabled(void);
bool_t LctrMstInitIsPrivAddr(void);
/*! \} */ /* LL_LCTR_API_INIT_MST */
#ifdef __cplusplus

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller extended initiating master interface file.
* \file
* \brief Link layer controller extended initiating master interface file.
*/
/*************************************************************************************************/
@ -39,6 +40,11 @@ extern "C" {
/**************************************************************************************************
Constants
**************************************************************************************************/
/*! \brief Change supervision timeout value to us. */
#define LL_SUP_TIMEOUT_VAL_TO_US(x) x * 10000
/*! \brief Change connection interval value to us. */
#define LL_CONN_INTERVAL_VAL_TO_US(x) x * 1250
/*! \brief Master extended initiate task messages for \a LCTR_DISP_EXT_INIT dispatcher. */
enum
@ -72,6 +78,10 @@ void LctrMstExtInitParam(uint8_t initPhy, const LlExtInitScanParam_t *pScanParam
void LctrMstExtInitSetScanPhy(uint8_t scanPhy);
void LctrMstExtInitClearScanPhy(uint8_t scanPhy);
/* Utility */
bool_t LctrMstExtInitIsEnabled(uint8_t scanPhy);
bool_t LctrMstExtInitIsPrivAddr(uint8_t scanPhy);
/*! \} */ /* LL_LCTR_API_INIT_MST_AE */
#ifdef __cplusplus

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller PHY features interface file.
* \file
* \brief Link layer controller PHY features interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller privacy interface file.
* \file
* \brief Link layer controller privacy interface file.
*/
/*************************************************************************************************/
@ -39,10 +40,11 @@ extern "C" {
Constants
**************************************************************************************************/
/*! \brief Slave advertising task messages for \a LCTR_DISP_ADV dispatcher. */
/*! \brief Slave advertising task messages for \a LCTR_DISP_PRIV dispatcher. */
enum
{
/* Privacy events */
LCTR_PRIV_MSG_RESET, /*!< HCI reset event. */
LCTR_PRIV_MSG_RES_PRIV_ADDR_TIMEOUT, /*!< Resolvable private address timeout event. */
LCTR_PRIV_MSG_ADDR_RES_NEEDED /*!< Address resolution needed. */
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller secure connections interface file.
* \file
* \brief Link layer controller secure connections interface file.
*/
/*************************************************************************************************/
@ -42,6 +43,8 @@ void LctrScInit(void);
/* Execution. */
uint8_t LctrGenerateP256KeyPair(void);
uint8_t LctrGenerateDhKey(const uint8_t *pPubKey, const uint8_t *pPrivKey);
uint8_t LctrGenerateDebugDhKey(void);
uint8_t LctrSetValidatePublicKeyMode(uint8_t validateMode);
/*! \} */ /* LL_LCTR_API_SC */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer manager common interface file.
* \file
* \brief Link layer manager common interface file.
*/
/*************************************************************************************************/
@ -25,6 +26,7 @@
#include "ll_api.h"
#include "ll_defs.h"
#include "hci_defs.h"
#ifdef __cplusplus
extern "C" {
@ -67,9 +69,16 @@ typedef struct
wsfHandlerId_t handlerId; /*!< System event handler ID. */
uint16_t connCtxSize; /*!< Size of the connection context. */
uint16_t advSetCtxSize; /*!< Size of the advertising set context. */
uint16_t extScanCtxSize; /*!< Size of the extended scanner context. */
uint16_t extInitCtxSize; /*!< Size of the extended initiator context. */
uint16_t perScanCtxSize; /*!< Size of the periodic scanning context. */
uint16_t cisCtxSize; /*!< Size of the CIS context. */
uint16_t cigCtxSize; /*!< Size of the CIG context. */
uint64_t featuresDefault; /*!< Default supported features. */
llIsoCback_t sendIsoCompCback; /*!< ISO data send complete callback. */
llIsoCback_t recvIsoPendCback; /*!< ISO data receive pending callback. */
/* Device parameters */
uint64_t bdAddr; /*!< Public device address. */
uint64_t supStates; /*!< Supported states. */
@ -108,12 +117,35 @@ typedef struct
bool_t addrResEna; /*!< Address resolution enabled. */
bool_t useLegacyCmds; /*!< Use only legacy advertising, scan or initiate commands. */
bool_t useExtCmds; /*!< Use only extended advertising, scan or initiate commands. */
uint64_t chanClass; /*!< Channel class. */
/* Sleep clock accuracy override value. */
int8_t scaMod; /*!< SCA override value. */
/* Power Class 1. */
int8_t powerThreshold[LL_MAX_PHYS]; /*!< Power threshold for each PHY. */
uint8_t localMinUsedChan[LL_MAX_PHYS]; /*!< Local minimum number of used channels for each PHY. */
uint8_t hciSupCommands[HCI_SUP_CMD_LEN]; /*!< Supported HCI commands bit mask. */
} lmgrCtrlBlk_t;
/*! \brief Channel parameters. */
typedef struct
{
/* Channel parameters */
uint8_t lastChanIdx; /*!< Current channel index. */
uint8_t numUsedChan; /*!< Number of used channels. */
uint64_t chanMask; /*!< Channel mask. */
uint8_t chanRemapTbl[LL_CHAN_DATA_MAX_IDX + 1]; /*!< Channel remapping table. */
uint8_t usedChSel; /*!< Used channel selection. */
uint16_t chIdentifier; /*!< Channel identifier. */
/* For subevent calculation only */
uint16_t prnLast; /*!< Last used permutation. */
uint8_t subEvtIdx; /*!< Subevent index. */
} lmgrChanParam_t;
/**************************************************************************************************
Global Variables
**************************************************************************************************/
@ -143,12 +175,35 @@ bool_t LmgrIsAddressTypeAvailable(uint8_t ownAddrType);
bool_t LmgrIsLegacyCommandAllowed(void);
bool_t LmgrIsExtCommandAllowed(void);
/* Utility */
void LmgrBuildRemapTable(lmgrChanParam_t *pChanParam);
uint8_t LmgrSelectNextChannel(lmgrChanParam_t *pChanParam, uint16_t eventCounter, uint16_t numSkip, bool_t calSubEvt);
uint32_t LmgrCalcWindowWideningUsec(uint32_t unsyncTimeUsec, uint32_t caPpm);
uint8_t LmgrSelectNextSubEvtChannel(lmgrChanParam_t *pChanParam);
uint8_t * LmgrReadHciSupCmd(void);
/* Event Messages */
void LmgrSendAdvEnableCnf(uint8_t status);
void LmgrSendScanEnableCnf(uint8_t status);
void LmgrSendAdvSetTermInd(uint8_t handle, uint8_t status, uint16_t connHandle, uint8_t numEvents);
bool_t LmgrSendEvent(LlEvt_t *pEvt);
/*************************************************************************************************/
/*!
* \brief Get operational mode flag.
*
* \param flag Flag to check.
*
* \return TRUE if flag is set.
*
* Get mode flag governing LL operations.
*/
/*************************************************************************************************/
static inline bool_t lmgrGetOpFlag(uint32_t flag)
{
return (lmgrCb.opModeFlags & flag) ? TRUE : FALSE;
}
/*! \} */ /* LL_LMGR_API */
#ifdef __cplusplus

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer manager advertising master interface file.
* \file
* \brief Link layer manager advertising master interface file.
*/
/*************************************************************************************************/
@ -52,7 +53,6 @@ typedef struct
typedef struct
{
lmgrScanParam_t scanParam; /*!< Scan parameters. */
uint64_t chanClass; /*!< Channel class. */
uint8_t scanChanMap; /*!< Scan channel map. */
uint8_t numAdvReport; /*!< Number of pending advertising reports. */
} lmgrMstScanCtrlBlk_t;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer manager advertising extension interface file.
* \file
* \brief Link layer manager advertising extension interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer manager advertising slave interface file.
* \file
* \brief Link layer manager advertising slave interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer manager advertising extension interface file.
* \file
* \brief Link layer manager advertising extension interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer manager connection interface file.
* \file
* \brief Link layer manager connection interface file.
*/
/*************************************************************************************************/
@ -55,6 +56,10 @@ typedef struct
uint8_t txPhys; /*!< Default transmitter PHYs. */
uint8_t rxPhys; /*!< Default receiver PHYs. */
uint8_t syncMode; /*!< Default sync transfer mode. */
uint16_t syncSkip; /*!< Default sync skip for periodic adv sync transfer. */
uint16_t syncTimeout; /*!< Default sync timeout for periodic adv sync transfer. */
} lmgrConnCtrlBlk_t;
/**************************************************************************************************

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer manager privacy interface file.
* \file
* \brief Link layer manager privacy interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer manager secure connections interface file.
* \file
* \brief Link layer manager secure connections interface file.
*/
/*************************************************************************************************/
@ -41,11 +42,21 @@ extern "C" {
/*! \brief Secure connections parameter definition. */
typedef struct
{
uint8_t privKey[LL_ECC_KEY_LEN]; /*!< P-256 private key. */
uint8_t privKey[LL_ECC_KEY_LEN]; /*!< P-256 private key. */
bool_t eccOpActive; /*!< An ECC generation operation is active. */
bool_t privKeySet; /*!< P-256 private key set; do not generate new one. */
bool_t pubKeyValid; /*!< DHKey won't start to generate unless public key is valid. */
uint8_t validatePubKeyMode; /*!< Validate public key mode between ALT1 and ALT2. */
} lmgrScCtrlBlk_t;
/*! \brief Key validation mode between ALT1 and ALT2. */
enum
{
KEY_VALIDATE_MODE_ALT2 = 0, /*!< Return error code 0x12 in command complete event. (Default mode) */
KEY_VALIDATE_MODE_ALT1 = 1, /*!< Return error code 0x12 in command status event. */
KEY_VALIDATE_MODE_MAX = 1 /*!< Key validate mode maximum value. */
};
/**************************************************************************************************
Global Variables
**************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,12 +16,15 @@
/*************************************************************************************************/
/*!
* \brief LL initialization for SoC configuration.
* \file
* \brief LL initialization for SoC configuration.
*/
/*************************************************************************************************/
#include "ll_init_api.h"
#include "bb_ble_api.h"
#include "pal_bb_ble.h"
#include "pal_radio.h"
#include "sch_api.h"
/**************************************************************************************************
@ -59,6 +62,36 @@ void LlInitBbInit(void)
#endif
#endif
#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_0)
#ifdef INIT_OBSERVER
BbBleAuxScanMasterInit();
BbBlePerScanMasterInit();
#endif
#ifdef INIT_BROADCASTER
BbBleAuxAdvSlaveInit();
PalRadioInitPathComp();
#endif
#endif
#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN)
#ifdef INIT_CENTRAL
BbBleCisMasterInit();
#else
#ifdef INIT_OBSERVER
/* TODO BIS observer */
#endif
#endif
#ifdef INIT_PERIPHERAL
BbBleCisSlaveInit();
#else
#ifdef INIT_BROADCASTER
/* TODO BIS broadcaster */
#endif
#endif
#endif
BbBleTestInit();
}
@ -79,20 +112,11 @@ void LlInitSchInit(void)
/*!
* \brief Initialize LL.
*
* \param initHandler Initialize WSF handler.
*
* \return None.
*/
/*************************************************************************************************/
void LlInitLlInit(bool_t initHandler)
void LlInitLlInit(void)
{
if (initHandler)
{
wsfHandlerId_t handlerId = WsfOsSetNextHandler(LlHandler);
LlHandlerInit(handlerId);
}
/* else LlHandlerInit() is called by client */
#ifdef INIT_CENTRAL
LlScanMasterInit();
LlInitMasterInit();
@ -124,6 +148,44 @@ void LlInitLlInit(bool_t initHandler)
LlPrivInit();
LlScInit();
#endif
#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_0)
#ifdef INIT_CENTRAL
LlExtScanMasterInit();
LlExtInitMasterInit();
LlPhyMasterInit();
#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN)
LlCisMasterInit();
#endif
#else
#ifdef INIT_OBSERVER
LlExtScanMasterInit();
#endif
#endif
#ifdef INIT_PERIPHERAL
LlExtAdvSlaveInit();
LlPhySlaveInit();
#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN)
LlCisSlaveInit();
#endif
#else
#ifdef INIT_BROADCASTER
LlExtAdvSlaveInit();
#endif
#endif
#if defined(INIT_PERIPHERAL) || defined(INIT_CENTRAL)
LlChannelSelection2Init();
#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_1)
LlPastInit();
#endif
#endif
#endif
/* Initialize handler after feature bits are set. */
wsfHandlerId_t handlerId = WsfOsSetNextHandler(LlHandler);
LlHandlerInit(handlerId);
}
/*************************************************************************************************/
@ -153,10 +215,12 @@ uint32_t LlInitSetBbRtCfg(const BbRtCfg_t *pBbRtCfg, const uint8_t wlSizeCfg, co
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
memUsed = BbBleInitPeriodicList(plSizeCfg, pFreeMem, freeMemAvail);
pFreeMem += memUsed;
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_0)
memUsed = BbBleInitPeriodicList(plSizeCfg, pFreeMem, freeMemAvail);
pFreeMem += memUsed;
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
#endif
#ifdef INIT_ENCRYPTED
memUsed = BbBleInitResolvingList(rlSizeCfg, pFreeMem, freeMemAvail);
@ -185,13 +249,40 @@ uint32_t LlInitSetLlRtCfg(const LlRtCfg_t *pLlRtCfg, uint8_t *pFreeMem, uint32_t
{
uint32_t totalMemUsed = 0;
#if defined (INIT_PERIPHERAL) || defined (INIT_CENTRAL) || (BT_VER >= LL_VER_BT_CORE_SPEC_5_0)
uint32_t memUsed;
#endif
LlInitRunTimeCfg(pLlRtCfg);
#if defined (INIT_PERIPHERAL) || defined (INIT_CENTRAL)
uint32_t memUsed;
memUsed = LlInitConnMem(pFreeMem, freeMemAvail);
/* pFreeMem += memUsed; */
/* freeMemAvail -= memUsed; */
pFreeMem += memUsed;
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
#endif
#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_0)
memUsed = LlInitExtScanMem(pFreeMem, freeMemAvail);
pFreeMem += memUsed;
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
memUsed = LlInitExtAdvMem(pFreeMem, freeMemAvail);
pFreeMem += memUsed;
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
#endif
#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN)
memUsed = LlInitCisMem(pFreeMem, freeMemAvail);
pFreeMem += memUsed;
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
memUsed = LlInitIsoMem(pFreeMem, freeMemAvail);
/* pFreeMem += memUsed;
freeMemAvail -= memUsed; */
totalMemUsed += memUsed;
#endif
@ -200,20 +291,20 @@ uint32_t LlInitSetLlRtCfg(const LlRtCfg_t *pLlRtCfg, uint8_t *pFreeMem, uint32_t
/*************************************************************************************************/
/*!
* \brief Initialize standard configuration.
* \brief Initialize configuration.
*
* \param pCfg Runtime configuration.
*
* \return Memory used.
*/
/*************************************************************************************************/
uint32_t LlInitStdInit(LlInitRtCfg_t *pCfg)
uint32_t LlInit(LlInitRtCfg_t *pCfg)
{
uint32_t memUsed;
uint32_t totalMemUsed = 0;
memUsed = LlInitSetBbRtCfg(pCfg->pBbRtCfg, pCfg->wlSizeCfg, pCfg->rlSizeCfg, pCfg->plSizeCfg,
pCfg->pFreeMem, pCfg->freeMemAvail);
pCfg->pFreeMem, pCfg->freeMemAvail);
pCfg->pFreeMem += memUsed;
pCfg->freeMemAvail -= memUsed;
totalMemUsed += memUsed;
@ -225,7 +316,7 @@ uint32_t LlInitStdInit(LlInitRtCfg_t *pCfg)
LlInitBbInit();
LlInitSchInit();
LlInitLlInit(TRUE);
LlInitLlInit();
return totalMemUsed;
}

View File

@ -2,16 +2,20 @@
/*!
* \brief LL initialization for controller configuration.
*
* Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved.
* ARM Ltd. confidential and proprietary.
* Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved.
* Arm Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*************************************************************************************************/
@ -26,6 +30,26 @@
/*! \brief Extended VS command decoder. */
extern bool_t lhciVsExtDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf);
/*************************************************************************************************/
/*!
* \brief Initialize controller LHCI handler.
*
* \return None.
*/
/*************************************************************************************************/
void LlInitLhciHandler(void)
{
wsfHandlerId_t handlerId;
#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN)
handlerId = WsfOsSetNextHandler(LhciIsoHandler);
LhciIsoHandlerInit(handlerId);
#else
handlerId = WsfOsSetNextHandler(LhciHandler);
LhciHandlerInit(handlerId);
#endif
}
/*************************************************************************************************/
/*!
* \brief Initialize controller HCI transport.
@ -78,13 +102,50 @@ void LlInitLhciInit(void)
LhciScInit();
#endif
wsfHandlerId_t handlerId = WsfOsSetNextHandler(LhciHandler);
LhciHandlerInit(handlerId);
LhciVsExtInit(lhciVsExtDecodeCmdPkt);
#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_0)
#ifdef INIT_CENTRAL
LhciExtScanMasterInit();
LhciExtConnMasterInit();
#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN)
LhciCisMasterInit();
#endif
#else
#ifdef INIT_OBSERVER
LhciExtScanMasterInit();
#endif
#endif
#ifdef INIT_BROADCASTER
LhciExtAdvSlaveInit();
#endif
#ifdef INIT_PERIPHERAL
#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN)
LhciCisSlaveInit();
#endif
#endif
#if defined(INIT_PERIPHERAL) || defined(INIT_CENTRAL)
LhciChannelSelection2Init();
LhciPhyInit();
#if defined(INIT_OBSERVER) || defined(INIT_BROADCASTER)
#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_1)
LhciPastInit();
#endif
#endif
#endif
#endif
#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN)
LhciIsoInit();
#endif
}
/*************************************************************************************************/
/*!
* \brief Initialize standard controller configuration.
* \brief Initialize controller configuration.
*
* \param pCfg Runtime configuration.
*
@ -95,12 +156,11 @@ uint32_t LlInitControllerInit(LlInitRtCfg_t *pCfg)
{
uint32_t totalMemUsed;
totalMemUsed = LlInitStdInit(pCfg);
totalMemUsed = LlInit(pCfg);
LlInitChciTrInit();
LlInitLhciInit();
LhciVsExtInit(lhciVsExtDecodeCmdPkt);
LlInitLhciHandler();
return totalMemUsed;
}

View File

@ -1,79 +0,0 @@
/*************************************************************************************************/
/*!
* \brief LL initialization for extended controller configuration.
*
* Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
#include "ll_init_api.h"
#include "lhci_api.h"
#include "chci_api.h"
/**************************************************************************************************
Functions
**************************************************************************************************/
/*! \brief Extended VS command decoder. */
extern bool_t lhciVsExtDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf);
/*************************************************************************************************/
/*!
* \brief Initialize LL HCI extended features.
*
* \return None.
*/
/*************************************************************************************************/
void LlInitLhciExtInit(void)
{
LhciVsExtInit(lhciVsExtDecodeCmdPkt);
#ifdef INIT_CENTRAL
LhciExtScanMasterInit();
LhciExtConnMasterInit();
#else
#ifdef INIT_OBSERVER
LhciExtScanMasterInit();
#endif
#endif
#ifdef INIT_BROADCASTER
LhciExtAdvSlaveInit();
#endif
#if defined(INIT_PERIPHERAL) || defined(INIT_CENTRAL)
LhciChannelSelection2Init();
LhciPhyInit();
#endif
}
/*************************************************************************************************/
/*!
* \brief Initialize extended controller configuration.
*
* \param pCfg Runtime configuration.
*
* \return Memory used.
*/
/*************************************************************************************************/
uint32_t LlInitControllerExtInit(LlInitRtCfg_t *pCfg)
{
uint32_t totalMemUsed;
totalMemUsed = LlInitExtInit(pCfg);
LlInitChciTrInit();
LlInitLhciInit();
LlInitLhciExtInit();
return totalMemUsed;
}

View File

@ -1,152 +0,0 @@
/* Copyright (c) 2009-2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*************************************************************************************************/
/*!
* \brief LL initialization for extended SoC configuration.
*/
/*************************************************************************************************/
#include "ll_init_api.h"
#include "bb_ble_api.h"
/**************************************************************************************************
Functions
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \brief Initialize auxiliary BB operations.
*
* \return None.
*/
/*************************************************************************************************/
void LlInitBbAuxInit(void)
{
#ifdef INIT_OBSERVER
BbBleAuxScanMasterInit();
BbBlePerScanMasterInit();
#endif
#ifdef INIT_BROADCASTER
BbBleAuxAdvSlaveInit();
BbBleInitRfPathComp();
#endif
}
/*************************************************************************************************/
/*!
* \brief Initialize LL extended features.
*
* \return None.
*/
/*************************************************************************************************/
void LlInitLlExtInit(void)
{
#ifdef INIT_CENTRAL
LlExtScanMasterInit();
LlExtInitMasterInit();
LlPhyMasterInit();
#else
#ifdef INIT_OBSERVER
LlExtScanMasterInit();
#endif
#endif
#ifdef INIT_PERIPHERAL
LlExtAdvSlaveInit();
LlPhySlaveInit();
#else
#ifdef INIT_BROADCASTER
LlExtAdvSlaveInit();
#endif
#endif
#if defined(INIT_PERIPHERAL) || defined(INIT_CENTRAL)
LlChannelSelection2Init();
#endif
/* Initialize handler after feature bits are set. */
wsfHandlerId_t handlerId = WsfOsSetNextHandler(LlHandler);
LlHandlerInit(handlerId);
}
/*************************************************************************************************/
/*!
* \brief Set extended LL runtime configuration.
*
* \param pLlRtCfg LL runtime configuration (must be static).
* \param pFreeMem Free memory.
* \param freeMemAvail Amount of free memory in bytes.
*
* \return Amount of free memory consumed.
*/
/*************************************************************************************************/
uint32_t LlInitSetExtLlRtCfg(const LlRtCfg_t *pLlRtCfg, uint8_t *pFreeMem, uint32_t freeMemAvail)
{
uint32_t memUsed;
uint32_t totalMemUsed = 0;
memUsed = LlInitSetLlRtCfg(pLlRtCfg, pFreeMem, freeMemAvail);
pFreeMem += memUsed;
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
memUsed = LlInitExtScanMem(pFreeMem, freeMemAvail);
pFreeMem += memUsed;
freeMemAvail -= memUsed;
totalMemUsed += memUsed;
memUsed = LlInitExtAdvMem(pFreeMem, freeMemAvail);
/* pFreeMem += memUsed; */
/* freeMemAvail -= memUsed; */
totalMemUsed += memUsed;
return totalMemUsed;
}
/*************************************************************************************************/
/*!
* \brief Initialize extended configuration.
*
* \param pCfg Runtime configuration.
*
* \return Memory used.
*/
/*************************************************************************************************/
uint32_t LlInitExtInit(LlInitRtCfg_t *pCfg)
{
uint32_t memUsed;
uint32_t totalMemUsed = 0;
memUsed = LlInitSetBbRtCfg(pCfg->pBbRtCfg, pCfg->wlSizeCfg, pCfg->rlSizeCfg, pCfg->plSizeCfg,
pCfg->pFreeMem, pCfg->freeMemAvail);
pCfg->pFreeMem += memUsed;
pCfg->freeMemAvail -= memUsed;
totalMemUsed += memUsed;
memUsed = LlInitSetExtLlRtCfg(pCfg->pLlRtCfg, pCfg->pFreeMem, pCfg->freeMemAvail);
pCfg->pFreeMem += memUsed;
pCfg->freeMemAvail -= memUsed;
totalMemUsed += memUsed;
LlInitBbInit();
LlInitBbAuxInit();
LlInitSchInit();
LlInitLlInit(FALSE);
LlInitLlExtInit();
return totalMemUsed;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master scan action routines.
* \file
* \brief Link layer controller master scan action routines.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master scan action routines.
* \file
* \brief Link layer controller master scan action routines.
*/
/*************************************************************************************************/
@ -28,7 +29,7 @@
#include "wsf_assert.h"
#include "wsf_msg.h"
#include "wsf_trace.h"
#include "bb_ble_api_reslist.h"
#include "util/bstream.h"
#include <string.h>
@ -42,7 +43,7 @@
* \return TRUE if successful, FALSE otherwise.
*/
/*************************************************************************************************/
static uint8_t lctrPerScanSetup(lctrPerCreateSyncCtrlBlk_t *pPerCreateSync, lctrPerCreateSyncMsg_t *pMsg)
static uint8_t lctrPerScanSetup(lctrPerCreateSyncCtrlBlk_t *pPerCreateSync, lctrPerCreateSyncMsg_t *pMsg, uint8_t createDispId)
{
lctrPerScanCtx_t *pPerScanCtx;
@ -58,6 +59,8 @@ static uint8_t lctrPerScanSetup(lctrPerCreateSyncCtrlBlk_t *pPerCreateSync, lctr
pPerScanCtx->filtParam.advAddr = pMsg->advAddr;
pPerScanCtx->skip = pMsg->skip;
pPerScanCtx->syncTimeOutMs = LCTR_PER_SYNC_TIMEOUT_TO_MS(pMsg->syncTimeOut);
pPerScanCtx->createDispId = createDispId;
pPerScanCtx->repDisabled = pMsg->repDisabled;
return LL_SUCCESS;
}
@ -324,8 +327,8 @@ void lctrCreateSyncActCreate(void)
lctrPerCreateSync.filtParam.advAddrType = pMsg->advAddrType;
lctrPerCreateSync.filtParam.advSID = pMsg->advSID;
lctrPerScanSetup(&lctrPerCreateSync, pMsg);
lctrMstPerScanBuildOp(lctrPerCreateSync.pPerScanCtx, pMsg);
lctrPerScanSetup(&lctrPerCreateSync, pMsg, LCTR_DISP_PER_CREATE_SYNC);
lctrMstPerScanBuildOp(lctrPerCreateSync.pPerScanCtx);
LmgrIncResetRefCount();
}
@ -360,12 +363,37 @@ void lctrCreateSyncActCancel(void)
SchRemove(&lctrPerCreateSync.pPerScanCtx->bod);
}
lctrSendCreateSyncMsg(LCTR_CREATE_SYNC_MSG_TERMINATE);
lctrPerCreateSync.pPerScanCtx->cancelByHost = TRUE;
lctrSendCreateSyncMsg(lctrPerCreateSync.pPerScanCtx, LCTR_CREATE_SYNC_MSG_TERMINATE);
}
/*************************************************************************************************/
/*!
* \brief Create sync cancel action function.
* \brief Create sync failed action function.
*
* \return None.
*/
/*************************************************************************************************/
void lctrCreateSyncActFailed(void)
{
if (lctrPerCreateSync.createSyncPending == TRUE)
{
lctrPerCreateSync.pPerScanCtx->cancelCreateSync = TRUE;
lctrPerCreateSync.pPerScanCtx->cancelByHost = FALSE;
SchRemove(&lctrPerCreateSync.pPerScanCtx->bod);
lctrPerCreateSync.createSyncPending = FALSE;
}
/* Pack and notify the host about sync established event with failed status. */
lmgrPerAdvSyncEstdInd_t rpt;
lctrPerAdvSyncEstRptPack(lctrPerCreateSync.pPerScanCtx, &rpt);
LmgrSendSyncEstInd(LL_ERROR_CODE_CONN_FAILED_TO_ESTABLISH, LCTR_GET_PER_SCAN_HANDLE(lctrPerCreateSync.pPerScanCtx), &rpt);
}
/*************************************************************************************************/
/*!
* \brief Create sync terminate action function.
*
* \return None.
*/
@ -379,9 +407,143 @@ void lctrCreateSyncActTerminate(void)
lctrMstPerScanCleanupOp(lctrPerCreateSync.pPerScanCtx);
lmgrPerAdvSyncEstdInd_t rpt;
memset(&rpt, 0, sizeof(lmgrPerAdvSyncEstdInd_t));
LmgrSendSyncEstInd(LL_ERROR_CODE_OP_CANCELLED_BY_HOST, LCTR_GET_PER_SCAN_HANDLE(lctrPerCreateSync.pPerScanCtx), &rpt);
if (lctrPerCreateSync.pPerScanCtx->cancelByHost)
{
lmgrPerAdvSyncEstdInd_t rpt;
memset(&rpt, 0, sizeof(lmgrPerAdvSyncEstdInd_t));
LmgrSendSyncEstInd(LL_ERROR_CODE_OP_CANCELLED_BY_HOST, LCTR_GET_PER_SCAN_HANDLE(lctrPerCreateSync.pPerScanCtx), &rpt);
}
}
/*************************************************************************************************/
/*!
* \brief Transfer sync start action function.
*
* \return None.
*/
/*************************************************************************************************/
void lctrTransferSyncActStart(void)
{
lctrPerScanCtx_t *pPerScanCtx;
lctrPerTransferSyncMsg_t *pMsg = (lctrPerTransferSyncMsg_t *)pLctrMstPerScanMsg;
if ((pPerScanCtx = lctrAllocPerScanCtx()) == NULL)
{
return;
}
BbStart(BB_PROT_BLE);
lctrPerTransferSync.pPerScanCtx = pPerScanCtx;
pPerScanCtx->filtParam.filterPolicy = LL_PER_SCAN_FILTER_NONE; //TODO: to be handled later.
pPerScanCtx->filtParam.advSID = pMsg->advSID;
pPerScanCtx->filtParam.advAddrType = pMsg->advAddrType;
pPerScanCtx->filtParam.advAddr = pMsg->advAddr;
pPerScanCtx->rxPhys = pMsg->rxPhy;
pPerScanCtx->syncTimeOutMs = LCTR_PER_SYNC_TIMEOUT_TO_MS(100); //TODO: to be handled later.
pPerScanCtx->skip = 0; //TODO: to be handled later.
pPerScanCtx->createDispId = LCTR_DISP_TRANFER_SYNC;
/* Decode syncInfo */
lctrUnpackSyncInfo(&trsfSyncInfo, pMsg->bSyncInfo);
pPerScanCtx->perInter = BB_US_TO_BB_TICKS(LCTR_PER_INTER_TO_US(trsfSyncInfo.syncInter));
pPerScanCtx->advSID = pMsg->advSID;
pPerScanCtx->advAddrType = pMsg->advAddrType;
pPerScanCtx->advAddr = pMsg->advAddr;
/* Check if received address is resolvable. */
if ((pMsg->advAddrType & LL_ADDR_RANDOM_BIT) && BDA64_ADDR_IS_RPA(pMsg->advAddr))
{
uint64_t peerIdAddr = 0;
uint8_t peerIdAddrType = 0;
if (BbBleResListResolvePeer(pMsg->advAddr, &peerIdAddrType, &peerIdAddr))
{
pPerScanCtx->advAddrType = peerIdAddrType | LL_ADDR_IDENTITY_BIT;
pPerScanCtx->advAddr = peerIdAddr;
}
}
LL_TRACE_INFO1("Periodic sync transfer -- syncInfo --, syncOffset=%u", trsfSyncInfo.syncOffset);
LL_TRACE_INFO1(" offsetUnits=%u", trsfSyncInfo.offsetUnits);
LL_TRACE_INFO1(" syncInter=%u", trsfSyncInfo.syncInter);
LL_TRACE_INFO1(" eventCounter=%u", trsfSyncInfo.eventCounter);
lctrMstPerScanBuildOp(lctrPerTransferSync.pPerScanCtx);
LmgrIncResetRefCount();
/* All information is transfered, we can start scanning periodic sync immediately. */
lctrPerTransferSync.connHandle = pMsg->connHandle;
lctrPerTransferSync.serviceData = pMsg->id;
lctrPerTransferSync.ceRef = pMsg->ceRef;
lctrPerTransferSync.ceRcvd = pMsg->ceRcvd;
lctrPerTransferSync.syncCe = pMsg->syncConnEvtCounter;
lctrPerTransferSync.scaB = pMsg->scaB;
lctrPerTransferSync.lastPECounter = pMsg->lastPECounter;
lctrMstPerScanTransferOpCommit(pMsg->connHandle);
lctrMstPerScanIsrInit();
}
/*************************************************************************************************/
/*!
* \brief Transfer sync done action function.
*
* \return None.
*/
/*************************************************************************************************/
void lctrTransferSyncActDone(void)
{
}
/*************************************************************************************************/
/*!
* \brief Transfer sync failed action function.
*
* \return None.
*/
/*************************************************************************************************/
void lctrTransferSyncActFailed(void)
{
lctrPerTransferSync.pPerScanCtx->cancelCreateSync = TRUE;
SchRemove(&lctrPerTransferSync.pPerScanCtx->bod);
/* Notify the host that controller failed to receive AUX_SYNC_IND within 6 periodic ADV events. */
LctrSendPerSyncTrsfRcvdEvt(LL_ERROR_CODE_CONN_FAILED_TO_ESTABLISH, lctrPerTransferSync.pPerScanCtx);
}
/*************************************************************************************************/
/*!
* \brief Transfer sync cancel action function.
*
* \return None.
*/
/*************************************************************************************************/
void lctrTransferSyncActCancel(void)
{
lctrPerTransferSync.pPerScanCtx->cancelCreateSync = TRUE;
SchRemove(&lctrPerTransferSync.pPerScanCtx->bod);
}
/*************************************************************************************************/
/*!
* \brief Transfer sync terminate action function.
*
* \return None.
*/
/*************************************************************************************************/
void lctrTransferSyncActTerminate(void)
{
if (lctrPerTransferSync.pPerScanCtx->cancelCreateSync == TRUE)
{
lctrPerTransferSync.pPerScanCtx->cancelCreateSync = FALSE;
}
lctrMstPerScanCleanupOp(lctrPerTransferSync.pPerScanCtx);
}
/*************************************************************************************************/
@ -395,11 +557,19 @@ void lctrCreateSyncActTerminate(void)
/*************************************************************************************************/
void lctrPerScanActSyncEstd(lctrPerScanCtx_t *pPerScanCtx)
{
/* Pack and notify the host about sync established event. */
lmgrPerAdvSyncEstdInd_t rpt;
if (pPerScanCtx->createDispId == LCTR_DISP_PER_CREATE_SYNC)
{
/* Pack and notify the host about sync established event. */
lmgrPerAdvSyncEstdInd_t rpt;
lctrPerAdvSyncEstRptPack(pPerScanCtx, &rpt);
LmgrSendSyncEstInd(LL_SUCCESS, LCTR_GET_PER_SCAN_HANDLE(pPerScanCtx), &rpt);
lctrPerAdvSyncEstRptPack(pPerScanCtx, &rpt);
LmgrSendSyncEstInd(LL_SUCCESS, LCTR_GET_PER_SCAN_HANDLE(pPerScanCtx), &rpt);
}
else if (pPerScanCtx->createDispId == LCTR_DISP_TRANFER_SYNC)
{
/* Notify the host about periodic sync transfer received event. */
LctrSendPerSyncTrsfRcvdEvt(LL_SUCCESS, pPerScanCtx);
}
}
/*************************************************************************************************/
@ -455,3 +625,35 @@ void lctrPerScanActSyncTimeout(lctrPerScanCtx_t *pPerScanCtx)
/* Shutdown completes with events generated in BOD end callback. */
}
/*************************************************************************************************/
/*!
* \brief Process acad that need to be serviced.
*
* \param pMsg Acad message.
*
* \return None
*/
/*************************************************************************************************/
void lctrPerScanActProcessAcad(lctrAcadMsg_t *pMsg)
{
lctrPerScanCtx_t *pPerScanCtx = LCTR_GET_PER_SCAN_CTX(pMsg->hdr.handle);
switch(pMsg->hdr.acadId)
{
case LCTR_ACAD_ID_CHAN_MAP_UPDATE:
{
lctrAcadChanMapUpd_t *pData = &pPerScanCtx->acadParams[pMsg->hdr.acadId].chanMapUpdate;
if ((pData->instant - pMsg->hdr.eventCtr) <= pMsg->hdr.skip)
{
pPerScanCtx->chanParam.chanMask = pData->chanMask;
LmgrBuildRemapTable(&pPerScanCtx->chanParam);
pData->hdr.state = LCTR_ACAD_STATE_DISABLED;
}
break;
}
default:
break;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,13 +16,15 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller slave advertising action routines.
* \file
* \brief Link layer controller slave advertising action routines.
*/
/*************************************************************************************************/
#include "lctr_int_adv_slave.h"
#include "sch_api.h"
#include "bb_ble_api_reslist.h"
#include "lctr_pdu_adv.h"
#include "wsf_assert.h"
#include "wsf_msg.h"
#include "wsf_trace.h"
@ -199,27 +201,40 @@ void lctrAdvActSelfTerm(void)
restartAdv = TRUE;
}
lctrConnEstablish_t *pMsg;
if ((pMsg = (lctrConnEstablish_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL)
{
lctrUnpackConnIndPdu(&pMsg->connInd, pBuf + LL_ADV_HDR_LEN);
if (!lctrValidateConnIndPdu(&pMsg->connInd))
{
restartAdv = TRUE;
}
}
if (restartAdv)
{
if (pMsg != NULL)
{
WsfMsgFree(pMsg);
}
/* Reuse message. */
lctrMsgHdr_t *pMsg = (lctrMsgHdr_t *)pBuf - 1;
pMsg->dispId = LCTR_DISP_ADV;
pMsg->event = LCTR_ADV_MSG_INT_START;
WsfMsgSend(lmgrPersistCb.handlerId, pMsg);
lctrMsgHdr_t *pResMsg = (lctrMsgHdr_t *)pBuf - 1;
pResMsg->dispId = LCTR_DISP_ADV;
pResMsg->event = LCTR_ADV_MSG_INT_START;
WsfMsgSend(lmgrPersistCb.handlerId, pResMsg);
BbStop(BB_PROT_BLE);
}
else
{
lctrConnEstablish_t *pMsg;
if ((pMsg = (lctrConnEstablish_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL)
if (pMsg != NULL)
{
/* pMsg->hdr.handle = 0; */
pMsg->hdr.dispId = LCTR_DISP_CONN_IND;
/* pMsg->hdr.event = 0; */
lctrUnpackConnIndPdu(&pMsg->connInd, pBuf + LL_ADV_HDR_LEN);
pMsg->connIndEndTs = lctrSlvAdv.reqEndTs;
BbBlePduFiltResultsGetPeerIdAddr(&pAdv->filtResults, &pMsg->peerIdAddr, &pMsg->peerIdAddrType);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller slave extended advertising action routines.
* \file
* \brief Link layer controller slave extended advertising action routines.
*/
/*************************************************************************************************/
@ -34,6 +35,21 @@
#include <string.h>
/*************************************************************************************************/
/*!
* \brief Disable and clean a generic acad parameter
*
* \param pAcadParam Generic acad parameter type
*
* \return None.
*/
/*************************************************************************************************/
static void lctrSlvAcadDisable(lctrAcadParam_t *pAcadParam)
{
memset(pAcadParam, 0, sizeof(*pAcadParam));
pAcadParam->hdr.state = LCTR_ACAD_STATE_DISABLED;
}
/*************************************************************************************************/
/*!
* \brief Common advertise resource cleanup.
@ -64,7 +80,7 @@ static void lctrExtAdvCleanup(lctrAdvSet_t *pAdvSet)
pAdv->pRxReqBuf = NULL;
}
if (pAdvSet->param.advFiltPolicy & LL_ADV_FILTER_SCAN_WL_BIT)
if (pAdvSet->param.advFiltPolicy)
{
LmgrDecWhitelistRefCount();
}
@ -73,6 +89,23 @@ static void lctrExtAdvCleanup(lctrAdvSet_t *pAdvSet)
lmgrCb.numExtAdvEnabled--;
}
/*************************************************************************************************/
/*!
* \brief Common periodic advertising cleanup.
*
* \param pAdvSet Advertising set.
*
* \return None.
*/
/*************************************************************************************************/
static void lctrPeriodicAdvACleanup(lctrAdvSet_t *pAdvSet)
{
BbStop(BB_PROT_BLE);
SchRmRemove(LCTR_GET_PER_RM_HANDLE(pAdvSet));
LmgrDecResetRefCount();
}
/*************************************************************************************************/
/*!
* \brief Start extended advertising.
@ -119,6 +152,43 @@ void lctrExtAdvActStart(lctrAdvSet_t *pAdvSet)
LmgrSendExtAdvEnableCnf(pAdvSet->handle, LL_SUCCESS);
}
/*************************************************************************************************/
/*!
* \brief Start extended advertising internally.
*
* \param pAdvSet Advertising set.
*
* \return None.
*/
/*************************************************************************************************/
void lctrExtAdvActSelfStart(lctrAdvSet_t *pAdvSet)
{
BbStart(BB_PROT_BLE);
/* Reset state. */
pAdvSet->maxEvents = pLctrSlvExtAdvMsg->enable.maxEvents;
pAdvSet->numEvents = 0;
pAdvSet->termReason = LL_SUCCESS;
pAdvSet->pExtAdvAuxPtr = NULL;
pAdvSet->connIndRcvd = FALSE;
pAdvSet->shutdown = FALSE;
pAdvSet->bodTermCnt = 0;
uint8_t status;
if ((status = lctrSlvExtAdvBuildOp(pAdvSet, pLctrSlvExtAdvMsg->enable.durMs)) != LL_SUCCESS)
{
// TODO suppress terminate event on failed start
LmgrSendExtAdvEnableCnf(pAdvSet->handle, status);
lctrSendAdvSetMsg(pAdvSet, LCTR_EXT_ADV_MSG_TERMINATE);
return;
}
if (pLctrSlvExtAdvMsg->enable.durMs)
{
WsfTimerStartMs(&pAdvSet->tmrAdvDur, pLctrSlvExtAdvMsg->enable.durMs);
}
}
/*************************************************************************************************/
/*!
* \brief Restart extended advertising.
@ -164,6 +234,29 @@ void lctrExtAdvActShutdown(lctrAdvSet_t *pAdvSet)
/* Shutdown completes with events generated in BOD end callback. */
}
/*************************************************************************************************/
/*!
* \brief Shutdown active advertising operation due to host reset.
*
* \param pAdvSet Advertising set.
*
* \return None.
*/
/*************************************************************************************************/
void lctrExtAdvActResetShutdown(lctrAdvSet_t *pAdvSet)
{
/* LCTR_MSG_RESET is broadcasted by hciReset and the processing order between ext ADV SM and periodic ADV SM is not guaranteed. */
/* If ext ADV SM runs first, it will purge all info and periodic ADV SM may not run as intended. */
/* So, reset cleanup of periodic advertising has to be done from extended ADV SM. */
if (pAdvSet->perParam.perState == LCTR_PER_ADV_STATE_ENABLED)
{
lctrPeriodicAdvActShutdown(pAdvSet);
lctrPeriodicAdvACleanup(pAdvSet);
}
lctrExtAdvActShutdown(pAdvSet);
}
/*************************************************************************************************/
/*!
* \brief Send advertising operation confirm.
@ -232,7 +325,7 @@ void lctrExtAdvActSelfTerm(lctrAdvSet_t *pAdvSet)
BbBleSlvAuxAdvEvent_t * const pAuxAdv = &pAdvSet->auxBleData.op.slvAuxAdv;
uint8_t *pBuf;
bool_t startConn = TRUE;
bool_t restartAdv = FALSE;
if ((pBuf = pAdv->pRxReqBuf) != NULL)
{
@ -241,7 +334,7 @@ void lctrExtAdvActSelfTerm(lctrAdvSet_t *pAdvSet)
/* If peer address was not resolved, attempt to resolve it now. */
if (!BbBlePduFiltCheck(pBuf, &pBle->pduFilt, TRUE, &pAdv->filtResults))
{
startConn = FALSE;
restartAdv = TRUE;
}
}
else if ((pBuf = pAuxAdv->pRxAuxReqBuf) != NULL)
@ -267,11 +360,13 @@ void lctrExtAdvActSelfTerm(lctrAdvSet_t *pAdvSet)
if (!BbBleExtPduFiltCheck(&params, &pBle->pduFilt, TRUE, &pAuxAdv->filtResults))
{
startConn = FALSE;
restartAdv = TRUE;
}
}
if (startConn && pBuf)
WSF_ASSERT(pBuf); /* pBuf must not be NULL since conn_ind/aux_conn_req is received. */
if (restartAdv == FALSE)
{
lctrConnEstablish_t *pMsg;
@ -283,6 +378,7 @@ void lctrExtAdvActSelfTerm(lctrAdvSet_t *pAdvSet)
pMsg->hdr.dispId = LCTR_DISP_CONN_IND;
/* pMsg->hdr.event = 0; */
/* coverity[var_deref_model] */
pBuf += lctrUnpackAdvbPduHdr(&hdr, pBuf);
lctrUnpackConnIndPdu(&pMsg->connInd, pBuf);
@ -316,14 +412,25 @@ void lctrExtAdvActSelfTerm(lctrAdvSet_t *pAdvSet)
}
else
{
/* Restart advertising. */
lctrSendAdvSetMsg(pAdvSet, LCTR_EXT_ADV_MSG_INT_START);
/* Do not cleanup. Restarting will reuse resources. */
/* lctrExtAdvCleanup(pAdvSet); */
/* BbStop(BB_PROT_BLE); */
restartAdv = TRUE;
}
}
if (restartAdv == TRUE)
{
/* Restart advertising. */
/* Reuse message. */
/* coverity[alias_transfer] */
lctrMsgHdr_t *pMsg = (lctrMsgHdr_t *)pBuf - 1;
pMsg->handle = pAdvSet->handle;
pMsg->dispId = LCTR_DISP_EXT_ADV;
pMsg->event = LCTR_EXT_ADV_MSG_INT_START;
WsfMsgSend(lmgrPersistCb.handlerId, pMsg);
BbStop(BB_PROT_BLE);
}
}
}
@ -355,6 +462,15 @@ void lctrExtAdvActAdvTerm(lctrAdvSet_t *pAdvSet)
/*************************************************************************************************/
void lctrExtAdvActReset(lctrAdvSet_t *pAdvSet)
{
/* LCTR_MSG_RESET is broadcasted by hciReset and the processing order between ext ADV SM and periodic ADV SM is not guaranteed. */
/* If ext ADV SM runs first, it will purge all info and periodic ADV SM may not run as intended. */
/* So, reset cleanup of periodic advertising has to be done from extended ADV SM. */
if (pAdvSet->perParam.perState == LCTR_PER_ADV_STATE_ENABLED)
{
lctrPeriodicAdvActShutdown(pAdvSet);
lctrPeriodicAdvACleanup(pAdvSet);
}
/* Although the AdvSet is freed here, some benign modifications to the context may occurs
* to complete the SM call path. */
lctrFreeAdvSet(pAdvSet);
@ -405,7 +521,7 @@ void lctrExtAdvActDurationExpired(lctrAdvSet_t *pAdvSet)
* \return None.
*/
/*************************************************************************************************/
void lctrPeriodicBuildRemapTable(lctrChanParam_t *pChanParam)
void lctrPeriodicBuildRemapTable(lmgrChanParam_t *pChanParam)
{
unsigned int chanIdx;
unsigned int numUsedChan = 0;
@ -441,8 +557,8 @@ void lctrPeriodicAdvActStart(lctrAdvSet_t *pAdvSet)
pAdvSet->perParam.shutdown = FALSE;
pAdvSet->perParam.perAccessAddr = lctrComputeAccessAddr();
pAdvSet->perParam.perEventCounter = 0;
pAdvSet->perParam.perChanParam.chanMask = LL_CHAN_DATA_ALL;
lctrPeriodicBuildRemapTable(&pAdvSet->perParam.perChanParam);
pAdvSet->perParam.perChanParam.chanMask = lmgrCb.chanClass;
LmgrBuildRemapTable(&pAdvSet->perParam.perChanParam);
pAdvSet->perParam.perChanParam.usedChSel = LL_CH_SEL_2;
pAdvSet->perParam.perChanParam.chIdentifier = (pAdvSet->perParam.perAccessAddr >> 16) ^
(pAdvSet->perParam.perAccessAddr >> 0);
@ -464,7 +580,15 @@ void lctrPeriodicAdvActStart(lctrAdvSet_t *pAdvSet)
pAdvSet->perParam.perAuxStart = TRUE;
}
if (pAdvSet->state == LCTR_EXT_ADV_STATE_ENABLED)
{
/* The Advertising DID is required to change when a SyncInfo field is added to or removed. */
pAdvSet->advData.alt.ext.did = lctrCalcDID(pAdvSet->advData.pBuf, pAdvSet->advData.len);
pAdvSet->didPerUpdate = TRUE;
}
LmgrSendPeriodicAdvEnableCnf(pAdvSet->handle, LL_SUCCESS);
LmgrIncResetRefCount();
}
/*************************************************************************************************/
@ -521,10 +645,20 @@ void lctrPeriodicAdvActDisallowAdvCnf(lctrAdvSet_t *pAdvSet)
/*************************************************************************************************/
void lctrPeriodicAdvActShutdown(lctrAdvSet_t *pAdvSet)
{
if ((pAdvSet->state == LCTR_EXT_ADV_STATE_ENABLED) && (pAdvSet->perParam.perAdvEnabled == TRUE))
{
/* The Advertising DID is required to change when a SyncInfo field is added to or removed. */
pAdvSet->advData.alt.ext.did = lctrCalcDID(pAdvSet->advData.pBuf, pAdvSet->advData.len);
pAdvSet->didPerUpdate = TRUE;
}
pAdvSet->perParam.shutdown = TRUE;
pAdvSet->perParam.perAdvEnabled = FALSE;
pAdvSet->perParam.perAuxStart = FALSE;
/* Shutdown completes with events generated in BOD end callback. */
/* By removing BOD from scheduler, BOD end callback will be called. */
/* Shutdown completes with events generated in BOD end callback. */
SchRemove(&pAdvSet->perParam.perAdvBod);
}
/*************************************************************************************************/
@ -538,9 +672,7 @@ void lctrPeriodicAdvActShutdown(lctrAdvSet_t *pAdvSet)
/*************************************************************************************************/
void lctrPeriodicAdvActAdvTerm(lctrAdvSet_t *pAdvSet)
{
BbStop(BB_PROT_BLE);
SchRmRemove(LL_MAX_CONN + LCTR_GET_EXT_ADV_INDEX(pAdvSet));
lctrPeriodicAdvACleanup(pAdvSet);
LmgrSendPeriodicAdvEnableCnf(pAdvSet->handle, LL_SUCCESS);
}
@ -556,7 +688,44 @@ void lctrPeriodicAdvActAdvTerm(lctrAdvSet_t *pAdvSet)
/*************************************************************************************************/
void lctrPeriodicAdvActResetTerm(lctrAdvSet_t *pAdvSet)
{
BbStop(BB_PROT_BLE);
SchRmRemove(LL_MAX_CONN + LCTR_GET_EXT_ADV_INDEX(pAdvSet));
lctrPeriodicAdvACleanup(pAdvSet);
}
/*************************************************************************************************/
/*!
* \brief Acad channel map start handler
*
* \param pAdvSet Advertising set.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSlvAcadActChanMapUpdateStart(lctrAdvSet_t *pAdvSet)
{
lctrAcadChanMapUpd_t *pAcadParam = &pAdvSet->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE].chanMapUpdate;
/* A new channel map update cannot replace a currently running one. */
if (pAcadParam->hdr.state == LCTR_ACAD_STATE_ENABLED)
{
return;
}
pAcadParam->chanMask = pAdvSet->perParam.updChanMask;
pAcadParam->instant = pAdvSet->perParam.perEventCounter + LL_MIN_INSTANT;
pAcadParam->hdr.len = LL_ACAD_UPDATE_CHANNEL_MAP_LEN;
pAcadParam->hdr.state = LCTR_ACAD_STATE_ENABLED;
}
/*************************************************************************************************/
/*!
* \brief Acad channel map finish handler
*
* \param pAdvSet Advertising set.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSlvAcadActChanMapUpdateFinish(lctrAdvSet_t *pAdvSet)
{
lctrSlvAcadDisable(&pAdvSet->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE]);
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,12 +16,14 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller connection state machine action routines.
* \file
* \brief Link layer controller connection state machine action routines.
*/
/*************************************************************************************************/
#include "lctr_int_conn.h"
#include "lctr_int_adv_slave.h"
#include "lctr_int_adv_master_ae.h"
#include "sch_api.h"
#include "sch_api_ble.h"
#include "lmgr_api_conn.h"
@ -51,11 +53,28 @@
LL_FEAT_STABLE_MOD_IDX_RECEIVER | \
LL_FEAT_LE_CODED_PHY | \
LL_FEAT_CH_SEL_2 | \
LL_FEAT_LE_POWER_CLASS_1)
LL_FEAT_LE_POWER_CLASS_1 | \
LL_FEAT_MIN_NUM_USED_CHAN | \
LL_FEAT_CONN_CTE_REQ | \
LL_FEAT_CONN_CTE_RSP | \
LL_FEAT_RECV_CTE | \
LL_FEAT_PAST_SENDER | \
LL_FEAT_PAST_RECIPIENT | \
LL_FEAT_SCA_UPDATE | \
LL_FEAT_CIS_MASTER_ROLE | \
LL_FEAT_CIS_SLAVE_ROLE | \
LL_FEAT_ISO_BROADCASTER | \
LL_FEAT_ISO_SYNC)
/*! \brief Used feature bitmask, i.e. FeatureSet[0]. */
#define LCTR_USED_FEAT_SET_MASK 0xFF
/*! \brief Used feature bitmask, i.e. FeatureSet[0]. */
#define LCTR_USED_FEAT_SET_MASK 0xFF
/*! \brief Features bits mask over the air */
#define LCTR_OTA_FEAT_MASK (~LL_FEAT_REMOTE_PUB_KEY_VALIDATION & LL_FEAT_ALL_MASK)
/*************************************************************************************************/
/*!
* \brief Validate connection parameter range.
@ -79,6 +98,33 @@ static bool_t lctrValidateConnParam(const lctrConnParam_t *pConnParam)
return TRUE;
}
/*************************************************************************************************/
/*!
* \brief Compute the sleep clock accuracy index in connection context.
*
* \param pCtx Connection context.
*
* \return SCA index.
*/
/*************************************************************************************************/
static uint8_t lctrComputeConnSca(lctrConnCtx_t *pCtx)
{
const uint16_t clkPpm = BbGetClockAccuracy();
int8_t sca;
if (clkPpm <= 20) sca = 7;
else if (clkPpm <= 30) sca = 6;
else if (clkPpm <= 50) sca = 5;
else if (clkPpm <= 75) sca = 4;
else if (clkPpm <= 100) sca = 3;
else if (clkPpm <= 150) sca = 2;
else if (clkPpm <= 250) sca = 1;
else sca = 0;
return (uint8_t) (sca + pCtx->scaMod);
}
/*************************************************************************************************/
/*!
* \brief Notify host of connect indication.
@ -262,7 +308,7 @@ void lctrSendChanMapUpdateInd(lctrConnCtx_t *pCtx)
uint8_t *pBuf = pPdu;
#if (LL_ENABLE_TESTER)
if (llTesterCb.eventCounterOffset)
if (llTesterCb.eventCounterOverride == TRUE)
{
pCtx->chanMapUpd.instant = pCtx->eventCounter +
llTesterCb.eventCounterOffset + 1; /* +1 for next CE */
@ -330,7 +376,7 @@ void lctrSendFeatureReq(lctrConnCtx_t *pCtx)
/*** Assemble control PDU. ***/
UINT8_TO_BSTREAM(pBuf, opcode);
UINT64_TO_BSTREAM(pBuf, (lmgrCb.features & LCTR_FEAT_PEER_MASK));
UINT64_TO_BSTREAM(pBuf, (lmgrCb.features & LCTR_OTA_FEAT_MASK));
/*** Queue for transmit. ***/
@ -361,7 +407,7 @@ void lctrSendFeatureRsp(lctrConnCtx_t *pCtx)
uint64_t featSet = (pCtx->usedFeatSet & LCTR_USED_FEAT_SET_MASK) | /* FeatureSet[0] used by master and slave */
(lmgrCb.features & ~LCTR_USED_FEAT_SET_MASK); /* FeatureSet[1..7] used by sender */
UINT64_TO_BSTREAM(pBuf, (featSet & LCTR_FEAT_PEER_MASK)); /* Only send valid features bits between controllers. */
UINT64_TO_BSTREAM(pBuf, (featSet & LCTR_OTA_FEAT_MASK)); /* Only send valid features bits between controllers. */
/*** Queue for transmit. ***/
@ -380,7 +426,7 @@ void lctrSendFeatureRsp(lctrConnCtx_t *pCtx)
/*************************************************************************************************/
void lctrStoreUsedFeatures(lctrConnCtx_t *pCtx)
{
pCtx->usedFeatSet = lmgrCb.features & lctrDataPdu.pld.featReqRsp.featSet;
pCtx->usedFeatSet = lmgrCb.features & lctrDataPdu.pld.featReqRsp.featSet & LCTR_FEAT_PEER_MASK;
pCtx->featExchFlag = TRUE;
/* Update stable modulation index. */
@ -806,7 +852,12 @@ void lctrSendConnParamReq(lctrConnCtx_t *pCtx)
pCtx->connUpdSpec.supTimeout = llTesterCb.connParamReq.supTimeout;
pCtx->connUpdSpec.minCeLen = 0;
pCtx->connUpdSpec.maxCeLen = 0;
llTesterCb.connParamReqEnabled = FALSE;
lctrSendConnParamPdu(pCtx, LL_PDU_CONN_PARAM_REQ, &pCtx->connUpdSpec, llTesterCb.connParamReq.prefPeriod);
return;
}
#endif
@ -828,7 +879,6 @@ void lctrSendConnParamRsp(lctrConnCtx_t *pCtx)
(lmgrCb.numConnEnabled > 1))
{
/* TODO resolve scheduling with multiple connections */
WSF_ASSERT(0);
}
lctrSendConnParamPdu(pCtx, LL_PDU_CONN_PARAM_RSP, &pLctrConnMsg->connParamReply.connSpec, 1);
@ -959,6 +1009,17 @@ static void lctrSendDataLengthPdu(lctrConnCtx_t *pCtx, uint8_t opcode)
maxRxTime = WSF_MIN(pCtx->localDataPdu.maxRxTime, LL_MAX_DATA_TIME_ABS_MAX_1M);
maxTxTime = WSF_MIN(pCtx->localDataPdu.maxTxTime, LL_MAX_DATA_TIME_ABS_MAX_1M);
}
else
{
if (pCtx->bleData.chan.rxPhy == BB_PHY_BLE_CODED)
{
maxRxTime = WSF_MAX(pCtx->localDataPdu.maxRxTime, LL_MAX_DATA_TIME_ABS_MIN_CODED);
}
if (pCtx->bleData.chan.txPhy == BB_PHY_BLE_CODED)
{
maxTxTime = WSF_MAX(pCtx->localDataPdu.maxTxTime, LL_MAX_DATA_TIME_ABS_MIN_CODED);
}
}
UINT16_TO_BSTREAM(pBuf, pCtx->localDataPdu.maxRxLen);
UINT16_TO_BSTREAM(pBuf, maxRxTime);
@ -1019,13 +1080,36 @@ void lctrStoreRemoteDataLength(lctrConnCtx_t *pCtx)
LL_TRACE_WARN0("Received invalid parameters in LENGTH_PDU");
return;
}
lctrDataLen_t oldEffDataPdu = pCtx->effDataPdu;
uint16_t maxRxTime = pCtx->localDataPdu.maxRxTime;
uint16_t maxTxTime = pCtx->localDataPdu.maxTxTime;
/* If LL_FEAT_LE_CODED_PHY is not supported, maxRxTime and maxTxTime can not be more than 2120. */
if (!(pCtx->usedFeatSet & LL_FEAT_LE_CODED_PHY))
{
maxRxTime = WSF_MIN(pCtx->localDataPdu.maxRxTime, LL_MAX_DATA_TIME_ABS_MAX_1M);
maxTxTime = WSF_MIN(pCtx->localDataPdu.maxTxTime, LL_MAX_DATA_TIME_ABS_MAX_1M);
}
/* Compute effective values */
pCtx->effDataPdu.maxTxLen = WSF_MIN(pCtx->localDataPdu.maxTxLen, lctrDataPdu.pld.lenReq.maxRxLen);
pCtx->effDataPdu.maxRxLen = WSF_MIN(pCtx->localDataPdu.maxRxLen, lctrDataPdu.pld.lenReq.maxTxLen);
pCtx->effDataPdu.maxTxTime = WSF_MIN(pCtx->localDataPdu.maxTxTime, lctrDataPdu.pld.lenReq.maxRxTime);
pCtx->effDataPdu.maxRxTime = WSF_MIN(pCtx->localDataPdu.maxRxTime, lctrDataPdu.pld.lenReq.maxTxTime);
pCtx->effDataPdu.maxTxTime = WSF_MIN(maxTxTime, lctrDataPdu.pld.lenReq.maxRxTime);
pCtx->effDataPdu.maxRxTime = WSF_MIN(maxRxTime, lctrDataPdu.pld.lenReq.maxTxTime);
/* connEffectiveMaxRxTimeCoded - the greater of 2704 and connEffectiveMaxRxTimeUncoded. */
if (pCtx->bleData.chan.rxPhy == BB_PHY_BLE_CODED)
{
pCtx->effDataPdu.maxRxTime = WSF_MAX(pCtx->effDataPdu.maxRxTime, LL_MAX_DATA_TIME_ABS_MIN_CODED);
}
if (pCtx->bleData.chan.txPhy == BB_PHY_BLE_CODED)
{
pCtx->effDataPdu.maxTxTime = WSF_MAX(pCtx->effDataPdu.maxTxTime, LL_MAX_DATA_TIME_ABS_MIN_CODED);
}
if ((oldEffDataPdu.maxTxLen != pCtx->effDataPdu.maxTxLen) ||
(oldEffDataPdu.maxRxLen != pCtx->effDataPdu.maxRxLen) ||
(oldEffDataPdu.maxTxTime != pCtx->effDataPdu.maxTxTime) ||
@ -1035,11 +1119,46 @@ void lctrStoreRemoteDataLength(lctrConnCtx_t *pCtx)
}
pCtx->effConnDurUsec = lctrCalcConnDurationUsec(pCtx, &pCtx->effDataPdu);
LL_TRACE_INFO2("Effective data lengths maxTxLen=%u, maxRxLen=%u", pCtx->effDataPdu.maxTxLen, pCtx->effDataPdu.maxRxLen);
LL_TRACE_INFO2("Effective data times maxTxTime=%u, maxRxTime=%u", pCtx->effDataPdu.maxTxTime, pCtx->effDataPdu.maxRxTime);
}
/*************************************************************************************************/
/*!
* \brief Notify host of data length change indication.
*
* \param pCtx Connection context.
* \param status Status.
*
* \return None.
*/
/*************************************************************************************************/
void lctrNotifyHostDataLengthInd(lctrConnCtx_t *pCtx, uint8_t status)
{
const uint16_t handle = LCTR_GET_CONN_HANDLE(pCtx);
LlDataLenChangeInd_t evt =
{
.hdr =
{
.param = handle,
.event = LL_DATA_LEN_CHANGE_IND,
.status = status
},
.handle = handle,
};
evt.maxTxLen = pCtx->effDataPdu.maxTxLen;
evt.maxTxTime = pCtx->effDataPdu.maxTxTime;
evt.maxRxLen = pCtx->effDataPdu.maxRxLen;
evt.maxRxTime = pCtx->effDataPdu.maxRxTime;
LL_TRACE_INFO2("### LlEvent ### LL_DATA_LEN_CHANGE_IND, handle=%u, status=%u", handle, status);
LmgrSendEvent((LlEvt_t *)&evt);
}
/*************************************************************************************************/
/*!
* \brief Send set minimum number of used channels indication PDU to peer.
@ -1113,36 +1232,170 @@ void lctrStoreSetMinUsedChan(lctrConnCtx_t *pCtx)
/*************************************************************************************************/
/*!
* \brief Notify host of data length change indication.
* \brief Send peer SCA request PDU.
*
* \param pCtx Connection context.
* \param status Status.
* \param opcode PDU opcode.
*
* \return None.
*/
/*************************************************************************************************/
void lctrNotifyHostDataLengthInd(lctrConnCtx_t *pCtx, uint8_t status)
static void lctrSendPeerScaReqPdu(lctrConnCtx_t *pCtx, uint8_t opcode)
{
uint8_t *pPdu;
if ((pPdu = lctrTxCtrlPduAlloc(LL_PEER_SCA_REQ_LEN)) != NULL)
{
uint8_t *pBuf = pPdu;
/*** Assemble control PDU. ***/
UINT8_TO_BSTREAM (pBuf, opcode);
UINT8_TO_BSTREAM (pBuf, lctrComputeConnSca(pCtx));
/*** Queue for transmit. ***/
lctrTxCtrlPduQueue(pCtx, pPdu);
}
}
/*************************************************************************************************/
/*!
* \brief Update action for sca processing.
*
* \param pCtx Connection Context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrStoreScaAction(lctrConnCtx_t *pCtx)
{
pCtx->scaUpdAction = pLctrConnMsg->scaReq.action;
}
/*************************************************************************************************/
/*!
* \brief Send peer SCA request.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSendPeerScaReq(lctrConnCtx_t *pCtx)
{
switch (pCtx->scaUpdAction)
{
/* Update by syncing instead of increment/decrement to prevent desync of the SCA value. */
case LL_MODIFY_SCA_MORE_ACCURATE:
if (pCtx->scaMod < lmgrCb.scaMod)
{
pCtx->scaMod = lmgrCb.scaMod;
}
break;
case LL_MODIFY_SCA_LESS_ACCURATE:
if (pCtx->scaMod > lmgrCb.scaMod)
{
pCtx->scaMod = lmgrCb.scaMod;
}
break;
default: /* LL_MODIFY_SCA_NO_ACTION */
/* This happens when we are sending a tester REQ. */
break;
}
lctrSendPeerScaReqPdu(pCtx, LL_PDU_PEER_SCA_REQ);
}
/*************************************************************************************************/
/*!
* \brief Send peer SCA response PDU.
*
* \param pCtx Connection context.
* \param opcode PDU opcode.
*
* \return None.
*/
/*************************************************************************************************/
static void lctrSendPeerScaRspPdu(lctrConnCtx_t *pCtx, uint8_t opcode)
{
uint8_t *pPdu;
if ((pPdu = lctrTxCtrlPduAlloc(LL_PEER_SCA_RSP_LEN)) != NULL)
{
uint8_t *pBuf = pPdu;
/*** Assemble control PDU. ***/
UINT8_TO_BSTREAM (pBuf, opcode);
UINT8_TO_BSTREAM (pBuf, lctrComputeConnSca(pCtx));
/*** Queue for transmit. ***/
lctrTxCtrlPduQueue(pCtx, pPdu);
}
}
/*************************************************************************************************/
/*!
* \brief Send peer SCA response.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSendPeerScaRsp(lctrConnCtx_t *pCtx)
{
lctrSendPeerScaRspPdu(pCtx, LL_PDU_PEER_SCA_RSP);
}
/*************************************************************************************************/
/*!
* \brief Store peer SCA.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrStorePeerSca(lctrConnCtx_t *pCtx)
{
pCtx->peerSca = lctrDataPdu.pld.peerSca.sca;
if (pCtx->role == LL_ROLE_SLAVE)
{
pCtx->data.slv.totalAcc = lctrCalcTotalAccuracy(pCtx->peerSca);
LL_TRACE_INFO1("lctrStorePeerSca pCtx->data.slv.totalAcc=%d", pCtx->data.slv.totalAcc);
}
}
/*************************************************************************************************/
/*!
* \brief Notify host of peer SCA request confirmation.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrNotifyHostPeerScaCnf(lctrConnCtx_t *pCtx)
{
const uint16_t handle = LCTR_GET_CONN_HANDLE(pCtx);
LlDataLenChangeInd_t evt =
LlPeerScaCnf_t evt =
{
.hdr =
{
.param = handle,
.event = LL_DATA_LEN_CHANGE_IND,
.status = status
.param = handle,
.event = LL_REQ_PEER_SCA_IND,
.status = LL_SUCCESS
},
.handle = handle,
.status = LL_SUCCESS,
.connHandle = handle,
.peerSca = pCtx->peerSca,
};
evt.maxTxLen = pCtx->effDataPdu.maxTxLen;
evt.maxTxTime = pCtx->effDataPdu.maxTxTime;
evt.maxRxLen = pCtx->effDataPdu.maxRxLen;
evt.maxRxTime = pCtx->effDataPdu.maxRxTime;
LL_TRACE_INFO2("### LlEvent ### LL_DATA_LEN_CHANGE_IND, handle=%u, status=%u", handle, status);
LL_TRACE_INFO1("### LlEvent ### LL_REQ_PEER_SCA_CNF, handle=%u, status=LL_SUCCESS", handle);
LmgrSendEvent((LlEvt_t *)&evt);
}
@ -1382,3 +1635,54 @@ void lctrUnpauseRxData(lctrConnCtx_t *pCtx)
pCtx->pauseRxData = FALSE;
LL_TRACE_INFO1(" >>> Data Path Rx Unpaused/Resumed, handle=%u <<<", LCTR_GET_CONN_HANDLE(pCtx));
}
/*************************************************************************************************/
/*!
* \brief Store periodic advertising sync transfer parameters.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrActStorePeriodicSyncTrsf(lctrConnCtx_t *pCtx)
{
if (lctrStorePeriodicSyncTrsfFn)
{
lctrStorePeriodicSyncTrsfFn(pCtx);
}
}
/*************************************************************************************************/
/*!
* \brief Send periodic sync indication PDU to peer.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrActSendPeriodicSyncInd(lctrConnCtx_t *pCtx)
{
if (lctrSendPeriodicSyncIndFn)
{
lctrSendPeriodicSyncIndFn(pCtx);
}
}
/*************************************************************************************************/
/*!
* \brief Handle received periodic sync indication PDU.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrActReceivePeriodicSyncInd(lctrConnCtx_t *pCtx)
{
if (lctrReceivePeriodicSyncIndFn)
{
lctrReceivePeriodicSyncIndFn(pCtx);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master connection state machine action routines.
* \file
* \brief Link layer controller master connection state machine action routines.
*/
/*************************************************************************************************/
@ -61,8 +62,10 @@ void lctrSendConnUpdateInd(lctrConnCtx_t *pCtx)
uint32_t durUsec = pCtx->localConnDurUsec;
uint32_t connIntervalUsec;
/* TODO: accommodate pCtx->connParam.prefPeriod. */
if (!SchRmStartUpdate(LCTR_GET_CONN_HANDLE(pCtx), interMinUsec, interMaxUsec, durUsec, &connIntervalUsec))
/* Accommodate peer PreferredPeriodicity. */
uint32_t commonPrefPerUsec = SchRmCalcCommonPeriodicityUsec(LCTR_CONN_IND_US(pCtx->connParam.prefPeriod));
if (!SchRmStartUpdate(LCTR_GET_CONN_HANDLE(pCtx), interMinUsec, interMaxUsec, commonPrefPerUsec, durUsec, &connIntervalUsec))
{
LL_TRACE_WARN1("Could not update connection, handle=%u", LCTR_GET_CONN_HANDLE(pCtx));
lctrSendConnMsg(pCtx, LCTR_CONN_LLCP_REJECT_CONN_UPD);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master connection state machine action routines.
* \file
* \brief Link layer controller master connection state machine action routines.
*/
/*************************************************************************************************/
@ -52,10 +53,10 @@ static uint8_t lctrExtInitSetupConn(lctrExtScanCtx_t *pExtInitCtx, LlConnSpec_t
uint32_t interMaxUsec = LCTR_CONN_IND_US(pConnSpec->connIntervalMax);
uint32_t durUsec = pCtx->localConnDurUsec;
if (!SchRmAdd(LCTR_GET_CONN_HANDLE(pCtx), interMinUsec, interMaxUsec, durUsec, &connInterUsec))
if (!SchRmAdd(LCTR_GET_CONN_HANDLE(pCtx), SCH_RM_PREF_PERFORMANCE, interMinUsec, interMaxUsec, durUsec, &connInterUsec, lctrGetConnRefTime))
{
lctrFreeConnCtx(pCtx);
return LL_ERROR_CODE_UNACCEPTABLE_CONN_INTERVAL;
return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES;
}
pExtInitCtx->data.init.connHandle = LCTR_GET_CONN_HANDLE(pCtx);

View File

@ -0,0 +1,386 @@
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*************************************************************************************************/
/*!
* \file
* \brief Link layer controller connection state machine action routines for PAST feature.
*/
/*************************************************************************************************/
#include "lctr_int_conn.h"
#include "lctr_int_adv_slave.h"
#include "lctr_int_adv_master_ae.h"
#include "sch_api.h"
#include "sch_api_ble.h"
#include "lmgr_api_conn.h"
#include "wsf_assert.h"
#include "wsf_math.h"
#include "wsf_msg.h"
#include "wsf_timer.h"
#include "wsf_trace.h"
#include "util/bstream.h"
#include <string.h>
/*************************************************************************************************/
/*!
* \brief Send periodic sync indication from scanner to peer.
*
* \param pCtx Connection context.
*
* \return None.
*
* This function is called from BOD end callback of master/slave connection.
*/
/*************************************************************************************************/
void lctrSendPerSyncFromScan(lctrConnCtx_t *pCtx)
{
uint8_t *pPdu;
lctrPerScanCtx_t *pPerScanCtx = LCTR_GET_PER_SCAN_CTX(pCtx->perSyncHandle);
WSF_ASSERT((pPerScanCtx->enabled == TRUE) && (pPerScanCtx->state == LCTR_PER_SCAN_STATE_SYNC_ESTD));
if ((pPdu = lctrTxCtrlPduAlloc(LL_PERIODIC_SYNC_PDU_LEN)) != NULL)
{
uint8_t *pBuf = pPdu;
uint8_t field8 = 0;
/* Use the same logic as connection update to set connEventCounter. */
uint16_t ceOffset = LL_MIN_INSTANT + 1 + /* +1 for next CE */
pCtx->maxLatency; /* ensure slave will listen this packet */
#if (LL_ENABLE_TESTER == TRUE)
if (llTesterCb.eventCounterOverride == TRUE)
{
/* ceOffset can be in the range of -0x3FFF ~ +0x3FFF. */
ceOffset = llTesterCb.eventCounterOffset + 1; /* +1 for next CE */
}
#endif
/* Find PEa, event counter of PE whose starting time is after CEref. */
uint16_t paEventCounter = pPerScanCtx->lastActiveEvent;
uint32_t paAnchor = pPerScanCtx->lastAnchorPoint;
uint32_t ceRefStart, ceRefEnd;
/* Calculate the end time of CEref. */
ceRefStart = lctrConnGetAnchorPoint(pCtx, (pCtx->eventCounter + ceOffset));
ceRefEnd = ceRefStart + BB_US_TO_BB_TICKS(pCtx->localConnDurUsec + BbGetSchSetupDelayUs());
/* paAnchor is for the first PE in the future from ceRefEnd. */
if ((ceRefEnd - paAnchor) < LCTR_SCH_MAX_SPAN)
{
uint16_t numPE = (ceRefEnd - paAnchor) / pPerScanCtx->perInter + 1;
paAnchor += numPE * pPerScanCtx->perInter;
paEventCounter += numPE;
}
else
{
uint16_t numPE = (paAnchor - ceRefEnd) / pPerScanCtx->perInter;
paAnchor -= numPE * pPerScanCtx->perInter;
paEventCounter -= numPE;
}
uint8_t offsUnits;
uint8_t offsAdjust = 0;
uint16_t offs;
uint32_t offsUsec = BB_TICKS_TO_US(paAnchor - ceRefStart);
if (offsUsec < LL_30_USEC_OFFS_MAX_USEC)
{
offsUnits = LCTR_OFFS_UNITS_30_USEC;
offs = LL_MATH_DIV_30(offsUsec);
}
else
{
if (offsUsec >= LL_SYNC_OFFS_ADJUST_USEC)
{
offsAdjust = 1;
offsUsec -= LL_SYNC_OFFS_ADJUST_USEC;
}
offsUnits = LCTR_OFFS_UNITS_300_USEC;
offs = LL_MATH_DIV_300(offsUsec);
}
LL_TRACE_INFO1("LL_PERIODIC_SYNC_IND from SCAN ceRef anchor point = %u", ceRefStart);
LL_TRACE_INFO1(" PA lastAnchorPoint = %u", pPerScanCtx->lastAnchorPoint);
LL_TRACE_INFO1(" PA REF paAnchor = %u", paAnchor);
LL_TRACE_INFO1(" offsUsec = %u", offsUsec);
/*** Assemble control PDU. ***/
UINT8_TO_BSTREAM (pBuf, LL_PDU_PERIODIC_SYNC_IND);
UINT16_TO_BSTREAM(pBuf, pCtx->perServiceData); /* ID */
/* Fill in syncInfo (18 octets) */
UINT16_TO_BSTREAM(pBuf, offs |
(offsUnits << 13) | /* Offset units. */
(offsAdjust << 14)); /* Offset adjust. */
UINT16_TO_BSTREAM(pBuf, LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pPerScanCtx->perInter))); /* Interval */
uint64_t temp = pPerScanCtx->chanParam.chanMask | /* SyncInfo - ChMap */
((uint64_t)pPerScanCtx->sca << 37); /* SyncInfo - SCA of the device sending AUX_SYNC_IND. */
UINT40_TO_BSTREAM(pBuf, temp);
UINT32_TO_BSTREAM(pBuf, pPerScanCtx->bleData.chan.accAddr);
UINT24_TO_BSTREAM(pBuf, pPerScanCtx->bleData.chan.crcInit);
UINT16_TO_BSTREAM(pBuf, paEventCounter); /* SyncInfo - Event Counter */
UINT16_TO_BSTREAM(pBuf, (pCtx->eventCounter + ceOffset)); /* ref connEventCounter */
UINT16_TO_BSTREAM(pBuf, pPerScanCtx->lastActiveEvent); /* lastPaEventCounter */
field8 = (pPerScanCtx->advSID << 0) |
(pPerScanCtx->trsfAddrType << 4) |
(lctrComputeSca() << 5); /* SCA of the device sending this PDU. */
UINT8_TO_BSTREAM(pBuf, field8);
UINT8_TO_BSTREAM(pBuf, lctrPhyToPhysBit(pPerScanCtx->rxPhys));
BDA64_TO_BSTREAM(pBuf, pPerScanCtx->trsfAdvAddr);
UINT16_TO_BSTREAM(pBuf, pCtx->eventCounter); /* syncConnEventCounter */
/*** Queue for transmit. ***/
lctrTxCtrlPduQueue(pCtx, pPdu);
}
}
/*************************************************************************************************/
/*!
* \brief Send periodic sync indication from broadcaster to peer.
*
* \param pCtx Connection context.
*
* \return None.
*
* This function is called from BOD end callback of master/slave connection.
*/
/*************************************************************************************************/
void lctrSendPerSyncFromBcst(lctrConnCtx_t *pCtx)
{
uint8_t *pPdu;
lctrAdvSet_t *pAdvSet = lctrFindAdvSet((uint8_t)pCtx->perSyncHandle);
WSF_ASSERT(pAdvSet);
WSF_ASSERT(pAdvSet->perParam.perAdvEnabled == TRUE);
if ((pPdu = lctrTxCtrlPduAlloc(LL_PERIODIC_SYNC_PDU_LEN)) != NULL)
{
BbOpDesc_t * const pPerOp = &pAdvSet->perParam.perAdvBod;
BbBleData_t *pBle = &pAdvSet->perParam.perBleData;
uint8_t *pBuf = pPdu;
uint8_t field8 = 0;
/* Use the same logic as connection update to set connEventCounter. */
uint16_t ceOffset = LL_MIN_INSTANT + 1 + /* +1 for next CE */
pCtx->maxLatency; /* ensure slave will listen this packet */
#if (LL_ENABLE_TESTER == TRUE)
if (llTesterCb.eventCounterOverride == TRUE)
{
/* ceOffset can be in the range of -0x3FFF ~ +0x3FFF. */
ceOffset = llTesterCb.eventCounterOffset + 1; /* +1 for next CE */
}
#endif
/* Find PEa, event counter of PE whose starting time is after CEref. */
uint16_t paEventCounter = pAdvSet->perParam.perEventCounter;
uint32_t paAnchor = pPerOp->due;
uint32_t ceRefStart, ceRefEnd;
/* Calculate the end time of CEref. */
ceRefStart = lctrConnGetAnchorPoint(pCtx, (pCtx->eventCounter + ceOffset));
ceRefEnd = ceRefStart + BB_US_TO_BB_TICKS(pCtx->localConnDurUsec + BbGetSchSetupDelayUs());
/* paAnchor is for the first PE in the future from ceRefEnd. */
if ((ceRefEnd - paAnchor) < LCTR_SCH_MAX_SPAN)
{
uint16_t numPE = (ceRefEnd - paAnchor) / pAdvSet->perParam.perAdvInter + 1;
paAnchor += numPE * pAdvSet->perParam.perAdvInter;
paEventCounter += numPE;
}
else
{
uint16_t numPE = (paAnchor - ceRefEnd) / pAdvSet->perParam.perAdvInter;
paAnchor -= numPE * pAdvSet->perParam.perAdvInter;
paEventCounter -= numPE;
}
uint8_t offsUnits;
uint8_t offsAdjust = 0;
uint16_t offs;
uint32_t offsUsec = BB_TICKS_TO_US(paAnchor - ceRefStart);
if (offsUsec < LL_30_USEC_OFFS_MAX_USEC)
{
offsUnits = LCTR_OFFS_UNITS_30_USEC;
offs = LL_MATH_DIV_30(offsUsec);
}
else
{
if (offsUsec >= LL_SYNC_OFFS_ADJUST_USEC)
{
offsAdjust = 1;
offsUsec -= LL_SYNC_OFFS_ADJUST_USEC;
}
offsUnits = LCTR_OFFS_UNITS_300_USEC;
offs = LL_MATH_DIV_300(offsUsec);
}
LL_TRACE_INFO1("LL_PERIODIC_SYNC_IND from BCST ceRef anchor point = %u", ceRefStart);
LL_TRACE_INFO1(" PA lastAnchorPoint = %u", pPerOp->due);
LL_TRACE_INFO1(" PA REF paAnchor = %u", paAnchor);
LL_TRACE_INFO1(" offsUsec = %u", offsUsec);
/*** Assemble control PDU. ***/
UINT8_TO_BSTREAM (pBuf, LL_PDU_PERIODIC_SYNC_IND);
UINT16_TO_BSTREAM(pBuf, pCtx->perServiceData); /* ID */
/* Fill in syncInfo (18 octets) */
UINT16_TO_BSTREAM(pBuf, offs |
(offsUnits << 13) | /* Offset units. */
(offsAdjust << 14)); /* Offset adjust. */
UINT16_TO_BSTREAM(pBuf, LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pAdvSet->perParam.perAdvInter))); /* Interval */
uint64_t temp = pAdvSet->perParam.perChanParam.chanMask | /* SyncInfo - ChMap */
((uint64_t)lctrComputeSca() << 37); /* SyncInfo - SCA of the device sending AUX_SYNC_IND. */
UINT40_TO_BSTREAM(pBuf, temp);
UINT32_TO_BSTREAM(pBuf, pBle->chan.accAddr);
UINT24_TO_BSTREAM(pBuf, pBle->chan.crcInit);
UINT16_TO_BSTREAM(pBuf, paEventCounter); /* SyncInfo - Event Counter */
UINT16_TO_BSTREAM(pBuf, (pCtx->eventCounter + ceOffset));
/* If the Periodic Advertiser is sending the PDU, */
/* lastPaEventCount shall be set to the same value as the EventCounter field of SyncInfo. */
UINT16_TO_BSTREAM(pBuf, pAdvSet->perParam.perEventCounter); /* lastPaEventCounter */
uint8_t aType = 0; /* 0 for public address, 1 for random address */
if ((pAdvSet->param.ownAddrType & LL_ADDR_RANDOM_BIT) && (pAdvSet->bdAddrRndValid == TRUE))
{
aType = 1;
}
else if ((pAdvSet->param.ownAddrType == LL_ADDR_PUBLIC_IDENTITY) && (BDA64_ADDR_IS_RPA(pAdvSet->advA)))
{
aType = 1;
}
field8 = (pAdvSet->param.advSID << 0) |
(aType << 4) |
(lctrComputeSca() << 5); /* SCA of the device sending this PDU. */
UINT8_TO_BSTREAM(pBuf, field8);
UINT8_TO_BSTREAM(pBuf, lctrPhyToPhysBit(pBle->chan.txPhy));
BDA64_TO_BSTREAM(pBuf, pAdvSet->advA);
UINT16_TO_BSTREAM(pBuf, pCtx->eventCounter); /* syncConnEventCounter */
/*** Queue for transmit. ***/
lctrTxCtrlPduQueue(pCtx, pPdu);
}
}
/*************************************************************************************************/
/*!
* \brief Store periodic advertising sync transfer parameters.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrStorePeriodicSyncTrsf(lctrConnCtx_t *pCtx)
{
pCtx->perSyncSrc = pLctrConnMsg->perAdvSyncTrsf.syncSource;
pCtx->perServiceData = pLctrConnMsg->perAdvSyncTrsf.serviceData;
pCtx->perSyncHandle = pLctrConnMsg->perAdvSyncTrsf.syncHandle;
}
/*************************************************************************************************/
/*!
* \brief Send periodic sync indication PDU to peer.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSendPeriodicSyncInd(lctrConnCtx_t *pCtx)
{
if (!pCtx->sendPerSync)
{
/* The PDU will be queued at the next BOD end callback. */
pCtx->sendPerSync = TRUE;
/* The procedure completes after sending out the indication. */
pCtx->llcpNotifyMask &= ~(1 << LCTR_PROC_CMN_PER_ADV_SYNC_TRSF);
lctrSendConnMsg(pCtx, LCTR_CONN_LLCP_PROC_CMPL);
}
}
/*************************************************************************************************/
/*!
* \brief Handle received periodic sync indication PDU.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
void lctrReceivePeriodicSyncInd(lctrConnCtx_t *pCtx)
{
lctrPerTransferSyncMsg_t *pMsg;
/* Check if the controller is already sync with the same periodic advertiser. */
if (LctrMstPerIsSync(lctrDataPdu.pld.perSyncInd.sid, lctrDataPdu.pld.perSyncInd.aType, lctrDataPdu.pld.perSyncInd.advA))
{
LL_TRACE_WARN0(" ---- Ignore LL_PERIODIC_SYNC_IND, already in sync");
return;
}
LL_TRACE_INFO1("### LlEvent ### Periodic sync transfer received, handle=%u", LCTR_GET_CONN_HANDLE(pCtx));
LL_TRACE_INFO1(" ceRef=%u", lctrDataPdu.pld.perSyncInd.ceCounter);
LL_TRACE_INFO1(" ceRcvd=%u", pCtx->eventCounter);
LL_TRACE_INFO1(" lastPECounter=%u", lctrDataPdu.pld.perSyncInd.lastPECounter);
LL_TRACE_INFO1(" ID=%u", lctrDataPdu.pld.perSyncInd.id);
if (pCtx->syncMode != LL_SYNC_TRSF_MODE_OFF)
{
if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL)
{
pMsg->hdr.dispId = LCTR_DISP_TRANFER_SYNC;
pMsg->hdr.event = LCTR_TRANSFER_SYNC_MSG_START;
pMsg->id = lctrDataPdu.pld.perSyncInd.id;
memcpy(pMsg->bSyncInfo, lctrDataPdu.pld.perSyncInd.syncInfo, LL_SYNC_INFO_LEN);
pMsg->connHandle = LCTR_GET_CONN_HANDLE(pCtx);
pMsg->ceRef = lctrDataPdu.pld.perSyncInd.ceCounter;
pMsg->ceRcvd = pCtx->eventCounter;
pMsg->lastPECounter = lctrDataPdu.pld.perSyncInd.lastPECounter;
pMsg->advSID = lctrDataPdu.pld.perSyncInd.sid;
pMsg->advAddrType = lctrDataPdu.pld.perSyncInd.aType;
pMsg->scaB = lctrDataPdu.pld.perSyncInd.sca;
pMsg->rxPhy = lctrPhysBitToPhy(lctrDataPdu.pld.perSyncInd.phy);
pMsg->advAddr = lctrDataPdu.pld.perSyncInd.advA;
pMsg->syncConnEvtCounter = lctrDataPdu.pld.perSyncInd.syncConnEvtCounter;
WsfMsgSend(lmgrPersistCb.handlerId, pMsg);
}
}
else
{
LL_TRACE_INFO1(" ---- Ignore LL_PERIODIC_SYNC_IND, syncMode = %u", pCtx->syncMode);
}
/* The procedure completes without further action. */
lctrSendConnMsg(pCtx, LCTR_CONN_LLCP_PROC_CMPL);
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller slave encryption action routines.
* \file
* \brief Link layer controller slave encryption action routines.
*/
/*************************************************************************************************/
@ -26,6 +27,7 @@
#include "wsf_msg.h"
#include "wsf_trace.h"
#include "util/bstream.h"
#include "pal_crypto.h"
#include <string.h>
/*************************************************************************************************/
@ -144,10 +146,10 @@ void lctrGenerateSlvVectors(lctrConnCtx_t *pCtx)
memcpy(pCtx->iv, lctrDataPdu.pld.encReq.iv_m + LCTR_IV_M_OFFS, LL_IV_LEN / 2);
/* Generate slave part of IV. */
BbBleDrvRand(pCtx->iv + LCTR_IV_S_OFFS, LL_IV_LEN / 2);
PalCryptoGenerateRandomNumber(pCtx->iv + LCTR_IV_S_OFFS, LL_IV_LEN / 2);
/* Generate slave part of SKD. */
BbBleDrvRand(pCtx->skd + LCTR_SKD_S_OFFS, LL_SKD_LEN / 2);
PalCryptoGenerateRandomNumber(pCtx->skd + LCTR_SKD_S_OFFS, LL_SKD_LEN / 2);
}
/*************************************************************************************************/
@ -189,14 +191,15 @@ void lctrStoreLtkNegRepTerminateReason(lctrConnCtx_t *pCtx)
/*************************************************************************************************/
void lctrCalcSessionKey(lctrConnCtx_t *pCtx)
{
BbBleEnc_t * const pEnc = &pCtx->bleData.chan.enc;
PalCryptoEnc_t * const pEnc = &pCtx->bleData.chan.enc;
/* Use AES to transform LTK to session key using session key diversifier as seed. */
LlMathAesEcb(pCtx->ltk, pEnc->sk, pCtx->skd);
PalCryptoAesEcb(pCtx->ltk, pEnc->sk, pCtx->skd);
WSF_ASSERT(lctrInitCipherBlkHdlr);
memcpy(pEnc->iv, pCtx->iv, sizeof(pEnc->iv));
uint8_t dir = (pCtx->role == LL_ROLE_MASTER) ? 1 : 0; /* master = 1; slave = 0 */
pEnc->type = PAL_BB_TYPE_ACL;
lctrInitCipherBlkHdlr(pEnc, LCTR_GET_CONN_HANDLE(pCtx), dir);
}
@ -455,7 +458,7 @@ void lctrEncNotifyHostLtkReqInd(lctrConnCtx_t *pCtx)
void lctrNotifyEncChangeInd(lctrConnCtx_t *pCtx, uint8_t status)
{
const uint16_t handle = LCTR_GET_CONN_HANDLE(pCtx);
BbBleEnc_t * const pEnc = &pCtx->bleData.chan.enc;
PalCryptoEnc_t * const pEnc = &pCtx->bleData.chan.enc;
LlEncChangeInd_t evt =
{

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master encryption action routines.
* \file
* \brief Link layer controller master encryption action routines.
*/
/*************************************************************************************************/
@ -46,10 +47,10 @@ void lctrGenerateMstVectors(lctrConnCtx_t *pCtx)
pCtx->ediv = pLctrConnMsg->startEnc.diversifier;
/* Generate master part of IV. */
BbBleDrvRand(pCtx->iv + LCTR_IV_M_OFFS, LL_IV_LEN / 2);
PalCryptoGenerateRandomNumber(pCtx->iv + LCTR_IV_M_OFFS, LL_IV_LEN / 2);
/* Generate master part of SKD. */
BbBleDrvRand(pCtx->skd + LCTR_SKD_M_OFFS, LL_SKD_LEN / 2);
PalCryptoGenerateRandomNumber(pCtx->skd + LCTR_SKD_M_OFFS, LL_SKD_LEN / 2);
}
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master connection state machine action routines.
* \file
* \brief Link layer controller master connection state machine action routines.
*/
/*************************************************************************************************/
@ -55,11 +56,11 @@ void lctrInitActInitiate(void)
uint32_t interMaxUsec = LCTR_CONN_IND_US(pInitMsg->connSpec.connIntervalMax);
uint32_t durUsec = pCtx->localConnDurUsec;
if (!SchRmAdd(LCTR_GET_CONN_HANDLE(pCtx), interMinUsec, interMaxUsec, durUsec, &connInterUsec))
if (!SchRmAdd(LCTR_GET_CONN_HANDLE(pCtx), SCH_RM_PREF_PERFORMANCE, interMinUsec, interMaxUsec, durUsec, &connInterUsec, lctrGetConnRefTime))
{
lctrFreeConnCtx(pCtx);
result = FALSE;
lctrScanNotifyHostInitiateError(LL_ERROR_CODE_UNACCEPTABLE_CONN_INTERVAL, pInitMsg->peerAddrType, pInitMsg->peerAddr);
lctrScanNotifyHostInitiateError(LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES, pInitMsg->peerAddrType, pInitMsg->peerAddr);
break;
}
} while (FALSE);
@ -176,8 +177,6 @@ void lctrInitActShutdown(void)
{
if (lmgrCb.numInitEnabled)
{
SchRmRemove(lctrMstInit.data.init.connHandle);
lctrFreeConnCtx(LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle));
lctrMstInit.shutdown = TRUE;
SchRemove(&lctrMstInit.scanBod);
@ -202,6 +201,9 @@ void lctrInitActScanTerm(void)
lctrScanCleanup(&lctrMstInit);
SchRmRemove(lctrMstInit.data.init.connHandle);
lctrFreeConnCtx(LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle));
LlCreateConnCancelCnf_t evt =
{
.hdr =

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master connection state machine action routines.
* \file
* \brief Link layer controller master connection state machine action routines.
*/
/*************************************************************************************************/
#include "lctr_int_init_master_ae.h"
@ -61,6 +62,24 @@ void lctrExtInitActShutdown(lctrExtScanCtx_t *pExtInitCtx)
/*************************************************************************************************/
void lctrExtInitActScanTerm(lctrExtScanCtx_t *pExtInitCtx)
{
for (unsigned i = 0; i < LCTR_SCAN_PHY_TOTAL; i++)
{
if (lctrMstExtInit.enaPhys & (1 << i))
{
if ((lctrMstExtInit.estConnPhys & (1 << i)) == 0)
{
lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(lctrMstExtInitTbl[i].data.init.connHandle);
if (pCtx->enabled == TRUE)
{
/* Cleanup unused initiate PHY connection context. */
SchRmRemove(lctrMstExtInitTbl[i].data.init.connHandle);
lctrFreeConnCtx(pCtx);
}
}
}
}
lctrMstExtInitCleanupOp(pExtInitCtx);
if (pExtInitCtx->state != LCTR_EXT_INIT_STATE_RESET)

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller PHY features action routines.
* \file
* \brief Link layer controller PHY features action routines.
*/
/*************************************************************************************************/
@ -191,7 +192,7 @@ void lctrSendPhyUpdateIndPdu(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhys
uint16_t ceOffset;
#if (LL_ENABLE_TESTER == TRUE)
if (llTesterCb.eventCounterOffset)
if (llTesterCb.eventCounterOverride == TRUE)
{
ceOffset = llTesterCb.eventCounterOffset + 1; /* +1 for next CE */
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller interface file.
* \file
* \brief Internal link layer controller interface file.
*/
/*************************************************************************************************/
@ -27,6 +28,7 @@
#include "ll_defs.h"
#include "lmgr_api.h"
#include "ll_math.h"
#include "util/crc32.h"
#if (LL_ENABLE_TESTER)
#include "ll_tester_api.h"
@ -68,7 +70,7 @@ extern "C" {
/*! \brief Convert BLE protocol ticks to microseconds. */
#define LCTR_BLE_TO_US(x) ((x) * LL_BLE_US_PER_TICK)
/*! \brief Convert periodic interval milliseconds to microseconds. */
/*! \brief Convert periodic interval units to microseconds. */
#define LCTR_PER_INTER_TO_US(x) ((x) * 1250)
/*! \brief Convert periodic interval microseconds to milliseconds. */
@ -77,6 +79,9 @@ extern "C" {
/*! \brief Convert periodic sync timeout unit to milliseconds. */
#define LCTR_PER_SYNC_TIMEOUT_TO_MS(x) ((x) * 10)
/*! \brief Convert isochronous interval to microseconds. */
#define LCTR_ISO_INT_TO_US(x) ((x) * 1250)
/*! \brief Fast termination supervision multiplier. */
#define LCTR_FAST_TERM_CNT 6
@ -102,25 +107,15 @@ extern "C" {
#define LCTR_ADVB_BUF_OFFSET_CRC ((LCTR_ADVB_BUF_SIZE - LCTR_ADVB_BUF_EXTRA_SIZE) + 2)
/*! \brief LCTR Maximum span of scheduler elements. */
#define LCTR_SCH_MAX_SPAN 0x80000000
#define LCTR_SCH_MAX_SPAN 0x80000000
/*! \brief LCTR Maximum value for sleep clock accuracy. */
#define LCTR_MAX_SCA 7
/**************************************************************************************************
Data Types
**************************************************************************************************/
/*! \brief Channel parameters. */
typedef struct
{
/* Channel parameters */
uint8_t lastChanIdx; /*!< Current channel index. */
uint8_t numUsedChan; /*!< Number of used channels. */
uint64_t chanMask; /*!< Channel mask. */
uint8_t chanRemapTbl[LL_CHAN_DATA_MAX_IDX + 1]; /*!< Channel remapping table. */
uint8_t usedChSel; /*!< Used channel selection. */
uint16_t chIdentifier; /*!< Channel identifier. */
} lctrChanParam_t;
/*! \brief Call signature of a reset handler. */
typedef void (*LctrResetHdlr_t)(void);
@ -141,8 +136,7 @@ extern LctrResetHdlr_t lctrResetHdlrTbl[LCTR_DISP_TOTAL];
extern LctrMsgDisp_t lctrMsgDispTbl[LCTR_DISP_TOTAL];
extern LctrEvtHdlr_t lctrEventHdlrTbl[LCTR_EVENT_TOTAL];
extern lctrMsgHdr_t *pLctrMsg;
extern LctrRmCback_t lctrGetConnOffsetsCback;
extern LctrRmCback_t lctrGetPerOffsetsCback;
extern const uint16_t scaPpmTbl[];
/**************************************************************************************************
Functions
@ -151,10 +145,11 @@ extern LctrRmCback_t lctrGetPerOffsetsCback;
/* Helper routines. */
uint32_t lctrComputeAccessAddr(void);
uint8_t lctrComputeHopInc(void);
uint8_t lctrPeriodicSelectNextChannel(lctrChanParam_t *pChanParam, uint16_t eventCounter);
void lctrPeriodicBuildRemapTable(lctrChanParam_t *pChanParam);
uint8_t lctrPeriodicSelectNextChannel(lmgrChanParam_t *pChanParam, uint16_t eventCounter);
void lctrPeriodicBuildRemapTable(lmgrChanParam_t *pChanParam);
uint16_t lctrCalcTotalAccuracy(uint8_t mstScaIdx);
uint32_t lctrComputeCrcInit(void);
uint32_t lctrCalcWindowWideningUsec(uint32_t unsyncTimeUsec, uint32_t caPpm);
/* Host events */
void lctrNotifyHostHwErrInd(uint8_t code);
@ -169,18 +164,17 @@ void lctrSlvAdvExecuteSm(uint8_t event);
/*************************************************************************************************/
/*!
* \brief Get operational mode flag.
* \brief Calculate DID.
*
* \param flag Flag to check.
* \param pBuf Data buffer.
* \param len Length of data buffer.
*
* \return TRUE if flag is set.
*
* Get mode flag governing LL operations.
* \return DID value.
*/
/*************************************************************************************************/
static inline bool_t lctrGetOpFlag(uint32_t flag)
static inline uint16_t lctrCalcDID(const uint8_t *pBuf, uint16_t len)
{
return (lmgrCb.opModeFlags & flag) ? TRUE : FALSE;
return CalcCrc32(LlMathRandNum(), len, pBuf);
}
#ifdef __cplusplus

View File

@ -0,0 +1,94 @@
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*************************************************************************************************/
/*!
* \file
* \brief Extended advertising common header file */
/*************************************************************************************************/
#ifndef LCTR_INT_ADV_AE_H
#define LCTR_INT_ADV_AE_H
#include "ll_defs.h"
#include "lctr_api.h"
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/*! \brief Acad parameter indicies */
enum
{
LCTR_ACAD_ID_CHAN_MAP_UPDATE,
/* Total number of Acad IDs. */
LCTR_ACAD_NUM_ID,
/* Invalid ID type. */
LCTR_ACAD_INVALID_ID = 0xFF
};
/*! \brief Acad states */
enum
{
LCTR_ACAD_STATE_DISABLED = 0,
LCTR_ACAD_STATE_ENABLED,
LCTR_ACAD_STATE_TOTAL
};
/*! \brief Acad Common events */
enum
{
LCTR_ACAD_COMM_MSG_START,
LCTR_ACAD_COMM_MSG_FINISH,
LCTR_ACAD_COMM_MSG_TOTAL,
LCTR_ACAD_COMM_MSG_INVALID = 0xFF
};
/*! \brief Acad header */
typedef struct
{
uint8_t state; /* State of Acad. */
uint8_t opcode; /* Opcode of Acad. */
uint8_t len; /* Length of Acad data field. */
} lctrAcadHdr_t;
/*! \brief Acad data field for channel map update */
typedef struct
{
lctrAcadHdr_t hdr; /* Acad header. */
uint64_t chanMask; /* Channel mask for the update. */
uint16_t instant; /* Instant for the update. */
} lctrAcadChanMapUpd_t;
/*! \brief Generic Acad packet. */
typedef union
{
lctrAcadHdr_t hdr; /* Acad header. */
lctrAcadChanMapUpd_t chanMapUpdate; /* Channel map update. */
} lctrAcadParam_t;
#ifdef __cplusplus
};
#endif
#endif /* LCTR_INT_ADV_AE_H */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller scanning master interface file.
* \file
* \brief Internal link layer controller scanning master interface file.
*/
/*************************************************************************************************/
@ -37,8 +38,8 @@ extern "C" {
Macros
**************************************************************************************************/
/*! \brief Minimum amount of time required for scanning, (minimum scanWindow size is 2.5ms). */
#define LCTR_MIN_SCAN_USEC 0
/*! \brief Minimum amount of time required for scanning, to be same as minimum time in BB(1528us). */
#define LCTR_MIN_SCAN_USEC BB_SCAN_GUARD_US
/**************************************************************************************************
Constants

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,18 +16,21 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller extended scanning master interface file.
* \file
* \brief Internal link layer controller extended scanning master interface file.
*/
/*************************************************************************************************/
#ifndef LCTR_INT_ADV_MASTER_AE_H
#define LCTR_INT_ADV_MASTER_AE_H
#include "lctr_int_adv_ae.h"
#include "lctr_int.h"
#include "lctr_api_adv_master_ae.h"
#include "lctr_int_adv_master.h"
#include "lctr_pdu_adv_ae.h"
#include "bb_ble_api.h"
#include "ll_defs.h"
#include "wsf_timer.h"
#ifdef __cplusplus
@ -71,6 +74,16 @@ enum
LCTR_CREATE_SYNC_STATE_TOTAL /*!< Total number of Create sync states. */
};
/*! \brief Transfer sync states. */
enum
{
LCTR_TRANSFER_SYNC_STATE_DISABLED = LCTR_CREATE_SYNC_STATE_DISABLED, /*!< Transfer sync disabled state. */
LCTR_TRANSFER_SYNC_STATE_DISCOVER = LCTR_CREATE_SYNC_STATE_DISCOVER, /*!< Transfer sync enabled state. */
LCTR_TRANSFER_SYNC_STATE_SHUTDOWN = LCTR_CREATE_SYNC_STATE_SHUTDOWN, /*!< Transfer sync shutdown in process state. */
LCTR_TRANSFER_SYNC_STATE_RESET = LCTR_CREATE_SYNC_STATE_RESET, /*!< Transfer sync reset in progress. */
LCTR_TRANSFER_SYNC_STATE_TOTAL = LCTR_CREATE_SYNC_STATE_TOTAL /*!< Total number of Transfer sync states. */
};
/*! \brief Periodic scanning states. */
enum
{
@ -117,7 +130,9 @@ typedef struct
{
/* Report handling. */
LlExtAdvReportInd_t advRpt; /*!< Advertising report. */
lctrRptState_t advRptState:8; /*!< Advertising report state. */
lctrRptState_t advRptState; /*!< Advertising report state. */
LlExtAdvReportInd_t auxAdvRpt; /*!< Auxiliary Advertising report (only used with scannable advertising). */
lctrRptState_t auxAdvRptState; /*!< Auxiliary Advertising report state. */
/* Backoff. */
uint16_t upperLimit; /*!< Scan backoff upper limit. */
@ -188,16 +203,6 @@ typedef struct
wsfTimer_t tmrScanPer; /*!< Scan period timer. */
} lctrExtScanCtrlBlk_t;
/*! \brief Periodic advertising create sync parameters. */
typedef struct
{
uint8_t filterPolicy; /*!< Filter Policy. */
uint8_t advSID; /*!< Advertising SID. */
uint8_t advAddrType; /*!< Advertiser Address Type. */
uint64_t advAddr; /*!< Advertiser Address. */
} lctrPerParam_t;
/*! \brief Periodic scanning context. */
typedef struct
{
@ -205,7 +210,11 @@ typedef struct
uint8_t state; /*!< Current state. */
bool_t shutdown; /*!< Client initiated shutdown flag. */
bool_t cancelCreateSync; /*!< Shut down due to create sync cancel. */
bool_t cancelByHost; /*!< Cancel command was issued from host. */
bool_t firstPerAdvRcv; /*!< True if first periodic advertising packet is received. */
bool_t repDisabled; /*!< Reporting disabled. */
bool_t bodAborted; /*!< Tue if periodic scan BOD was aborted. */
uint8_t createDispId; /*!< Dispatcher id to tell if periodic sync was created or transferred. */
/* Report handling. */
LlPerAdvReportInd_t advRpt; /*!< Periodic advertising report. */
@ -225,6 +234,11 @@ typedef struct
uint32_t rxSyncDelayUsec; /*!< Receive timeout in microseconds. */
uint32_t lastAnchorPoint; /*!< Last anchor point in BB tick. */
uint16_t lastActiveEvent; /*!< Last active event counter. */
uint16_t initEventCounter; /*!< Initial event counter received from sync_info. */
/* Acad control block */
/* Note: for now, the acad type only applies to the periodic context. */
lctrAcadParam_t acadParams[LCTR_ACAD_NUM_ID]; /*!< Acad control block array. */
/* Local periodic scanning parameters */
uint16_t skip; /*!< Skip. */
@ -236,7 +250,7 @@ typedef struct
/* RF parameters */
int8_t rssi; /*!< RSSI. */
lctrChanParam_t chanParam; /*!< Channel parameters. */
lmgrChanParam_t chanParam; /*!< Channel parameters. */
/* Supervision */
wsfTimer_t tmrSupTimeout; /*!< Supervision timer. */
@ -244,7 +258,9 @@ typedef struct
/* Peer device info */
uint8_t advSID; /*!< Advertising SID. */
uint8_t advAddrType; /*!< Advertiser Address Type. */
uint8_t trsfAddrType; /*!< Advertiser Address Type to be used for sync transfer. */
uint64_t advAddr; /*!< Advertiser Address. */
uint64_t trsfAdvAddr; /*!< Advertiser Address to be used for sync transfer. */
/* Packet state. */
lctrExtAdvHdr_t extAdvHdr; /*!< Coalesced extended advertising header. */
@ -263,6 +279,35 @@ typedef struct
lctrPerScanCtx_t *pPerScanCtx; /*!< Current synchronous context. */
} lctrPerCreateSyncCtrlBlk_t;
/*! \brief Acad message header. */
typedef struct
{
uint16_t eventCtr; /*!< Current event counter. */
uint16_t skip; /*!< Skip amount. */
uint8_t acadId; /*!< Acad ID being processed. */
uint16_t handle; /*!< Active Handle. */
} lctrAcadMsgHdr_t;
/*! \brief Acad message generic type. */
typedef union
{
lctrAcadMsgHdr_t hdr; /*!< Header of an Acad Msg. */
} lctrAcadMsg_t;
/*! \brief Periodic sync transfer state context. */
typedef struct
{
uint8_t state; /*!< Periodic sync transfer state. */
uint16_t connHandle; /*!< Connection handle. */
uint16_t serviceData; /*!< Service Data. */
uint16_t ceRef; /*!< Reference connection event counter. */
uint16_t ceRcvd; /*!< Connection event counter when LL_PERIODIC_SYNC_IND was received. */
uint16_t syncCe; /*!< Connection event counter when the contents of the PDU is determined. */
uint8_t scaB; /*!< Sleep clock accuracy of the device sending LL_PERIODIC_SYNC_IND. */
uint16_t lastPECounter; /*!< Last PA event counter. */
lctrPerScanCtx_t *pPerScanCtx; /*!< Current synchronous context. */
} lctrPerTransferSyncCtrlBlk_t;
/**************************************************************************************************
Globals
**************************************************************************************************/
@ -270,7 +315,9 @@ typedef struct
extern lctrExtScanCtx_t lctrMstExtScanTbl[LCTR_SCAN_PHY_TOTAL];
extern lctrExtScanCtrlBlk_t lctrMstExtScan;
extern lctrPerCreateSyncCtrlBlk_t lctrPerCreateSync;
extern lctrPerTransferSyncCtrlBlk_t lctrPerTransferSync;
extern lctrPerScanCtx_t lctrMstPerScanTbl[LL_MAX_PER_SCAN];
extern lctrSyncInfo_t trsfSyncInfo;
/**************************************************************************************************
Function Declarations
@ -280,8 +327,9 @@ extern lctrPerScanCtx_t lctrMstPerScanTbl[LL_MAX_PER_SCAN];
uint8_t lctrMstExtDiscoverBuildOp(lctrExtScanCtx_t *pExtScanCtx);
uint8_t lctrMstAuxDiscoverBuildOp(lctrExtScanCtx_t *pExtScanCtx);
void lctrMstAuxDiscoverOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr, uint32_t startTs, uint32_t endTs);
uint8_t lctrMstPerScanBuildOp(lctrPerScanCtx_t *pPerScanCtx, lctrPerCreateSyncMsg_t *pMsg);
uint8_t lctrMstPerScanBuildOp(lctrPerScanCtx_t *pPerScanCtx);
void lctrMstPerScanOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr, lctrSyncInfo_t *pSyncInfo, uint32_t startTs, uint32_t endTs);
void lctrMstPerScanTransferOpCommit(uint16_t connHandle);
/* ISR: Discovery packet handlers */
bool_t lctrMstDiscoverRxExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf);
@ -297,6 +345,7 @@ bool_t lctrMstDiscoverRxLegacyScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRs
void lctrMstExtDiscoverEndOp(BbOpDesc_t *pOp);
void lctrMstAuxDiscoverEndOp(BbOpDesc_t *pOp);
void lctrMstPerScanEndOp(BbOpDesc_t *pOp);
void lctrMstPerScanAbortOp(BbOpDesc_t *pOp);
uint32_t lctrMstPerScanRxPerAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf, uint8_t status);
bool_t lctrMstPerScanRxPerAdvPktPostHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf);
@ -310,25 +359,37 @@ void lctrExtScanActSelfTerm(lctrExtScanCtx_t *pExtScanCtx);
void lctrExtScanActUpdateDiscover(lctrExtScanCtx_t *pExtScanCtx);
void lctrCreateSyncActCreate(void);
void lctrCreateSyncActCancel(void);
void lctrCreateSyncActFailed(void);
void lctrCreateSyncActTerminate(void);
void lctrCreateSyncActDone(void);
void lctrTransferSyncActStart(void);
void lctrTransferSyncActDone(void);
void lctrTransferSyncActFailed(void);
void lctrTransferSyncActCancel(void);
void lctrTransferSyncActTerminate(void);
void lctrPerScanActSyncEstd(lctrPerScanCtx_t *pPerScanCtx);
void lctrPerScanActSyncTerminate(lctrPerScanCtx_t *pPerScanCtx);
void lctrPerScanActSyncTerminateDone(lctrPerScanCtx_t *pPerScanCtx);
void lctrPerScanActSyncTimeout(lctrPerScanCtx_t *pPerScanCtx);
void lctrPerScanActProcessAcad(lctrAcadMsg_t *pMsg);
/* State machine */
void lctrMstExtScanExecuteSm(lctrExtScanCtx_t *pExtScanCtx, uint8_t event);
void lctrMstCreateSyncExecuteSm(uint8_t event);
void lctrMstTransferSyncExecuteSm(uint8_t event);
void lctrMstPerScanExecuteSm(lctrPerScanCtx_t *pPerScanCtx, uint8_t event);
/* Helpers */
lctrPerScanCtx_t *lctrAllocPerScanCtx(void);
BbOpDesc_t *lctrPerScanResolveConflict(BbOpDesc_t *pNewOp, BbOpDesc_t *pExistOp);
void lctrMstPerScanIsrInit(void);
/* Messaging */
void lctrSendExtScanMsg(lctrExtScanCtx_t *pExtScanCtx, uint8_t event);
void lctrSendCreateSyncMsg(uint8_t event);
void lctrSendCreateSyncMsg(lctrPerScanCtx_t *pCtx, uint8_t event);
void lctrSendPerScanMsg(lctrPerScanCtx_t *pCtx, uint8_t event);
void LctrSendPerSyncTrsfRcvdEvt(uint8_t status, lctrPerScanCtx_t *pPerScanCtx);
/*************************************************************************************************/
/*!
@ -376,35 +437,6 @@ static inline uint8_t lctrConvertAuxPtrPhyToBbPhy(uint8_t auxPtrPhy)
}
}
/*************************************************************************************************/
/*!
* \brief Compute the connection interval window widening delay in microseconds.
*
* \param unsyncTimeUsec Unsynchronized time in microseconds.
* \param caPpm Total clock accuracy.
*
* \return Window widening delay in microseconds.
*/
/*************************************************************************************************/
static inline uint32_t lctrCalcAuxAdvWindowWideningUsec(uint32_t unsyncTimeUsec, uint32_t caPpm)
{
if (lctrGetOpFlag(LL_OP_MODE_FLAG_ENA_WW))
{
/* Largest unsynchronized time is 1,996 seconds (interval=4s and latency=499) and
* largest total accuracy is 1000 ppm. */
/* coverity[overflow_before_widen] */
uint64_t wwDlyUsec = LL_MATH_DIV_10E6(((uint64_t)unsyncTimeUsec * caPpm) +
999999); /* round up */
/* Reduce to 32-bits and always round up to a sleep clock tick. */
return wwDlyUsec + pLctrRtCfg->ceJitterUsec;
}
else
{
return 0;
}
}
/*************************************************************************************************/
/*!
* \brief Compute auxiliary offset.
@ -420,7 +452,7 @@ static inline void lctrMstComputeAuxOffset(lctrAuxPtr_t *pAuxPtr, uint32_t *pOff
{
uint32_t offsetUsec = pAuxPtr->auxOffset * ((pAuxPtr->offsetUnits == LCTR_OFFS_UNITS_30_USEC) ? 30 : 300);
uint32_t caPpm = BbGetClockAccuracy() + ((pAuxPtr->ca == LCTR_CLK_ACC_0_50_PPM) ? 50 : 500);
uint32_t wwUsec = lctrCalcAuxAdvWindowWideningUsec(offsetUsec, caPpm);
uint32_t wwUsec = lctrCalcWindowWideningUsec((offsetUsec + (pAuxPtr->offsetUnits == LCTR_OFFS_UNITS_30_USEC) ? 30 : 300), caPpm);
*pOffsetUsec = offsetUsec - wwUsec;
*pSyncDelayUsec = (wwUsec << 1) + ((pAuxPtr->offsetUnits == LCTR_OFFS_UNITS_30_USEC) ? 30 : 300); /* rounding compensation */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller advertising slave interface file.
* \file
* \brief Internal link layer controller advertising slave interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,13 +16,15 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller slave extended advertising interface file.
* \file
* \brief Internal link layer controller slave extended advertising interface file.
*/
/*************************************************************************************************/
#ifndef LCTR_INT_ADV_SLAVE_AE_H
#define LCTR_INT_ADV_SLAVE_AE_H
#include "lctr_int_adv_ae.h"
#include "lctr_int.h"
#include "lctr_api_adv_slave_ae.h"
#include "lmgr_api_adv_slave_ae.h"
@ -58,7 +60,10 @@ extern "C" {
#define LCTR_COMP_EXT_ADV_DATA_MAX_LEN 251 /* TODO: cfg_mac_ble.h configuration */
/*! \brief Resolve the extended advertising index from the context pointer. */
#define LCTR_GET_EXT_ADV_INDEX(pAdvSet) (pAdvSet - &pLctrAdvSetTbl[0])
#define LCTR_GET_EXT_ADV_INDEX(pAdvSet) (pAdvSet - &pLctrAdvSetTbl[0])
/*! \brief Get reservation manager handle for periodic ADV from the context pointer. */
#define LCTR_GET_PER_RM_HANDLE(pAdvSet) (LL_MAX_CONN + LCTR_GET_EXT_ADV_INDEX(pAdvSet))
/**************************************************************************************************
Constants
@ -104,6 +109,7 @@ typedef struct
uint8_t priAdvPhy; /*!< Primary Advertising PHY. */
uint8_t secAdvMaxSkip; /*!< Secondary Advertising Maximum Skip. */
uint8_t secAdvPhy; /*!< Secondary Advertising PHY. */
uint16_t advDID; /*!< Advertising Data ID. */
uint8_t advSID; /*!< Advertising SID. */
uint8_t scanReqNotifEna; /*!< Scan Request Notification Enable. */
} lctrExtAdvParam_t;
@ -131,13 +137,13 @@ typedef struct
bool_t advParamReady; /*!< Periodic Advertising Parameter is ready or not. */
/* Channel parameters */
lctrChanParam_t perChanParam; /*!< Periodic Advertising Channel parameter. */
lmgrChanParam_t perChanParam; /*!< Periodic Advertising Channel parameter. */
uint64_t updChanMask; /*!< Last updated channel mask */
} lctrPerAdvParam_t;
/*! \brief Advertising data buffer descriptor. */
typedef struct
{
uint16_t did; /*!< Advertising Data ID. */
uint16_t len; /*!< Advertising data length. */
uint8_t *pBuf; /*!< Advertising data buffer. */
bool_t ready; /*!< Advertising data buffer complete. */
@ -184,6 +190,9 @@ typedef struct
uint32_t auxDelayUsec; /*!< Auxiliary advertising event delay. */
uint8_t advDataFragLen; /*!< Advertising data fragmentation length. */
/* Acad control block */
lctrAcadParam_t acadParams[LCTR_ACAD_NUM_ID]; /*!< Acad parameters. */
/* Periodic advertising parameters */
lctrPerAdvParam_t perParam; /*!< Periodic advertising parameters. */
@ -230,6 +239,8 @@ typedef struct
uint32_t auxOffsUsec; /*!< Offset in microseconds to the next auxiliary PDU. */
uint8_t auxChIdx; /*!< AUX LL Channel. */
bool_t auxBodUsed; /*!< Auxiliary BOD in use flag. */
bool_t didPerUpdate; /*!< Data ID update due to periodic enable or disable. */
bool_t advBodAbort; /*!< TRUE if extended advertising BOD is aborted. */
lctrAdvbPduHdr_t rspPduHdr; /*!< Response PDU header. */
} lctrAdvSet_t;
@ -254,6 +265,7 @@ extern LctrPerAdvMsg_t *pLctrSlvPerAdvMsg;
/* Context */
void lctrFreeAdvSet(lctrAdvSet_t *pAdvSet);
lctrAdvSet_t *lctrFindAdvSet(uint8_t handle);
/* Address selection */
void lctrChooseSetAdvA(lctrAdvbPduHdr_t *pPduHdr, BbBleData_t * const pBle, lctrAdvSet_t *pAdvSet);
@ -282,16 +294,21 @@ bool_t lctrSlvRxAuxConnReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf);
bool_t lctrSlvRxLegacyReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf);
void lctrSlvRxLegacyReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf);
uint32_t lctrSlvTxSetupPeriodicAdvDataHandler(BbOpDesc_t *pOp, bool_t isChainInd);
void lctrSlvAcadHandler(lctrAdvSet_t *pAdvSet);
/* ISR: BOD handlers */
void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp);
void lctrSlvExtAdvAbortOp(BbOpDesc_t *pOp);
void lctrSlvAuxAdvEndOp(BbOpDesc_t *pOp);
void lctrSlvPeriodicAdvEndOp(BbOpDesc_t *pOp);
void lctrSlvPeriodicAdvAbortOp(BbOpDesc_t *pOp);
/* Action routines */
void lctrExtAdvActStart(lctrAdvSet_t *pAdvSet);
void lctrExtAdvActSelfStart(lctrAdvSet_t *pAdvSet);
void lctrExtAdvActRestart(lctrAdvSet_t *pAdvSet);
void lctrExtAdvActShutdown(lctrAdvSet_t *pAdvSet);
void lctrExtAdvActResetShutdown(lctrAdvSet_t *pAdvSet);
void lctrExtAdvActAdvCnf(lctrAdvSet_t *pAdvSet);
void lctrExtAdvActDisallowAdvCnf(lctrAdvSet_t *pAdvSet);
void lctrExtAdvActSelfTerm(lctrAdvSet_t *pAdvSet);
@ -305,13 +322,16 @@ void lctrPeriodicAdvActDisallowAdvCnf(lctrAdvSet_t *pAdvSet);
void lctrPeriodicAdvActShutdown(lctrAdvSet_t *pAdvSet);
void lctrPeriodicAdvActResetTerm(lctrAdvSet_t *pAdvSet);
void lctrPeriodicAdvActAdvTerm(lctrAdvSet_t *pAdvSet);
void lctrSlvAcadActChanMapUpdateStart(lctrAdvSet_t *pAdvSet);
void lctrSlvAcadActChanMapUpdateFinish(lctrAdvSet_t *pAdvSet);
/* Reservation */
void lctrGetPerAdvOffsets(uint32_t rsvnOffs[], uint32_t refTime);
uint32_t lctrGetPerRefTime(uint8_t perHandle, uint32_t *pDurUsec);
/* State machine */
void lctrSlvExtAdvExecuteSm(lctrAdvSet_t *pAdvSet, uint8_t event);
void lctrSlvPeriodicAdvExecuteSm(lctrAdvSet_t *pAdvSet, uint8_t event);
void lctrSlvAcadExecuteSm(lctrAdvSet_t *pAdvSet, uint8_t event);
/* Messaging */
void lctrSendAdvSetMsg(lctrAdvSet_t *pAdvSet, uint8_t event);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller connection interface file.
* \file
* \brief Internal link layer controller connection interface file.
*/
/*************************************************************************************************/
@ -96,6 +97,23 @@ enum
LCTR_CMN_STATE_TOTAL /*!< Total number of LLCP states. */
};
/*! \brief SVT states. */
enum
{
LCTR_SVT_STATE_IDLE, /*!< SVT idle state. */
LCTR_SVT_STATE_URGENT, /*!< SVT urgent state. */
LCTR_SVT_STATE_FATAL, /*!< SVT fatal state. */
LCTR_SVT_STATE_TOTAL /*!< Total number of SVT state. */
};
/*! \brief Periodic sync source. */
enum
{
LCTR_SYNC_SRC_SCAN, /*!< Periodic sync info from scanner. */
LCTR_SYNC_SRC_BCST, /*!< Periodic sync info from broadcaster. */
LCTR_SYNC_SRC_TOTAL /*!< Total number of periodic sync source. */
};
/*! \brief Common LLCP procedure IDs. */
enum
{
@ -106,6 +124,8 @@ enum
LCTR_PROC_CMN_VER_EXCH, /*!< Version exchange procedure. */
LCTR_PROC_CMN_DATA_LEN_UPD, /*!< Data length update procedure. */
LCTR_PROC_CMN_SET_MIN_USED_CHAN, /*!< Set minimum number of used channels procedure. */
LCTR_PROC_CMN_PER_ADV_SYNC_TRSF, /*!< Periodic advertising sync transfer procedure. */
LCTR_PROC_CMN_REQ_PEER_SCA, /*!< Request peer SCA procedure. */
LCTR_PROC_CMN_TOTAL, /*!< Total number of common procedures. */
/* Custom SM LLCP procedures. */
@ -115,12 +135,23 @@ enum
LCTR_PROC_LE_PING, /*!< LE Ping procedure. */
LCTR_PROC_PHY_UPD, /*!< PHY update procedure. */
LCTR_PROC_PHY_UPD_PEER, /*!< Peer-initiated PHY update procedure. */
LCTR_PROC_CIS_EST, /*!< CIS establishment procedure. */
LCTR_PROC_CIS_EST_PEER, /*!< Peer-initiated CIS establishment procedure. */
LCTR_PROC_CIS_TERM, /*!< CIS termination procedure. */
LCTR_PROC_CIS_TERM_PEER, /*!< Peer-initiated CIS termination procedure. */
LCTR_PROC_INVALID = 0xFF /*!< Invalid ID. */
/* Note: additional procedures without instants can be overridden. */
};
/*! \brief Check if CIS is enabled by the CIS handle signature. */
typedef bool_t (*lctrCheckCisEstCisFn_t)(uint16_t cisHandle);
/*! \brief Check for CIS termination signature. */
typedef bool_t (*lctrCheckTermFn_t)(uint16_t aclHandle);
/*! \brief Check if there is a CIS established by the ACL handle signature. */
typedef bool_t (*lctrCheckCisEstAclFn_t)(uint16_t aclHandle);
/*! \brief Connection context. */
typedef struct
{
@ -148,6 +179,12 @@ typedef struct
uint32_t unsyncedTime; /*!< Unsynced time in BB tick before connection update. */
bool_t initAckRcvd; /*!< Ack received from master. */
bool_t abortSlvLatency; /*!< If TRUE abort slave latency. */
uint8_t consCrcFailed; /*!< Number of consecutive CRC failures. */
bool_t syncWithMaster; /*!< Flag indicating synchronize packet received from master. */
bool_t rxFromMaster; /*!< At least one successful packet received from master. */
uint32_t firstRxStartTs; /*!< Timestamp of the first received frame regardless of CRC error. */
} slv; /*!< Slave connection specific data. */
struct
@ -173,6 +210,8 @@ typedef struct
/*!< Channel remapping table. */
uint8_t usedChSel; /*!< Used channel selection. */
uint16_t chIdentifier; /*!< Channel identifier. */
uint32_t crcInit; /*!< CRC initialization value. */
uint32_t accessAddr; /*!< Connection access address. */
/* Flow control */
lctrDataPduHdr_t txHdr; /*!< Transmit data PDU header. */
@ -184,11 +223,13 @@ typedef struct
uint8_t numRxPend; /*!< Number of Rx pending buffers. */
bool_t emptyPduPend; /*!< Empty PDU ACK pending. */
bool_t emptyPduFirstAtt; /*!< Empty PDU first attempt. */
bool_t forceStartPdu; /*!< Next data will be forced to be a start PDU */
/* Supervision */
uint16_t supTimeoutMs; /*!< Supervision timeout in milliseconds. */
wsfTimer_t tmrSupTimeout; /*!< Supervision timer. */
bool_t connEst; /*!< Connection established. */
uint8_t svtState; /*!< SVT urgency state. */
/* Encryption */
bool_t pauseRxData; /*!< Pause Rx data PDUs. */
@ -219,6 +260,7 @@ typedef struct
lctrVerInd_t remoteVer; /*!< Peer version data. */
bool_t featExchFlag; /*!< Flag for completed feature exchange. */
uint64_t usedFeatSet; /*!< Used feature set. */
uint8_t peerSca; /*!< Peer SCA. */
/* Data length */
lctrDataLen_t localDataPdu; /*!< Local Data PDU parameters. */
@ -236,6 +278,17 @@ typedef struct
uint8_t peerMinUsedChan[LL_MAX_PHYS];
/*!< Peer minimum number of used channels for PHYs. */
/* Periodic sync indication */
bool_t sendPerSync; /*!< Send LL_PERIODIC_SYNC_IND flag. */
uint8_t perSyncSrc; /*!< Periodic sync source. */
uint16_t perServiceData; /*!< ID for periodic sync indication. */
uint16_t perSyncHandle; /*!< Periodic sync handle. */
/* PAST(Periodic advertising sync transfer) parameters. */
uint8_t syncMode; /*!< Sync transfer mode. */
uint16_t syncSkip; /*!< Sync skip for periodic adv sync transfer. */
uint16_t syncTimeout; /*!< Sync timeout for periodic adv sync transfer. */
/* LLCP */
uint8_t llcpState; /*!< Current LLCP state. */
uint8_t encState; /*!< Current encryption state. */
@ -252,9 +305,9 @@ typedef struct
bool_t isFirstNonCtrlPdu; /*!< True if first non-control PDU from master and slave. */
bool_t isSlvPhyUpdInstant; /*!< True if slave is in PHY update instant state. */
uint8_t llcpActiveProc; /*!< Current procedure. */
uint16_t llcpNotifyMask; /*!< Host notification mask. */
uint16_t llcpPendMask; /*!< Pending LLCP procedures. */
uint16_t llcpIncompMask; /*!< Incomplete LLCP procedures. */
uint32_t llcpNotifyMask; /*!< Host notification mask. */
uint32_t llcpPendMask; /*!< Pending LLCP procedures. */
uint32_t llcpIncompMask; /*!< Incomplete LLCP procedures. */
LlConnSpec_t connUpdSpec; /*!< Host connection update specification. */
lctrConnUpdInd_t connUpd; /*!< Connection update parameters. */
lctrConnParam_t connParam; /*!< Stored peer connection parameter request or response. */
@ -262,19 +315,26 @@ typedef struct
lctrPhy_t phyReq; /*!< Stored peer PHY request. */
lctrPhyUpdInd_t phyUpd; /*!< PHY update parameters. */
wsfTimer_t tmrProcRsp; /*!< Procedure response timer. */
uint8_t scaUpdAction; /*!< Sca update action variable. */
int8_t scaMod; /*!< Local sca override modifier. */
/* CIS */
uint16_t llcpCisHandle; /*!< CIS handle for the LLCP procedure. */
lctrCheckTermFn_t checkCisTerm; /*!< Pointer to the check CIS termination function. */
lctrCheckCisEstAclFn_t checkCisEstAcl;/*!< Pointer to the check if CIS is established function. */
} lctrConnCtx_t;
/*! \brief Call signature of a cipher block handler. */
typedef void (*lctrCipherBlkHdlr_t)(BbBleEnc_t *pEnc, uint8_t id, uint8_t dir);
typedef void (*lctrCipherBlkHdlr_t)(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t dir);
/*! \brief Call signature of a packet encryption handler. */
typedef bool_t (*lctrPktEncHdlr_t)(BbBleEnc_t *pEnc, uint8_t *pHdr, uint8_t *pBuf, uint8_t *pMic);
typedef bool_t (*lctrPktEncHdlr_t)(PalCryptoEnc_t *pEnc, uint8_t *pHdr, uint8_t *pBuf, uint8_t *pMic);
/*! \brief Call signature of a packet decryption handler. */
typedef bool_t (*lctrPktDecHdlr_t)(BbBleEnc_t *pEnc, uint8_t *pBuf);
typedef bool_t (*lctrPktDecHdlr_t)(PalCryptoEnc_t *pEnc, uint8_t *pBuf);
/*! \brief Call signature of a set packet count handler. */
typedef void (*lctrPktCntHdlr_t)(BbBleEnc_t *pEnc, uint64_t pktCnt);
typedef void (*lctrPktCntHdlr_t)(PalCryptoEnc_t *pEnc, uint64_t pktCnt);
/*! \brief Call signature of a LLCP state machine handler. */
typedef bool_t (*LctrLlcpHdlr_t)(lctrConnCtx_t *pCtx, uint8_t event);
@ -285,6 +345,9 @@ typedef void (*lctrCtrlPduHdlr_t)(lctrConnCtx_t *pCtx, uint8_t *pBuf);
/*! \brief Call signature of a Channel state machine handler. */
typedef uint8_t (*LctrChSelHdlr_t)(lctrConnCtx_t *pCtx, uint16_t numSkip);
/*! \brief Call signature of an action handler. */
typedef void (*lctrLlcpEh_t)(lctrConnCtx_t *pCtx);
/*! \brief LLCP state machine handlers. */
enum
{
@ -292,6 +355,8 @@ enum
LCTR_LLCP_SM_PING, /*!< Ping state machine. */
LCTR_LLCP_SM_CONN_UPD, /*!< Connection update state machine. */
LCTR_LLCP_SM_PHY_UPD, /*!< PHY update state machine. */
LCTR_LLCP_SM_CIS_EST, /*!< CIS establishment state machine. */
LCTR_LLCP_SM_CIS_TERM, /*!< CIS termination state machine. */
LCTR_LLCP_SM_CMN, /*!< Common LLCP state machine. */
LCTR_LLCP_SM_TOTAL /*!< Total number of LLCP state machine. */
};
@ -311,6 +376,12 @@ extern lctrConnMsg_t *pLctrConnMsg;
extern const LctrVsHandlers_t *pLctrVsHdlrs;
extern lctrCtrlPduHdlr_t lctrCtrlPduHdlr;
extern LctrChSelHdlr_t lctrChSelHdlr[LCTR_CH_SEL_MAX];
extern lctrCheckCisEstCisFn_t lctrCheckCisEstCisFn;
extern lctrLlcpEh_t lctrSendPerSyncFromScanFn;
extern lctrLlcpEh_t lctrSendPerSyncFromBcstFn;
extern lctrLlcpEh_t lctrStorePeriodicSyncTrsfFn;
extern lctrLlcpEh_t lctrSendPeriodicSyncIndFn;
extern lctrLlcpEh_t lctrReceivePeriodicSyncIndFn;
/**************************************************************************************************
Function Declarations
@ -384,6 +455,23 @@ void lctrNotifyHostDataLengthInd(lctrConnCtx_t *pCtx, uint8_t status);
void lctrSendSetMinUsedChanInd(lctrConnCtx_t *pCtx);
void lctrStoreSetMinUsedChan(lctrConnCtx_t *pCtx);
/* Send periodic sync indication actions */
void lctrActStorePeriodicSyncTrsf(lctrConnCtx_t *pCtx);
void lctrActSendPeriodicSyncInd(lctrConnCtx_t *pCtx);
void lctrActReceivePeriodicSyncInd(lctrConnCtx_t *pCtx);
void lctrStorePeriodicSyncTrsf(lctrConnCtx_t *pCtx);
void lctrSendPeriodicSyncInd(lctrConnCtx_t *pCtx);
void lctrReceivePeriodicSyncInd(lctrConnCtx_t *pCtx);
void lctrSendPerSyncFromScan(lctrConnCtx_t *pCtx);
void lctrSendPerSyncFromBcst(lctrConnCtx_t *pCtx);
/* Request peer SCA actions */
void lctrStoreScaAction(lctrConnCtx_t *pCtx);
void lctrSendPeerScaReq(lctrConnCtx_t *pCtx);
void lctrSendPeerScaRsp(lctrConnCtx_t *pCtx);
void lctrStorePeerSca(lctrConnCtx_t *pCtx);
void lctrNotifyHostPeerScaCnf(lctrConnCtx_t *pCtx);
/* Unknown/Unsupported */
void lctrSendUnknownRsp(lctrConnCtx_t *pCtx);
void lctrSendRejectInd(lctrConnCtx_t *pCtx, uint8_t reason, bool_t forceRejectExtInd);
@ -394,7 +482,7 @@ uint16_t lctrTxInitMem(uint8_t *pFreeMem, uint32_t freeMemSize);
uint8_t *lctrTxCtrlPduAlloc(uint8_t pduLen);
void lctrTxDataPduQueue(lctrConnCtx_t *pCtx, uint16_t fragLen, lctrAclHdr_t *pAclHdr, uint8_t *pAclBuf);
void lctrTxCtrlPduQueue(lctrConnCtx_t *pCtx, uint8_t *pBuf);
uint8_t lctrTxQueuePeek(lctrConnCtx_t *pCtx, BbBleDrvTxBufDesc_t *bbDescs, bool_t *pMd);
uint8_t lctrTxQueuePeek(lctrConnCtx_t *pCtx, PalBbBleTxBufDesc_t *bbDescs, bool_t *pMd);
bool_t lctrTxQueuePop(lctrConnCtx_t *pCtx);
void lctrTxQueuePopCleanup(lctrConnCtx_t *pCtx);
uint8_t lctrTxQueueClear(lctrConnCtx_t *pCtx);
@ -441,26 +529,10 @@ void lctrSendConnMsg(lctrConnCtx_t *pCtx, uint8_t event);
bool_t lctrExceededMaxDur(lctrConnCtx_t *pCtx, uint32_t ceStart, uint32_t pendDurUsec);
uint32_t lctrCalcPingPeriodMs(lctrConnCtx_t *pCtx, uint32_t authTimeoutMs);
uint8_t lctrComputeSca(void);
uint32_t lctrConnGetAnchorPoint(lctrConnCtx_t *pCtx, uint16_t ceCounter);
/* Reservation */
void lctrGetConnOffsets(uint32_t rsvnOffs[], uint32_t refTime);
/*************************************************************************************************/
/*!
* \brief Check for a queue depth of 1 element.
*
* \param pArqQ Queue.
*
* \return TRUE if ARQ only has 1 element, FALSE otherwise.
*
* \note Checks without resource protection. This routine is only intended to be used in task
* context.
*/
/*************************************************************************************************/
static inline bool_t lctrIsQueueDepthOne(wsfQueue_t *pArqQ)
{
return pArqQ->pHead == pArqQ->pTail;
}
uint32_t lctrGetConnRefTime(uint8_t connHandle, uint32_t *pDurUsec);
/*************************************************************************************************/
/*!
@ -563,10 +635,10 @@ static inline void lctrIncPacketCounterTx(lctrConnCtx_t *pCtx)
{
if (lctrSetEncryptPktCountHdlr)
{
BbBleEnc_t * const pEnc = &pCtx->bleData.chan.enc;
PalCryptoEnc_t * const pEnc = &pCtx->bleData.chan.enc;
if ((pEnc->enaEncrypt) &&
(pEnc->nonceMode == BB_NONCE_MODE_PKT_CNTR))
(pEnc->nonceMode == PAL_BB_NONCE_MODE_PKT_CNTR))
{
pCtx->txPktCounter++;
}
@ -586,10 +658,10 @@ static inline void lctrIncPacketCounterRx(lctrConnCtx_t *pCtx)
{
if (lctrSetEncryptPktCountHdlr)
{
BbBleEnc_t * const pEnc = &pCtx->bleData.chan.enc;
PalCryptoEnc_t * const pEnc = &pCtx->bleData.chan.enc;
if ((pEnc->enaEncrypt) &&
(pEnc->nonceMode == BB_NONCE_MODE_PKT_CNTR))
(pEnc->nonceMode == PAL_BB_NONCE_MODE_PKT_CNTR))
{
pCtx->rxPktCounter++;
}
@ -609,7 +681,7 @@ static inline void lctrSetBbPacketCounterTx(lctrConnCtx_t *pCtx)
{
if (lctrSetEncryptPktCountHdlr)
{
BbBleEnc_t * const pEnc = &pCtx->bleData.chan.enc;
PalCryptoEnc_t * const pEnc = &pCtx->bleData.chan.enc;
if (!pEnc->enaEncrypt)
{
@ -618,10 +690,10 @@ static inline void lctrSetBbPacketCounterTx(lctrConnCtx_t *pCtx)
switch (pEnc->nonceMode)
{
case BB_NONCE_MODE_PKT_CNTR:
case PAL_BB_NONCE_MODE_PKT_CNTR:
lctrSetEncryptPktCountHdlr(pEnc, pCtx->txPktCounter);
break;
case BB_NONCE_MODE_EVT_CNTR:
case PAL_BB_NONCE_MODE_EVT_CNTR:
lctrSetEncryptPktCountHdlr(pEnc, pCtx->eventCounter);
break;
default:
@ -643,7 +715,7 @@ static inline void lctrSetBbPacketCounterRx(lctrConnCtx_t *pCtx)
{
if (lctrSetDecryptPktCountHdlr)
{
BbBleEnc_t * const pEnc = &pCtx->bleData.chan.enc;
PalCryptoEnc_t * const pEnc = &pCtx->bleData.chan.enc;
if (!pEnc->enaDecrypt)
{
@ -652,10 +724,10 @@ static inline void lctrSetBbPacketCounterRx(lctrConnCtx_t *pCtx)
switch (pEnc->nonceMode)
{
case BB_NONCE_MODE_PKT_CNTR:
case PAL_BB_NONCE_MODE_PKT_CNTR:
lctrSetDecryptPktCountHdlr(pEnc, pCtx->rxPktCounter);
break;
case BB_NONCE_MODE_EVT_CNTR:
case PAL_BB_NONCE_MODE_EVT_CNTR:
lctrSetDecryptPktCountHdlr(pEnc, pCtx->eventCounter);
break;
default:
@ -848,6 +920,12 @@ static inline uint8_t lctrGetProcId(uint8_t event)
case LCTR_CONN_MSG_API_DATA_LEN_CHANGE:
return LCTR_PROC_CMN_DATA_LEN_UPD;
case LCTR_CONN_MSG_API_PER_ADV_SYNC_TRSF:
return LCTR_PROC_CMN_PER_ADV_SYNC_TRSF;
case LCTR_CONN_MSG_API_REQ_PEER_SCA:
return LCTR_PROC_CMN_REQ_PEER_SCA;
case LCTR_CONN_MSG_API_CONN_UPDATE:
return LCTR_PROC_CONN_UPD;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller master connection interface file.
* \file
* \brief Internal link layer controller master connection interface file.
*/
/*************************************************************************************************/
@ -74,7 +75,7 @@ void lctrMstSetEstablishConn(lctrConnCtx_t *pCtx);
void lctrMstReloadDataPdu(lctrConnCtx_t *pCtx);
/* Helper */
uint32_t lctrMstConnAdjustOpStart(lctrConnCtx_t *pCtx, uint32_t scanRefTime, lctrConnInd_t *pConnInd);
uint32_t lctrMstConnAdjustOpStart(lctrConnCtx_t *pCtx, uint32_t scanRefTime, uint32_t scanMinDurUsec, lctrConnInd_t *pConnInd);
#ifdef __cplusplus
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller slave connection interface file.
* \file
* \brief Internal link layer controller slave connection interface file.
*/
/*************************************************************************************************/
@ -58,7 +59,6 @@ bool_t lctrSlvCheckEncOverrideCommonParam(lctrConnCtx_t *pCtx);
bool_t lctrSlvCheckConnUpdInstant(lctrConnCtx_t *pCtx);
/* Builder */
uint32_t lctrCalcIntervalWindowWideningUsec(lctrConnCtx_t *pCtx, uint32_t unsyncTimeUsec);
void lctrSlvConnBuildOp(lctrConnCtx_t *pCtx);
/* ISR */
@ -67,6 +67,7 @@ void lctrSlvConnCleanupOp(BbOpDesc_t *pOp);
void lctrSlvConnEndOp(BbOpDesc_t *pOp);
void lctrSlvConnTxCompletion(BbOpDesc_t *pOp, uint8_t status);
void lctrSlvConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status);
void lctrSlvConnAbortOp(BbOpDesc_t *pOp);
#ifdef __cplusplus
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller master connection interface file.
* \file
* \brief Internal link layer controller master connection interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller slave connection interface file.
* \file
* \brief Internal link layer controller slave connection interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller scanning master interface file.
* \file
* \brief Internal link layer controller scanning master interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller scanning master interface file.
* \file
* \brief Internal link layer controller scanning master interface file.
*/
/*************************************************************************************************/
@ -66,7 +67,6 @@ typedef struct
/* State. */
uint8_t enaPhys; /*!< Enabled PHYs. */
bool_t initTermByHost; /*!< Host initiated initiate disable. */
} lctrExtInitCtrlBlk_t;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller PHY features (master) interface file.
* \file
* \brief Internal link layer controller PHY features (master) interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller privacy interface file.
* \file
* \brief Internal link layer controller privacy interface file.
*/
/*************************************************************************************************/

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Internal link layer controller PHY features (slave) interface file.
* \file
* \brief Internal link layer controller PHY features (slave) interface file.
*/
/*************************************************************************************************/

View File

@ -1,71 +0,0 @@
/* Copyright (c) 2009-2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*************************************************************************************************/
/*!
* \brief Internal link layer controller connection interface file.
*/
/*************************************************************************************************/
#ifndef LCTR_INT_TESTER_H
#define LCTR_INT_TESTER_H
#include "ll_tester_api.h"
#include "wsf_msg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
void LctrForceTxAcl(uint8_t *pAclBuf);
/*************************************************************************************************/
/*!
* \brief Force transmission of a data PDU.
*
* \param connHandle Connection handle.
*
* \return None.
*/
/*************************************************************************************************/
static inline void lctrForceTxData(uint16_t connHandle)
{
uint8_t *pAclBuf;
if ((pAclBuf = WsfMsgAlloc(4 + 4 + 1)) != NULL)
{
pAclBuf[0] = connHandle & 0xFF;
pAclBuf[1] = connHandle >> 8;
pAclBuf[2] = 0x05;
pAclBuf[3] = 0x00;
pAclBuf[4] = 0x01;
pAclBuf[5] = 0x00;
pAclBuf[6] = 0x40;
pAclBuf[7] = 0x00;
pAclBuf[8] = 0xFF;
LctrForceTxAcl(pAclBuf);
}
}
#ifdef __cplusplus
};
#endif
#endif /* LCTR_INT_TESTER_H */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master advertising event ISR callbacks.
* \file
* \brief Link layer controller master advertising event ISR callbacks.
*/
/*************************************************************************************************/
@ -34,6 +35,9 @@
#include "bb_ble_api_reslist.h"
#include "util/bstream.h"
#include <string.h>
#if (LL_ENABLE_TESTER == TRUE)
extern bool_t bbTxAccAddrShiftMask;
#endif
/*************************************************************************************************/
/*!
@ -100,7 +104,8 @@ void lctrMstDiscoverEndOp(BbOpDesc_t *pOp)
/* Reset due time to start of scan window. */
pOp->due = pCtx->scanWinStart;
if ((pScan->elapsedUsec + pOp->minDurUsec) < LCTR_BLE_TO_US(pCtx->scanParam.scanWindow))
if ((pCtx->scanParam.scanInterval != pCtx->scanParam.scanWindow) &&
((pScan->elapsedUsec + pOp->minDurUsec) < LCTR_BLE_TO_US(pCtx->scanParam.scanWindow)))
{
const uint32_t min = BB_US_TO_BB_TICKS(pScan->elapsedUsec);
const uint32_t max = BB_BLE_TO_BB_TICKS(pCtx->scanParam.scanWindow);
@ -217,7 +222,11 @@ bool_t lctrMstDiscoverAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf)
lctrPackAdvbPduHdr(lctrMstScan.reqBuf, &lctrMstScan.reqPduHdr);
/* Scan backoff. */
if (lctrGetOpFlag(LL_OP_MODE_FLAG_ENA_SCAN_BACKOFF))
if (lmgrGetOpFlag(LL_OP_MODE_FLAG_ENA_SCAN_BACKOFF)
#if (LL_ENABLE_TESTER == TRUE)
&& !bbTxAccAddrShiftMask
#endif
)
{
if (lctrMstScan.backoffCount)
{

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master advertising event ISR callbacks.
* \file
* \brief Link layer controller master advertising event ISR callbacks.
*/
/*************************************************************************************************/
@ -141,6 +142,55 @@ static inline void lctrGetLocalIdAddr(lctrExtScanCtx_t *pExtScanCtx, uint64_t ta
}
}
/*************************************************************************************************/
/*!
* \brief Master Acad handler.
*
* \param pPerScanCtx Periodic scan context.
*
* \return None
*/
/*************************************************************************************************/
void lctrMstAcadHandler(lctrPerScanCtx_t * const pPerScanCtx)
{
if (pPerScanCtx->extAdvHdr.acadLen == 0)
{
return;
}
/* Enable any new Acad if necessary */
uint8_t len = pPerScanCtx->extAdvHdr.acadLen;
uint8_t *pBuf = (uint8_t *) pPerScanCtx->extAdvHdr.pAcad;
while(len > 0)
{
uint8_t acadLen = 0;
BSTREAM_TO_UINT8(acadLen, pBuf);
uint8_t opcode = 0;
BSTREAM_TO_UINT8(opcode, pBuf);
switch (opcode) {
case LL_ACAD_OPCODE_CHANNEL_MAP_UPDATE:
{
lctrAcadParam_t *pAcadParam = &pPerScanCtx->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE];
if (pAcadParam->hdr.state == LCTR_ACAD_STATE_DISABLED)
{
pAcadParam->hdr.state = LCTR_ACAD_STATE_ENABLED;
BSTREAM_TO_UINT40(pAcadParam->chanMapUpdate.chanMask, pBuf);
BSTREAM_TO_UINT16(pAcadParam->chanMapUpdate.instant, pBuf);
}
break;
}
default:
break;
}
len -= (acadLen + 1); /* Minus the Acad plus the acadLen field. */
}
}
/**************************************************************************************************
Functions: Extended advertising reports
**************************************************************************************************/
@ -150,22 +200,22 @@ static inline void lctrGetLocalIdAddr(lctrExtScanCtx_t *pExtScanCtx, uint64_t ta
* \brief Pend extended advertising report notification.
*
* \param pExtScanCtx Extended scan context.
* \param pRpt Report data.
* \param pState Report state.
*
* \return TRUE if report pended, FALSE otherwise.
*/
/*************************************************************************************************/
static bool_t lctrExtAdvRptPend(lctrExtScanCtx_t *pExtScanCtx)
static bool_t lctrExtAdvRptPend(lctrExtScanCtx_t *pExtScanCtx, LlExtAdvReportInd_t *pRpt, lctrRptState_t *pState)
{
/* Only called with the first report in the sequence. */
WSF_ASSERT(pExtScanCtx->data.scan.advRptState == LCTR_RPT_STATE_IDLE);
WSF_ASSERT(*pState == LCTR_RPT_STATE_IDLE);
if (pExtScanCtx->state != LCTR_EXT_SCAN_STATE_DISCOVER)
{
return FALSE;
}
LlExtAdvReportInd_t * const pRpt = &pExtScanCtx->data.scan.advRpt;
/* Check for duplicate report. */
uint64_t hash;
lctrAdvRptGenerateExtHash(&hash, pRpt->addrType, BstreamToBda64(pRpt->addr),
@ -176,7 +226,7 @@ static bool_t lctrExtAdvRptPend(lctrExtScanCtx_t *pExtScanCtx)
return FALSE;
}
pExtScanCtx->data.scan.advRptState = LCTR_RPT_STATE_IN_PROGRESS;
*pState = LCTR_RPT_STATE_IN_PROGRESS;
/* Event handling offloaded to task context, cf. lctrMstExtDiscoverEndOp(), lctrMstAuxDiscoverEndOp(). */
return TRUE;
@ -187,16 +237,16 @@ static bool_t lctrExtAdvRptPend(lctrExtScanCtx_t *pExtScanCtx)
* \brief Pend extended advertising report notification.
*
* \param pExtScanCtx Extended scan context.
* \param pRpt Report data.
* \param pState Report state.
*
* \return TRUE if report pended, FALSE otherwise.
*/
/*************************************************************************************************/
static void lctrExtAdvRptSubmit(lctrExtScanCtx_t *pExtScanCtx)
static void lctrExtAdvRptSubmit(lctrExtScanCtx_t *pExtScanCtx, LlExtAdvReportInd_t *pRpt, lctrRptState_t *pState)
{
if (pExtScanCtx->data.scan.advRptState == LCTR_RPT_STATE_IN_PROGRESS)
if (*pState == LCTR_RPT_STATE_IN_PROGRESS)
{
LlExtAdvReportInd_t * const pRpt = &pExtScanCtx->data.scan.advRpt;
if (((pRpt->eventType >> 5) & LL_RPT_DATA_INC_TRUNC) == 0)
{
/* Only save the hash to the table when complete data is received. */
@ -206,7 +256,7 @@ static void lctrExtAdvRptSubmit(lctrExtScanCtx_t *pExtScanCtx)
lctrAdvRptAddEntry(&lctrMstExtScan.advFilt, hash);
}
pExtScanCtx->data.scan.advRptState = LCTR_RPT_STATE_COMP;
*pState = LCTR_RPT_STATE_COMP;
WsfSetEvent(lmgrPersistCb.handlerId, (1 << LCTR_EVENT_RX_ADVB));
}
}
@ -623,7 +673,7 @@ static void lctrScanBackoffRspFailed(lctrExtScanCtx_t *pExtScanCtx)
/*************************************************************************************************/
static bool_t lctrScanBackoffCheckReqAllowed(lctrExtScanCtx_t *pExtScanCtx)
{
if (!lctrGetOpFlag(LL_OP_MODE_FLAG_ENA_SCAN_BACKOFF))
if (!lmgrGetOpFlag(LL_OP_MODE_FLAG_ENA_SCAN_BACKOFF))
{
/* Backoff is disabled, always send request. */
return TRUE;
@ -783,16 +833,32 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t
/* else case, delay connectable and scannable PDU filtering in the AUX_ADV_IND. */
/*** Periodic advertising event filtering. ***/
bool_t advAMatch = FALSE;
lctrMstPerScanIsr.filtResult = TRUE;
if ((lctrPerCreateSync.state == LCTR_CREATE_SYNC_STATE_DISCOVER) &&
(extAdvHdrFlags & LL_EXT_HDR_ADI_BIT) &&
(extAdvHdrFlags & LL_EXT_HDR_ADV_ADDR_BIT))
{
bool_t advAMatch = FALSE;
bbBlePduExtFiltParams_t params;
uint64_t peerIdAddr = 0;
uint8_t peerIdAddrType = 0;
params.pduType = advHdr.pduType;
params.extHdrFlags = pExtScanCtx->extAdvHdr.extHdrFlags;
params.peerAddr = pExtScanCtx->extAdvHdr.advAddr;
params.peerAddrRand = advHdr.txAddrRnd;
params.localAddr = pExtScanCtx->extAdvHdr.tgtAddr;
params.localAddrRand = advHdr.rxAddrRnd;
/* This function is only used here for address conversion, not for filtering. */
(void)BbBleExtPduFiltCheck(&params, &pOp->prot.pBle->pduFilt, FALSE, &pScan->filtResults);
BbBlePduFiltResultsGetPeerIdAddr(&pScan->filtResults, &peerIdAddr, &peerIdAddrType);
if (lctrPerCreateSync.filtParam.filterPolicy == LL_PER_SCAN_FILTER_PL_BIT)
{
if ((BbBlePeriodicListCheckAddr(advHdr.txAddrRnd, pExtScanCtx->extAdvHdr.advAddr,
if ((BbBlePeriodicListCheckAddr((peerIdAddrType & LL_ADDR_RANDOM_BIT), peerIdAddr,
pExtScanCtx->extAdvHdr.sid)) == FALSE)
{
/* Not in the periodic list. */
@ -807,8 +873,8 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t
else
{
if ((lctrPerCreateSync.filtParam.advSID != pExtScanCtx->extAdvHdr.sid) ||
(lctrPerCreateSync.filtParam.advAddrType != advHdr.txAddrRnd) ||
(lctrPerCreateSync.filtParam.advAddr != pExtScanCtx->extAdvHdr.advAddr))
(lctrPerCreateSync.filtParam.advAddrType != (peerIdAddrType & LL_ADDR_RANDOM_BIT)) ||
(lctrPerCreateSync.filtParam.advAddr != peerIdAddr))
{
/* Address type, address or SID does not match. */
break;
@ -819,14 +885,18 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t
advAMatch = TRUE;
}
}
}
if (advAMatch == TRUE)
{
/* AdvA is received in the adv_ext_ind and pass the filtering, save info in the context. */
lctrPerCreateSync.pPerScanCtx->advAddr = pExtScanCtx->extAdvHdr.advAddr;
lctrPerCreateSync.pPerScanCtx->advAddrType = advHdr.txAddrRnd;
lctrPerCreateSync.pPerScanCtx->advSID = pExtScanCtx->extAdvHdr.sid;
if (advAMatch == TRUE)
{
/* AdvA is received in the adv_ext_ind and pass the filtering, save info in the context. */
lctrPerCreateSync.pPerScanCtx->advAddr = peerIdAddr;
lctrPerCreateSync.pPerScanCtx->advAddrType = peerIdAddrType;
lctrPerCreateSync.pPerScanCtx->advSID = pExtScanCtx->extAdvHdr.sid;
/* Address to be used for sync transfer. */
lctrPerCreateSync.pPerScanCtx->trsfAdvAddr = pExtScanCtx->extAdvHdr.advAddr;
lctrPerCreateSync.pPerScanCtx->trsfAddrType = advHdr.txAddrRnd;
}
}
if (extAdvHdrFlags & LL_EXT_HDR_AUX_PTR_BIT)
@ -838,6 +908,15 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t
BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pScan->advRxPhyOptions, LL_ADV_HDR_LEN + pScan->filtResults.pduLen));
lctrMstAuxDiscoverOpCommit(pExtScanCtx, &pExtScanCtx->priChAuxPtr, pScan->advStartTs, endTs);
if ((pExtScanCtx->auxOpPending == FALSE) &&
(lctrPerCreateSync.state == LCTR_CREATE_SYNC_STATE_DISCOVER) &&
(lctrMstPerScanIsr.filtResult == FALSE))
{
/* Reset the flag if cannot schedule the auxiliary operation. */
LL_TRACE_WARN0("Reset filter flag due to auxiliary operation scheduling conflict.");
lctrMstPerScanIsr.filtResult = TRUE;
}
if (pExtScanCtx->auxOpPending)
{
/* Extended advertising event continues with auxiliary BOD */
@ -856,13 +935,12 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t
LlExtAdvReportInd_t * const pRpt = &pExtScanCtx->data.scan.advRpt;
if (lctrExtAdvRptPack(pExtScanCtx, 0, &advHdr,
peerIdAddr, peerIdAddrType, pScan->advRssi, pAdvBuf,
pRpt))
peerIdAddr, peerIdAddrType, pScan->advRssi, pAdvBuf, pRpt))
{
pRpt->secPhy = LL_PHY_NONE;
if (lctrExtAdvRptPend(pExtScanCtx))
if (lctrExtAdvRptPend(pExtScanCtx, pRpt, &pExtScanCtx->data.scan.advRptState))
{
lctrExtAdvRptSubmit(pExtScanCtx);
lctrExtAdvRptSubmit(pExtScanCtx, pRpt, &pExtScanCtx->data.scan.advRptState);
}
}
}
@ -879,13 +957,12 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t
LlExtAdvReportInd_t * const pRpt = &pExtScanCtx->data.scan.advRpt;
if (lctrExtAdvRptPack(pExtScanCtx, 0, &advHdr,
peerIdAddr,peerIdAddrType, pScan->advRssi, pAdvBuf,
pRpt))
peerIdAddr,peerIdAddrType, pScan->advRssi, pAdvBuf, pRpt))
{
pRpt->secPhy = LL_PHY_NONE;
if (lctrExtAdvRptPend(pExtScanCtx))
if (lctrExtAdvRptPend(pExtScanCtx, pRpt, &pExtScanCtx->data.scan.advRptState))
{
lctrExtAdvRptSubmit(pExtScanCtx);
lctrExtAdvRptSubmit(pExtScanCtx, pRpt, &pExtScanCtx->data.scan.advRptState);
}
}
break;
@ -980,11 +1057,27 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf
{
LL_TRACE_INFO1("Ignoring LL_PDU_AUX_ADV_IND due to PDU filtering, SID=%u", pExtScanCtx->extAdvHdr.sid);
lctrMstExtScanIsr.filtResult = TRUE;
return FALSE;
/* Continue processing for sync establishment filter even when scan filtering failed. */
}
/*** Periodic advertising event filtering. ***/
bool_t advAMatch = FALSE;
uint64_t peerIdAddr = 0;
uint8_t peerIdAddrType = 0;
BbBlePduFiltResultsGetPeerIdAddr(&pAuxScan->filtResults, &peerIdAddr, &peerIdAddrType);
if ((lctrPerCreateSync.state == LCTR_CREATE_SYNC_STATE_DISCOVER) &&
(lctrMstPerScanIsr.filtResult == FALSE))
{
if ((lctrPerCreateSync.filtParam.advSID != pExtScanCtx->extAdvHdr.sid) ||
(lctrPerCreateSync.filtParam.advAddrType != (peerIdAddrType & LL_ADDR_RANDOM_BIT)) ||
(lctrPerCreateSync.filtParam.advAddr != peerIdAddr))
{
/* Address type, address or SID does not match. */
lctrMstPerScanIsr.filtResult = TRUE;
}
}
if ((lctrPerCreateSync.state == LCTR_CREATE_SYNC_STATE_DISCOVER) &&
(lctrMstPerScanIsr.filtResult == TRUE) &&
@ -993,7 +1086,7 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf
{
if (lctrPerCreateSync.filtParam.filterPolicy == LL_PER_SCAN_FILTER_PL_BIT)
{
if ((BbBlePeriodicListCheckAddr(lctrMstExtScanIsr.advHdr.txAddrRnd, pExtScanCtx->extAdvHdr.advAddr,
if ((BbBlePeriodicListCheckAddr((peerIdAddrType & LL_ADDR_RANDOM_BIT), peerIdAddr,
pExtScanCtx->extAdvHdr.sid)) == FALSE)
{
/* Not in the periodic list. */
@ -1008,8 +1101,8 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf
else
{
if ((lctrPerCreateSync.filtParam.advSID != pExtScanCtx->extAdvHdr.sid) ||
(lctrPerCreateSync.filtParam.advAddrType != lctrMstExtScanIsr.advHdr.txAddrRnd) ||
(lctrPerCreateSync.filtParam.advAddr != pExtScanCtx->extAdvHdr.advAddr))
(lctrPerCreateSync.filtParam.advAddrType != (peerIdAddrType & LL_ADDR_RANDOM_BIT)) ||
(lctrPerCreateSync.filtParam.advAddr != peerIdAddr))
{
/* Address type, address or SID does not match. */
break;
@ -1035,6 +1128,7 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf
lctrPerScanCtx_t *pPerScanCtx = lctrPerCreateSync.pPerScanCtx;
/*** Save peer periodic advertising parameters. ***/
pPerScanCtx->eventCounter = pExtScanCtx->secSyncInfo.eventCounter;
pPerScanCtx->initEventCounter = pExtScanCtx->secSyncInfo.eventCounter;
pPerScanCtx->perInter = BB_US_TO_BB_TICKS(LCTR_PER_INTER_TO_US(pExtScanCtx->secSyncInfo.syncInter));
pPerScanCtx->sca = pExtScanCtx->secSyncInfo.sca;
pPerScanCtx->rxPhys = lctrConvertAuxPtrPhyToBbPhy(pExtScanCtx->priChAuxPtr.auxPhy);
@ -1043,13 +1137,17 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf
if (advAMatch == TRUE)
{
/* AdvA is received in the aux_adv_ind and pass the filtering, save info in the context. */
pPerScanCtx->advAddr = pExtScanCtx->extAdvHdr.advAddr;
pPerScanCtx->advAddrType = lctrMstExtScanIsr.advHdr.txAddrRnd;
pPerScanCtx->advAddr = peerIdAddr;
pPerScanCtx->advAddrType = peerIdAddrType;
pPerScanCtx->advSID = pExtScanCtx->extAdvHdr.sid;
/* Address to be used for sync transfer. */
pPerScanCtx->trsfAdvAddr = pExtScanCtx->extAdvHdr.advAddr;
pPerScanCtx->trsfAddrType = lctrMstExtScanIsr.advHdr.txAddrRnd;
}
uint32_t endTs = pAuxScan->auxStartTs +
BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxScan->auxRxPhyOptions, LL_ADV_HDR_LEN + pAuxScan->txAuxReqLen));
BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxScan->auxRxPhyOptions, pAuxScan->txAuxReqLen));
lctrMstPerScanOpCommit(pExtScanCtx, &pExtScanCtx->priChAuxPtr, &pExtScanCtx->secSyncInfo, pAuxScan->auxStartTs, endTs);
lctrMstPerScanIsr.syncWithSlave = FALSE;
}
@ -1059,7 +1157,12 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf
default:
LL_TRACE_WARN1("Received advertising PDU with invalid PDU type=%u", lctrMstExtScanIsr.advHdr.pduType);
lctrMstExtScanIsr.filtResult = TRUE;
return FALSE;
}
if (lctrMstExtScanIsr.filtResult == TRUE)
{
/* No more processing needed. */
return FALSE;
}
/*** ACAD processing. ***/
@ -1096,22 +1199,39 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf
Bda64ToBstream(pScanReqAdvA, pAuxScan->filtResults.peerAddr);
pExtScanCtx->reqPduHdr.rxAddrRnd = pAuxScan->filtResults.peerAddrRand;
/* Save adv address here and compare it with the one from aux_scan_rsp later. */
/* Save adv address here and compare it with the one from AUX_SCAN_RSP later. */
pExtScanCtx->data.scan.scanReqAdvAddr = pAuxScan->filtResults.peerAddr;
/* TODO need to check if targetA is present, check whether we need to generate a new RPA. */
/* Update scan request header with scanner's address. */
if (pExtScanCtx->scanParam.ownAddrType & LL_ADDR_IDENTITY_BIT)
{
bool_t localAddrRand = BB_BLE_PDU_FILT_FLAG_IS_SET(&pBle->pduFilt, LOCAL_ADDR_MATCH_RAND);
uint64_t localAddr = pBle->pduFilt.localAddrMatch;
if (BbBleResListReadLocal(pAuxScan->filtResults.peerIdAddrRand, pAuxScan->filtResults.peerIdAddr, &localAddr))
bool_t localAddrRand;
uint64_t localAddr;
if (pExtScanCtx->extAdvHdr.extHdrFlags & LL_EXT_HDR_TGT_ADDR_BIT)
{
localAddrRand = TRUE;
/* If peer is using directed advertising then use tgtA from the */
/* AUX_ADV_IND as our scanA in the auxiliary scan request. */
localAddrRand = lctrMstExtScanIsr.advHdr.rxAddrRnd;
localAddr = pExtScanCtx->extAdvHdr.tgtAddr;
/* Update the local RPA if the received one is RPA. */
if (BDA64_ADDR_IS_RPA(localAddr))
{
BbBleResListUpdateLocal(pAuxScan->filtResults.peerIdAddrRand, pAuxScan->filtResults.peerIdAddr, &localAddr);
}
}
uint8_t *pScanReqScanA = pExtScanCtx->reqBuf + LL_ADV_HDR_LEN;
Bda64ToBstream(pScanReqScanA, localAddr);
else
{
/* Otherwise, use local address, could be public, static random or RPA. */
localAddrRand = BB_BLE_PDU_FILT_FLAG_IS_SET(&pBle->pduFilt, LOCAL_ADDR_MATCH_RAND);
localAddr = pBle->pduFilt.localAddrMatch;
if (BbBleResListReadLocal(pAuxScan->filtResults.peerIdAddrRand, pAuxScan->filtResults.peerIdAddr, &localAddr))
{
localAddrRand = TRUE;
}
}
uint8_t *pAuxScanReqScanA = pExtScanCtx->reqBuf + LL_ADV_HDR_LEN;
Bda64ToBstream(pAuxScanReqScanA, localAddr);
pExtScanCtx->reqPduHdr.txAddrRnd = localAddrRand;
}
@ -1126,6 +1246,13 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf
lctrMstExtScanIsr.chainAdvMode = pExtScanCtx->extAdvHdr.advMode;
lctrMstExtScanIsr.chainExtraEventType = 0;
/*** Advertising report processing. ***/
/* Store relevant AUX_ADV_IND report data; submitted in the lctrMstDiscoverRxAuxChainPostProcessHandler(). */
pExtScanCtx->data.scan.auxAdvRpt.eventType = (pExtScanCtx->extAdvHdr.extHdrFlags & LL_EXT_HDR_TGT_ADDR_BIT) ?
LL_RPT_EVT_DIRECT_ADV_BIT : 0;
pExtScanCtx->data.scan.auxAdvRpt.rssi = pAuxScan->auxAdvRssi;
return txScanReq;
}
@ -1187,7 +1314,7 @@ bool_t lctrMstDiscoverRxAuxScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRspBu
/* scanReqAdvAddr is assigned when LL_PDU_ADV_SCAN_IND is received. */
if (pExtScanCtx->data.scan.scanReqAdvAddr != pAuxScan->filtResults.peerAddr)
{
LL_TRACE_WARN0("Ignore aux_scan_rsp since advAddr doesn't match the one sent in the aux_scan_req.");
LL_TRACE_WARN0("Ignore AUX_SCAN_RSP since advAddr doesn't match the one sent in the AUX_SCAN_REQ.");
lctrMstExtScanIsr.filtResult = TRUE;
return FALSE;
}
@ -1228,7 +1355,7 @@ uint32_t lctrMstDiscoverRxAuxChainHandler(BbOpDesc_t *pOp, const uint8_t *pChain
if (pChainBuf == NULL)
{
/* The report will be submitted in the lctrMstDiscoverRxAuxChainPostProcessHandler */
/* The report will be submitted in the lctrMstDiscoverRxAuxChainPostProcessHandler(). */
return 0;
}
@ -1314,7 +1441,7 @@ bool_t lctrMstDiscoverRxAuxChainPostProcessHandler(BbOpDesc_t *pOp, const uint8_
{
WSF_ASSERT(pExtScanCtx->data.scan.advRptState == LCTR_RPT_STATE_IN_PROGRESS);
pExtScanCtx->data.scan.advRpt.eventType |= LL_RPT_DATA_INC_TRUNC << LCTR_DATA_STATUS_SHIFT;
lctrExtAdvRptSubmit(pExtScanCtx);
lctrExtAdvRptSubmit(pExtScanCtx, &pExtScanCtx->data.scan.advRpt, &pExtScanCtx->data.scan.advRptState);
return FALSE;
}
@ -1339,10 +1466,35 @@ bool_t lctrMstDiscoverRxAuxChainPostProcessHandler(BbOpDesc_t *pOp, const uint8_
BbBlePduFiltResultsGetPeerIdAddr(&pAuxScan->filtResults, &peerIdAddr, &peerIdAddrType);
LlExtAdvReportInd_t * const pRpt = &pExtScanCtx->data.scan.advRpt;
if (pExtScanCtx->extAdvHdr.advMode & LCTR_ADV_MODE_SCAN_BIT)
{
/* Complete the AUX_ADV_IND report for Auxiliary Advertising Event. */
LlExtAdvReportInd_t * const pAuxAdvRpt = &pExtScanCtx->data.scan.auxAdvRpt;
if (!lctrExtAdvRptPack(pExtScanCtx, pExtScanCtx->data.scan.auxAdvRpt.eventType, &lctrMstExtScanIsr.advHdr,
peerIdAddr, peerIdAddrType , pAuxAdvRpt->rssi, NULL, pAuxAdvRpt))
{
LL_TRACE_WARN1("Invalid report parameters; do not receive CHAIN_IND, SID=%u", pExtScanCtx->extAdvHdr.sid);
pExtScanCtx->data.scan.auxAdvRptState = LCTR_RPT_STATE_IDLE;
result = FALSE;
break;
}
/* Update report properties for AUX_ADV_IND report. */
pAuxAdvRpt->eventType &= ~LL_RPT_EVT_SCAN_RSP_BIT;
pAuxAdvRpt->len = 0;
pAuxAdvRpt->pData = NULL;
/* Auxiliary Advertising report is ready; check filter and submit now. */
if (lctrExtAdvRptPend(pExtScanCtx, pAuxAdvRpt, &pExtScanCtx->data.scan.auxAdvRptState))
{
lctrExtAdvRptSubmit(pExtScanCtx, pAuxAdvRpt, &pExtScanCtx->data.scan.auxAdvRptState);
}
}
LlExtAdvReportInd_t * const pAdvRpt = &pExtScanCtx->data.scan.advRpt;
if (!lctrExtAdvRptPack(pExtScanCtx, lctrMstExtScanIsr.chainExtraEventType, &lctrMstExtScanIsr.advHdr,
peerIdAddr, peerIdAddrType , pAuxScan->auxAdvRssi, NULL,
pRpt))
peerIdAddr, peerIdAddrType, pAuxScan->auxAdvRssi, NULL, pAdvRpt))
{
/* Do not start receiving chain. */
LL_TRACE_WARN1("Invalid report parameters; do not receive CHAIN_IND, SID=%u", pExtScanCtx->extAdvHdr.sid);
@ -1350,10 +1502,9 @@ bool_t lctrMstDiscoverRxAuxChainPostProcessHandler(BbOpDesc_t *pOp, const uint8_
break;
}
if (!lctrExtAdvRptPend(pExtScanCtx))
if (!lctrExtAdvRptPend(pExtScanCtx, pAdvRpt, &pExtScanCtx->data.scan.advRptState))
{
/* Do not start receiving chain. */
LL_TRACE_WARN1("Filter report; do not receive CHAIN_IND, SID=%u", pExtScanCtx->extAdvHdr.sid);
result = FALSE;
break;
}
@ -1370,11 +1521,11 @@ bool_t lctrMstDiscoverRxAuxChainPostProcessHandler(BbOpDesc_t *pOp, const uint8_
} while (FALSE);
if ((result == FALSE) || /* Invalid packet, duplicate found or insufficient buffer. */
if ((result == FALSE) || /* Invalid packet, duplicate found or insufficient buffer. */
((lctrMstExtScanIsr.extAdvHdrFlags & LL_EXT_HDR_AUX_PTR_BIT) == 0)) /* No more auxiliary packet. */
{
/* End of auxiliary sequence. */
lctrExtAdvRptSubmit(pExtScanCtx);
lctrExtAdvRptSubmit(pExtScanCtx, &pExtScanCtx->data.scan.advRpt, &pExtScanCtx->data.scan.advRptState);
}
return result;
@ -1514,13 +1665,12 @@ bool_t lctrMstDiscoverRxLegacyScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRs
LlExtAdvReportInd_t * const pRpt = &pExtScanCtx->data.scan.advRpt;
if (lctrExtAdvRptPack(pExtScanCtx, 0, &advHdr,
peerIdAddr, peerIdAddrType, pScan->advRssi, pRspBuf,
pRpt))
peerIdAddr, peerIdAddrType, pScan->advRssi, pRspBuf, pRpt))
{
pRpt->secPhy = LL_PHY_NONE;
if (lctrExtAdvRptPend(pExtScanCtx))
if (lctrExtAdvRptPend(pExtScanCtx, pRpt, &pExtScanCtx->data.scan.advRptState))
{
lctrExtAdvRptSubmit(pExtScanCtx);
lctrExtAdvRptSubmit(pExtScanCtx, pRpt, &pExtScanCtx->data.scan.advRptState);
}
}
break;
@ -1562,10 +1712,14 @@ static void lctrMstExtDiscoverReschedule(lctrExtScanCtx_t *pExtScanCtx)
/*** Reschedule primary operation ***/
/* Recover primary scan BOD min duration so that its run will be guaranteed in BB. */
pOp->minDurUsec = LCTR_MIN_SCAN_USEC;
/* Reset due time to start of scan window. */
pOp->due = pExtScanCtx->scanWinStart;
if ((pScan->elapsedUsec + pOp->minDurUsec) < LCTR_BLE_TO_US(pExtScanCtx->scanParam.scanWindow))
if ((pExtScanCtx->scanParam.scanInterval != pExtScanCtx->scanParam.scanWindow) &&
((pScan->elapsedUsec + pOp->minDurUsec) < LCTR_BLE_TO_US(pExtScanCtx->scanParam.scanWindow)))
{
const uint32_t min = BB_US_TO_BB_TICKS(pScan->elapsedUsec);
const uint32_t max = BB_BLE_TO_BB_TICKS(pExtScanCtx->scanParam.scanWindow);
@ -1705,7 +1859,7 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp)
if (pPerScanCtx->cancelCreateSync)
{
lctrSendCreateSyncMsg(LCTR_CREATE_SYNC_MSG_TERMINATE);
lctrSendCreateSyncMsg(pPerScanCtx, LCTR_CREATE_SYNC_MSG_TERMINATE);
return;
}
@ -1718,6 +1872,22 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp)
return;
}
/* Failed to receive AUX_SYNC_IND within the first 6 periodic intervals. */
if (pPerScanCtx->firstPerAdvRcv == FALSE)
{
/* Make sure create sync failed event is sent out after 6th RX is over. */
uint16_t fastTermCnt = pPerScanCtx->bodAborted ? (LCTR_FAST_TERM_CNT + 1) : LCTR_FAST_TERM_CNT;
if ((pPerScanCtx->eventCounter - pPerScanCtx->initEventCounter) == (fastTermCnt - 1))
{
LL_TRACE_ERR0("!!! lctrMstPerScanEndOp: Failed to receive AUX_SYNC_IND within first 6 intervals.");
/* Notify create sync state machine with sync failed. */
lctrSendCreateSyncMsg(pPerScanCtx, LCTR_CREATE_SYNC_MSG_FAILED);
}
}
pPerScanCtx->bodAborted = FALSE;
/*** Reschedule operation ***/
uint16_t skip;
if (lctrMstPerScanIsr.syncWithSlave)
@ -1726,6 +1896,8 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp)
pPerScanCtx->lastAnchorPoint = lctrMstPerScanIsr.firstRxStartTs;
lctrMstPerScanIsr.syncWithSlave = FALSE;
pPerScanCtx->lastActiveEvent = pPerScanCtx->eventCounter;
/* Reset supervision timer. */
WsfTimerStartMs(&pPerScanCtx->tmrSupTimeout, pPerScanCtx->syncTimeOutMs);
if (pPerScanCtx->skipInter &&
pPerScanCtx->skipInter < BB_US_TO_BB_TICKS(pPerScanCtx->syncTimeOutMs * 1000))
@ -1748,12 +1920,27 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp)
while (TRUE)
{
/* Handle Acad if any pending actions are waiting. */
lctrAcadMsg_t acadMsg;
acadMsg.hdr.eventCtr = pPerScanCtx->eventCounter;
acadMsg.hdr.skip = skip;
acadMsg.hdr.handle = LCTR_GET_PER_SCAN_HANDLE(pPerScanCtx);
for (uint8_t acadId = 0; acadId < LCTR_ACAD_NUM_ID; acadId++)
{
if (pPerScanCtx->acadParams[acadId].hdr.state != LCTR_ACAD_STATE_DISABLED)
{
acadMsg.hdr.acadId = acadId;
lctrPerScanActProcessAcad(&acadMsg);
}
}
pPerScanCtx->eventCounter += skip;
numUnsyncIntervals += skip;
uint32_t unsyncTimeUsec = BB_TICKS_TO_US(pPerScanCtx->perInter * numUnsyncIntervals);
uint32_t caPpm = lctrCalcTotalAccuracy(pPerScanCtx->sca);
uint32_t wwTotalUsec = lctrCalcAuxAdvWindowWideningUsec(unsyncTimeUsec, caPpm);
uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, caPpm);
uint32_t wwTotal = BB_US_TO_BB_TICKS(wwTotalUsec);
uint32_t connInterUsec = BB_TICKS_TO_US(numUnsyncIntervals * pPerScanCtx->perInter);
uint32_t connInter = BB_US_TO_BB_TICKS(connInterUsec);
@ -1767,7 +1954,7 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp)
pBle->chan.chanIdx = lctrPeriodicSelectNextChannel(&pPerScanCtx->chanParam, pPerScanCtx->eventCounter);
if (SchInsertAtDueTime(pOp, NULL))
if (SchInsertAtDueTime(pOp, lctrPerScanResolveConflict))
{
break;
}
@ -1775,6 +1962,23 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp)
}
}
/*************************************************************************************************/
/*!
* \brief Abort an periodic scan operation in the master role.
*
* \param pOp Completed operation.
*
* \return None.
*/
/*************************************************************************************************/
void lctrMstPerScanAbortOp(BbOpDesc_t *pOp)
{
lctrPerScanCtx_t * const pPerScanCtx = pOp->pCtx;
pPerScanCtx->bodAborted = TRUE;
lctrMstPerScanEndOp(pOp);
}
/*************************************************************************************************/
/*!
* \brief Master periodic scan Rx periodic adv handler.
@ -1794,7 +1998,7 @@ uint32_t lctrMstPerScanRxPerAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBu
BbBleData_t * const pBle = pOp->prot.pBle;
lctrPerScanCtx_t * const pPerScanCtx = pOp->pCtx;
/* RX_TIMEOUT with pAdvBuf NULL. */
/* BB_STATUS_RX_TIMEOUT or BB_STATUS_CRC_FAILED with pAdvBuf NULL. */
if (pAdvBuf == NULL)
{
/* The report will be submitted in the lctrMstPerScanRxPerAdvPktPostHandler */
@ -1810,25 +2014,29 @@ uint32_t lctrMstPerScanRxPerAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBu
if (pPerScanCtx->firstPerAdvRcv == FALSE)
{
pPerScanCtx->firstPerAdvRcv = TRUE;
lctrMstPerScanIsr.filtResult = TRUE;
/* Notify create sync state machine with sync done. */
lctrSendCreateSyncMsg(LCTR_CREATE_SYNC_MSG_DONE);
lctrSendCreateSyncMsg(pPerScanCtx, LCTR_CREATE_SYNC_MSG_DONE);
/* Notify periodic scan state machine with sync established. */
lctrSendPerScanMsg(pPerScanCtx, LCTR_PER_SCAN_MSG_SYNC_ESTD);
if (lctrPerTransferSync.state == LCTR_TRANSFER_SYNC_STATE_DISCOVER)
{
pPerScanCtx->skipInter = pPerScanCtx->perInter * pPerScanCtx->skip;
}
}
/* Store anchor point. */
if ((!lctrMstPerScanIsr.syncWithSlave) &&
(pMstPerScan->perIsFirstTs == TRUE) &&
((status == BB_STATUS_SUCCESS) || (status == BB_STATUS_CRC_FAILED)))
(status == BB_STATUS_SUCCESS))
{
lctrMstPerScanIsr.firstRxStartTs = pMstPerScan->perStartTs;
lctrMstPerScanIsr.syncWithSlave = TRUE;
}
/*** ACAD processing. ***/
/* TODO route ACAD */
(void)pPerScanCtx->extAdvHdr.pAcad;
lctrMstAcadHandler(pPerScanCtx);
/*** Periodic Advertising Data processing. ***/
uint32_t auxOffsetUsec = 0;
@ -1867,18 +2075,15 @@ bool_t lctrMstPerScanRxPerAdvPktPostHandler(BbOpDesc_t *pOp, const uint8_t *pAdv
WsfTimerStartMs(&pPerScanCtx->tmrSupTimeout, pPerScanCtx->syncTimeOutMs);
}
/* RX_TIMEOUT with pAdvBuf NULL. */
/* BB_STATUS_RX_TIMEOUT or BB_STATUS_CRC_FAILED with pAdvBuf NULL. */
if (pAdvBuf == NULL)
{
/* Send truncated event. */
if (pPerScanCtx->advRptState == LCTR_RPT_STATE_IDLE)
if (pPerScanCtx->advRptState == LCTR_RPT_STATE_IN_PROGRESS && pPerScanCtx->state == LCTR_PER_SCAN_STATE_SYNC_ESTD)
{
if (lctrPerAdvRptPackTruncate(pOp, pAdvBuf, &pPerScanCtx->advRpt))
{
if (lctrPerAdvRptPend(pPerScanCtx))
{
lctrPerAdvRptSubmit(pPerScanCtx);
}
lctrPerAdvRptSubmit(pPerScanCtx);
}
}
return FALSE;
@ -1934,3 +2139,15 @@ bool_t lctrMstPerScanRxPerAdvPktPostHandler(BbOpDesc_t *pOp, const uint8_t *pAdv
}
return result;
}
/*************************************************************************************************/
/*!
* \brief Initialize periodic scan ISR context.
*
* \return None
*/
/*************************************************************************************************/
void lctrMstPerScanIsrInit(void)
{
lctrMstPerScanIsr.syncWithSlave = FALSE;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller slave advertising ISR callbacks.
* \file
* \brief Link layer controller slave advertising ISR callbacks.
*/
/*************************************************************************************************/
@ -310,7 +311,7 @@ void lctrSlvAdvEndOp(BbOpDesc_t *pOp)
}
#endif
}
SchBleCalcAdvOpDuration(pOp);
SchBleCalcAdvOpDuration(pOp, 0);
/*** Reschedule operation ***/
@ -325,7 +326,7 @@ void lctrSlvAdvEndOp(BbOpDesc_t *pOp)
do
{
if (lctrGetOpFlag(LL_OP_MODE_FLAG_ENA_ADV_DLY))
if (lmgrGetOpFlag(LL_OP_MODE_FLAG_ENA_ADV_DLY))
{
/* maxDelay is 16, it times 625 still fits in uint32_t. */
/* coverity[overflow_before_widen] */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller slave extended advertising ISR callbacks.
* \file
* \brief Link layer controller slave extended advertising ISR callbacks.
*/
/*************************************************************************************************/
@ -32,6 +33,7 @@
#include "wsf_assert.h"
#include "wsf_cs.h"
#include "wsf_msg.h"
#include "wsf_math.h"
#include "wsf_trace.h"
#include "util/bstream.h"
#include <string.h>
@ -80,6 +82,7 @@ void lctrSlvTxSetupExtAdvHandler(BbOpDesc_t *pOp, uint32_t advTxTime)
LL_TRACE_WARN1("AUX Offset does not meet T_MAFS, afsUsec=%u", (auxOffsetUsec - txAdvUsec));
}
/* The time pointed by auxPtr is earlier than aux bod due time by auxPtrOffsetUsec. */
lctrPackAuxPtr(pAdvSet, auxOffsetUsec, pAdvSet->auxChIdx, pAdvSet->pExtAdvAuxPtr);
}
}
@ -100,8 +103,15 @@ uint32_t lctrSlvTxSetupAuxAdvDataHandler(BbOpDesc_t *pOp, bool_t isChainInd)
BbBleData_t * const pBle = &pAdvSet->auxBleData;
BbBleSlvAuxAdvEvent_t * const pAuxAdv = &pBle->op.slvAuxAdv;
if ((isChainInd == TRUE) && (pAdvSet->auxOffsUsec == 0))
{
/* Tell the caller(BB) there is no more chained packet. */
return 0;
}
/* Store/use current AuxPtr values. */
uint32_t auxOffsUsec = pAdvSet->auxOffsUsec;
/* Due time of the aux packet is delayed by auxPtrOffsetUsec from the time specified by auxPtr. */
uint32_t auxOffsUsec = pAdvSet->auxOffsUsec + pLctrRtCfg->auxPtrOffsetUsec;
pBle->chan.chanIdx = pAdvSet->auxChIdx;
if (!isChainInd)
@ -110,7 +120,6 @@ uint32_t lctrSlvTxSetupAuxAdvDataHandler(BbOpDesc_t *pOp, bool_t isChainInd)
pAdvSet->advData.txOffs = 0;
/* Compute new AuxPtr values. */
pAdvSet->auxChHopInc = lctrComputeHopInc();
lctrSelectNextAuxChannel(pAdvSet);
pAuxAdv->txAuxAdvPdu[0].len = lctrPackAuxAdvIndPdu(pAdvSet, pAdvSet->auxAdvHdrBuf, &pAdvSet->advData, FALSE);
@ -210,8 +219,15 @@ uint32_t lctrSlvTxSetupAuxScanRspDataHandler(BbOpDesc_t *pOp, bool_t isChainInd)
BbBleData_t * const pBle = &pAdvSet->auxBleData;
BbBleSlvAuxAdvEvent_t * const pAuxAdv = &pBle->op.slvAuxAdv;
if ((isChainInd == TRUE) && (pAdvSet->auxOffsUsec == 0))
{
/* Tell the caller(BB) there is no more chained packet. */
return 0;
}
/* Store/use current AuxPtr values. */
uint32_t auxOffsUsec = pAdvSet->auxOffsUsec;
/* Due time of the aux packet is delayed by auxPtrOffsetUsec from the time specified by auxPtr. */
uint32_t auxOffsUsec = pAdvSet->auxOffsUsec + pLctrRtCfg->auxPtrOffsetUsec;
pBle->chan.chanIdx = pAdvSet->auxChIdx;
if (!isChainInd)
@ -379,7 +395,8 @@ bool_t lctrSlvRxAuxConnReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf)
if ((lctrAdvIsrAdvHdr.pduType == LL_PDU_AUX_CONNECT_REQ) &&
(lctrMsgDispTbl[LCTR_DISP_CONN]) &&
(lctrAdvIsrAdvHdr.len == LL_CONN_IND_PDU_LEN))
(lctrAdvIsrAdvHdr.len == LL_CONN_IND_PDU_LEN) &&
(lctrValidateConnIndPdu(&connInd)))
{
/*** Extended advertising event filtering. ***/
@ -428,6 +445,22 @@ bool_t lctrSlvRxAuxConnReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf)
Bda64ToBstream(pAuxConnRspAdvA, localAddr);
pAdvSet->rspPduHdr.txAddrRnd = localAddrRand;
#if (LL_ENABLE_TESTER)
if (llTesterCb.auxRsp.len)
{
/* Overriding AUX_CONNECT_RSP from test script. */
memcpy(pAuxConnRspAdvA, llTesterCb.auxRsp.buf + LL_ADV_HDR_LEN, llTesterCb.auxRsp.len - LL_ADV_HDR_LEN); /* Exclude LL_ADV_HDR_LEN */
uint16_t hdr;
uint8_t *ptr = llTesterCb.auxRsp.buf;
BSTREAM_TO_UINT16(hdr, ptr);
pAdvSet->rspPduHdr.txAddrRnd = (hdr >> LCTR_ADV_HDR_TX_ADD_SHIFT) & 0x0001;
pAdvSet->rspPduHdr.rxAddrRnd = (hdr >> LCTR_ADV_HDR_RX_ADD_SHIFT) & 0x0001;
}
#endif
lctrPackAdvbPduHdr(pAdvSet->auxRspHdrBuf, &pAdvSet->rspPduHdr);
/* Stop advertising. */
@ -444,7 +477,7 @@ bool_t lctrSlvRxAuxConnReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf)
pAdvSet->connIndEndTs = pAuxAdv->auxReqStartTs +
/* N.B.: May round to an earlier time. */
BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxAdv->auxRxPhyOptions,
LL_CONN_IND_PDU_LEN));
LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN));
sendRsp = TRUE;
}
@ -546,6 +579,55 @@ void lctrSlvRxLegacyReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBu
}
}
/*************************************************************************************************/
/*!
* \brief Acad handler for post op.
*
* \param pAdvSet Advertising Set.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSlvAcadHandler(lctrAdvSet_t *pAdvSet)
{
for (uint8_t acadId = 0; acadId < LCTR_ACAD_NUM_ID; acadId++)
{
lctrAcadParam_t *pData = &pAdvSet->acadParams[acadId];
if (pData->hdr.state != LCTR_ACAD_STATE_ENABLED)
{
continue;
}
/* coverity[dead_error_condition] */
switch(acadId)
{
case LCTR_ACAD_ID_CHAN_MAP_UPDATE:
{
if (pData->chanMapUpdate.instant == pAdvSet->perParam.perEventCounter)
{
/* Update the channel map. */
pAdvSet->perParam.perChanParam.chanMask = pData->chanMapUpdate.chanMask;
LmgrBuildRemapTable(&pAdvSet->perParam.perChanParam);
/* Disable the ACAD. */
lctrSlvAcadExecuteSm(pAdvSet, LCTR_ACAD_MSG_CHAN_UPDATE_FINISH);
/* If the most updated channel map does not match the current mask, start a new update. */
if (pAdvSet->perParam.perChanParam.chanMask != pAdvSet->perParam.updChanMask)
{
lctrSlvAcadExecuteSm(pAdvSet, LCTR_ACAD_MSG_CHAN_UPDATE);
}
}
break;
}
default:
break;
}
}
}
/**************************************************************************************************
Functions: BOD handlers
**************************************************************************************************/
@ -592,7 +674,7 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp)
{
/* Ensure all BODs are de-scheduled. */
bool_t result = SchRemove(&pAdvSet->auxAdvBod);
WSF_ASSERT(result); /* Non-head elements are always removeable. */
(void)result;
}
else
@ -627,7 +709,7 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp)
pAdvSet->advData.alt.ext.modified = FALSE;
memcpy(pAdvSet->advData.pBuf, pAdvSet->advData.alt.ext.buf, pAdvSet->advData.alt.ext.len);
pAdvSet->advData.len = pAdvSet->advData.alt.ext.len;
pAdvSet->advData.did = pAdvSet->advData.alt.ext.did;
pAdvSet->param.advDID = pAdvSet->advData.alt.ext.did;
pAdvSet->advData.fragPref = pAdvSet->advData.alt.ext.fragPref;
/* Advertising offloading to auxiliary channel. */
@ -649,6 +731,13 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp)
lctrSlvAuxNonConnNonScanBuildOp(pAdvSet);
pAdvSet->auxBodUsed = TRUE;
}
/* Update Data ID when periodic advertising is enabled or disabled. */
if ((pAdvSet->didPerUpdate == TRUE) && (pAdvSet->auxBodUsed == FALSE))
{
pAdvSet->param.advDID = pAdvSet->advData.alt.ext.did;
pAdvSet->didPerUpdate = FALSE;
}
}
else /* (pAdvSet->param.advEventProp & LL_ADV_EVT_PROP_LEGACY_ADV_BIT) */
{
@ -749,7 +838,7 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp)
}
}
SchBleCalcAdvOpDuration(pOp);
SchBleCalcAdvOpDuration(pOp, 0);
/*** Reschedule operation ***/
const uint8_t LEGACY_HIGH_DUTY = (LL_ADV_EVT_PROP_LEGACY_ADV_BIT | LL_ADV_EVT_PROP_HIGH_DUTY_ADV_BIT |
@ -792,41 +881,51 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp)
}
else
{
bool_t result;
uint32_t totalDuration = pOp->minDurUsec;
uint32_t prefInterval;
do
if (lmgrGetOpFlag(LL_OP_MODE_FLAG_ENA_ADV_DLY))
{
if (lctrGetOpFlag(LL_OP_MODE_FLAG_ENA_ADV_DLY))
{
pOp->due += BB_BLE_TO_BB_TICKS(lctrCalcAdvDelay());
}
pOp->due += BB_BLE_TO_BB_TICKS(lctrCalcAdvDelay());
}
if (pAdvSet->param.priAdvInterMin == pAdvSet->param.priAdvInterMax)
{
pOp->due += pAdvSet->param.priAdvInterMin;
result = SchInsertAtDueTime(pOp, NULL);
}
else
{
result = SchInsertEarlyAsPossible(pOp,
pAdvSet->param.priAdvInterMin,
pAdvSet->param.priAdvInterMax);
if (!result)
{
pOp->due += pAdvSet->param.priAdvInterMax;
}
}
if (pAdvSet->auxBodUsed)
{
totalDuration += pAdvSet->auxAdvBod.minDurUsec;
}
if (!result)
{
LL_TRACE_WARN1("!!! ExtAdv schedule conflict at due=%u", pOp->due);
LL_TRACE_WARN1("!!! handle=%u", pAdvSet->handle);
}
/* Pick an interval so that advertising(primary + aux) BOD would take less than half of total bandwidth. */
prefInterval = WSF_MAX(BB_US_TO_BB_TICKS(totalDuration * 2), pAdvSet->param.priAdvInterMin);
} while (!result);
if (pAdvSet->advBodAbort)
{
pAdvSet->advBodAbort = FALSE;
(void)SchInsertEarlyAsPossible(pOp, 0, LCTR_SCH_MAX_SPAN);
}
else
{
(void)SchInsertEarlyAsPossible(pOp, prefInterval, LCTR_SCH_MAX_SPAN);
}
}
}
/*************************************************************************************************/
/*!
* \brief Abort an extended advertising primary channel operation.
*
* \param pOp Completed operation.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSlvExtAdvAbortOp(BbOpDesc_t *pOp)
{
lctrAdvSet_t * const pAdvSet = pOp->pCtx;
pAdvSet->advBodAbort = TRUE;
lctrSlvExtAdvEndOp(pOp);
}
/*************************************************************************************************/
/*!
* \brief End an extended advertising secondary channel operation.
@ -867,8 +966,8 @@ void lctrSlvAuxAdvEndOp(BbOpDesc_t *pOp)
{
/* Ensure all BODs are de-scheduled. */
bool_t result = SchRemove(&pAdvSet->advBod);
WSF_ASSERT(result); /* Non-head elements are always removeable. */
(void)result;
(void)result; /* It is possible to fail to remove BOD when BOD is not in the list(scheduling conflict) or there is not enough time to remove the BOD. */
}
else
{
@ -897,7 +996,7 @@ void lctrSlvAuxAdvEndOp(BbOpDesc_t *pOp)
pAdvSet->advData.alt.ext.modified = FALSE;
memcpy(pAdvSet->advData.pBuf, pAdvSet->advData.alt.ext.buf, pAdvSet->advData.alt.ext.len);
pAdvSet->advData.len = pAdvSet->advData.alt.ext.len;
pAdvSet->advData.did = pAdvSet->advData.alt.ext.did;
pAdvSet->param.advDID = pAdvSet->advData.alt.ext.did;
pAdvSet->advData.fragPref = pAdvSet->advData.alt.ext.fragPref;
/* Update superior PDU. */
@ -917,14 +1016,28 @@ void lctrSlvAuxAdvEndOp(BbOpDesc_t *pOp)
pAdvSet->scanRspData.alt.ext.modified = FALSE;
memcpy(pAdvSet->scanRspData.pBuf, pAdvSet->scanRspData.alt.ext.buf, pAdvSet->scanRspData.alt.ext.len);
pAdvSet->scanRspData.len = pAdvSet->scanRspData.alt.ext.len;
pAdvSet->scanRspData.did = pAdvSet->scanRspData.alt.ext.did;
pAdvSet->param.advDID = pAdvSet->scanRspData.alt.ext.did;
pAdvSet->scanRspData.fragPref = pAdvSet->scanRspData.alt.ext.fragPref;
}
/* Update Data ID when periodic advertising is enabled or disabled. */
if (pAdvSet->didPerUpdate == TRUE)
{
pAdvSet->param.advDID = pAdvSet->advData.alt.ext.did;
pAdvSet->didPerUpdate = FALSE;
}
/*** Update operation ***/
if (BbBleResListIsRpaUpd(pAdvSet->param.peerAddrType, pAdvSet->param.peerAddr))
{
/* Update AUX_ADV_IND in case advA or/and tgtA are changed, AUX_ADV_IND for non-conn and non-scan will be updated again if necessary in the lctrSlvTxSetupAuxAdvDataHandler. */
BbBleSlvAuxAdvEvent_t * const pAuxAdv = &pBle->op.slvAuxAdv;
/* Updated in lctrSlvTxSetupAuxAdvDataHandler(). */
pAdvSet->advData.txOffs = 0;
pAuxAdv->txAuxAdvPdu[0].len = lctrPackAuxAdvIndPdu(pAdvSet, pAdvSet->auxAdvHdrBuf, &pAdvSet->advData, FALSE);
pAuxAdv->txAuxAdvPdu[1].pBuf = pAdvSet->advData.pBuf;
pAuxAdv->txAuxAdvPdu[1].len = pAdvSet->advData.len;
}
/*** Reschedule operation ***/
lctrSlvAuxRescheduleOp(pAdvSet, pOp);
@ -985,6 +1098,10 @@ void lctrSlvPeriodicAdvEndOp(BbOpDesc_t *pOp)
pOp->due += pAdvSet->perParam.perAdvInter;
pAdvSet->perParam.perEventCounter++;
/*** Process ACAD fields if necessary ***/
lctrSlvAcadHandler(pAdvSet);
pAdvSet->perParam.perChIdx = lctrPeriodicSelectNextChannel(&pAdvSet->perParam.perChanParam,
pAdvSet->perParam.perEventCounter);
@ -995,3 +1112,22 @@ void lctrSlvPeriodicAdvEndOp(BbOpDesc_t *pOp)
LL_TRACE_WARN1("!!! Periodic advertising schedule conflict eventCounter=%u", pAdvSet->perParam.perEventCounter);
}
}
/*************************************************************************************************/
/*!
* \brief Abort an periodic advertising channel operation.
*
* \param pOp Aborted operation.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSlvPeriodicAdvAbortOp(BbOpDesc_t *pOp)
{
WSF_ASSERT(pOp->protId == BB_PROT_BLE);
WSF_ASSERT(pOp->prot.pBle->chan.opType == BB_BLE_OP_SLV_PER_ADV_EVENT);
LL_TRACE_WARN1("!!! Periodic advertising BOD aborted, eventCounter=%u", ((lctrAdvSet_t *)pOp->pCtx)->perParam.perEventCounter);
lctrSlvPeriodicAdvEndOp(pOp);
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,14 +16,15 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller slave connection ISR callbacks.
* \file
* \brief Link layer controller slave connection ISR callbacks.
*/
/*************************************************************************************************/
#include "lctr_int_conn.h"
#include "lmgr_api_conn.h"
#include "bb_ble_api.h"
#include "bb_drv.h"
#include "pal_bb.h"
#include "wsf_assert.h"
#include "wsf_math.h"
#include "wsf_msg.h"
@ -270,7 +271,7 @@ uint16_t lctrSetupForTx(lctrConnCtx_t *pCtx, uint8_t rxStatus, bool_t reqTx)
pCtx->txHdr.md || /* peer is informed more data is pending */
reqTx)
{
BbBleDrvTxBufDesc_t bbDesc[3];
PalBbBleTxBufDesc_t bbDesc[3];
uint8_t bbDescCnt;
bool_t md;
@ -329,7 +330,7 @@ uint16_t lctrSetupForTx(lctrConnCtx_t *pCtx, uint8_t rxStatus, bool_t reqTx)
/* Transmit empty PDU. */
lctrBuildEmptyPdu(pCtx);
BbBleDrvTxBufDesc_t desc = {.pBuf = lctrConnIsr.emptyPdu, .len = sizeof(lctrConnIsr.emptyPdu)};
PalBbBleTxBufDesc_t desc = {.pBuf = lctrConnIsr.emptyPdu, .len = sizeof(lctrConnIsr.emptyPdu)};
BbBleTxData(&desc, 1);
numTxBytes = desc.len;
@ -397,7 +398,7 @@ bool_t lctrExceededMaxDur(lctrConnCtx_t *pCtx, uint32_t ceStart, uint32_t pendDu
return FALSE;
}
const uint32_t curTime = BbDrvGetCurrentTime();
const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK);
const uint32_t setupDelayUsec = BbGetSchSetupDelayUs();
uint32_t availCeUsec = LCTR_CONN_IND_US(pCtx->connInterval);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master connection ISR callbacks.
* \file
* \brief Link layer controller master connection ISR callbacks.
*/
/*************************************************************************************************/
@ -56,7 +57,7 @@ WSF_CT_ASSERT((BB_FIXED_DATA_PKT_LEN == 0) ||
**************************************************************************************************/
#if (LL_ENABLE_TESTER)
void LctrProcessRxTxAck(lctrConnCtx_t *pCtx, uint8_t *pRxBuf, uint8_t **pNextRxBuf, bool_t *pTxPduIsAcked);
extern void LctrProcessRxTxAck(lctrConnCtx_t *pCtx, uint8_t *pRxBuf, uint8_t **pNextRxBuf, bool_t *pTxPduIsAcked);
#endif
/*************************************************************************************************/
@ -294,6 +295,11 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp)
SchRmSetReference(LCTR_GET_CONN_HANDLE(pCtx));
if (pCtx->checkCisTerm)
{
(pCtx->checkCisTerm)(LCTR_GET_CONN_HANDLE(pCtx));
}
/* Terminate connection */
if (lctrCheckForLinkTerm(pCtx))
{
@ -312,10 +318,9 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp)
uint16_t ceOffset;
#if (LL_ENABLE_TESTER)
if (llTesterCb.eventCounterOffset)
if (llTesterCb.eventCounterOverride == TRUE)
{
ceOffset = pCtx->eventCounter +
llTesterCb.eventCounterOffset + 1; /* +1 for next CE */
ceOffset = llTesterCb.eventCounterOffset + 1; /* +1 for next CE */
}
else
#endif
@ -327,18 +332,8 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp)
}
pCtx->connUpd.instant = pCtx->eventCounter + ceOffset;
uint32_t rsvnOffs[SCH_RM_MAX_RSVN];
memset(&rsvnOffs[0], 0, sizeof(rsvnOffs));
if (lctrGetConnOffsetsCback)
{
lctrGetConnOffsetsCback(rsvnOffs, pOp->due);
}
if (lctrGetPerOffsetsCback)
{
lctrGetPerOffsetsCback(&rsvnOffs[LL_MAX_CONN], pOp->due);
}
/* Use smallest txWindowOffset (i.e. 0) to minimize data loss. */
uint32_t txWinOffsetUsec = SchRmGetOffsetUsec(rsvnOffs, 0, LCTR_GET_CONN_HANDLE(pCtx));
uint32_t txWinOffsetUsec = SchRmGetOffsetUsec(0, LCTR_GET_CONN_HANDLE(pCtx), pOp->due);
pCtx->connUpd.txWinOffset = LCTR_US_TO_CONN_IND(txWinOffsetUsec);
lctrPackConnUpdInd(pPdu, &pCtx->connUpd);
@ -347,6 +342,25 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp)
/* else retry at next lctrMstConnEndOp() event. */
}
if (pCtx->sendPerSync)
{
pCtx->sendPerSync = FALSE;
if (pCtx->perSyncSrc == LCTR_SYNC_SRC_SCAN)
{
if (lctrSendPerSyncFromScanFn)
{
lctrSendPerSyncFromScanFn(pCtx);
}
}
else /* (pCtx->perSyncSrc == LCTR_SYNC_SRC_BCST) */
{
if (lctrSendPerSyncFromBcstFn)
{
lctrSendPerSyncFromBcstFn(pCtx);
}
}
}
/*** Update for next operation ***/
uint32_t anchorPoint = pOp->due;
@ -375,21 +389,15 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp)
#if (LL_ENABLE_TESTER)
if (llTesterCb.connIntervalUs)
{
connInter = BB_US_TO_BB_TICKS(llTesterCb.connIntervalUs);
dueOffsetUsec = llTesterCb.connIntervalUs - BB_TICKS_TO_US(connInter);
connInterUsec = (numIntervals * llTesterCb.connIntervalUs) + anchorPointOffsetUsec;
connInter = BB_US_TO_BB_TICKS(connInterUsec);
dueOffsetUsec = 0;
}
#endif
/* Advance to next interval. */
pOp->due = anchorPoint + connInter;
pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0);
#if (LL_ENABLE_TESTER)
if (llTesterCb.connIntervalUs)
{
pOp->due = anchorPoint + BB_US_TO_BB_TICKS(llTesterCb.connIntervalUs);
pOp->dueOffsetUsec = 0;
}
#endif
if ((pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) &&
(pCtx->eventCounter == pCtx->connUpd.instant))

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller slave connection ISR callbacks.
* \file
* \brief Link layer controller slave connection ISR callbacks.
*/
/*************************************************************************************************/
@ -33,23 +34,13 @@
#include "wsf_os.h"
#include "wsf_trace.h"
#include "util/bstream.h"
#include "bb_drv.h"
#include "pal_bb.h"
#include <string.h>
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! \brief Slave connection ISR control block (used only by active operation). */
static struct
{
uint8_t consCrcFailed; /*!< Number of consecutive CRC failures. */
bool_t syncWithMaster; /*!< Flag indicating synchronize packet received from master. */
uint8_t syncConnHandle; /*!< Connection handle where synchronized packet was received. */
bool_t rxFromMaster; /*!< At least one successful packet received from master. */
uint32_t firstRxStartTs; /*!< Timestamp of the first received frame regardless of CRC error. */
} lctrSlvConnIsr;
/*! \brief Assert BB meets data PDU requirements. */
WSF_CT_ASSERT((BB_FIXED_DATA_PKT_LEN == 0) ||
(BB_FIXED_DATA_PKT_LEN >= LCTR_DATA_PDU_MAX_LEN));
@ -59,7 +50,7 @@ WSF_CT_ASSERT((BB_FIXED_DATA_PKT_LEN == 0) ||
**************************************************************************************************/
#if (LL_ENABLE_TESTER)
void LctrProcessRxTxAck(lctrConnCtx_t *pCtx, uint8_t *pRxBuf, uint8_t **pNextRxBuf, bool_t *pTxPduIsAcked);
extern void LctrProcessRxTxAck(lctrConnCtx_t *pCtx, uint8_t *pRxBuf, uint8_t **pNextRxBuf, bool_t *pTxPduIsAcked);
#endif
/*************************************************************************************************/
@ -74,7 +65,7 @@ void LctrProcessRxTxAck(lctrConnCtx_t *pCtx, uint8_t *pRxBuf, uint8_t **pNextRxB
static void lctrSlvAbortSlvLatency(BbOpDesc_t *pOp)
{
lctrConnCtx_t * const pCtx = pOp->pCtx;
const uint32_t curTime = BbDrvGetCurrentTime();
const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK);
uint32_t connInterval = BB_US_TO_BB_TICKS(LCTR_CONN_IND_US(pCtx->connInterval));
uint32_t count = 0;
@ -118,12 +109,13 @@ static void lctrSlvAbortSlvLatency(BbOpDesc_t *pOp)
/*!
* \brief Update a connection operation.
*
* \param pCtx Connection context.
* \param pCtx Connection context.
* \param ignoreOffset txWinOffset will be ignored if TRUE.
*
* \return None.
*/
/*************************************************************************************************/
static void lctrSlvConnUpdateOp(lctrConnCtx_t *pCtx)
static void lctrSlvConnUpdateOp(lctrConnCtx_t *pCtx, bool_t ignoreOffset)
{
/* Pre-resolve common structures for efficient access. */
BbOpDesc_t * const pOp = &pCtx->connBod;
@ -156,28 +148,29 @@ static void lctrSlvConnUpdateOp(lctrConnCtx_t *pCtx)
pCtx->supTimeoutMs = LCTR_CONN_IND_TO_MS(pConnUpdInd->timeout);
/*** General setup ***/
if (ignoreOffset == FALSE)
{
const uint32_t txWinOffsetUsec = LCTR_CONN_IND_US(pConnUpdInd->txWinOffset);
const uint32_t txWinOffset = BB_US_TO_BB_TICKS(txWinOffsetUsec);
const uint32_t txWinSizeUsec = LCTR_CONN_IND_US(pConnUpdInd->txWinSize);
const uint32_t wwTxWinOffsetUsec = lctrCalcWindowWideningUsec((txWinOffsetUsec + txWinSizeUsec), pCtx->data.slv.totalAcc);
const uint32_t wwTxWinOffset = BB_US_TO_BB_TICKS(wwTxWinOffsetUsec);
const uint32_t txWinOffsetUsec = LCTR_CONN_IND_US(pConnUpdInd->txWinOffset);
const uint32_t txWinOffset = BB_US_TO_BB_TICKS(txWinOffsetUsec);
const uint32_t txWinSizeUsec = LCTR_CONN_IND_US(pConnUpdInd->txWinSize);
const uint32_t wwTxWinOffsetUsec = lctrCalcIntervalWindowWideningUsec(pCtx, txWinOffsetUsec);
const uint32_t wwTxWinOffset = BB_US_TO_BB_TICKS(wwTxWinOffsetUsec);
/* txWinOffset is relative to anchorPoint. */
pCtx->data.slv.anchorPoint += txWinOffset;
/* txWinOffset is relative to anchorPoint. */
pCtx->data.slv.anchorPoint += txWinOffset;
/* Add additional time due to Tx window offset and subtract WW due to Tx window offset. */
pOp->due += txWinOffset - wwTxWinOffset;
/* Add additional time due to Tx window offset and subtract WW due to Tx window offset. */
pOp->due += txWinOffset - wwTxWinOffset;
pCtx->data.slv.txWinSizeUsec = txWinSizeUsec;
pCtx->data.slv.txWinSizeUsec = txWinSizeUsec;
/* Add additional time due to Tx window size and WW due to Tx window offset. */
pOp->minDurUsec += txWinSizeUsec + wwTxWinOffsetUsec;
/* Add additional time due to Tx window size and WW due to Tx window offset. */
pOp->minDurUsec += txWinSizeUsec + wwTxWinOffsetUsec;
/*** BLE general setup ***/
pConn->rxSyncDelayUsec += txWinSizeUsec + (wwTxWinOffsetUsec << 1);
/*** BLE general setup ***/
pConn->rxSyncDelayUsec += txWinSizeUsec + (wwTxWinOffsetUsec << 1);
}
/* Unconditionally reset supervision timer with transitional value.
* connIntervalOld + supervisionTimeoutNew */
WsfTimerStartMs(&pCtx->tmrSupTimeout, LCTR_CONN_IND_MS(connIntervalOld) + pCtx->supTimeoutMs);
@ -260,6 +253,23 @@ static void lctrSlvPhyUpdateOp(lctrConnCtx_t *pCtx)
LL_TRACE_INFO2(" >>> PHY updated, handle=%u, eventCounter=%u <<<", LCTR_GET_CONN_HANDLE(pCtx), pCtx->eventCounter);
}
/*************************************************************************************************/
/*!
* \brief Initialize connection event resources.
*
* \param pCtx Connection context.
*
* \return None.
*/
/*************************************************************************************************/
static void lctrSlvInitConnIsr(lctrConnCtx_t *pCtx)
{
pCtx->data.slv.consCrcFailed = 0;
pCtx->data.slv.syncWithMaster = FALSE;
pCtx->data.slv.rxFromMaster = FALSE;
pCtx->data.slv.firstRxStartTs = 0;
}
/*************************************************************************************************/
/*!
* \brief Begin a connection operation.
@ -280,6 +290,7 @@ void lctrSlvConnBeginOp(BbOpDesc_t *pOp)
if (lctrCheckForLinkTerm(pCtx))
{
BbSetBodTerminateFlag();
return;
}
if (pLctrVsHdlrs && pLctrVsHdlrs->ceSetup)
@ -288,11 +299,7 @@ void lctrSlvConnBeginOp(BbOpDesc_t *pOp)
}
/*** Initialize connection event resources. ***/
lctrSlvConnIsr.consCrcFailed = 0;
lctrSlvConnIsr.syncWithMaster = FALSE;
lctrSlvConnIsr.syncConnHandle = 0xFF;
lctrSlvConnIsr.rxFromMaster = FALSE;
lctrSlvInitConnIsr(pCtx);
/*** Setup receiver ***/
@ -344,15 +351,17 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
if (pCtx->data.slv.abortSlvLatency)
{
lctrSlvAbortSlvLatency(pOp);
pCtx->data.slv.abortSlvLatency = FALSE;
}
pCtx->rssi = pConn->rssi;
if ((lctrSlvConnIsr.syncWithMaster) && (lctrSlvConnIsr.syncConnHandle == LCTR_GET_CONN_HANDLE(pCtx)))
if (pCtx->data.slv.syncWithMaster)
{
/* Re-sync to master's clock. */
pCtx->data.slv.anchorPoint = lctrSlvConnIsr.firstRxStartTs;
pCtx->data.slv.anchorPoint = pCtx->data.slv.firstRxStartTs;
pCtx->data.slv.lastActiveEvent = pCtx->eventCounter + 1;
pCtx->svtState = LCTR_SVT_STATE_IDLE;
/* Tx window no longer needed. */
pCtx->data.slv.txWinSizeUsec = 0;
@ -361,19 +370,24 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
pCtx->data.slv.unsyncedTime = 0;
}
if (!pCtx->connEst && (lctrSlvConnIsr.rxFromMaster || (lctrSlvConnIsr.consCrcFailed > 0)))
if (!pCtx->connEst && (pCtx->data.slv.rxFromMaster || (pCtx->data.slv.consCrcFailed > 0)))
{
lctrStoreConnTimeoutTerminateReason(pCtx);
WsfTimerStartMs(&pCtx->tmrSupTimeout, pCtx->supTimeoutMs);
pCtx->connEst = TRUE;
}
else if (lctrSlvConnIsr.rxFromMaster)
else if (pCtx->data.slv.rxFromMaster)
{
/* Reset supervision timer. */
WsfTimerStartMs(&pCtx->tmrSupTimeout, pCtx->supTimeoutMs);
}
if (pCtx->checkCisTerm)
{
(pCtx->checkCisTerm)(LCTR_GET_CONN_HANDLE(pCtx));
}
/* Terminate connection */
if (lctrCheckForLinkTerm(pCtx))
{
@ -396,6 +410,34 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
lctrSendConnMsg(pCtx, LCTR_CONN_SLV_INIT_STARTUP_LLCP);
}
if (pCtx->sendPerSync)
{
pCtx->sendPerSync = FALSE;
if (pCtx->perSyncSrc == LCTR_SYNC_SRC_SCAN)
{
if (lctrSendPerSyncFromScanFn)
{
lctrSendPerSyncFromScanFn(pCtx);
}
}
else /* (pCtx->perSyncSrc == LCTR_SYNC_SRC_BCST) */
{
if (lctrSendPerSyncFromBcstFn)
{
lctrSendPerSyncFromBcstFn(pCtx);
}
}
}
/* Slave received connection update on the instant. */
/* Immediately use that packet as the new anchor point and do not apply txWinOffset and txWinSize. */
if ((pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) && lctrSlvCheckConnUpdInstant(pCtx) &&
(pCtx->eventCounter == pCtx->connUpd.instant))
{
lctrSlvConnUpdateOp(pCtx, TRUE);
LL_TRACE_WARN1("Received connection update at instant, applying immediately at CE=%d", pCtx->eventCounter);
}
/*** Update for next operation ***/
uint16_t numUnsyncIntervals = pCtx->eventCounter - pCtx->data.slv.lastActiveEvent + 1;
@ -406,7 +448,8 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
lctrGetConnOpFlag(pCtx, LL_OP_MODE_FLAG_ENA_SLV_LATENCY) &&
(pCtx->maxLatency &&
pCtx->data.slv.initAckRcvd &&
lctrSlvConnIsr.rxFromMaster &&
pCtx->data.slv.rxFromMaster &&
(WsfQueueEmpty(&pCtx->txArqQ)) &&
(pCtx->state != LCTR_CONN_STATE_TERMINATING)))
{
if ((pCtx->llcpActiveProc == LCTR_PROC_INVALID))
@ -418,36 +461,39 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
/* Still apply the slave latency if the instant is not reached for the following LLCPs. */
if ((pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) && lctrSlvCheckConnUpdInstant(pCtx))
{
if ((uint16_t)(pCtx->connUpd.instant - pCtx->eventCounter) >= (pCtx->maxLatency + 1))
if ((uint16_t)(pCtx->connUpd.instant - pCtx->eventCounter) > (pCtx->maxLatency + 1))
{
numSkipCe = pCtx->maxLatency;
}
else
else if ((pCtx->connUpd.instant - pCtx->eventCounter) > 1)
{
numSkipCe = pCtx->connUpd.instant - pCtx->eventCounter - 1;
/* Serve CE of (instant - 1) so that connection update is applied in the end callback of CE(instant - 1). */
numSkipCe = pCtx->connUpd.instant - pCtx->eventCounter - 2;
}
}
else if ((pCtx->llcpActiveProc == LCTR_PROC_CMN_CH_MAP_UPD) &&
(pCtx->cmnState == LCTR_CMN_STATE_BUSY))
{
if ((uint16_t)(pCtx->chanMapUpd.instant - pCtx->eventCounter) >= (pCtx->maxLatency + 1))
if ((uint16_t)(pCtx->chanMapUpd.instant - pCtx->eventCounter) > (pCtx->maxLatency + 1))
{
numSkipCe = pCtx->maxLatency;
}
else
else if ((pCtx->chanMapUpd.instant - pCtx->eventCounter) > 1)
{
numSkipCe = pCtx->chanMapUpd.instant - pCtx->eventCounter - 1;
/* Serve CE of (instant - 1) so that new channe map is applied in the end callback of CE(instant - 1). */
numSkipCe = pCtx->chanMapUpd.instant - pCtx->eventCounter - 2;
}
}
else if ((pCtx->llcpActiveProc == LCTR_PROC_PHY_UPD) && (pCtx->isSlvPhyUpdInstant == TRUE))
{
if ((uint16_t)(pCtx->phyUpd.instant - pCtx->eventCounter) >= (pCtx->maxLatency + 1))
if ((uint16_t)(pCtx->phyUpd.instant - pCtx->eventCounter) > (pCtx->maxLatency + 1))
{
numSkipCe = pCtx->maxLatency;
}
else
else if ((pCtx->phyUpd.instant - pCtx->eventCounter) > 1)
{
numSkipCe = pCtx->phyUpd.instant - pCtx->eventCounter - 1;
/* Serve CE of (instant - 1) so that phy update is applied in the end callback of CE(instant - 1). */
numSkipCe = pCtx->phyUpd.instant - pCtx->eventCounter - 2;
}
}
}
@ -463,11 +509,6 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
LL_TRACE_INFO2("Applying slave latency, waking up at eventCounter=%u, numSkipCE=%u", pCtx->eventCounter + 1, numSkipCe);
}
if (pCtx->data.slv.abortSlvLatency)
{
pCtx->data.slv.abortSlvLatency = FALSE;
}
while (TRUE)
{
pCtx->eventCounter += 1;
@ -478,7 +519,7 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
/* Need to add the unsynced time before connection update. */
unsyncTimeUsec += pCtx->data.slv.unsyncedTime;
uint32_t wwTotalUsec = lctrCalcIntervalWindowWideningUsec(pCtx, unsyncTimeUsec);
uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, pCtx->data.slv.totalAcc);
uint32_t wwTotal = BB_US_TO_BB_TICKS(wwTotalUsec);
uint32_t connInterUsec = LCTR_CONN_IND_US(numUnsyncIntervals * pCtx->connInterval);
uint32_t connInter = BB_US_TO_BB_TICKS(connInterUsec);
@ -498,10 +539,18 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
pOp->minDurUsec = pCtx->data.slv.txWinSizeUsec + pCtx->localConnDurUsec + wwTotalUsec;
pConn->rxSyncDelayUsec = pCtx->data.slv.txWinSizeUsec + (wwTotalUsec << 1);
if ((pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) &&
((pCtx->eventCounter + 1) == pCtx->connUpd.instant))
{
/* Last CE with the old connection parameter must be scheduled, */
/* especially when connection interval and SVT changes into smaller ones. */
pCtx->svtState = LCTR_SVT_STATE_FATAL;
}
if ((pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) &&
(pCtx->eventCounter == pCtx->connUpd.instant))
{
lctrSlvConnUpdateOp(pCtx);
lctrSlvConnUpdateOp(pCtx, FALSE);
}
else if ((pCtx->llcpActiveProc == LCTR_PROC_CMN_CH_MAP_UPD) &&
(pCtx->eventCounter == pCtx->chanMapUpd.instant))
@ -516,6 +565,24 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
pBle->chan.chanIdx = lctrChSelHdlr[pCtx->usedChSel](pCtx, 0);
/* Checking if SVT is imminent. */
if (pCtx->svtState != LCTR_SVT_STATE_FATAL)
{
uint8_t nthCE = (pCtx->eventCounter + 1) - pCtx->data.slv.lastActiveEvent; /* Nth CE since last active CE. */
uint8_t numCEforSVT = ((uint32_t)pCtx->supTimeoutMs * 1000) / (uint32_t)LCTR_CONN_IND_US(pCtx->connInterval);
if ((nthCE + 1) == numCEforSVT)
{
/* 2nd to the last CE before SVT. */
pCtx->svtState = LCTR_SVT_STATE_URGENT;
}
else if (nthCE >= numCEforSVT)
{
/* Last CE before SVT. */
pCtx->svtState = LCTR_SVT_STATE_FATAL;
}
}
if (SchInsertAtDueTime(pOp, lctrConnResolveConflict))
{
break;
@ -527,6 +594,23 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp)
}
}
/*************************************************************************************************/
/*!
* \brief Abort a connection operation.
*
* \param pOp Aborted operation.
*
* \return None.
*/
/*************************************************************************************************/
void lctrSlvConnAbortOp(BbOpDesc_t *pOp)
{
lctrConnCtx_t * const pCtx = pOp->pCtx;
lctrSlvInitConnIsr(pCtx);
lctrSlvConnEndOp(pOp);
}
/*************************************************************************************************/
/*!
* \brief Complete a transmitted data buffer.
@ -599,12 +683,12 @@ void lctrSlvConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status)
{
if (status == BB_STATUS_RX_TIMEOUT)
{
LL_TRACE_WARN3("lctrSlvConnRxCompletion: BB failed with status=RX_TIMEOUT, eventCounter=%u, bleChan=%u, handle=%u", pCtx->eventCounter, pBle->chan.chanIdx, LCTR_GET_CONN_HANDLE(pCtx));
LL_TRACE_WARN3("lctrSlvConnRxCompletion: BB failed with status=RX_TIMEOUT, handle=%u, bleChan=%u, eventCounter=%u", LCTR_GET_CONN_HANDLE(pCtx), pBle->chan.chanIdx, pCtx->eventCounter);
}
if (status == BB_STATUS_FAILED)
{
LL_TRACE_ERR3("lctrSlvConnRxCompletion: BB failed with status=FAILED, eventCounter=%u, bleChan=%u, handle=%u", pCtx->eventCounter, pBle->chan.chanIdx, LCTR_GET_CONN_HANDLE(pCtx));
LL_TRACE_ERR3("lctrSlvConnRxCompletion: BB failed with status=FAILED, handle=%u, bleChan=%u, eventCounter=%u", LCTR_GET_CONN_HANDLE(pCtx), pBle->chan.chanIdx, pCtx->eventCounter);
}
BbSetBodTerminateFlag();
@ -613,28 +697,28 @@ void lctrSlvConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status)
}
/* Store anchor point. */
if ((!lctrSlvConnIsr.syncWithMaster) &&
((status == BB_STATUS_SUCCESS) || (status == BB_STATUS_CRC_FAILED)))
if ((!pCtx->data.slv.syncWithMaster) &&
((status == BB_STATUS_SUCCESS) ||
(!lctrGetConnOpFlag(pCtx, LL_OP_MODE_FLAG_IGNORE_CRC_ERR_TS) && (status == BB_STATUS_CRC_FAILED))))
{
lctrSlvConnIsr.firstRxStartTs = pConn->startTs;
lctrSlvConnIsr.syncWithMaster = TRUE;
lctrSlvConnIsr.syncConnHandle = LCTR_GET_CONN_HANDLE(pCtx);
pCtx->data.slv.firstRxStartTs = pConn->startTs;
pCtx->data.slv.syncWithMaster = TRUE;
}
/*** Receive packet pre-processing ***/
if (status == BB_STATUS_SUCCESS)
{
lctrSlvConnIsr.rxFromMaster = TRUE;
pCtx->data.slv.rxFromMaster = TRUE;
/* Reset consecutive CRC failure counter. */
lctrSlvConnIsr.consCrcFailed = 0;
pCtx->data.slv.consCrcFailed = 0;
}
else if (status == BB_STATUS_CRC_FAILED)
{
lctrSlvConnIsr.consCrcFailed++;
pCtx->data.slv.consCrcFailed++;
if (lctrSlvConnIsr.consCrcFailed >= LCTR_MAX_CONS_CRC)
if (pCtx->data.slv.consCrcFailed >= LCTR_MAX_CONS_CRC)
{
/* Close connection event. */
BbSetBodTerminateFlag();
@ -665,12 +749,12 @@ void lctrSlvConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status)
{
pNextRxBuf = lctrProcessRxAck(pCtx);
txPduIsAcked = lctrProcessTxAck(pCtx);
}
if (!pCtx->data.slv.initAckRcvd &&
txPduIsAcked)
{
pCtx->data.slv.initAckRcvd = TRUE;
}
if (!pCtx->data.slv.initAckRcvd &&
txPduIsAcked)
{
pCtx->data.slv.initAckRcvd = TRUE;
}
/*** Setup for transmit ***/
@ -683,7 +767,7 @@ SetupTx:
goto PostProcessing;
}
/* Tx llid is obtained from lctrSetupForTx(). */
/* Tx LLID is obtained from lctrSetupForTx(). */
if ((pCtx->isSlvReadySent == FALSE) &&
(pCtx->isFirstNonCtrlPdu == TRUE) &&
(lctrGetConnOpFlag(pCtx, LL_OP_MODE_FLAG_SLV_DELAY_LLCP_STARTUP)))

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2019 Arm Limited
/* Copyright (c) 2019 Arm Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,8 @@
/*************************************************************************************************/
/*!
* \brief Link layer controller master advertising event ISR callbacks.
* \file
* \brief Link layer controller master advertising event ISR callbacks.
*/
/*************************************************************************************************/
@ -128,6 +129,10 @@ bool_t lctrMstInitiateAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf)
lctrMstInit.data.init.localRpa = localAddr;
BbBleResListUpdateLocal(pScan->filtResults.peerIdAddrRand, pScan->filtResults.peerIdAddr, &localAddr);
}
else
{
lctrMstInit.data.init.localRpa = 0;
}
}
else
{
@ -152,6 +157,15 @@ bool_t lctrMstInitiateAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf)
lctrMstInit.data.init.localRpa = 0;
}
#if (LL_ENABLE_TESTER)
if (llTesterCb.auxReq.len)
{
/* Overriding CONNECT_IND from test script. */
memcpy(pScan->pTxReqBuf, llTesterCb.auxReq.buf, llTesterCb.auxReq.len);
pScan->txReqLen = llTesterCb.auxReq.len;
}
#endif
lctrPackAdvbPduHdr(pScan->pTxReqBuf, &lctrMstInit.reqPduHdr);
/* Update txWinOffset field in CONN_IND PDU. */
@ -160,6 +174,24 @@ bool_t lctrMstInitiateAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf)
UINT16_TO_BUF(pScan->pTxReqBuf + LCTR_CONN_IND_TX_WIN_OFFSET, txWinOffset);
lctrMstInit.data.init.connInd.txWinOffset = txWinOffset;
#if (LL_ENABLE_TESTER)
switch (llTesterCb.connFirstCePos)
{
case LL_TESTER_FIRST_CE_POS_BEGIN:
/* BOD is not scheduled; force time adjustment here. */
pCtx->connBod.due = advEndTs + BB_US_TO_BB_TICKS(txWinOffsetUsec + LL_BLE_TIFS_US + LCTR_CONN_IND_PKT_1M_US);
break;
case LL_TESTER_FIRST_CE_POS_END:
/* BOD is not scheduled; force time adjustment here. */
pCtx->connBod.due = advEndTs + BB_US_TO_BB_TICKS(txWinOffsetUsec + LCTR_CONN_IND_US(lctrMstInit.data.init.connInd.txWinSize - 1) + LL_BLE_TIFS_US + LCTR_CONN_IND_PKT_1M_US);
break;
case LL_TESTER_FIRST_CE_POS_NORMAL:
default:
break;
}
llTesterCb.connFirstCePos = LL_TESTER_FIRST_CE_POS_NORMAL;
#endif
if (txWinOffsetUsec < LCTR_CONN_IND_US(LCTR_DATA_CHAN_DLY))
{
LL_TRACE_WARN1("AE too close to initial CE deltaUsec=%u, suppressed LL_CONN_IND delivery", BB_TICKS_TO_US(lctrMstInit.data.init.firstCeDue - advEndTs));
@ -207,6 +239,14 @@ bool_t lctrMstInitiateAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf)
/*************************************************************************************************/
bool_t lctrMstConnIndTxCompHandler(BbOpDesc_t *pOp, const uint8_t *pIndBuf)
{
#if (LL_ENABLE_TESTER == TRUE)
if (llTesterCb.auxReq.len)
{
/* Do not establish connection when CONNECT_IND is overridden. */
return FALSE;
}
#endif
WSF_ASSERT(pOp->protId == BB_PROT_BLE);
WSF_ASSERT(pOp->prot.pBle->chan.opType == BB_BLE_OP_MST_ADV_EVENT);

Some files were not shown because too many files have changed in this diff Show More