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-10-20 12:20:01

            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              :          *  Before returning the callback, @ref bt_goep::transport_ops should be initialized with
     147              :          *  valid address of type @ref bt_goep_transport_ops object. The field `mtu` of
     148              :          *  @ref bt_obex::rx could be passed with valid value. Or set it to zero, the mtu will be
     149              :          *  calculated according to @kconfig{CONFIG_BT_GOEP_RFCOMM_MTU}.
     150              :          *
     151              :          *  @warning It is the responsibility of the caller to zero out the parent of the GOEP
     152              :          *  object.
     153              :          *
     154              :          *  @param conn The connection that is requesting authorization.
     155              :          *  @param server Pointer to the server structure this callback relates to.
     156              :          *  @param goep Pointer to received the allocated GOEP object.
     157              :          *
     158              :          *  @return 0 in case of success or negative value in case of error.
     159              :          *  @return -ENOMEM if no available space for new object.
     160              :          *  @return -EACCES if application did not authorize the connection.
     161              :          *  @return -EPERM if encryption key size is too short.
     162              :          */
     163            1 :         int (*accept)(struct bt_conn *conn, struct bt_goep_transport_rfcomm_server *server,
     164              :                       struct bt_goep **goep);
     165              : 
     166            0 :         sys_snode_t node;
     167              : };
     168              : 
     169              : /** @brief Register GOEP RFCOMM server.
     170              :  *
     171              :  *  Register GOEP server for a RFCOMM channel @ref bt_rfcomm_server::channel, each new connection
     172              :  *  is authorized using the @ref bt_goep_transport_rfcomm_server::accept callback which in case of
     173              :  *  success shall allocate the GOEP structure @ref bt_goep to be used by the new GOEP connection.
     174              :  *
     175              :  *  @ref bt_rfcomm_server::channel may be pre-set to a given value (not recommended however). Or be
     176              :  *  left as 0, in which case the channel will be auto-allocated by RFCOMM.
     177              :  *
     178              :  *  @param server Server structure.
     179              :  *
     180              :  *  @return 0 in case of success or negative value in case of error.
     181              :  */
     182            1 : int bt_goep_transport_rfcomm_server_register(struct bt_goep_transport_rfcomm_server *server);
     183              : 
     184              : /** @brief Connect GOEP transport over RFCOMM
     185              :  *
     186              :  *  Connect GOEP transport over RFCOMM, once the connection is completed, the callback
     187              :  *  @ref bt_goep_transport_ops::connected is called. If the connection is rejected,
     188              :  *  @ref bt_goep_transport_ops::disconnected callback is called instead.
     189              :  *  The GOEP object is passed (over an address of it) as second parameter, application should
     190              :  *  create transport dedicated GOEP object @ref bt_goep. Then pass to this API the location
     191              :  *  (address).
     192              :  *  Before calling the API, @ref bt_goep::transport_ops should be initialized with valid address
     193              :  *  of type @ref bt_goep_transport_ops object. The field `mtu` of @ref bt_obex::rx could be passed
     194              :  *  with valid value. Or set it to zero, the mtu will be calculated according to
     195              :  *  @kconfig{CONFIG_BT_GOEP_RFCOMM_MTU}.
     196              :  *  The RFCOMM channel is passed as third parameter. It is the RFCOMM channel of RFCOMM server of
     197              :  *  peer device.
     198              :  *
     199              :  *  @warning It is the responsibility of the caller to zero out the parent of the GOEP object.
     200              :  *
     201              :  *  @param conn Connection object.
     202              :  *  @param goep GOEP object.
     203              :  *  @param channel RFCOMM channel to connect to.
     204              :  *
     205              :  *  @return 0 in case of success or negative value in case of error.
     206              :  */
     207            1 : int bt_goep_transport_rfcomm_connect(struct bt_conn *conn, struct bt_goep *goep, uint8_t channel);
     208              : 
     209              : /** @brief Disconnect GOEP transport from RFCOMM
     210              :  *
     211              :  *  Disconnect GOEP RFCOMM transport.
     212              :  *
     213              :  *  @param goep GOEP object.
     214              :  *
     215              :  *  @return 0 in case of success or negative value in case of error.
     216              :  */
     217            1 : int bt_goep_transport_rfcomm_disconnect(struct bt_goep *goep);
     218              : 
     219              : /** @} */
     220              : 
     221              : /**
     222              :  * @defgroup bt_goep_transport_l2cap GOEP transport L2CAP
     223              :  * @ingroup bt_goep
     224              :  * @{
     225              :  */
     226              : 
     227              : /** @brief GOEP Server structure for GOEP v2.0 and later. */
     228            1 : struct bt_goep_transport_l2cap_server {
     229              :         /** @brief L2CAP PSM for GOEP v2.0 and later
     230              :          *
     231              :          *  The @ref bt_goep_transport_l2cap_server::l2cap is used to register a l2cap server.
     232              :          *
     233              :          *  The @ref bt_l2cap_server::psm needs to be passed with a pre-set psm (not recommended
     234              :          *  however), Or give a value `0` to make the psm be auto-allocated when
     235              :          *  @ref bt_goep_transport_l2cap_server_register is called.
     236              :          *  The @ref bt_l2cap_server::sec_level is used to require minimum security level for l2cap
     237              :          *  server.
     238              :          *  The @ref bt_l2cap_server::accept should be not used by GOEP application, and instead
     239              :          *  the @ref bt_goep_transport_l2cap_server::accept will be used.
     240              :          */
     241            1 :         struct bt_l2cap_server l2cap;
     242              : 
     243              :         /** @brief Server accept callback
     244              :          *
     245              :          *  This callback is called whenever a new incoming GOEP connection requires
     246              :          *  authorization.
     247              :          *
     248              :          *  Before returning the callback, @ref bt_goep::transport_ops should be initialized with
     249              :          *  valid address of type @ref bt_goep_transport_ops object. The field `mtu` of
     250              :          *  @ref bt_obex::rx could be passed with valid value. Or set it to zero, the mtu will be
     251              :          *  calculated according to @kconfig{CONFIG_BT_GOEP_L2CAP_MTU}.
     252              :          *
     253              :          *  @warning It is the responsibility of the caller to zero out the parent of the GOEP
     254              :          *  object.
     255              :          *
     256              :          *  @param conn The connection that is requesting authorization.
     257              :          *  @param server Pointer to the server structure this callback relates to.
     258              :          *  @param goep Pointer to received the allocated GOEP object.
     259              :          *
     260              :          *  @return 0 in case of success or negative value in case of error.
     261              :          *  @return -ENOMEM if no available space for new object.
     262              :          *  @return -EACCES if application did not authorize the connection.
     263              :          *  @return -EPERM if encryption key size is too short.
     264              :          */
     265            1 :         int (*accept)(struct bt_conn *conn, struct bt_goep_transport_l2cap_server *server,
     266              :                       struct bt_goep **goep);
     267              : 
     268            0 :         sys_snode_t node;
     269              : };
     270              : 
     271              : /** @brief Register GOEP L2CAP server.
     272              :  *
     273              :  *  Register GOEP server for a L2CAP PSM @ref bt_l2cap_server::psm. each new connection is
     274              :  *  authorized using the @ref bt_goep_transport_l2cap_server::accept callback which in case of
     275              :  *  success shall allocate the GOEP structure @ref bt_goep to be used by the new GOEP connection.
     276              :  *
     277              :  *  For L2CAP PSM, for fixed, SIG-assigned PSMs (in the range 0x0001-0x0eff) the PSM should not be
     278              :  *  used. For dynamic PSMs (in the range 0x1000-0xffff),
     279              :  *  @ref bt_l2cap_server::psm may be pre-set to a given value (not recommended however). And it
     280              :  *  shall have the least significant bit of the most significant octet equal to 0 and the least
     281              :  *  significant bit of all other octets equal to 1. Or be left as 0, in which case the channel
     282              :  *  will be auto-allocated by L2CAP.
     283              :  *
     284              :  *  @param server Server structure.
     285              :  *
     286              :  *  @return 0 in case of success or negative value in case of error.
     287              :  */
     288            1 : int bt_goep_transport_l2cap_server_register(struct bt_goep_transport_l2cap_server *server);
     289              : 
     290              : /** @brief Connect GOEP transport over L2CAP
     291              :  *
     292              :  *  Connect GOEP transport by L2CAP, once the connection is completed, the callback
     293              :  *  @ref bt_goep_transport_ops::connected is called. If the connection is rejected,
     294              :  *  @ref bt_goep_transport_ops::disconnected callback is called instead.
     295              :  *  The GOEP object is passed (over an address of it) as second parameter, application should
     296              :  *  create transport dedicated GOEP object @ref bt_goep. Then pass to this API the location
     297              :  *  (address).
     298              :  *  Before calling the API, @ref bt_goep::transport_ops should be initialized with valid address
     299              :  *  of type @ref bt_goep_transport_ops object. The field `mtu` of @ref bt_obex::rx could be passed
     300              :  *  with valid value. Or set it to zero, the mtu will be calculated according to
     301              :  *  @kconfig{CONFIG_BT_GOEP_L2CAP_MTU}.
     302              :  *  The L2CAP PSM is passed as third parameter. It is the RFCOMM channel of RFCOMM server of peer
     303              :  *  device.
     304              :  *
     305              :  *  @warning It is the responsibility of the caller to zero out the parent of the GOEP object.
     306              :  *
     307              :  *  @param conn Connection object.
     308              :  *  @param goep GOEP object.
     309              :  *  @param psm L2CAP PSM to connect to.
     310              :  *
     311              :  *  @return 0 in case of success or negative value in case of error.
     312              :  */
     313            1 : int bt_goep_transport_l2cap_connect(struct bt_conn *conn, struct bt_goep *goep, uint16_t psm);
     314              : 
     315              : /** @brief Disconnect GOEP transport from L2CAP channel
     316              :  *
     317              :  *  Disconnect GOEP L2CAP transport.
     318              :  *
     319              :  *  @param goep GOEP object.
     320              :  *
     321              :  *  @return 0 in case of success or negative value in case of error.
     322              :  */
     323            1 : int bt_goep_transport_l2cap_disconnect(struct bt_goep *goep);
     324              : 
     325              : /** @} */
     326              : 
     327              : /** @brief Allocate the buffer from given pool after reserving head room for GOEP
     328              :  *
     329              :  *  For GOEP connection over RFCOMM, the reserved head room includes OBEX, RFCOMM, L2CAP and ACL
     330              :  *  headers.
     331              :  *  For GOEP connection over L2CAP, the reserved head room includes OBEX, L2CAP and ACL headers.
     332              :  *
     333              :  *  @param goep GOEP object.
     334              :  *  @param pool Which pool to take the buffer from.
     335              :  *
     336              :  *  @return New buffer.
     337              :  */
     338            1 : struct net_buf *bt_goep_create_pdu(struct bt_goep *goep, struct net_buf_pool *pool);
     339              : 
     340              : #ifdef __cplusplus
     341              : }
     342              : #endif
     343              : 
     344              : /**
     345              :  * @}
     346              :  */
     347              : 
     348              : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_GOEP_H_ */
        

Generated by: LCOV version 2.0-1