From 601b1056aa5f371964343f851610104880ff2e29 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 26 Jul 2023 16:41:37 +0200 Subject: [PATCH 1/9] host/gatt: add and update doxygen comments for the header file Adds missing macros and structures documentation. Corrects arguments names in functions documentation. --- nimble/host/include/host/ble_gatt.h | 184 +++++++++++++++++++++++++--- 1 file changed, 170 insertions(+), 14 deletions(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index 312126f532..b3bea2bdc4 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -38,80 +38,220 @@ struct ble_hs_conn; struct ble_att_error_rsp; struct ble_hs_cfg; +/** + * @defgroup ble_gatt_register_op_codes Generic Attribute Profile (GATT) Registration Operation Codes + * @{ + */ + +/** GATT Service registration. */ #define BLE_GATT_REGISTER_OP_SVC 1 + +/** GATT Characteristic registration. */ #define BLE_GATT_REGISTER_OP_CHR 2 + +/** GATT Descriptor registration. */ #define BLE_GATT_REGISTER_OP_DSC 3 +/** @} */ + +/** + * @defgroup ble_gatt_uuid Generic Attribute Profile (GATT) Service and Descriptor UUIDs + * @{ + */ + +/** GATT service 16-bit UUID. */ #define BLE_GATT_SVC_UUID16 0x1801 + +/** GATT Client Characteristic Configuration descriptor 16-bit UUID. */ #define BLE_GATT_DSC_CLT_CFG_UUID16 0x2902 +/** @} */ + +/** + * @defgroup ble_gatt_chr_properties Generic Attribute Profile (GATT) Characteristic Properties + * @{ + */ + +/** Characteristic property: Broadcast. */ #define BLE_GATT_CHR_PROP_BROADCAST 0x01 + +/** Characteristic property: Read. */ #define BLE_GATT_CHR_PROP_READ 0x02 + +/** Characteristic property: Write Without Response. */ #define BLE_GATT_CHR_PROP_WRITE_NO_RSP 0x04 + +/** Characteristic property: Write. */ #define BLE_GATT_CHR_PROP_WRITE 0x08 + +/** Characteristic property: Notify. */ #define BLE_GATT_CHR_PROP_NOTIFY 0x10 + +/** Characteristic property: Indicate. */ #define BLE_GATT_CHR_PROP_INDICATE 0x20 + +/** Characteristic property: Authenticated Signed Write. */ #define BLE_GATT_CHR_PROP_AUTH_SIGN_WRITE 0x40 + +/** Characteristic property: Extended Properties. */ #define BLE_GATT_CHR_PROP_EXTENDED 0x80 +/** @} */ + +/** @defgroup ble_gatt_access_op_codes Generic Attribute Profile (GATT) Access Operation Codes + * @{ + */ + +/** GATT attribute access operation: Read characteristic. */ #define BLE_GATT_ACCESS_OP_READ_CHR 0 + +/** GATT attribute access operation: Write characteristic. */ #define BLE_GATT_ACCESS_OP_WRITE_CHR 1 + +/** GATT attribute access operation: Read descriptor. */ #define BLE_GATT_ACCESS_OP_READ_DSC 2 + +/** GATT attribute access operation: Write descriptor. */ #define BLE_GATT_ACCESS_OP_WRITE_DSC 3 +/** @} */ + +/** + * @defgroup ble_gatt_chr_flags Generic Attribute Profile (GATT) Characteristic Flags + * @{ + */ + +/** GATT Characteristic Flag: Broadcast. */ #define BLE_GATT_CHR_F_BROADCAST 0x0001 + +/** GATT Characteristic Flag: Read. */ #define BLE_GATT_CHR_F_READ 0x0002 + +/** GATT Characteristic Flag: Write without Response. */ #define BLE_GATT_CHR_F_WRITE_NO_RSP 0x0004 + +/** GATT Characteristic Flag: Write. */ #define BLE_GATT_CHR_F_WRITE 0x0008 + +/** GATT Characteristic Flag: Notify. */ #define BLE_GATT_CHR_F_NOTIFY 0x0010 + +/** GATT Characteristic Flag: Indicate. */ #define BLE_GATT_CHR_F_INDICATE 0x0020 + +/** GATT Characteristic Flag: Authenticated Signed Writes. */ #define BLE_GATT_CHR_F_AUTH_SIGN_WRITE 0x0040 + +/** GATT Characteristic Flag: Reliable Writes. */ #define BLE_GATT_CHR_F_RELIABLE_WRITE 0x0080 + +/** GATT Characteristic Flag: Auxiliary Writes. */ #define BLE_GATT_CHR_F_AUX_WRITE 0x0100 + +/** GATT Characteristic Flag: Read Encrypted. */ #define BLE_GATT_CHR_F_READ_ENC 0x0200 + +/** GATT Characteristic Flag: Read Authenticated. */ #define BLE_GATT_CHR_F_READ_AUTHEN 0x0400 + +/** GATT Characteristic Flag: Read Authorized. */ #define BLE_GATT_CHR_F_READ_AUTHOR 0x0800 + +/** GATT Characteristic Flag: Write Encrypted. */ #define BLE_GATT_CHR_F_WRITE_ENC 0x1000 + +/** GATT Characteristic Flag: Write Authenticated. */ #define BLE_GATT_CHR_F_WRITE_AUTHEN 0x2000 + +/** GATT Characteristic Flag: Write Authorized. */ #define BLE_GATT_CHR_F_WRITE_AUTHOR 0x4000 + +/** @} */ + +/** + * @defgroup ble_gatt_service_types Generic Attribute Profile (GATT) Service Types + * @{ + */ + +/** GATT Service Type: End of Services. */ #define BLE_GATT_SVC_TYPE_END 0 + +/** GATT Service Type: Primary Service. */ #define BLE_GATT_SVC_TYPE_PRIMARY 1 + +/** GATT Service Type: Secondary Service. */ #define BLE_GATT_SVC_TYPE_SECONDARY 2 +/** @} */ + /*** @client. */ +/** Represents a GATT error. */ struct ble_gatt_error { + /** The GATT status code indicating the type of error. */ uint16_t status; + + /** The attribute handle associated with the error. */ uint16_t att_handle; }; +/** Represents a GATT Service. */ struct ble_gatt_svc { + /** The start handle of the GATT service. */ uint16_t start_handle; + + /** The end handle of the GATT service. */ uint16_t end_handle; + + /** The UUID of the GATT service. */ ble_uuid_any_t uuid; }; + +/** Represents a GATT attribute. */ struct ble_gatt_attr { + /** The handle of the GATT attribute. */ uint16_t handle; + + /** The offset of the data within the attribute. */ uint16_t offset; + + /** Pointer to the data buffer represented by an os_mbuf. */ struct os_mbuf *om; }; + +/** Represents a GATT characteristic. */ struct ble_gatt_chr { + /** The handle of the GATT characteristic definition. */ uint16_t def_handle; + + /** The handle of the GATT characteristic value. */ uint16_t val_handle; + + /** The properties of the GATT characteristic. */ uint8_t properties; + + /** The UUID of the GATT characteristic. */ ble_uuid_any_t uuid; }; + +/** Represents a GATT descriptor. */ struct ble_gatt_dsc { + /** The handle of the GATT descriptor. */ uint16_t handle; + + /** The UUID of the GATT descriptor. */ ble_uuid_any_t uuid; }; +/** Function prototype for the GATT MTU exchange callback. */ typedef int ble_gatt_mtu_fn(uint16_t conn_handle, const struct ble_gatt_error *error, uint16_t mtu, void *arg); + +/** Function prototype for the GATT service discovery callback. */ typedef int ble_gatt_disc_svc_fn(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service, @@ -137,10 +277,12 @@ typedef int ble_gatt_reliable_attr_fn(uint16_t conn_handle, struct ble_gatt_attr *attrs, uint8_t num_attrs, void *arg); +/** Function prototype for the GATT characteristic callback. */ typedef int ble_gatt_chr_fn(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_chr *chr, void *arg); +/** Function prototype for the GATT descriptor callback. */ typedef int ble_gatt_dsc_fn(uint16_t conn_handle, const struct ble_gatt_error *error, uint16_t chr_val_handle, @@ -180,7 +322,7 @@ int ble_gattc_disc_all_svcs(uint16_t conn_handle, * * @param conn_handle The connection over which to execute the * procedure. - * @param service_uuid128 The 128-bit UUID of the service to discover. + * @param uuid The 128-bit UUID of the service to discover. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -240,7 +382,7 @@ int ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle, * the service definition handle). * @param end_handle The handle to end the search at (generally the * last handle in the service). - * @param chr_uuid128 The 128-bit UUID of the characteristic to + * @param uuid The 128-bit UUID of the characteristic to * discover. * @param cb The function to call to report procedure status * updates; null for no callback. @@ -258,9 +400,9 @@ int ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle, * * @param conn_handle The connection over which to execute the * procedure. - * @param chr_val_handle The handle of the characteristic value + * @param start_handle The handle of the characteristic value * attribute. - * @param chr_end_handle The last handle in the characteristic + * @param end_handle The last handle in the characteristic * definition. * @param cb The function to call to report procedure status * updates; null for no callback. @@ -298,6 +440,8 @@ int ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle, * handle of the service definition). * @param end_handle The last handle to search (generally the * last handle in the service definition). + * @param uuid The 128-bit UUID of the characteristic to + * read. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -315,6 +459,8 @@ int ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle, * @param conn_handle The connection over which to execute the * procedure. * @param handle The handle of the characteristic value to read. + * @param offset The offset within the characteristic value to + * start reading. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -351,7 +497,7 @@ int ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param txom The value to write to the characteristic. + * @param om The value to write to the characteristic. * * @return 0 on success; nonzero on failure. */ @@ -366,8 +512,8 @@ int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param value The value to write to the characteristic. - * @param value_len The number of bytes to write. + * @param data The value to write to the characteristic. + * @param data_len The number of bytes to write. * * @return 0 on success; nonzero on failure. */ @@ -382,7 +528,7 @@ int ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param txom The value to write to the characteristic. + * @param om The value to write to the characteristic. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -401,8 +547,8 @@ int ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param value The value to write to the characteristic. - * @param value_len The number of bytes to write. + * @param data The value to write to the characteristic. + * @param data_len The number of bytes to write. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -422,7 +568,8 @@ int ble_gattc_write_flat(uint16_t conn_handle, uint16_t attr_handle, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param txom The value to write to the characteristic. + * @param offset The offset at which to begin writing the value. + * @param om The value to write to the characteristic. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -464,9 +611,9 @@ int ble_gattc_write_reliable(uint16_t conn_handle, * * @param conn_handle The connection over which to execute the * procedure. - * @param chr_val_handle The attribute handle to indicate in the + * @param att_handle The attribute handle to indicate in the * outgoing notification. - * @param txom The value to write to the characteristic. + * @param om The value to write to the characteristic. * * @return 0 on success; nonzero on failure. */ @@ -539,16 +686,21 @@ int ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle); */ int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle); +/** Initialize the BLE GATT client. */ int ble_gattc_init(void); /*** @server. */ struct ble_gatt_access_ctxt; + +/** Type definition for GATT access callback function. */ typedef int ble_gatt_access_fn(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +/** Type definition for GATT characteristic flags. */ typedef uint16_t ble_gatt_chr_flags; +/** Represents the definition of a GATT characteristic. */ struct ble_gatt_chr_def { /** * Pointer to characteristic UUID; use BLE_UUIDxx_DECLARE macros to declare @@ -585,6 +737,7 @@ struct ble_gatt_chr_def { uint16_t *val_handle; }; +/** Represents the definition of a GATT service. */ struct ble_gatt_svc_def { /** * One of the following: @@ -614,6 +767,7 @@ struct ble_gatt_svc_def { const struct ble_gatt_chr_def *characteristics; }; +/** Represents the definition of a GATT descriptor. */ struct ble_gatt_dsc_def { /** * Pointer to descriptor UUID; use BLE_UUIDxx_DECLARE macros to declare @@ -759,6 +913,7 @@ struct ble_gatt_register_ctxt { }; }; +/** Type definition for GATT registration callback function. */ typedef void ble_gatt_register_fn(struct ble_gatt_register_ctxt *ctxt, void *arg); @@ -855,7 +1010,7 @@ int ble_gatts_find_chr(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid, * @param svc_uuid The UUID of the grandparent service. * @param chr_uuid The UUID of the parent characteristic. * @param dsc_uuid The UUID of the descriptor ro look up. - * @param out_handle On success, populated with the handle + * @param out_dsc_handle On success, populated with the handle * of the descriptor attribute. Pass null if * you don't need this value. * @@ -867,6 +1022,7 @@ int ble_gatts_find_chr(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid, int ble_gatts_find_dsc(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid, uint16_t *out_dsc_handle); +/** Type definition for GATT service iteration callback function. */ typedef void (*ble_gatt_svc_foreach_fn)(const struct ble_gatt_svc_def *svc, uint16_t handle, uint16_t end_group_handle, From 4cf74c3bf50cc68302e2ce87176f300cac3afcac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 1 Aug 2023 09:48:06 +0200 Subject: [PATCH 2/9] apps/bttester: remove unstalled_cb from btp_l2cap.c Response to BTP_L2CAP_SEND_DATA command is already sent in command handler (`send_data()`). Sending further responses to already answered command is confusing - we cannot fail successful procedure retroactively. Data sending is already confirmed to be started successfully and no further responses are expected - more so, it appears to break `available_queue` management and further commands cannot be processed correctly. Similar callback may be proposed in the future if confirmation of sending data is needed, but not in form of BTP response, but BTP event. --- apps/bttester/src/btp_l2cap.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index 34749af7fb..916e714e7d 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -140,19 +140,6 @@ recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, tester_l2cap_coc_recv(chan, buf); } -static void -unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - int status, void *arg) -{ - if (status) { - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, - BTP_STATUS_FAILED); - } else { - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, - BTP_STATUS_SUCCESS); - } -} - static void reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info, @@ -349,10 +336,6 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg) (uint32_t) event->tx_unstalled.chan, event->tx_unstalled.conn_handle, event->tx_unstalled.status); - - unstalled_cb(event->tx_unstalled.conn_handle, - event->tx_unstalled.chan, - event->tx_unstalled.status, arg); return 0; case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED: if (ble_l2cap_get_chan_info(event->reconfigured.chan, From 765f9d97ba545578dacffae059a12478edcce995 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 19 Jun 2023 16:26:34 +0200 Subject: [PATCH 3/9] host/l2cap: add doxygen comments for the header file Adds missing macros, structures and functions documentation. --- nimble/host/include/host/ble_l2cap.h | 368 ++++++++++++++++++++++++++- 1 file changed, 366 insertions(+), 2 deletions(-) diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h index 6edfa85d78..f836e97c6c 100644 --- a/nimble/host/include/host/ble_l2cap.h +++ b/nimble/host/include/host/ble_l2cap.h @@ -17,6 +17,20 @@ * under the License. */ +/** + * @file ble_l2cap.h + * + * @brief L2CAP (Logical Link Control and Adaptation Protocol) API + * + * This header file provides the public API for interacting with the L2CAP layer of the BLE + * (Bluetooth Low Energy) stack. L2CAP is responsible for managing logical channels between + * two connected BLE devices. + * + * @defgroup bt_host_l2cap Bluetooth Host Logical Link Control and Adaptation Protocol + * @ingroup bt_host + * @{ + */ + #ifndef H_BLE_L2CAP_ #define H_BLE_L2CAP_ @@ -25,89 +39,311 @@ extern "C" { #endif +/** + * @brief L2CAP Signaling Connection Parameters Update Request. + * + * This structure represents a request to update the L2CAP connection parameters. + */ struct ble_l2cap_sig_update_req; + +/** + * @brief BLE Host Connection structure. + * + * This structure represents a connection between the BLE host and a remote device. + */ struct ble_hs_conn; +/** + * @defgroup ble_l2cap_channel_ids Channel Identifiers + * @{ + */ +/** Attribute Protocol (ATT) CID. */ #define BLE_L2CAP_CID_ATT 4 + +/** L2CAP LE Signaling CID. */ #define BLE_L2CAP_CID_SIG 5 + +/** Security Manager (SM) CID. */ #define BLE_L2CAP_CID_SM 6 +/** @} */ + +/** + * @defgroup ble_l2cap_signaling_op_codes Signaling Commands Operation Codes + * @{ + */ + +/** Reject */ #define BLE_L2CAP_SIG_OP_REJECT 0x01 + +/** Connect Request */ #define BLE_L2CAP_SIG_OP_CONNECT_REQ 0x02 + +/** Connect Response */ #define BLE_L2CAP_SIG_OP_CONNECT_RSP 0x03 + +/** Configuration Request */ #define BLE_L2CAP_SIG_OP_CONFIG_REQ 0x04 + +/** Configuration Response */ #define BLE_L2CAP_SIG_OP_CONFIG_RSP 0x05 + +/** Disconnect Request */ #define BLE_L2CAP_SIG_OP_DISCONN_REQ 0x06 + +/** Disconnect Response */ #define BLE_L2CAP_SIG_OP_DISCONN_RSP 0x07 + +/** Echo Request */ #define BLE_L2CAP_SIG_OP_ECHO_REQ 0x08 + +/** Echo Response */ #define BLE_L2CAP_SIG_OP_ECHO_RSP 0x09 + +/** Information Request */ #define BLE_L2CAP_SIG_OP_INFO_REQ 0x0a + +/** Information Response */ #define BLE_L2CAP_SIG_OP_INFO_RSP 0x0b + +/** Create Channel Request */ #define BLE_L2CAP_SIG_OP_CREATE_CHAN_REQ 0x0c + +/** Create Channel Response */ #define BLE_L2CAP_SIG_OP_CREATE_CHAN_RSP 0x0d + +/** Move Channel Request */ #define BLE_L2CAP_SIG_OP_MOVE_CHAN_REQ 0x0e + +/** Move Channel Response */ #define BLE_L2CAP_SIG_OP_MOVE_CHAN_RSP 0x0f + +/** Move Channel Confirmation Request */ #define BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_REQ 0x10 + +/** Move Channel Confirmation Response */ #define BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_RSP 0x11 + +/** Update Request */ #define BLE_L2CAP_SIG_OP_UPDATE_REQ 0x12 + +/** Update Response */ #define BLE_L2CAP_SIG_OP_UPDATE_RSP 0x13 + +/** LE Credit Based Connection Request */ #define BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_REQ 0x14 + +/** LE Credit Based Connection Response */ #define BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_RSP 0x15 + +/** Credit Based Flow Control Credit */ #define BLE_L2CAP_SIG_OP_FLOW_CTRL_CREDIT 0x16 + +/** Credit Based Connection Request */ #define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ 0x17 + +/** Credit Based Connection Response */ #define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP 0x18 + +/** Credit Based Reconfiguration Request */ #define BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_REQ 0x19 + +/** Credit Based Reconfiguration Response */ #define BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_RSP 0x1A + +/** Signaling Command Maximum Value */ #define BLE_L2CAP_SIG_OP_MAX 0x1B +/** @} */ + +/** + * @defgroup ble_l2cap_signaling_err_codes Signaling Commands Error Codes + * @{ + */ + +/** Command Not Understood */ #define BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD 0x0000 + +/** Maximum Transmission Unit (MTU) Exceeded */ #define BLE_L2CAP_SIG_ERR_MTU_EXCEEDED 0x0001 + +/** Invalid CID */ #define BLE_L2CAP_SIG_ERR_INVALID_CID 0x0002 +/** @} */ + +/** + * @defgroup ble_l2cap_coc_err_codes Connection-Oriented Channels (CoC) Error Codes + * @{ + */ + +/** Connection Success */ #define BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS 0x0000 + +/** Unknown LE Protocol/Service Multiplexer (PSM) */ #define BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM 0x0002 + +/** No Resources */ #define BLE_L2CAP_COC_ERR_NO_RESOURCES 0x0004 + +/** Insufficient Authentication */ #define BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN 0x0005 + +/** Insufficient Authorization */ #define BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR 0x0006 + +/** Insufficient Key Size */ #define BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ 0x0007 + +/** Insufficient Encryption */ #define BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC 0x0008 + +/** Invalid Source CID */ #define BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID 0x0009 + +/** Source CID Already Used */ #define BLE_L2CAP_COC_ERR_SOURCE_CID_ALREADY_USED 0x000A + +/** Unacceptable Parameters */ #define BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS 0x000B + +/** Invalid Parameters */ #define BLE_L2CAP_COC_ERR_INVALID_PARAMETERS 0x000C +/** @} */ + +/** + * @defgroup ble_l2cap_reconfig_err_codes Channel Reconfiguration Error Codes + * @{ + */ + +/** Reconfiguration Succeeded */ #define BLE_L2CAP_ERR_RECONFIG_SUCCEED 0x0000 + +/** Reduction of Maximum Transmission Unit (MTU) Not Allowed */ #define BLE_L2CAP_ERR_RECONFIG_REDUCTION_MTU_NOT_ALLOWED 0x0001 + +/** Reduction of Maximum Packet Size (MPS) Not Allowed */ #define BLE_L2CAP_ERR_RECONFIG_REDUCTION_MPS_NOT_ALLOWED 0x0002 + +/** Invalid Destination CID */ #define BLE_L2CAP_ERR_RECONFIG_INVALID_DCID 0x0003 + +/** Unaccepted Parameters */ #define BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM 0x0004 +/** @} */ + +/** + * @defgroup ble_l2cap_coc_event_types Connection-Oriented Channel (CoC) Event Types + * @{ + */ + +/** CoC Connected */ #define BLE_L2CAP_EVENT_COC_CONNECTED 0 + +/** CoC Disconnected */ #define BLE_L2CAP_EVENT_COC_DISCONNECTED 1 + +/** CoC Accept */ #define BLE_L2CAP_EVENT_COC_ACCEPT 2 + +/** CoC Data Received */ #define BLE_L2CAP_EVENT_COC_DATA_RECEIVED 3 + +/** CoC Transmission Unstalled */ #define BLE_L2CAP_EVENT_COC_TX_UNSTALLED 4 + +/** CoC Reconfiguration Completed */ #define BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED 5 + +/** CoC Peer Reconfigured */ #define BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED 6 +/** @} */ + + +/** + * @brief Function signature for L2CAP signaling update event callback. + * + * This function is used to handle signaling update events in the L2CAP layer, + * such as changes in connection parameters. + * + * @param conn_handle The connection handle associated with the signaling update event. + * @param status The status of the signaling update event. + * @param arg A pointer to additional arguments passed to the callback function. + */ typedef void ble_l2cap_sig_update_fn(uint16_t conn_handle, int status, void *arg); +/** + * @brief Represents the signaling update in L2CAP. + * + * This structure holds the parameters required for initiating a signaling update in the L2CAP layer. + * It defines the connection interval, slave latency, and supervision timeout multiplier for the update. + */ struct ble_l2cap_sig_update_params { + /** + * The minimum desired connection interval in increments of 1.25 ms. + * This value defines the lower bound for the connection interval range. + */ uint16_t itvl_min; + + /** + * The maximum desired connection interval in increments of 1.25 ms. + * This value defines the upper bound for the connection interval range. + */ uint16_t itvl_max; + + /** + * The desired number of connection events that a slave device can skip. + * It specifies the maximum allowed latency between consecutive connection events. + */ uint16_t slave_latency; + + /** + * The desired supervision timeout multiplier. + * The supervision timeout defines the time limit for detecting the loss of a connection. + * This value is multiplied by the connection interval to determine the supervision timeout duration. + */ uint16_t timeout_multiplier; }; +/** + * @brief Initiate an L2CAP connection update procedure. + * + * This function initiates an L2CAP connection update procedure for the specified connection handle. + * The update procedure is used to modify the connection parameters, such as interval, latency, and timeout. + * + * @param conn_handle The connection handle of the L2CAP connection. + * + * @param params A pointer to a structure containing the desired update parameters. + * This includes the new connection interval, slave latency, and + * supervision timeout multiplier. + * + * @param cb The callback function to be called when the update request completes. + * The function signature for the callback is defined by `ble_l2cap_sig_update_fn`. + * + * @param cb_arg An optional argument to be passed to the callback function. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_sig_update(uint16_t conn_handle, struct ble_l2cap_sig_update_params *params, ble_l2cap_sig_update_fn *cb, void *cb_arg); +/** + * @brief Structure representing a L2CAP channel. + * + * It is used to maintain the state and track the properties of an L2CAP channel + * during its lifecycle. + */ struct ble_l2cap_chan; /** - * Represents a L2CAP-related event. + * @brief Represents a L2CAP-related event. + * * When such an event occurs, the host notifies the application by passing an * instance of this structure to an application-specified callback. */ @@ -234,33 +470,161 @@ struct ble_l2cap_event { }; }; +/** + * @brief Represents information about an L2CAP channel. + * + * This structure is typically used to retrieve or provide information about an existing L2CAP channel. + */ struct ble_l2cap_chan_info { + /** Source Channel Identifier. */ uint16_t scid; + + /** Destination Channel Identifier. */ uint16_t dcid; + + /** Local L2CAP Maximum Transmission Unit. */ uint16_t our_l2cap_mtu; + + /** Peer L2CAP Maximum Transmission Unit. */ uint16_t peer_l2cap_mtu; + + /** Protocol/Service Multiplexer of the channel. */ uint16_t psm; + + /** Local CoC Maximum Transmission Unit. */ uint16_t our_coc_mtu; + + /** Peer CoC Maximum Transmission Unit. */ uint16_t peer_coc_mtu; }; +/** + * @brief Function pointer type for handling L2CAP events. + * + * @param event A pointer to the L2CAP event structure. + * @param arg A pointer to additional arguments passed to the callback function. + * + * @return Integer value representing the status or result of the event handling. + */ typedef int ble_l2cap_event_fn(struct ble_l2cap_event *event, void *arg); - +/** + * @brief Get the connection handle associated with an L2CAP channel. + * + * This function retrieves the connection handle associated with the specified L2CAP channel. + * + * @param chan A pointer to the L2CAP channel structure. + * + * @return The connection handle associated with the L2CAP channel on success; + * A Bluetooth Host Error Code on failure: + * BLE_HS_CONN_HANDLE_NONE: if the provided channel pointer is NULL. + */ uint16_t ble_l2cap_get_conn_handle(struct ble_l2cap_chan *chan); + +/** + * @brief Create an L2CAP server. + * + * This function creates an L2CAP server with the specified Protocol/Service Multiplexer (PSM) and Maximum + * Transmission Unit (MTU) size. The server is used to accept incoming L2CAP connections from remote clients. + * When a connection request is received, the provided callback function will be invoked with the corresponding + * event information. + * + * @param psm The Protocol/Service Multiplexer (PSM) for the server. + * @param mtu The Maximum Transmission Unit (MTU) size for the server. + * @param cb Pointer to the callback function to be invoked when a connection request is received. + * @param cb_arg An optional argument to be passed to the callback function. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_create_server(uint16_t psm, uint16_t mtu, ble_l2cap_event_fn *cb, void *cb_arg); +/** + * @brief Initiate an L2CAP connection. + * + * This function initiates an L2CAP connection to a remote device with the specified connection handle, + * Protocol/Service Multiplexer (PSM), Maximum Transmission Unit (MTU) size, and receive SDU buffer. + * When the connection is established or if there is an error during the connection process, the provided + * callback function will be invoked with the corresponding event information. + * + * @param conn_handle The connection handle for the remote device. + * @param psm The Protocol/Service Multiplexer (PSM) for the connection. + * @param mtu The Maximum Transmission Unit (MTU) size for the connection. + * @param sdu_rx Pointer to the receive Service Data Unit (SDU) buffer. + * @param cb Pointer to the callback function to be invoked when the connection is established. + * @param cb_arg An optional argument to be passed to the callback function. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg); + +/** + * @brief Disconnect an L2CAP channel. + * + * This function disconnects the specified L2CAP channel by sending a disconnect signal. + * + * @param chan Pointer to the L2CAP channel structure representing the channel to disconnect. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_disconnect(struct ble_l2cap_chan *chan); + +/** + * @brief Send an SDU (Service Data Unit) over an L2CAP channel. + * + * This function sends an SDU over the specified L2CAP channel. The SDU is encapsulated + * in L2CAP frames and transmitted to the remote device. + * + * @param chan Pointer to the L2CAP channel structure representing the channel to send the SDU on. + * @param sdu_tx Pointer to the os_mbuf structure containing the SDU (Service Data Unit) to send. + * + * @return 0 on success; + * BLE_HS_ESTALLED: if there was not enough credits available to send whole SDU. + * The application needs to wait for the event 'BLE_L2CAP_EVENT_COC_TX_UNSTALLED' + * before being able to transmit more data; + * Another non-zero value on failure. + */ int ble_l2cap_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx); + +/** + * @brief Check if the L2CAP channel is ready to receive an SDU. + * + * This function checks if the specified L2CAP channel is ready to receive an SDU (Service Data Unit). + * It can be used to determine if the channel is in a state where it can accept incoming data. + * + * @param chan Pointer to the L2CAP channel structure to check. + * @param sdu_rx Pointer to the os_mbuf structure to receive the incoming SDU. + * + * @return 0 if the channel is ready to receive an SDU; + * A non-zero value on failure. + */ int ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx); + +/** + * @brief Get information about an L2CAP channel. + * + * This function retrieves information about the specified L2CAP channel and populates + * the provided `ble_l2cap_chan_info` structure with the channel's details. + * + * @param chan Pointer to the L2CAP channel structure to retrieve information from. + * @param chan_info Pointer to the `ble_l2cap_chan_info` structure to populate with channel information. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_get_chan_info(struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info); #ifdef __cplusplus } #endif +/** + * @} + */ + #endif From 99e6c0e8fa8baa72ba1d76c31ecd69af2e17a4ae Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 19 Jul 2023 17:56:51 +0200 Subject: [PATCH 4/9] host/hs: add doxygen comments for the header file Adds missing macros and structures documentation. --- nimble/host/include/host/ble_hs.h | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index 1f4f19041f..09900fd39d 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -49,6 +49,7 @@ extern "C" { #endif +/** Represents an infinite value for timeouts or durations. */ #define BLE_HS_FOREVER INT32_MAX /** Connection handle not present */ @@ -64,36 +65,97 @@ extern "C" { * @{ */ +/** Operation failed and should be retried later. */ #define BLE_HS_EAGAIN 1 + +/** Operation already in progress. */ #define BLE_HS_EALREADY 2 + +/** Invalid parameter. */ #define BLE_HS_EINVAL 3 + +/** Message too long. */ #define BLE_HS_EMSGSIZE 4 + +/** No such entry. */ #define BLE_HS_ENOENT 5 + +/** Out of memory. */ #define BLE_HS_ENOMEM 6 + +/** Not connected. */ #define BLE_HS_ENOTCONN 7 + +/** Not supported. */ #define BLE_HS_ENOTSUP 8 + +/** Application error. */ #define BLE_HS_EAPP 9 + +/** Bad data. */ #define BLE_HS_EBADDATA 10 + +/** Operating System error. */ #define BLE_HS_EOS 11 + +/** Controller error. */ #define BLE_HS_ECONTROLLER 12 + +/** Operation timed out. */ #define BLE_HS_ETIMEOUT 13 + +/** Operation completed. */ #define BLE_HS_EDONE 14 + +/** Resource busy. */ #define BLE_HS_EBUSY 15 + +/** Operation rejected. */ #define BLE_HS_EREJECT 16 + +/** Unknown error. */ #define BLE_HS_EUNKNOWN 17 + +/** Role error. */ #define BLE_HS_EROLE 18 + +/** HCI operation timed out. */ #define BLE_HS_ETIMEOUT_HCI 19 + +/** Out of memory to handle an event. */ #define BLE_HS_ENOMEM_EVT 20 + +/** No valid address. */ #define BLE_HS_ENOADDR 21 + +/** Not synchronized with the controller. */ #define BLE_HS_ENOTSYNCED 22 + +/** Authentication error. */ #define BLE_HS_EAUTHEN 23 + +/** Authorization error. */ #define BLE_HS_EAUTHOR 24 + +/** Encryption error. */ #define BLE_HS_EENCRYPT 25 + +/** Invalid encryption key size. */ #define BLE_HS_EENCRYPT_KEY_SZ 26 + +/** Storage capacity exceeded. */ #define BLE_HS_ESTORE_CAP 27 + +/** Storage operation failed. */ #define BLE_HS_ESTORE_FAIL 28 + +/** Operation was preempted. */ #define BLE_HS_EPREEMPTED 29 + +/** Operation disabled. */ #define BLE_HS_EDISABLED 30 + +/** Operation stalled. */ #define BLE_HS_ESTALLED 31 /** Error base for ATT errors */ @@ -305,6 +367,7 @@ struct ble_hs_cfg { void *store_status_arg; }; +/** Configuration structure for the NimBLE Host stack. */ extern struct ble_hs_cfg ble_hs_cfg; /** From 68447ea14d4b5b9aa5cb2fb103db9084186a18e7 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 4 Aug 2023 13:17:29 +0200 Subject: [PATCH 5/9] ci: Fix build due to nrfx update We should move to using "newt upgrade" eventually. --- .github/workflows/build_targets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index 235a8c2840..3112cac803 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -54,7 +54,7 @@ jobs: git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb - git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.8.0 repos/nordic-nrfx + git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.11.0 repos/nordic-nrfx - name: Build targets shell: bash run: | From 5812f7d9824554eedaf49ebcc16f3618dcd24ac0 Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 28 Jul 2023 16:10:17 +0200 Subject: [PATCH 6/9] host: Added function to parse UUID from string --- nimble/host/include/host/ble_uuid.h | 19 ++++ nimble/host/src/ble_uuid.c | 150 ++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) diff --git a/nimble/host/include/host/ble_uuid.h b/nimble/host/include/host/ble_uuid.h index a63104b4c1..be96bb4227 100644 --- a/nimble/host/include/host/ble_uuid.h +++ b/nimble/host/include/host/ble_uuid.h @@ -253,6 +253,25 @@ void ble_uuid_copy(ble_uuid_any_t *dst, const ble_uuid_t *src); */ char *ble_uuid_to_str(const ble_uuid_t *uuid, char *dst); +/** + * @brief Converts the specified UUID string to ble_uuid_any_t representation. + * If the UUID is recognised as Bluetooth SIG UUID, it will provide its + * 32-bit or 16-bit representation. + * + * Example 128-bit string representations: + * o "12345678-1234-1234-1234-123456789abc" + * o "12345678123412341234123456789abc" + * + * @param uuid Destination UUID. + * @param str The source string UUID. + * + * @return 0 on success, + * BLE_HS_EINVAL if the specified UUID string has wrong size or + * contains disallowed characters. + */ +int +ble_uuid_from_str(ble_uuid_any_t *uuid, const char *str); + /** @brief Converts the specified 16-bit UUID to a uint16_t. * * @param uuid The source UUID to convert. diff --git a/nimble/host/src/ble_uuid.c b/nimble/host/src/ble_uuid.c index acf016a136..afc437b786 100644 --- a/nimble/host/src/ble_uuid.c +++ b/nimble/host/src/ble_uuid.c @@ -26,6 +26,10 @@ #include "ble_hs_priv.h" #include "host/ble_uuid.h" +#define BLE_UUID16_STR_MAX_LEN 6 +#define BLE_UUID32_STR_MAX_LEN 10 +#define BLE_UUID128_STR_MAX_LEN 36 + static uint8_t ble_uuid_base[16] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -40,6 +44,52 @@ static uint8_t ble_uuid_base[16] = { #define VERIFY_UUID(uuid) #endif +static int +hex2val(char c, uint8_t *value) +{ + if (c >= '0' && c <= '9') { + *value = c - '0'; + } else if (c >= 'a' && c <= 'f') { + *value = c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + *value = c - 'A' + 10; + } else { + return BLE_HS_EINVAL; + } + return 0; +} + + +static size_t +hex2bin(const char *hex, uint8_t *bin, size_t bin_len) +{ + size_t len = 0; + uint8_t tmp_val; + int rc; + + while (*hex && len < bin_len) { + rc = hex2val(*hex++, &tmp_val); + if (rc < 0) { + return 0; + } + + bin[len] = tmp_val << 4; + + if (!*hex) { + len++; + break; + } + + rc = hex2val(*hex++, &tmp_val); + if (rc < 0) { + return 0; + } + bin[len++] |= tmp_val; + } + + return len; +} + int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len) { @@ -136,6 +186,106 @@ ble_uuid_to_str(const ble_uuid_t *uuid, char *dst) return dst; } +int +ble_uuid_from_str(ble_uuid_any_t *uuid, const char *str) +{ + uint8_t tmp_rslt = 0; + uint8_t *u8p; + const char *str_ptr; + uint16_t u16 = 0; + uint32_t u32 = 0; + int len = (int) strlen(str); + + if ((len < 4) || (len % 2 != 0)) { + return BLE_HS_EINVAL; + } + + str_ptr = &str[len - 2]; + + if (len <= BLE_UUID16_STR_MAX_LEN) { + uuid->u.type = BLE_UUID_TYPE_16; + } else if (len <= BLE_UUID32_STR_MAX_LEN) { + uuid->u.type = BLE_UUID_TYPE_32; + } else if (len <= BLE_UUID128_STR_MAX_LEN) { + uuid->u.type = BLE_UUID_TYPE_128; + } else { + return BLE_HS_EINVAL; + } + + switch (uuid->u.type) { + case BLE_UUID_TYPE_128: + uuid->u.type = BLE_UUID_TYPE_128; + u8p = uuid->u128.value; + for (int i = 0; i < 16; i++) { + if (hex2bin(str_ptr, u8p, 1) != 1) { + return BLE_HS_EINVAL; + } + + /* Check if string end */ + if (str_ptr == str) { + break; + } + + /* Remove '-' */ + if (*(str_ptr - 1) == '-') { + str_ptr--; + } + + str_ptr -= 2; + u8p++; + } + + if (memcmp(ble_uuid_base, uuid->u128.value, 12) == 0) { + uint8_t *tmp_ptr = &uuid->u128.value[12]; + uint32_t tmp_val32 = 0; + for (int i = 0; i < 4; i++) { + tmp_val32 |= ((uint32_t)(*tmp_ptr++) << 8 * i); + } + + if (tmp_val32 <= UINT16_MAX) { + uuid->u.type = BLE_UUID_TYPE_16; + uuid->u16.value = (uint16_t) tmp_val32; + } else { + uuid->u.type = BLE_UUID_TYPE_32; + uuid->u32.value = tmp_val32; + } + } + break; + case BLE_UUID_TYPE_32: + for (int i = 0; i < 4; i++) { + if (hex2bin(str_ptr, &tmp_rslt, 1) != 1) { + return BLE_HS_EINVAL; + } + u32 |= ((uint32_t) tmp_rslt) << (i * 8); + + if (str_ptr == str) { + break; + } + str_ptr -= 2; + } + uuid->u32.value = u32; + break; + case BLE_UUID_TYPE_16: + for (int i = 0; i < 2; i++) { + if (hex2bin(str_ptr, &tmp_rslt, 1) != 1) { + return BLE_HS_EINVAL; + } + u16 |= ((uint32_t) tmp_rslt) << (i * 8); + + if (str_ptr == str) { + break; + } + str_ptr -= 2; + } + uuid->u16.value = u16; + break; + default: + return BLE_HS_EINVAL; + } + + return 0; +} + uint16_t ble_uuid_u16(const ble_uuid_t *uuid) { From ebae7a2252b14ad43a687cebfe7a29e0bcba315f Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 28 Jul 2023 16:10:57 +0200 Subject: [PATCH 7/9] nimble/host/test: Added unit tests for UUID from string --- nimble/host/test/src/ble_uuid_test.c | 229 ++++++++++++++++++++++++++- 1 file changed, 225 insertions(+), 4 deletions(-) diff --git a/nimble/host/test/src/ble_uuid_test.c b/nimble/host/test/src/ble_uuid_test.c index 786e371ac4..379fd1f441 100644 --- a/nimble/host/test/src/ble_uuid_test.c +++ b/nimble/host/test/src/ble_uuid_test.c @@ -24,8 +24,75 @@ #include "host/ble_uuid.h" #include "ble_hs_test_util.h" -TEST_CASE_SELF(ble_uuid_test) -{ +#define DEBUG 0 + +#if DEBUG +#define DEBUG_PRINT(fmt, ...) printf(fmt, ## __VA_ARGS__) +#else +#define DEBUG_PRINT(fmt, ...) +#endif + +#define TEST_UUID_128_1_STR "0329a25a-c4c4-4923-8039-4bacfa18eb72" +#define TEST_UUID_128_1 \ + 0x72, 0xeb, 0x18, 0xfa, 0xac, 0x4b, 0x39, 0x80, \ + 0x23, 0x49, 0xc4, 0xc4, 0x5a, 0xa2, 0x29, 0x03 + +#define TEST_UUID_128_2_STR "e3ec4966df944981a772985ff8d75dff" +#define TEST_UUID_128_2 \ + 0xff, 0x5d, 0xd7, 0xf8, 0x5f, 0x98, 0x72, 0xa7, \ + 0x81, 0x49, 0x94, 0xdf, 0x66, 0x49, 0xec, 0xe3 + +#define TEST_UUID_128_3_STR "00002a37-0000-1000-8000-00805f9b34fb" +#define TEST_UUID_128_3 \ + 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, \ + 0x00, 0x10, 0x00, 0x00, 0x37, 0x2a, 0x00, 0x00 +#define TEST_UUID_128_3_AS_16 ((uint16_t) 0x2a37) + +#define TEST_32UUID1_STR "0x0329a25a" +#define TEST_32UUID1 ((uint32_t)0x0329a25a) + +#define TEST_32UUID2_STR "e3ec4966" +#define TEST_32UUID2 ((uint32_t)0xe3ec4966) + +#define TEST_16UUID1_STR "0x0329" +#define TEST_16UUID1 ((uint16_t)0x0329) + +#define TEST_16UUID2_STR "e3ec" +#define TEST_16UUID2 ((uint16_t)0xe3ec) + +static const ble_uuid128_t test_uuid128[4] = { + BLE_UUID128_INIT(TEST_UUID_128_1), + BLE_UUID128_INIT(TEST_UUID_128_2), + BLE_UUID128_INIT(TEST_UUID_128_3) +}; + +static const char test_str128[][100] = { + TEST_UUID_128_1_STR, + TEST_UUID_128_2_STR, + TEST_UUID_128_3_STR +}; + +static const ble_uuid32_t test_uuid32[3] = { + BLE_UUID32_INIT(TEST_32UUID1), + BLE_UUID32_INIT(TEST_32UUID2), +}; + +static const char test_str32[][100] = { + TEST_32UUID1_STR, + TEST_32UUID2_STR, +}; + +static const ble_uuid16_t test_uuid16[3] = { + BLE_UUID16_INIT(TEST_16UUID1), + BLE_UUID16_INIT(TEST_16UUID2), +}; + +static const char test_str16[][100] = { + TEST_16UUID1_STR, + TEST_16UUID2_STR, +}; + +TEST_CASE_SELF(ble_uuid_test) { uint8_t buf_16[2] = { 0x00, 0x18 }; uint8_t buf_128[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; @@ -70,7 +137,161 @@ TEST_CASE_SELF(ble_uuid_test) ble_hs_test_util_assert_mbufs_freed(NULL); } -TEST_SUITE(ble_uuid_test_suite) -{ +TEST_CASE_SELF(ble_uuid_from_string_test) { + int rc; + ble_uuid_any_t uuid128[3]; + ble_uuid_any_t uuid32[3]; + ble_uuid_any_t uuid16[3]; + + for (int i = 0; i < 2; i++) { + DEBUG_PRINT("Test 128bit: %d\n", i); + ble_uuid_from_str((ble_uuid_any_t * ) &uuid128[i], test_str128[i]); + DEBUG_PRINT("Original:\n"); + for (int j = 0; j < 16; j++) { + DEBUG_PRINT("%2x, ", test_uuid128[i].value[j]); + } + DEBUG_PRINT("\nConverted:\n"); + for (int j = 0; j < 16; j++) { + DEBUG_PRINT("%2x, ", uuid128[i].u128.value[j]); + } + DEBUG_PRINT("\n"); + DEBUG_PRINT("The same: %s\n", + ble_uuid_cmp((const ble_uuid_t *) &uuid128[i].u128, + (const ble_uuid_t *) &test_uuid128[i]) == 0 + ? "true" : "false"); + rc = ble_uuid_cmp((const ble_uuid_t *) &uuid128[i].u128, + (const ble_uuid_t *) &test_uuid128[i]); + TEST_ASSERT(rc == 0); + } + + DEBUG_PRINT("\n"); + DEBUG_PRINT("\n"); + + for (int i = 0; i < 2; i++) { + DEBUG_PRINT("Test 32bit: %d\n", i); + ble_uuid_from_str((ble_uuid_any_t * ) &uuid32[i], test_str32[i]); + DEBUG_PRINT("Original:\n"); + DEBUG_PRINT("%x, ", test_uuid32[i].value); + DEBUG_PRINT("\nConverted:\n"); + DEBUG_PRINT("%x, ", uuid32[i].u32.value); + DEBUG_PRINT("\n"); + DEBUG_PRINT("The same: %s\n", + ble_uuid_cmp((const ble_uuid_t *) &uuid32[i].u32, + (const ble_uuid_t *) &test_uuid32[i]) == 0 + ? "true" : "false"); + rc = ble_uuid_cmp((const ble_uuid_t *) &uuid32[i].u32, + (const ble_uuid_t *) &test_uuid32[i]); + TEST_ASSERT(rc == 0); + } + + DEBUG_PRINT("\n"); + DEBUG_PRINT("\n"); + + for (int i = 0; i < 2; i++) { + DEBUG_PRINT("Test 16bit: %d\n", i); + ble_uuid_from_str((ble_uuid_any_t * ) &uuid16[i], test_str16[i]); + DEBUG_PRINT("Original:\n"); + DEBUG_PRINT("%x, ", test_uuid16[i].value); + DEBUG_PRINT("\nConverted:\n"); + DEBUG_PRINT("%x, ", uuid16[i].u16.value); + DEBUG_PRINT("\n"); + DEBUG_PRINT("The same: %s\n", + ble_uuid_cmp((const ble_uuid_t *) &uuid16[i].u16, + (const ble_uuid_t *) &test_uuid16[i]) == 0 + ? "true" : "false"); + rc = ble_uuid_cmp((const ble_uuid_t *) &uuid16[i].u16, + (const ble_uuid_t *) &test_uuid16[i]); + TEST_ASSERT(rc == 0); + } + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_uuid_from_string_sig_test) { + int rc; + ble_uuid_any_t uuid; + + ble_uuid16_t test_uuid = BLE_UUID16_INIT(TEST_UUID_128_3_AS_16); + + DEBUG_PRINT("Test %d\n", 0); + ble_uuid_from_str(&uuid, test_str128[2]); + DEBUG_PRINT("Original:\n"); + for (int j = 0; j < 16; j++) { + DEBUG_PRINT("%2x, ", test_uuid128[2].value[j]); + } + DEBUG_PRINT("\nConverted:\n"); + DEBUG_PRINT("%x\n", uuid.u16.value); + DEBUG_PRINT("The same: %s\n", + ble_uuid_cmp((const ble_uuid_t *) &uuid.u16, + (const ble_uuid_t *) &test_uuid) == 0 ? "true" + : "false"); + rc = ble_uuid_cmp((const ble_uuid_t *)&uuid.u16, + (const ble_uuid_t *)&test_uuid); + TEST_ASSERT(rc == 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_uuid_to_str_and_back_test) { + int rc; + ble_uuid128_t uuid = BLE_UUID128_INIT(TEST_UUID_128_1); + ble_uuid_any_t final_uuid; + char uuid_str[100]; + + ble_uuid_to_str((const ble_uuid_t *)&uuid, uuid_str); + + DEBUG_PRINT("String: %s\n", uuid_str); + + rc = ble_uuid_from_str(&final_uuid, (const char *)uuid_str); + TEST_ASSERT(rc == 0); + + rc = ble_uuid_cmp((const ble_uuid_t *)&uuid, (const ble_uuid_t *)&final_uuid.u128); + TEST_ASSERT(rc == 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_uuid_to_str_too_short) { + int rc; + ble_uuid_any_t final_uuid; + char uuid_str[4] = "012"; + + DEBUG_PRINT("String: %s\n", uuid_str); + + rc = ble_uuid_from_str(&final_uuid, (const char *)uuid_str); + TEST_ASSERT(rc == BLE_HS_EINVAL); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_uuid_to_str_sig_to_16_and_32) { + int rc; + ble_uuid_any_t final_uuid; + char uuid_str16[37] = "0000ffff-0000-1000-8000-00805f9b34fb"; + char uuid_str32[37] = "ffffffff-0000-1000-8000-00805f9b34fb"; + + DEBUG_PRINT("String16: %s\n", uuid_str16); + DEBUG_PRINT("String32: %s\n", uuid_str32); + + rc = ble_uuid_from_str(&final_uuid, (const char *)uuid_str16); + TEST_ASSERT(rc == 0); + TEST_ASSERT(final_uuid.u.type == BLE_UUID_TYPE_16); + TEST_ASSERT(final_uuid.u16.value == UINT16_MAX); + memset(&final_uuid, 0, sizeof(ble_uuid_any_t)); + + rc = ble_uuid_from_str(&final_uuid, (const char *)uuid_str32); + TEST_ASSERT(rc == 0); + TEST_ASSERT(final_uuid.u.type == BLE_UUID_TYPE_32); + TEST_ASSERT(final_uuid.u32.value == UINT32_MAX); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_SUITE(ble_uuid_test_suite) { ble_uuid_test(); + ble_uuid_from_string_test(); + ble_uuid_from_string_sig_test(); + ble_uuid_to_str_and_back_test(); + ble_uuid_to_str_too_short(); + ble_uuid_to_str_sig_to_16_and_32(); } From 74517c7e7658c6afac52c895f06cc9707e344931 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 7 Aug 2023 10:13:00 +0200 Subject: [PATCH 8/9] nimble/ll: Fix build with BLE_LL_HCI_LLCP_TRACE enabled This was not updated after HCI VS event sending cleanup. --- nimble/controller/src/ble_ll_hci_ev.c | 6 +++--- nimble/include/nimble/hci_common.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index fb4424a596..dc74806258 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -643,16 +643,16 @@ void ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, void *pdu, size_t length) { - struct ble_hci_ev_vs_debug *ev; + struct ble_hci_ev_vs *ev; struct ble_hci_ev *hci_ev; hci_ev = ble_transport_alloc_evt(1); if (hci_ev) { - hci_ev->opcode = BLE_HCI_EVCODE_VS_DEBUG; + hci_ev->opcode = BLE_HCI_EVCODE_VS; hci_ev->length = sizeof(*ev) + 8 + length; ev = (void *) hci_ev->data; - ev->id = 0x17; + ev->id = BLE_HCI_VS_SUBEV_ID_LLCP_TRACE; ev->data[0] = type; put_le16(&ev->data[1], handle); put_le16(&ev->data[3], count); diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 93429a2f52..742824d877 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1611,6 +1611,8 @@ struct ble_hci_ev_vs_css_slot_changed { uint16_t slot_idx; }; +#define BLE_HCI_VS_SUBEV_ID_LLCP_TRACE (0x17) + /* LE sub-event codes */ #define BLE_HCI_LE_SUBEV_CONN_COMPLETE (0x01) struct ble_hci_ev_le_subev_conn_complete { From fa5cc4702b46ab96003902921ba678db4cf67c98 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 7 Aug 2023 10:14:36 +0200 Subject: [PATCH 9/9] ci: Enable BLE_LL_HCI_LLCP_TRACE when building blehci nordic_pca10056_blehci_all_enabled was missing BLE_LL_HCI_LLCP_TRACE setting. --- .github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml b/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml index eace456a5c..5bb326eb62 100644 --- a/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml +++ b/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml @@ -36,3 +36,4 @@ syscfg.vals: BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: 12 BLE_PHY_DBG_TIME_WFR_PIN: 16 BLE_XTAL_SETTLE_TIME: 1500 + BLE_LL_HCI_LLCP_TRACE: 1