LCOV - code coverage report
Current view: top level - zephyr/bluetooth/classic - goep.h Coverage Total Hit
Test: new.info Lines: 76.0 % 25 19
Test Date: 2025-09-05 20:47:19

            Line data    Source code
       1            0 : /* goep.h - Bluetooth Generic Object Exchange Profile handling */
       2              : 
       3              : /*
       4              :  * Copyright 2024-2025 NXP
       5              :  *
       6              :  * SPDX-License-Identifier: Apache-2.0
       7              :  */
       8              : 
       9              : #ifndef ZEPHYR_INCLUDE_BLUETOOTH_GOEP_H_
      10              : #define ZEPHYR_INCLUDE_BLUETOOTH_GOEP_H_
      11              : 
      12              : /**
      13              :  * @brief Generic Object Exchange Profile (GOEP)
      14              :  * @defgroup bt_goep Generic Object Exchange Profile (GOEP)
      15              :  * @ingroup bluetooth
      16              :  * @{
      17              :  */
      18              : 
      19              : #include <zephyr/kernel.h>
      20              : #include <string.h>
      21              : #include <errno.h>
      22              : #include <stdbool.h>
      23              : 
      24              : #include <zephyr/bluetooth/bluetooth.h>
      25              : #include <zephyr/bluetooth/conn.h>
      26              : #include <zephyr/bluetooth/l2cap.h>
      27              : #include <zephyr/bluetooth/classic/rfcomm.h>
      28              : #include <zephyr/bluetooth/classic/obex.h>
      29              : 
      30              : #ifdef __cplusplus
      31              : extern "C" {
      32              : #endif
      33              : 
      34              : struct bt_goep;
      35              : 
      36              : /** @brief GOEP transport operations structure.
      37              :  *
      38              :  * The object has to stay valid and constant for the lifetime of the GOEP server and client.
      39              :  */
      40            1 : struct bt_goep_transport_ops {
      41              :         /** @brief GOEP transport connected callback
      42              :          *
      43              :          *  If this callback is provided it will be called whenever the GOEP transport connection
      44              :          *  completes.
      45              :          *
      46              :          *  @param conn The ACL connection.
      47              :          *  @param goep The GOEP object that has been connected.
      48              :          */
      49            1 :         void (*connected)(struct bt_conn *conn, struct bt_goep *goep);
      50              : 
      51              :         /** @brief GOEP transport disconnected callback
      52              :          *
      53              :          *  If this callback is provided it will be called whenever the GOEP transport is
      54              :          *  disconnected, including when a connection gets rejected.
      55              :          *
      56              :          *  @param goep The GOEP object that has been disconnected.
      57              :          */
      58            1 :         void (*disconnected)(struct bt_goep *goep);
      59              : };
      60              : 
      61              : /** @brief Life-span states of GOEP transport.
      62              :  *
      63              :  *  Used only by internal APIs dealing with setting GOEP to proper transport state depending on
      64              :  *  operational context.
      65              :  *
      66              :  *  GOEP transport enters the @ref BT_GOEP_TRANSPORT_CONNECTING state upon
      67              :  *  @ref bt_goep_transport_l2cap_connect, @ref bt_goep_transport_rfcomm_connect or upon returning
      68              :  *  from @ref bt_goep_transport_rfcomm_server::accept and bt_goep_transport_l2cap_server::accept.
      69              :  *
      70              :  *  When GOEP transport leaves the @ref BT_GOEP_TRANSPORT_CONNECTING state and enters the @ref
      71              :  *  BT_GOEP_TRANSPORT_CONNECTED, @ref bt_goep_transport_ops::connected is called.
      72              :  *
      73              :  *  When GOEP transport enters the @ref BT_GOEP_TRANSPORT_DISCONNECTED from other states,
      74              :  *  @ref bt_goep_transport_ops::disconnected is called.
      75              :  */
      76            1 : enum __packed bt_goep_transport_state {
      77              :         /** GOEP disconnected */
      78              :         BT_GOEP_TRANSPORT_DISCONNECTED,
      79              :         /** GOEP in connecting state */
      80              :         BT_GOEP_TRANSPORT_CONNECTING,
      81              :         /** GOEP ready for upper layer traffic on it */
      82              :         BT_GOEP_TRANSPORT_CONNECTED,
      83              :         /** GOEP in disconnecting state */
      84              :         BT_GOEP_TRANSPORT_DISCONNECTING,
      85              : };
      86              : 
      87            0 : struct bt_goep {
      88              :         /** @internal To be used for transport */
      89              :         union {
      90            0 :                 struct bt_rfcomm_dlc dlc;
      91            0 :                 struct bt_l2cap_br_chan chan;
      92              :         } _transport;
      93              : 
      94              :         /** @internal Peer GOEP Version
      95              :          *
      96              :          *  false - Peer supports GOEP v1.1. The GOEP transport is based on RFCOMM.
      97              :          *  `dlc` is used as transport.
      98              :          *
      99              :          *  true - peer supports GOEP v2.0 or later. The GOEP transport is based on L2CAP.
     100              :          *  `chan` is used as transport.
     101              :          */
     102              :         bool _goep_v2;
     103              : 
     104              :         /** @internal connection handle */
     105              :         struct bt_conn *_acl;
     106              : 
     107              :         /** @internal Saves the current transport state, @ref bt_goep_transport_state */
     108              :         atomic_t _state;
     109              : 
     110              :         /** @brief GOEP transport operations
     111              :          *
     112              :          *  The upper layer should pass the operations to `transport_ops` when
     113              :          *  providing the GOEP structure.
     114              :          */
     115            1 :         const struct bt_goep_transport_ops *transport_ops;
     116              : 
     117              :         /** @brief OBEX object */
     118            1 :         struct bt_obex obex;
     119              : };
     120              : 
     121              : /**
     122              :  * @defgroup bt_goep_transport_rfcomm GOEP transport RFCOMM
     123              :  * @ingroup bt_goep
     124              :  * @{
     125              :  */
     126              : 
     127              : /** @brief GOEP Server structure GOEP v1.1. */
     128            1 : struct bt_goep_transport_rfcomm_server {
     129              :         /** @brief RFCOMM server for GOEP v1.1
     130              :          *
     131              :          *  The @ref bt_goep_transport_rfcomm_server::rfcomm is used to register a rfcomm server.
     132              :          *
     133              :          *  The @ref bt_rfcomm_server::channel needs to be passed with a pre-set channel (not
     134              :          *  recommended however), Or give a value `0` to make the channel be auto-allocated when
     135              :          *  @ref bt_goep_transport_rfcomm_server_register is called.
     136              :          *  The @ref bt_rfcomm_server::accept should be not used by GOEP application, and instead
     137              :          *  the @ref bt_goep_transport_rfcomm_server::accept should be used.
     138              :          */
     139            1 :         struct bt_rfcomm_server rfcomm;
     140              : 
     141              :         /** @brief Server accept callback
     142              :          *
     143              :          *  This callback is called whenever a new incoming GOEP connection requires
     144              :          *  authorization.
     145              :          *
     146              :          *  @warning It is the responsibility of the caller to zero out the parent of the GOEP
     147              :          *  object.
     148              :          *
     149              :          *  @param conn The connection that is requesting authorization.
     150              :          *  @param server Pointer to the server structure this callback relates to.
     151              :          *  @param goep Pointer to received the allocated GOEP object.
     152              :          *
     153              :          *  @return 0 in case of success or negative value in case of error.
     154              :          *  @return -ENOMEM if no available space for new object.
     155              :          *  @return -EACCES if application did not authorize the connection.
     156              :          *  @return -EPERM if encryption key size is too short.
     157              :          */
     158            1 :         int (*accept)(struct bt_conn *conn, struct bt_goep_transport_rfcomm_server *server,
     159              :                       struct bt_goep **goep);
     160              : 
     161            0 :         sys_snode_t node;
     162              : };
     163              : 
     164              : /** @brief Register GOEP RFCOMM server.
     165              :  *
     166              :  *  Register GOEP server for a RFCOMM channel @ref bt_rfcomm_server::channel, each new connection
     167              :  *  is authorized using the @ref bt_goep_transport_rfcomm_server::accept callback which in case of
     168              :  *  success shall allocate the GOEP structure @ref bt_goep to be used by the new GOEP connection.
     169              :  *
     170              :  *  @ref bt_rfcomm_server::channel may be pre-set to a given value (not recommended however). Or be
     171              :  *  left as 0, in which case the channel will be auto-allocated by RFCOMM.
     172              :  *
     173              :  *  @param server Server structure.
     174              :  *
     175              :  *  @return 0 in case of success or negative value in case of error.
     176              :  */
     177            1 : int bt_goep_transport_rfcomm_server_register(struct bt_goep_transport_rfcomm_server *server);
     178              : 
     179              : /** @brief Connect GOEP transport over RFCOMM
     180              :  *
     181              :  *  Connect GOEP transport over RFCOMM, once the connection is completed, the callback
     182              :  *  @ref bt_goep_transport_ops::connected is called. If the connection is rejected,
     183              :  *  @ref bt_goep_transport_ops::disconnected callback is called instead.
     184              :  *  The GOEP object is passed (over an address of it) as second parameter, application should
     185              :  *  create transport dedicated GOEP object @ref bt_goep. Then pass to this API the location
     186              :  *  (address).
     187              :  *  Before calling the API, @ref bt_obex::client_ops and @ref bt_goep::transport_ops should
     188              :  *  be initialized with valid address of type @ref bt_obex_client_ops object and
     189              :  *  @ref bt_goep_transport_ops object. The field `mtu` of @ref bt_obex::rx could be passed with
     190              :  *  valid value. Or set it to zero, the mtu will be calculated according to
     191              :  *  @kconfig{CONFIG_BT_GOEP_RFCOMM_MTU}.
     192              :  *  The RFCOMM channel is passed as third parameter. It is the RFCOMM channel of RFCOMM server of
     193              :  *  peer device.
     194              :  *
     195              :  *  @warning It is the responsibility of the caller to zero out the parent of the GOEP object.
     196              :  *
     197              :  *  @param conn Connection object.
     198              :  *  @param goep GOEP object.
     199              :  *  @param channel RFCOMM channel to connect to.
     200              :  *
     201              :  *  @return 0 in case of success or negative value in case of error.
     202              :  */
     203            1 : int bt_goep_transport_rfcomm_connect(struct bt_conn *conn, struct bt_goep *goep, uint8_t channel);
     204              : 
     205              : /** @brief Disconnect GOEP transport from RFCOMM
     206              :  *
     207              :  *  Disconnect GOEP RFCOMM transport.
     208              :  *
     209              :  *  @param goep GOEP object.
     210              :  *
     211              :  *  @return 0 in case of success or negative value in case of error.
     212              :  */
     213            1 : int bt_goep_transport_rfcomm_disconnect(struct bt_goep *goep);
     214              : 
     215              : /** @} */
     216              : 
     217              : /**
     218              :  * @defgroup bt_goep_transport_l2cap GOEP transport L2CAP
     219              :  * @ingroup bt_goep
     220              :  * @{
     221              :  */
     222              : 
     223              : /** @brief GOEP Server structure for GOEP v2.0 and later. */
     224            1 : struct bt_goep_transport_l2cap_server {
     225              :         /** @brief L2CAP PSM for GOEP v2.0 and later
     226              :          *
     227              :          *  The @ref bt_goep_transport_l2cap_server::l2cap is used to register a l2cap server.
     228              :          *
     229              :          *  The @ref bt_l2cap_server::psm needs to be passed with a pre-set psm (not recommended
     230              :          *  however), Or give a value `0` to make the psm be auto-allocated when
     231              :          *  @ref bt_goep_transport_l2cap_server_register is called.
     232              :          *  The @ref bt_l2cap_server::sec_level is used to require minimum security level for l2cap
     233              :          *  server.
     234              :          *  The @ref bt_l2cap_server::accept should be not used by GOEP application, and instead
     235              :          *  the @ref bt_goep_transport_l2cap_server::accept will be used.
     236              :          */
     237            1 :         struct bt_l2cap_server l2cap;
     238              : 
     239              :         /** @brief Server accept callback
     240              :          *
     241              :          *  This callback is called whenever a new incoming GOEP connection requires
     242              :          *  authorization.
     243              :          *
     244              :          *  @warning It is the responsibility of the caller to zero out the parent of the GOEP
     245              :          *  object.
     246              :          *
     247              :          *  @param conn The connection that is requesting authorization.
     248              :          *  @param server Pointer to the server structure this callback relates to.
     249              :          *  @param goep Pointer to received the allocated GOEP object.
     250              :          *
     251              :          *  @return 0 in case of success or negative value in case of error.
     252              :          *  @return -ENOMEM if no available space for new object.
     253              :          *  @return -EACCES if application did not authorize the connection.
     254              :          *  @return -EPERM if encryption key size is too short.
     255              :          */
     256            1 :         int (*accept)(struct bt_conn *conn, struct bt_goep_transport_l2cap_server *server,
     257              :                       struct bt_goep **goep);
     258              : 
     259            0 :         sys_snode_t node;
     260              : };
     261              : 
     262              : /** @brief Register GOEP L2CAP server.
     263              :  *
     264              :  *  Register GOEP server for a L2CAP PSM @ref bt_l2cap_server::psm. each new connection is
     265              :  *  authorized using the @ref bt_goep_transport_l2cap_server::accept callback which in case of
     266              :  *  success shall allocate the GOEP structure @ref bt_goep to be used by the new GOEP connection.
     267              :  *
     268              :  *  For L2CAP PSM, for fixed, SIG-assigned PSMs (in the range 0x0001-0x0eff) the PSM should not be
     269              :  *  used. For dynamic PSMs (in the range 0x1000-0xffff),
     270              :  *  @ref bt_l2cap_server::psm may be pre-set to a given value (not recommended however). And it
     271              :  *  shall have the least significant bit of the most significant octet equal to 0 and the least
     272              :  *  significant bit of all other octets equal to 1. Or be left as 0, in which case the channel
     273              :  *  will be auto-allocated by L2CAP.
     274              :  *
     275              :  *  @param server Server structure.
     276              :  *
     277              :  *  @return 0 in case of success or negative value in case of error.
     278              :  */
     279            1 : int bt_goep_transport_l2cap_server_register(struct bt_goep_transport_l2cap_server *server);
     280              : 
     281              : /** @brief Connect GOEP transport over L2CAP
     282              :  *
     283              :  *  Connect GOEP transport by L2CAP, once the connection is completed, the callback
     284              :  *  @ref bt_goep_transport_ops::connected is called. If the connection is rejected,
     285              :  *  @ref bt_goep_transport_ops::disconnected callback is called instead.
     286              :  *  The GOEP object is passed (over an address of it) as second parameter, application should
     287              :  *  create transport dedicated GOEP object @ref bt_goep. Then pass to this API the location
     288              :  *  (address).
     289              :  *  Before calling the API, @ref bt_obex::client_ops and @ref bt_goep::transport_ops should
     290              :  *  be initialized with valid address of type @ref bt_obex_client_ops object and
     291              :  *  @ref bt_goep_transport_ops object. The field `mtu` of @ref bt_obex::rx could be passed with
     292              :  *  valid value. Or set it to zero, the mtu will be calculated according to
     293              :  *  @kconfig{CONFIG_BT_GOEP_L2CAP_MTU}.
     294              :  *  The L2CAP PSM is passed as third parameter. It is the RFCOMM channel of RFCOMM server of peer
     295              :  *  device.
     296              :  *
     297              :  *  @warning It is the responsibility of the caller to zero out the parent of the GOEP object.
     298              :  *
     299              :  *  @param conn Connection object.
     300              :  *  @param goep GOEP object.
     301              :  *  @param psm L2CAP PSM to connect to.
     302              :  *
     303              :  *  @return 0 in case of success or negative value in case of error.
     304              :  */
     305            1 : int bt_goep_transport_l2cap_connect(struct bt_conn *conn, struct bt_goep *goep, uint16_t psm);
     306              : 
     307              : /** @brief Disconnect GOEP transport from L2CAP channel
     308              :  *
     309              :  *  Disconnect GOEP L2CAP transport.
     310              :  *
     311              :  *  @param goep GOEP object.
     312              :  *
     313              :  *  @return 0 in case of success or negative value in case of error.
     314              :  */
     315            1 : int bt_goep_transport_l2cap_disconnect(struct bt_goep *goep);
     316              : 
     317              : /** @} */
     318              : 
     319              : /** @brief Allocate the buffer from given pool after reserving head room for GOEP
     320              :  *
     321              :  *  For GOEP connection over RFCOMM, the reserved head room includes OBEX, RFCOMM, L2CAP and ACL
     322              :  *  headers.
     323              :  *  For GOEP connection over L2CAP, the reserved head room includes OBEX, L2CAP and ACL headers.
     324              :  *
     325              :  *  @param goep GOEP object.
     326              :  *  @param pool Which pool to take the buffer from.
     327              :  *
     328              :  *  @return New buffer.
     329              :  */
     330            1 : struct net_buf *bt_goep_create_pdu(struct bt_goep *goep, struct net_buf_pool *pool);
     331              : 
     332              : #ifdef __cplusplus
     333              : }
     334              : #endif
     335              : 
     336              : /**
     337              :  * @}
     338              :  */
     339              : 
     340              : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_GOEP_H_ */
        

Generated by: LCOV version 2.0-1