Rename the data and metadata callbacks to _read(), for consistency with the corresponding function calls. Signed-off-by: Asbjørn Sæbø <asbjorn.sabo@nordicsemi.no>
1052 lines
31 KiB
C
1052 lines
31 KiB
C
/*
|
|
* Copyright (c) 2020-2022 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_OTS_H_
|
|
#define ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_OTS_H_
|
|
|
|
/**
|
|
* @brief Object Transfer Service (OTS)
|
|
* @defgroup bt_ots Object Transfer Service (OTS)
|
|
* @ingroup bluetooth
|
|
* @{
|
|
*
|
|
* [Experimental] Users should note that the APIs can change
|
|
* as a part of ongoing development.
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdbool.h>
|
|
#include <zephyr/types.h>
|
|
#include <sys/byteorder.h>
|
|
#include <sys/types.h>
|
|
#include <sys/util.h>
|
|
#include <bluetooth/conn.h>
|
|
#include <bluetooth/uuid.h>
|
|
#include <bluetooth/gatt.h>
|
|
|
|
/** @brief Size of OTS object ID (in bytes). */
|
|
#define BT_OTS_OBJ_ID_SIZE 6
|
|
|
|
/** @brief Minimum allowed value for object ID (except ID for directory listing) */
|
|
#define BT_OTS_OBJ_ID_MIN 0x000000000100
|
|
|
|
/** @brief Maximum allowed value for object ID (except ID for directory listing) */
|
|
#define BT_OTS_OBJ_ID_MAX 0xFFFFFFFFFFFF
|
|
|
|
/** @brief ID of the Directory Listing Object */
|
|
#define OTS_OBJ_ID_DIR_LIST 0x000000000000
|
|
|
|
/** @brief Mask for OTS object IDs, preserving the 48 bits */
|
|
#define BT_OTS_OBJ_ID_MASK BIT64_MASK(48)
|
|
|
|
/** @brief Length of OTS object ID string (in bytes). */
|
|
#define BT_OTS_OBJ_ID_STR_LEN 15
|
|
|
|
/** @brief Type of an OTS object. */
|
|
struct bt_ots_obj_type {
|
|
union {
|
|
/* Used to indicate UUID type */
|
|
struct bt_uuid uuid;
|
|
|
|
/* 16-bit UUID value */
|
|
struct bt_uuid_16 uuid_16;
|
|
|
|
/* 128-bit UUID value */
|
|
struct bt_uuid_128 uuid_128;
|
|
};
|
|
};
|
|
|
|
/** @brief Properties of an OTS object. */
|
|
enum {
|
|
/** Bit 0 Deletion of this object is permitted */
|
|
BT_OTS_OBJ_PROP_DELETE = 0,
|
|
|
|
/** Bit 1 Execution of this object is permitted */
|
|
BT_OTS_OBJ_PROP_EXECUTE = 1,
|
|
|
|
/** Bit 2 Reading this object is permitted */
|
|
BT_OTS_OBJ_PROP_READ = 2,
|
|
|
|
/** Bit 3 Writing data to this object is permitted */
|
|
BT_OTS_OBJ_PROP_WRITE = 3,
|
|
|
|
/** @brief Bit 4 Appending data to this object is permitted.
|
|
*
|
|
* Appending data increases its Allocated Size.
|
|
*/
|
|
BT_OTS_OBJ_PROP_APPEND = 4,
|
|
|
|
/** Bit 5 Truncation of this object is permitted */
|
|
BT_OTS_OBJ_PROP_TRUNCATE = 5,
|
|
|
|
/** @brief Bit 6 Patching this object is permitted
|
|
*
|
|
* Patching this object overwrites some of
|
|
* the object's existing contents.
|
|
*/
|
|
BT_OTS_OBJ_PROP_PATCH = 6,
|
|
|
|
/** Bit 7 This object is a marked object */
|
|
BT_OTS_OBJ_PROP_MARKED = 7,
|
|
};
|
|
|
|
/** @brief Set @ref BT_OTS_OBJ_PROP_DELETE property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_SET_PROP_DELETE(prop) \
|
|
WRITE_BIT(prop, BT_OTS_OBJ_PROP_DELETE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OBJ_PROP_EXECUTE property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_SET_PROP_EXECUTE(prop) \
|
|
WRITE_BIT(prop, BT_OTS_OBJ_PROP_EXECUTE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OBJ_PROP_READ property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_SET_PROP_READ(prop) \
|
|
WRITE_BIT(prop, BT_OTS_OBJ_PROP_READ, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OBJ_PROP_WRITE property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_SET_PROP_WRITE(prop) \
|
|
WRITE_BIT(prop, BT_OTS_OBJ_PROP_WRITE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OBJ_PROP_APPEND property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_SET_PROP_APPEND(prop) \
|
|
WRITE_BIT(prop, BT_OTS_OBJ_PROP_APPEND, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OBJ_PROP_TRUNCATE property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_SET_PROP_TRUNCATE(prop) \
|
|
WRITE_BIT(prop, BT_OTS_OBJ_PROP_TRUNCATE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OBJ_PROP_PATCH property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_SET_PROP_PATCH(prop) \
|
|
WRITE_BIT(prop, BT_OTS_OBJ_PROP_PATCH, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OBJ_SET_PROP_MARKED property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_SET_PROP_MARKED(prop) \
|
|
WRITE_BIT(prop, BT_OTS_OBJ_PROP_MARKED, 1)
|
|
|
|
/** @brief Get @ref BT_OTS_OBJ_PROP_DELETE property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_GET_PROP_DELETE(prop) \
|
|
((prop) & BIT(BT_OTS_OBJ_PROP_DELETE))
|
|
|
|
/** @brief Get @ref BT_OTS_OBJ_PROP_EXECUTE property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_GET_PROP_EXECUTE(prop) \
|
|
((prop) & BIT(BT_OTS_OBJ_PROP_EXECUTE))
|
|
|
|
/** @brief Get @ref BT_OTS_OBJ_PROP_READ property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_GET_PROP_READ(prop) \
|
|
((prop) & BIT(BT_OTS_OBJ_PROP_READ))
|
|
|
|
/** @brief Get @ref BT_OTS_OBJ_PROP_WRITE property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_GET_PROP_WRITE(prop) \
|
|
((prop) & BIT(BT_OTS_OBJ_PROP_WRITE))
|
|
|
|
/** @brief Get @ref BT_OTS_OBJ_PROP_APPEND property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_GET_PROP_APPEND(prop) \
|
|
((prop) & BIT(BT_OTS_OBJ_PROP_APPEND))
|
|
|
|
/** @brief Get @ref BT_OTS_OBJ_PROP_TRUNCATE property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_GET_PROP_TRUNCATE(prop) \
|
|
((prop) & BIT(BT_OTS_OBJ_PROP_TRUNCATE))
|
|
|
|
/** @brief Get @ref BT_OTS_OBJ_PROP_PATCH property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_GET_PROP_PATCH(prop) \
|
|
((prop) & BIT(BT_OTS_OBJ_PROP_PATCH))
|
|
|
|
/** @brief Get @ref BT_OTS_OBJ_PROP_MARKED property.
|
|
*
|
|
* @param prop Object properties.
|
|
*/
|
|
#define BT_OTS_OBJ_GET_PROP_MARKED(prop) \
|
|
((prop) & BIT(BT_OTS_OBJ_PROP_MARKED))
|
|
|
|
/** @brief Descriptor for OTS Object Size parameter. */
|
|
struct bt_ots_obj_size {
|
|
/** @brief Current Size */
|
|
uint32_t cur;
|
|
|
|
/** @brief Allocated Size */
|
|
uint32_t alloc;
|
|
} __packed;
|
|
|
|
/** @brief Object Action Control Point Feature bits. */
|
|
enum {
|
|
/** Bit 0 OACP Create Op Code Supported */
|
|
BT_OTS_OACP_FEAT_CREATE = 0,
|
|
|
|
/** Bit 1 OACP Delete Op Code Supported */
|
|
BT_OTS_OACP_FEAT_DELETE = 1,
|
|
|
|
/** Bit 2 OACP Calculate Checksum Op Code Supported */
|
|
BT_OTS_OACP_FEAT_CHECKSUM = 2,
|
|
|
|
/** Bit 3 OACP Execute Op Code Supported */
|
|
BT_OTS_OACP_FEAT_EXECUTE = 3,
|
|
|
|
/** Bit 4 OACP Read Op Code Supported */
|
|
BT_OTS_OACP_FEAT_READ = 4,
|
|
|
|
/** Bit 5 OACP Write Op Code Supported */
|
|
BT_OTS_OACP_FEAT_WRITE = 5,
|
|
|
|
/** Bit 6 Appending Additional Data to Objects Supported */
|
|
BT_OTS_OACP_FEAT_APPEND = 6,
|
|
|
|
/** Bit 7 Truncation of Objects Supported */
|
|
BT_OTS_OACP_FEAT_TRUNCATE = 7,
|
|
|
|
/** Bit 8 Patching of Objects Supported */
|
|
BT_OTS_OACP_FEAT_PATCH = 8,
|
|
|
|
/** Bit 9 OACP Abort Op Code Supported */
|
|
BT_OTS_OACP_FEAT_ABORT = 9,
|
|
};
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_SET_FEAT_CREATE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_CREATE(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_CREATE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_DELETE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_DELETE(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_DELETE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_CHECKSUM feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_CHECKSUM(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_CHECKSUM, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_EXECUTE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_EXECUTE(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_EXECUTE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_READ feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_READ(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_READ, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_WRITE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_WRITE(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_WRITE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_APPEND feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_APPEND(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_APPEND, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_TRUNCATE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_TRUNCATE(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_TRUNCATE, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_PATCH feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_PATCH(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_PATCH, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OACP_FEAT_ABORT feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_SET_FEAT_ABORT(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OACP_FEAT_ABORT, 1)
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_CREATE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_CREATE(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_CREATE))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_DELETE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_DELETE(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_DELETE))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_CHECKSUM feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_CHECKSUM(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_CHECKSUM))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_EXECUTE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_EXECUTE(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_EXECUTE))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_READ feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_READ(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_READ))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_WRITE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_WRITE(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_WRITE))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_APPEND feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_APPEND(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_APPEND))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_TRUNCATE feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_TRUNCATE(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_TRUNCATE))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_PATCH feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_PATCH(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_PATCH))
|
|
|
|
/** @brief Get @ref BT_OTS_OACP_FEAT_ABORT feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OACP_GET_FEAT_ABORT(feat) \
|
|
((feat) & BIT(BT_OTS_OACP_FEAT_ABORT))
|
|
|
|
/** @brief Object List Control Point Feature bits. */
|
|
enum {
|
|
/** Bit 0 OLCP Go To Op Code Supported */
|
|
BT_OTS_OLCP_FEAT_GO_TO = 0,
|
|
|
|
/** Bit 1 OLCP Order Op Code Supported */
|
|
BT_OTS_OLCP_FEAT_ORDER = 1,
|
|
|
|
/** Bit 2 OLCP Request Number of Objects Op Code Supported */
|
|
BT_OTS_OLCP_FEAT_NUM_REQ = 2,
|
|
|
|
/** Bit 3 OLCP Clear Marking Op Code Supported*/
|
|
BT_OTS_OLCP_FEAT_CLEAR = 3,
|
|
};
|
|
|
|
/** @brief Set @ref BT_OTS_OLCP_FEAT_GO_TO feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OLCP_SET_FEAT_GO_TO(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OLCP_FEAT_GO_TO, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OLCP_FEAT_ORDER feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OLCP_SET_FEAT_ORDER(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OLCP_FEAT_ORDER, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OLCP_FEAT_NUM_REQ feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OLCP_SET_FEAT_NUM_REQ(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OLCP_FEAT_NUM_REQ, 1)
|
|
|
|
/** @brief Set @ref BT_OTS_OLCP_FEAT_CLEAR feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OLCP_SET_FEAT_CLEAR(feat) \
|
|
WRITE_BIT(feat, BT_OTS_OLCP_FEAT_CLEAR, 1)
|
|
|
|
/** @brief Get @ref BT_OTS_OLCP_GET_FEAT_GO_TO feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OLCP_GET_FEAT_GO_TO(feat) \
|
|
((feat) & BIT(BT_OTS_OLCP_FEAT_GO_TO))
|
|
|
|
/** @brief Get @ref BT_OTS_OLCP_GET_FEAT_ORDER feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OLCP_GET_FEAT_ORDER(feat) \
|
|
((feat) & BIT(BT_OTS_OLCP_FEAT_ORDER))
|
|
|
|
/** @brief Get @ref BT_OTS_OLCP_GET_FEAT_NUM_REQ feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OLCP_GET_FEAT_NUM_REQ(feat) \
|
|
((feat) & BIT(BT_OTS_OLCP_FEAT_NUM_REQ))
|
|
|
|
/** @brief Get @ref BT_OTS_OLCP_GET_FEAT_CLEAR feature.
|
|
*
|
|
* @param feat OTS features.
|
|
*/
|
|
#define BT_OTS_OLCP_GET_FEAT_CLEAR(feat) \
|
|
((feat) & BIT(BT_OTS_OLCP_FEAT_CLEAR))
|
|
|
|
/**@brief Features of the OTS. */
|
|
struct bt_ots_feat {
|
|
/* OACP Features */
|
|
uint32_t oacp;
|
|
|
|
/* OLCP Features */
|
|
uint32_t olcp;
|
|
} __packed;
|
|
|
|
/** @brief Object metadata request bit field values */
|
|
enum {
|
|
/** @brief Request object name */
|
|
BT_OTS_METADATA_REQ_NAME = BIT(0),
|
|
/** @brief Request object type */
|
|
BT_OTS_METADATA_REQ_TYPE = BIT(1),
|
|
/** @brief Request object size */
|
|
BT_OTS_METADATA_REQ_SIZE = BIT(2),
|
|
/** @brief Request object first created time */
|
|
BT_OTS_METADATA_REQ_CREATED = BIT(3),
|
|
/** @brief Request object last modified time */
|
|
BT_OTS_METADATA_REQ_MODIFIED = BIT(4),
|
|
/** @brief Request object ID */
|
|
BT_OTS_METADATA_REQ_ID = BIT(5),
|
|
/** @brief Request object properties */
|
|
BT_OTS_METADATA_REQ_PROPS = BIT(6),
|
|
/** @brief Request all object metadata */
|
|
BT_OTS_METADATA_REQ_ALL = 0x7F,
|
|
};
|
|
|
|
/** @brief Date and Time structure */
|
|
struct bt_ots_date_time {
|
|
uint16_t year;
|
|
uint8_t month;
|
|
uint8_t day;
|
|
uint8_t hours;
|
|
uint8_t minutes;
|
|
uint8_t seconds;
|
|
};
|
|
#define BT_OTS_DATE_TIME_FIELD_SIZE 7
|
|
|
|
/** @brief Metadata of an OTS object
|
|
*
|
|
* Used by the server as a descriptor for OTS object initialization.
|
|
* Used by the client to present object metadata to the application.
|
|
*/
|
|
struct bt_ots_obj_metadata {
|
|
|
|
#if defined(CONFIG_BT_OTS)
|
|
/** @brief Object Name */
|
|
char *name;
|
|
#endif /* CONFIG_BT_OTS */
|
|
|
|
#if defined(CONFIG_BT_OTS_CLIENT)
|
|
/* TODO: Unify client/server name */
|
|
/** @brief Object name (client) */
|
|
char name_c[CONFIG_BT_OTS_OBJ_MAX_NAME_LEN + 1];
|
|
#endif /* CONFIG_BT_OTS_CLIENT */
|
|
|
|
/** @brief Object Type */
|
|
struct bt_ots_obj_type type;
|
|
|
|
/** @brief Object Size */
|
|
struct bt_ots_obj_size size;
|
|
|
|
#if defined(CONFIG_BT_OTS_CLIENT)
|
|
/** @brief Object first created time */
|
|
struct bt_ots_date_time first_created;
|
|
|
|
/** @brief Object last modified time */
|
|
struct bt_ots_date_time modified;
|
|
|
|
/** @brief Object ID */
|
|
uint64_t id;
|
|
#endif /* CONFIG_BT_OTS_CLIENT */
|
|
|
|
/** @brief Object Properties */
|
|
uint32_t props;
|
|
};
|
|
|
|
/** @brief Opaque OTS instance. */
|
|
struct bt_ots;
|
|
|
|
/** @brief Descriptor for OTS object addition */
|
|
struct bt_ots_obj_add_param {
|
|
/** @brief Object size to allocate */
|
|
uint32_t size;
|
|
|
|
/** @brief Object type */
|
|
struct bt_ots_obj_type type;
|
|
};
|
|
|
|
/** @brief Descriptor for OTS created object.
|
|
*
|
|
* Descriptor for OTS object created by the application. This descriptor is
|
|
* returned by @ref bt_ots_cb.obj_created callback which contains further
|
|
* documentation on distinguishing between server and client object creation.
|
|
*/
|
|
struct bt_ots_obj_created_desc {
|
|
/** @brief Object name
|
|
*
|
|
* The object name as a NULL terminated string.
|
|
*
|
|
* When the server creates a new object the name
|
|
* shall be > 0 and <= BT_OTS_OBJ_MAX_NAME_LEN
|
|
* When the client creates a new object the name
|
|
* shall be an empty string
|
|
*/
|
|
char *name;
|
|
|
|
/** @brief Object size
|
|
*
|
|
* @ref bt_ots_obj_size.alloc shall be >= @ref bt_ots_obj_add_param.size
|
|
*
|
|
* When the server creates a new object @ref bt_ots_obj_size.cur
|
|
* shall be <= @ref bt_ots_obj_add_param.size
|
|
* When the client creates a new object @ref bt_ots_obj_size.cur
|
|
* shall be 0
|
|
*/
|
|
struct bt_ots_obj_size size;
|
|
|
|
/** @brief Object properties */
|
|
uint32_t props;
|
|
};
|
|
|
|
/** @brief OTS callback structure. */
|
|
struct bt_ots_cb {
|
|
/** @brief Object created callback
|
|
*
|
|
* This callback is called whenever a new object is created.
|
|
* Application can reject this request by returning an error
|
|
* when it does not have necessary resources to hold this new
|
|
* object. This callback is also triggered when the server
|
|
* creates a new object with bt_ots_obj_add() API.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param conn The connection that is requesting object creation or
|
|
* NULL if object is created by bt_ots_obj_add().
|
|
* @param id Object ID.
|
|
* @param add_param Object creation requested parameters.
|
|
* @param created_desc Created object descriptor that shall be filled by the
|
|
* receiver of this callback.
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
* @return -ENOTSUP if object type is not supported
|
|
* @return -ENOMEM if no available space for new object.
|
|
* @return -EINVAL if an invalid parameter is provided
|
|
* @return other negative values are treated as a generic operation failure
|
|
*/
|
|
int (*obj_created)(struct bt_ots *ots, struct bt_conn *conn, uint64_t id,
|
|
const struct bt_ots_obj_add_param *add_param,
|
|
struct bt_ots_obj_created_desc *created_desc);
|
|
|
|
/** @brief Object deleted callback
|
|
*
|
|
* This callback is called whenever an object is deleted. It is
|
|
* also triggered when the server deletes an object with
|
|
* bt_ots_obj_delete() API.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param conn The connection that deleted the object or NULL if
|
|
* this request came from the server.
|
|
* @param id Object ID.
|
|
*
|
|
* @retval When an error is indicated by using a negative value, the
|
|
* object delete procedure is aborted and a corresponding failed
|
|
* status is returned to the client.
|
|
* @return 0 in case of success.
|
|
* @return -EBUSY if the object is locked. This is generally not expected
|
|
* to be returned by the application as the OTS layer tracks object
|
|
* accesses. An object locked status is returned to the client.
|
|
* @return Other negative values in case of error. A generic operation
|
|
* failed status is returned to the client.
|
|
*/
|
|
int (*obj_deleted)(struct bt_ots *ots, struct bt_conn *conn,
|
|
uint64_t id);
|
|
|
|
/** @brief Object selected callback
|
|
*
|
|
* This callback is called on successful object selection.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param conn The connection that selected new object.
|
|
* @param id Object ID.
|
|
*/
|
|
void (*obj_selected)(struct bt_ots *ots, struct bt_conn *conn,
|
|
uint64_t id);
|
|
|
|
/** @brief Object read callback
|
|
*
|
|
* This callback is called multiple times during the Object read
|
|
* operation. OTS module will keep requesting successive Object
|
|
* fragments from the application until the read operation is
|
|
* completed. The end of read operation is indicated by NULL data
|
|
* parameter.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param conn The connection that read object.
|
|
* @param id Object ID.
|
|
* @param data In: NULL once the read operations is completed.
|
|
* Out: Next chunk of data to be sent.
|
|
* @param len Remaining length requested by the client.
|
|
* @param offset Object data offset.
|
|
*
|
|
* @return Data length to be sent via data parameter. This value
|
|
* shall be smaller or equal to the len parameter.
|
|
* @return Negative value in case of an error.
|
|
*/
|
|
ssize_t (*obj_read)(struct bt_ots *ots, struct bt_conn *conn,
|
|
uint64_t id, void **data, size_t len,
|
|
off_t offset);
|
|
|
|
/** @brief Object write callback
|
|
*
|
|
* This callback is called multiple times during the Object write
|
|
* operation. OTS module will keep providing successive Object
|
|
* fragments to the application until the write operation is
|
|
* completed. The offset and length of each write fragment is
|
|
* validated by the OTS module to be within the allocated size
|
|
* of the object. The remaining length indicates data length
|
|
* remaining to be written and will decrease each write iteration
|
|
* until it reaches 0 in the last write fragment.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param conn The connection that wrote object.
|
|
* @param id Object ID.
|
|
* @param data Next chunk of data to be written.
|
|
* @param len Length of the current chunk of data in the buffer.
|
|
* @param offset Object data offset.
|
|
* @param rem Remaining length in the write operation.
|
|
*
|
|
* @return Number of bytes written in case of success, if the number
|
|
* of bytes written does not match len, -EIO is returned to
|
|
* the L2CAP layer.
|
|
* @return A negative value in case of an error.
|
|
* @return -EINPROGRESS has a special meaning and is unsupported at
|
|
* the moment. It should not be returned.
|
|
*/
|
|
ssize_t (*obj_write)(struct bt_ots *ots, struct bt_conn *conn, uint64_t id,
|
|
const void *data, size_t len, off_t offset,
|
|
size_t rem);
|
|
|
|
/** @brief Object name written callback
|
|
*
|
|
* This callback is called when the object name is written.
|
|
* This is a notification to the application that the object name
|
|
* has been updated by the OTS service implementation.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param conn The connection that wrote object name.
|
|
* @param id Object ID.
|
|
* @param name Object name.
|
|
*/
|
|
void (*obj_name_written)(struct bt_ots *ots, struct bt_conn *conn,
|
|
uint64_t id, const char *name);
|
|
};
|
|
|
|
/** @brief Descriptor for OTS initialization. */
|
|
struct bt_ots_init {
|
|
/* OTS features */
|
|
struct bt_ots_feat features;
|
|
|
|
/* Callbacks */
|
|
struct bt_ots_cb *cb;
|
|
};
|
|
|
|
/** @brief Add an object to the OTS instance.
|
|
*
|
|
* This function adds an object to the OTS database. When the
|
|
* object is being added, a callback obj_created() is called
|
|
* to notify the user about a new object ID.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param param Object addition parameters.
|
|
*
|
|
* @return ID of created object in case of success.
|
|
* @return negative value in case of error.
|
|
*/
|
|
int bt_ots_obj_add(struct bt_ots *ots, const struct bt_ots_obj_add_param *param);
|
|
|
|
/** @brief Delete an object from the OTS instance.
|
|
*
|
|
* This function deletes an object from the OTS database. When the
|
|
* object is deleted a callback obj_deleted() is called
|
|
* to notify the user about this event. At this point, it is possible
|
|
* to free allocated buffer for object data.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param id ID of the object to be deleted (uint48).
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_ots_obj_delete(struct bt_ots *ots, uint64_t id);
|
|
|
|
/** @brief Get the service declaration attribute.
|
|
*
|
|
* This function is enabled for CONFIG_BT_OTS_SECONDARY_SVC configuration.
|
|
* The first service attribute can be included in any other GATT service.
|
|
*
|
|
* @param ots OTS instance.
|
|
*
|
|
* @return The first OTS attribute instance.
|
|
*/
|
|
void *bt_ots_svc_decl_get(struct bt_ots *ots);
|
|
|
|
/** @brief Initialize the OTS instance.
|
|
*
|
|
* @param ots OTS instance.
|
|
* @param ots_init OTS initialization descriptor.
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_ots_init(struct bt_ots *ots, struct bt_ots_init *ots_init);
|
|
|
|
/** @brief Get a free instance of OTS from the pool.
|
|
*
|
|
* @return OTS instance in case of success or NULL in case of error.
|
|
*/
|
|
struct bt_ots *bt_ots_free_instance_get(void);
|
|
|
|
#define BT_OTS_STOP 0
|
|
#define BT_OTS_CONTINUE 1
|
|
|
|
/* TODO: Merge server and client instance as opaque type */
|
|
/** @brief OTS client instance */
|
|
struct bt_ots_client {
|
|
uint16_t start_handle;
|
|
uint16_t end_handle;
|
|
uint16_t feature_handle;
|
|
uint16_t obj_name_handle;
|
|
uint16_t obj_type_handle;
|
|
uint16_t obj_size_handle;
|
|
uint16_t obj_properties_handle;
|
|
uint16_t obj_created_handle;
|
|
uint16_t obj_modified_handle;
|
|
uint16_t obj_id_handle;
|
|
uint16_t oacp_handle;
|
|
uint16_t olcp_handle;
|
|
|
|
struct bt_gatt_subscribe_params oacp_sub_params;
|
|
struct bt_gatt_discover_params oacp_sub_disc_params;
|
|
struct bt_gatt_subscribe_params olcp_sub_params;
|
|
struct bt_gatt_discover_params olcp_sub_disc_params;
|
|
|
|
struct bt_gatt_write_params write_params;
|
|
struct bt_gatt_read_params read_proc;
|
|
struct bt_ots_client_cb *cb;
|
|
|
|
struct bt_ots_feat features;
|
|
|
|
struct bt_ots_obj_metadata cur_object;
|
|
};
|
|
|
|
/** OTS client callback structure */
|
|
struct bt_ots_client_cb {
|
|
/** @brief Callback function when a new object is selected.
|
|
*
|
|
* Called when the a new object is selected and the current
|
|
* object has changed. The `cur_object` in `ots_inst` will
|
|
* have been reset, and metadata should be read again with
|
|
* bt_ots_client_read_object_metadata().
|
|
*
|
|
* @param ots_inst Pointer to the OTC instance.
|
|
* @param conn The connection to the peer device.
|
|
* @param err Error code (bt_ots_olcp_res_code).
|
|
*/
|
|
void (*obj_selected)(struct bt_ots_client *ots_inst,
|
|
struct bt_conn *conn, int err);
|
|
|
|
|
|
/** @brief Callback function for the data of the selected
|
|
* object.
|
|
*
|
|
* Called when the data of the selected object are read using
|
|
* bt_ots_client_read_object_data().
|
|
*
|
|
* @param ots_inst Pointer to the OTC instance.
|
|
* @param conn The connection to the peer device.
|
|
* @param offset Offset of the received data.
|
|
* @param len Length of the received data.
|
|
* @param data_p Pointer to the received data.
|
|
* @param is_complete Indicate if the whole object has been received.
|
|
*
|
|
* @return int BT_OTS_STOP or BT_OTS_CONTINUE. BT_OTS_STOP can
|
|
* be used to stop reading.
|
|
*/
|
|
int (*obj_data_read)(struct bt_ots_client *ots_inst,
|
|
struct bt_conn *conn, uint32_t offset,
|
|
uint32_t len, uint8_t *data_p, bool is_complete);
|
|
|
|
/** @brief Callback function for metadata of the selected object.
|
|
*
|
|
* Called when metadata of the selected object are read using
|
|
* bt_ots_client_read_object_metadata().
|
|
* Not all of the metadata may have been initialized.
|
|
*
|
|
* @param ots_inst Pointer to the OTC instance.
|
|
* @param conn The connection to the peer device.
|
|
* @param err Error value. 0 on success,
|
|
* GATT error or ERRNO on fail.
|
|
* @param metadata_read Bitfield of the metadata that was
|
|
* successfully read.
|
|
*/
|
|
void (*obj_metadata_read)(struct bt_ots_client *ots_inst,
|
|
struct bt_conn *conn, int err,
|
|
uint8_t metadata_read);
|
|
};
|
|
|
|
/** @brief Register an Object Transfer Service Instance.
|
|
*
|
|
* Register an Object Transfer Service instance discovered on the peer.
|
|
* Call this function when an OTS instance is discovered
|
|
* (discovery is to be handled by the higher layer).
|
|
*
|
|
* @param[in] ots_inst Discovered OTS instance.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_register(struct bt_ots_client *ots_inst);
|
|
|
|
/** @brief OTS Indicate Handler function.
|
|
*
|
|
* Set this function as callback for indicate handler when discovering OTS.
|
|
*
|
|
* @param conn Connection object. May be NULL, indicating that the
|
|
* peer is being unpaired.
|
|
* @param params Subscription parameters.
|
|
* @param data Attribute value data. If NULL then subscription was
|
|
* removed.
|
|
* @param length Attribute value length.
|
|
*/
|
|
uint8_t bt_ots_client_indicate_handler(struct bt_conn *conn,
|
|
struct bt_gatt_subscribe_params *params,
|
|
const void *data, uint16_t length);
|
|
|
|
/** @brief Read the OTS feature characteristic.
|
|
*
|
|
* @param otc_inst Pointer to the OTC instance.
|
|
* @param conn Pointer to the connection object.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_read_feature(struct bt_ots_client *otc_inst,
|
|
struct bt_conn *conn);
|
|
|
|
/** @brief Select an object by its Object ID.
|
|
*
|
|
* @param otc_inst Pointer to the OTC instance.
|
|
* @param conn Pointer to the connection object.
|
|
* @param obj_id Object's ID.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_select_id(struct bt_ots_client *otc_inst,
|
|
struct bt_conn *conn,
|
|
uint64_t obj_id);
|
|
|
|
/** @brief Select the first object.
|
|
*
|
|
* @param otc_inst Pointer to the OTC instance.
|
|
* @param conn Pointer to the connection object.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_select_first(struct bt_ots_client *otc_inst,
|
|
struct bt_conn *conn);
|
|
|
|
/** @brief Select the last object.
|
|
*
|
|
* @param otc_inst Pointer to the OTC instance.
|
|
* @param conn Pointer to the connection object.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_select_last(struct bt_ots_client *otc_inst,
|
|
struct bt_conn *conn);
|
|
|
|
/** @brief Select the next object.
|
|
*
|
|
* @param otc_inst Pointer to the OTC instance.
|
|
* @param conn Pointer to the connection object.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_select_next(struct bt_ots_client *otc_inst,
|
|
struct bt_conn *conn);
|
|
|
|
/** @brief Select the previous object.
|
|
*
|
|
* @param otc_inst Pointer to the OTC instance.
|
|
* @param conn Pointer to the connection object.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_select_prev(struct bt_ots_client *otc_inst,
|
|
struct bt_conn *conn);
|
|
|
|
/** @brief Read the metadata of the current object.
|
|
*
|
|
* The metadata are returned in the obj_metadata_read() callback.
|
|
*
|
|
* @param otc_inst Pointer to the OTC instance.
|
|
* @param conn Pointer to the connection object.
|
|
* @param metadata Bitfield (`BT_OTS_METADATA_REQ_*`) of the metadata
|
|
* to read.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_read_object_metadata(struct bt_ots_client *otc_inst,
|
|
struct bt_conn *conn,
|
|
uint8_t metadata);
|
|
|
|
/** @brief Read the data of the current selected object.
|
|
*
|
|
* This will trigger an OACP read operation for the current size of the object
|
|
* with a 0 offset and then expect receiving the content via the L2CAP CoC.
|
|
*
|
|
* The data of the object are returned in the obj_data_read() callback.
|
|
*
|
|
* @param otc_inst Pointer to the OTC instance.
|
|
* @param conn Pointer to the connection object.
|
|
*
|
|
* @return int 0 if success, ERRNO on failure.
|
|
*/
|
|
int bt_ots_client_read_object_data(struct bt_ots_client *otc_inst,
|
|
struct bt_conn *conn);
|
|
|
|
/** @brief Directory listing object metadata callback
|
|
*
|
|
* If a directory listing is decoded using bt_ots_client_decode_dirlisting(),
|
|
* this callback will be called for each object in the directory listing.
|
|
*
|
|
* @param meta The metadata of the decoded object
|
|
*
|
|
* @return int BT_OTS_STOP or BT_OTS_CONTINUE. BT_OTS_STOP can be used to
|
|
* stop the decoding.
|
|
*/
|
|
typedef int (*bt_ots_client_dirlisting_cb)(struct bt_ots_obj_metadata *meta);
|
|
|
|
/** @brief Decode Directory Listing object into object metadata.
|
|
*
|
|
* If the Directory Listing object contains multiple objects, then the
|
|
* callback will be called for each of them.
|
|
*
|
|
* @param data The data received for the directory listing object.
|
|
* @param length Length of the data.
|
|
* @param cb The callback that will be called for each object.
|
|
*/
|
|
int bt_ots_client_decode_dirlisting(uint8_t *data, uint16_t length,
|
|
bt_ots_client_dirlisting_cb cb);
|
|
|
|
/** @brief Converts binary OTS Object ID to string.
|
|
*
|
|
* @param obj_id Object ID.
|
|
* @param str Address of user buffer with enough room to store
|
|
* formatted string containing binary Object ID.
|
|
* @param len Length of data to be copied to user string buffer.
|
|
* Refer to BT_OTS_OBJ_ID_STR_LEN about
|
|
* recommended value.
|
|
*
|
|
* @return Number of successfully formatted bytes from binary ID.
|
|
*/
|
|
static inline int bt_ots_obj_id_to_str(uint64_t obj_id, char *str, size_t len)
|
|
{
|
|
uint8_t id[6];
|
|
|
|
sys_put_le48(obj_id, id);
|
|
|
|
return snprintk(str, len, "0x%02X%02X%02X%02X%02X%02X",
|
|
id[5], id[4], id[3], id[2], id[1], id[0]);
|
|
}
|
|
|
|
/** @brief Displays one or more object metadata as text with BT_INFO.
|
|
*
|
|
* @param metadata Pointer to the first (or only) metadata in an array.
|
|
* @param count Number of metadata objects to display information of.
|
|
*/
|
|
void bt_ots_metadata_display(struct bt_ots_obj_metadata *metadata,
|
|
uint16_t count);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_OTS_H_ */
|