#ifndef _ATT_H_ | |
#define _ATT_H_ | |
#include "types.h" | |
#include "l2cap.h" | |
#include "uniq.h" | |
#include "uuid.h" | |
#include "sm.h" | |
typedef uniq_t att_range_t; | |
/* we WILL negotiate, but only this much is ever guaranteed */ | |
#define ATT_MTU_MIN_EDR 48 | |
#define ATT_MTU_MIN_LE 23 | |
#define ATT_SIG_LEN SM_SIG_LEN | |
#define ATT_PERM_READ 0x01 | |
#define ATT_PERM_READ_ENCR 0x02 | |
#define ATT_PERM_READ_ENCR_MITM 0x04 | |
#define ATT_PERM_WRITE 0x08 | |
#define ATT_PERM_WRITE_ENCR 0x10 | |
#define ATT_PERM_WRITE_ENCR_MITM 0x20 | |
#define ATT_PERM_WRITE_SIGNED 0x40 | |
/* other permissions shall be handled by higher-layer code */ | |
#define ATT_ATTR_MAX_LEN 512 | |
#define ATT_MAX_LEN_FOR_RD_BY_TYPE 253 /* no more than this many bytes of an att will ever be returned for a ReadByType request */ | |
#define ATT_MAX_LEN_FOR_RD_BY_GRP_TYP 251 /* no more than this many bytes of an att will ever be returned for a ReadByGroupType request */ | |
#define ATT_MIN_HANDLES_IN_READ_MULT 2 | |
#define ATT_ERROR_NONE 0x00 | |
#define ATT_ERROR_INVALID_HANDLE 0x01 | |
#define ATT_ERROR_READ_NOT_ALLOWED 0x02 | |
#define ATT_ERROR_WRITE_NOT_ALLOWED 0x03 | |
#define ATT_ERROR_INVALID_PDU 0x04 | |
#define ATT_ERROR_INSUFFICIENT_AUTH 0x05 | |
#define ATT_ERROR_REQ_NOT_SUPPORTED 0x06 | |
#define ATT_ERROR_INVALID_OFFSET 0x07 | |
#define ATT_ERROR_INSUFFICIENT_ATHOR 0x08 | |
#define ATT_ERROR_PREPARE_QUEUE_FULL 0x09 | |
#define ATT_ERROR_ATTRIBUTE_NOT_FOUND 0x0A | |
#define ATT_ERROR_ATTRIBUTE_NOT_LONG 0x0B | |
#define ATT_ERROR_INSUFF_ENCR_KEY_SZ 0x0C | |
#define ATT_ERROR_INVAL_ATTR_VAL_LEN 0x0D | |
#define ATT_ERROR_UNLIKELY_ERROR 0x0E | |
#define ATT_ERROR_INSUFFICIENT_ENCR 0x0F | |
#define ATT_ERROR_UNSUPP_GROUP_TYPE 0x10 | |
#define ATT_ERROR_INSUFFICIENT_RSRCS 0x11 | |
#define ATT_ERROR_APP_ERR_FIRST 0x80 | |
#define ATT_ERROR_APP_ERR_LAST 0x9F | |
#define ATT_ERROR_COMMON_FIRST 0xE0 | |
#define ATT_ERROR_COMMON_LAST 0xFF | |
#define ATT_FIRST_VALID_HANDLE 0x0001 | |
#define ATT_LAST_VALID_HANDLE 0xFFFF | |
#define ATT_TX_RET_ACCEPTED L2C_TX_ACCEPTED | |
#define ATT_TX_RET_NO_CONN L2C_TX_NO_CONN | |
#define ATT_TX_RET_TRY_LATER L2C_TX_TRY_LATER | |
#define ATT_TX_RET_L2C_ERR L2C_TX_ERROR | |
#define ATT_TX_RET_OOM 0x20 | |
#define ATT_TX_RET_ATT_ERROR 0x21 | |
#define ATT_TX_RET_ATT_BUSY 0x22 | |
#define ATT_READ_FOR_FIND_BY_TYPE_VAL 0x01 | |
#define ATT_READ_FOR_READ_BY_TYPE 0x02 | |
#define ATT_READ_FOR_READ 0x03 | |
#define ATT_READ_FOR_READ_BLOB 0x04 | |
#define ATT_READ_FOR_READ_MULT 0x05 | |
#define ATT_READ_FOR_READ_BY_GRP_TYPE 0x06 | |
#define ATT_WRITE_FOR_WRITE_REQ 0x01 | |
#define ATT_WRITE_FOR_WRITE_CMD 0x02 | |
#define ATT_WRITE_FOR_SIGNED_WRITE_CMD 0x03 | |
#define ATT_WRITE_FOR_PREPARE 0x04 | |
/* ind/notif srv events */ | |
#define ATT_SRV_EVT_NOTIF_SENT 1 | |
#define ATT_SRV_EVT_IND_ACKED 2 | |
#define ATT_SRV_EVT_IND_TIMEOUT 3 | |
#define ATT_SRV_EVT_IND_SRV_DESTROYED 4 /* could happen before a timeout */ | |
/* att common api */ | |
typedef void (*attMtuCbk)(l2c_handle_t to, uint32_t mtu); | |
bool attInit(void); | |
void attDeinit(void); | |
bool attSync(void); /* verifies all pending att work before now is finished. Use this after deleting things to make sure all refs to them are gone */ | |
void attSetMtu(l2c_handle_t to, uint32_t mtu); /* EDR uses this since L2C negotiates MTU */ | |
void attNotifConnClose(l2c_handle_t conn); /* allows server to no longer try to notify it */ | |
bool attEncrAuthUpdate(l2c_handle_t who, bool encr, bool mitmSafe); | |
/* att server api */ | |
/* these callbacks call attSrvReadCbkReply/attSrvWriteCbkReply on completion of actual work */ | |
typedef bool (*attSrvValueReadCbk)(l2c_handle_t who, int cid, att_range_t range, uint16_t ofst, int transId, uint16_t byteOfst, uint8_t reason, uint16_t maxLen); | |
typedef bool (*attSrvValueWriteCbk)(l2c_handle_t who, int cid, att_range_t range, uint16_t ofst, int transId, uint16_t byteOfst, uint8_t reason, uint16_t len, const void *data); | |
typedef bool (*attSrvValueExecWriteCbk)(l2c_handle_t who, int cid, int transId, bool exec); | |
typedef uint8_t (*attSrvTxCbk)(l2c_handle_t to, sg s); /* -> ATT_TX_RET_* */ | |
typedef void (*attSrvIndResultCbk)(l2c_handle_t to, int cid, att_range_t rangeRef, uint16_t offset, uint8_t evt, uint64_t ref); | |
void attSrvInit(attSrvTxCbk txF, attMtuCbk srvMtuF, attSrvIndResultCbk indF, attSrvValueExecWriteCbk execF, attSrvValueReadCbk readF, attSrvValueWriteCbk writeF); | |
void attSrvDeinit(void); | |
l2c_handle_t attSrvCidResolve(int cid); //or 0 on failure | |
att_range_t attSrvHandleRangeReserve(uint16_t len); /* -> 0 on failure */ | |
void attSrvHandleRangeRelease(att_range_t rangeRef); | |
uint16_t attSrvHandleRangeGetBase(att_range_t rangeRef); /* -> 0 on failure */ | |
uint16_t attSrvHandleRangeGetLen(att_range_t rangeRef); | |
bool aapiSrvHandleRangeSetAllowedTransports(att_range_t rangeRef, bool allowLE, bool allowEDR); | |
bool attSrvValueRegister(att_range_t rangeRef, uint16_t offset, const struct uuid *type, uint8_t perms); | |
bool attSrvValueSetGrpLen(att_range_t rangeRef, uint16_t offset, uint16_t grpLen); | |
bool attSrvValueGetGrpLen(att_range_t rangeRef, uint16_t offset, uint16_t *grpLenP); | |
bool attSrvValueUnregister(att_range_t rangeRef, uint16_t offset); | |
uint8_t attSrvValueNotifyChanged(att_range_t rangeRef, uint16_t offset, int cid, sg data, bool notify, uint64_t ref); /* -> ATT_NOTIF_RET_* */ | |
void attSrvDataRx(l2c_handle_t from, sg s); | |
void attSrvCbkReply(int cid, int transId, uint16_t handle, uint8_t err, const void *data, uint16_t len); /* err is ATT_ERROR_* */ | |
/* att client api */ | |
/* haveMore is used for requests that can return more than one item per read, handleP & endGrpHandleP are non-null when available. return false to get no more even if haveMore is true */ | |
typedef bool (*attCliFindInfoCbk)(uniq_t trans, l2c_handle_t to, uint16_t handle, const struct uuid *uuid, bool haveMore); | |
typedef bool (*attCliFindByTypeValCbk)(uniq_t trans, l2c_handle_t to, uint16_t handle, uint16_t grpEndHandle, bool haveMore); | |
typedef bool (*attCliReadCbk)(uniq_t trans, l2c_handle_t to, const uint16_t *handleP, const uint16_t *endGrpHandleP, sg data, bool haveMore); | |
typedef void (*attCliWriteCbk)(uniq_t trans, l2c_handle_t to); /* prepare write data is not sent to you */ | |
typedef void (*attCliError)(uniq_t trans, l2c_handle_t to, const uint16_t *handleP, const uint8_t *errP, const uint8_t *errOpcodeP); /* will be called with NULLs if case of timeout */ | |
typedef void (*attCliIndNotif)(l2c_handle_t to, bool needsAck, uint16_t handle, sg data); | |
void attCliInit(attMtuCbk cliMtuF, attCliFindInfoCbk cliFindInfoCbk, attCliFindByTypeValCbk cliFindByTypeValCbk, attCliReadCbk cliReadF, attCliWriteCbk cliWriteF, attCliError cliErrF, attCliIndNotif cliIndNotifF); | |
void attCliDeinit(void); | |
bool attCliRequestMtu(l2c_handle_t to, uint32_t mtu); /* LE only. once per connection only */ | |
bool attClientInvalidateCache(l2c_handle_t to); | |
/* these all return the Id of this transaction and callback will have it too for matching. zero is returned in case of failure to start operation */ | |
uniq_t attCliFindInformation(l2c_handle_t to, uint16_t hStart, uint16_t hEnd); | |
uniq_t attCliFindByTypeValue(l2c_handle_t to, uint16_t hStart, uint16_t hEnd, uint16_t typeUuid16, sg value); | |
uniq_t attCliReadByType(l2c_handle_t to, uint16_t hStart, uint16_t hEnd, const struct uuid *type); | |
uniq_t attCliReadByGroupType(l2c_handle_t to, uint16_t hStart, uint16_t hEnd, const struct uuid *type); | |
uniq_t attCliRead(l2c_handle_t to, uint16_t handle); | |
uniq_t attCliReadBlob(l2c_handle_t to, uint16_t handle, uint16_t offset); | |
uniq_t attCliWrite(l2c_handle_t to, uint16_t handle, sg data); | |
bool attCliWriteNoAck(l2c_handle_t to, uint16_t handle, sg data); | |
bool attCliSignedWriteNoAck(l2c_handle_t to, uint16_t handle, sg data); | |
uniq_t attCliPrepareWrite(l2c_handle_t to, uint16_t handle, uint16_t offset, sg data); | |
uniq_t attCliExecuteStagedWrites(l2c_handle_t to, bool commit); | |
bool attCliSendIndicationAck(l2c_handle_t to); | |
/* completely stateless helpers */ | |
bool attReadUuid(struct uuid *dst, sg s); //read uuid-16 or uuid-128 from an sg assuming it is the only thing in there | |
#endif |