/*
 * Copyright 2018 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include <stdlib.h>
#include <string.h>
#include "newblue-macros.h"
#include "workQueue.h"
#include "persist.h"
#include "config.h"
#include "timer.h"
#include "l2cap.h"
#include "types.h"
#include "uuid.h"
#include "uniq.h"
#include "util.h"
#include "log.h"
#include "att.h"
#include "bt.h"
#include "sg.h"
#include "mt.h"
#include "sm.h"


//TODO: proper error when reading chars that need encr!

/* ERRORS */
#define ATT_OPCODE_ERROR                 0x01 /* struct attPduError */

/* REQUESTS */
#define ATT_OPCODE_MTU_EXCH_REQ          0x02 /* struct attPduMtu */
#define ATT_OPCODE_FIND_INFO_REQ         0x04 /* struct attPduFindInfoReq */
#define ATT_OPCODE_FIND_BY_TYPE_VAL_REQ  0x06 /* struct attPduFindByTypeValReq */
#define ATT_OPCODE_READ_BY_TYPE_REQ      0x08 /* struct attPduReadByTypeReq */
#define ATT_OPCODE_READ_REQ              0x0A /* struct attPduReadReq */
#define ATT_OPCODE_READ_BLOB_REQ         0x0C /* struct attPduReadBlobReq */
#define ATT_OPCODE_READ_MULT_REQ         0x0E /* uint16_t[] - at least two handles required */
#define ATT_OPCODE_READ_BY_GRP_TYPE_REQ  0x10 /* struct attPduReadByGrpTypeReq */
#define ATT_OPCODE_WRITE_REQ             0x12 /* struct attPduWriteReq */
#define ATT_OPCODE_PREPARE_WRITE_REQ     0x16 /* struct attPduPrepareWriteReq */
#define ATT_OPCODE_EXECUTE_WRITE_REQ     0x18 /* struct attPduExecuteWriteReq */

/* RESPONSES */
#define ATT_OPCODE_MTU_EXCH_RSP          0x03 /* struct attPduMtu */
#define ATT_OPCODE_FIND_INFO_RSP         0x05 /* struct attPduFindInfoRsp */
#define ATT_OPCODE_FIND_BY_TYPE_VAL_RSP  0x07 /* struct attPduFindByTypeValRspItem[] */
#define ATT_OPCODE_READ_BY_TYPE_RSP      0x09 /* struct attPduReadByTypeRsp */
#define ATT_OPCODE_READ_RSP              0x0B /* uint8_t[] */
#define ATT_OPCODE_READ_BLOB_RSP         0x0D /* uint8_t[] */
#define ATT_OPCODE_READ_MULT_RSP         0x0F /* uint8_t[] - values concatenated together */
#define ATT_OPCODE_READ_BY_GRP_TYPE_RSP  0x11 /* struct attPduReadByGrpTypeRsp */
#define ATT_OPCODE_WRITE_RSP             0x13 /* NO ADDITIONAL DATA SENT */
#define ATT_OPCODE_PREPARE_WRITE_RSP     0x17 /* struct attPduPrepareWriteRsp */
#define ATT_OPCODE_EXECUTE_WRITE_RSP     0x19 /* NO ADDITIONAL DATA SENT */

/* NOTIFICATIONS */
#define ATT_OPCODE_HANDLE_VALUE_NOTIF    0x1B /* struct attPduHandleValueNotif */

/* INDICATIONS */
#define ATT_OPCODE_HANDLE_VALUE_IND      0x1D /* struct attPduHandleValueInd */

/* CONFIRMATION */
#define ATT_OPCODE_HANDLE_VALUE_CONF     0x1E /* NO ADDITIONAL DATA SENT */

/* COMMANDS */
#define ATT_OPCODE_WRITE_CMD             0x52 /* struct attPduWriteCmd */
#define ATT_OPCODE_SIGNED_WRITE_CMD      0xD2 /* struct attPduSignedWriteCmd */



#define ATT_FIND_INFO_RSP_FMT_16         0x01 /* attPduFindInfoData16 */
#define ATT_FIND_INFO_RSP_FMT_128        0x02 /* attPduFindInfoData128 */

#define ATT_EXECUTE_WRITE_FLG_CANCEL     0x00 /* cancel all prepared writes */
#define ATT_EXECUTE_WRITE_FLG_EXECUTE    0x01 /* perform all prepared writes */



struct attHdr {
    uint8_t opcode; /* ATT_OPCODE_* */
} __packed;

struct attPduError {
    uint8_t reqOpcode;
    uint16_t handle;
    uint8_t err; /* ATT_ERROR_* */
} __packed;

struct attPduMtu {
    uint16_t mtu;
} __packed;

struct attPduFindInfoReq {
    uint16_t startHandle;
    uint16_t endHandle;
}__packed;

struct attPduFindInfoData16 {
    uint16_t handle;
    uint16_t uuid16;
} __packed;

struct attPduFindInfoData128 {
    uint16_t handle;
    struct uuid uuid128;
} __packed;

struct attPduFindInfoRsp {
    uint8_t format; /* ATT_FIND_INFO_RSP_FMT_* */
    /* data here: attPduFindInfoData16[] or attPduFindInfoData128[] */
} __packed;

struct attPduFindByTypeValReq {
    uint16_t startHandle;
    uint16_t endHandle;
    uint16_t uuid16;
    /* value follows as a byte array */
} __packed;

struct attPduFindByTypeValRspItem {
    uint16_t firstHandle;
    uint16_t groupEndHandle; /* meaning defined by higher layer */
} __packed;

struct attPduReadByTypeReq {
    uint16_t startHandle;
    uint16_t endHandle;
    /* either a 16 or a 128 bit uuid follows */
} __packed;

struct attHandleValuePair {
    uint16_t handle;
    /* value bytes here */
} __packed;

struct attPduReadByTypeRsp {
    uint8_t handleValuePairSz;
    /* attHandleValuePair array follows */
} __packed;

struct attPduReadReq {
    uint16_t handle;
} __packed;

struct attPduReadBlobReq {
    uint16_t handle;
    uint16_t offset;
} __packed;

struct attPduReadByGrpTypeReq {
    uint16_t startHandle;
    uint16_t endHandle;
    /* either a 16 or a 128 bit uuid follows */
} __packed;

struct attGrpValuePair {
    uint16_t handle;
    uint16_t groupEndHadle;
    /* data here */
} __packed;

struct attPduReadByGrpTypeRsp {
    uint8_t attGrpValuePairSz;
    /* attGrpValuePair array follows */
} __packed;

struct attPduWriteReq {
    uint16_t handle;
    /* data follows */
} __packed;

struct attPduPrepareWriteReq {
    uint16_t handle;
    uint16_t offset;
    /* data */
} __packed;

struct attPduPrepareWriteRsp {
    uint16_t handle;
    uint16_t offset;
    /* data echo */
} __packed;

struct attPduExecuteWriteReq {
    uint8_t flags; /* ATT_EXECUTE_WRITE_FLG_* */
} __packed;

struct attPduHandleValueNotif {
    uint16_t handle;
    /* data */
} __packed;

struct attPduHandleValueInd {
    uint16_t handle;
    /* data */
} __packed;

struct attPduWriteCmd {
     uint16_t handle;
     /* data */
} __packed;

struct attPduSignedWriteCmd {
     uint16_t handle;
     /* data */
     /* 12 bytes of signature follow from pdu type byte to last data byte */
} __packed;


#define ATT_CONN_LIST_GROW_BY     16
#define ATT_FIRST_CONTINUE_CALL   0xFF

struct attSrvPendingOp { /* an op we have an outstanding callback for */

    uint8_t  origOpcode; /* set to 0 when nothing is in progress, since all possible in-progress opcodes are nonzero */
    sg       replyInProgress;
    uint16_t origStartHandle;
    uint16_t startHandle;
    uint16_t endHandle;
    uint16_t mtu;

    union {
        struct {
            struct uuid      uuid;
            void            *wantedVal;
            uint16_t         wantedLen;
            uint16_t         valGrpLen;
        } findByTypeValue;
        struct {
            struct uuid      uuid;
            bool             grpType;
            uint16_t         valGrpLen;
            uint16_t         itemLen;
        } readByType;
        struct {
            uint16_t         offset;
        } read;
        struct {
            sg               handles;
            uint16_t         lastReadHandle;
        } readMult;
    };
};

struct attConn {

    /* list */
    struct attConn *next;
    struct attConn *prev;

    /* comon for client and server */
    l2c_handle_t conn;
    uint32_t mtu;
    bool isEncr;
    bool isMitmProtected;
    bool isLE;

    /* used if we're acting as client on this connection */
    struct {
        uniq_t ongoingTrans; /* is a timer ID */
    } cli;

    /* used if we're acting as server */
    struct {
        att_range_t indRangeRef;
        uniq_t indTimer;
        uint64_t indRef;
        uint16_t indOffset;

        att_cid_t cid; /* for higher layer */
        att_trans_t expectedTransId;

        struct attSrvPendingOp penOp;
    } srv;
};

struct attConnListNode {
    struct attConnListNode *next;
    l2c_handle_t conn;
};

struct attSrvVal {
    struct attSrvVal *next;
    struct attSrvVal *prev;
    struct uuid type;
    uint16_t offset;
    uint16_t grpLen;
    uint8_t perms;
};

struct attSrvRange {
    att_range_t rangeRef;
    struct attSrvRange *next;
    struct attSrvRange *prev;
    uint16_t start;
    uint16_t len;
    struct attSrvVal *valsHead;
    struct attSrvVal *valsTail;
    struct attConnListNode *seenBy;
    bool allowLE;
    bool allowEDR;
};

struct attWorkItem {
    uint8_t type;
    l2c_handle_t who;
    union {
        struct {
            att_cid_t cid; /* having both this and "who" here makes life a bit easier */
        } srv;
        struct {
            uniq_t trans;
        } cli;
    };

    union {
        struct {
            att_range_t          range;
            uint16_t             ofst;
            att_trans_t          transId;
            uint16_t             byteOfst;
            uint16_t             maxLen;
            uint8_t              reason;
        } srvRead;
        struct {
            att_range_t          range;
            uint16_t             ofst;
            att_trans_t          transId;
            uint16_t             byteOfst;
            uint16_t             len;
            uint8_t              reason;
            /* data follows */
        } srvWrite;
        struct {
            att_trans_t          transId;
            bool                 exec;
        } srvExecWrite;
        struct {
            att_range_t          range;
            uint16_t             ofst;
            uint64_t             ref;
            uint8_t              evt;
        } srvIndResult;
        struct {
            uint16_t             mtu;
            bool                 asServer;
        } mtuInfo;
        struct {
            sem_t               *sem;
        } sync;
        struct {
            sg                   data;
        } cliJustData;
        struct {
            uint16_t             handle;
            uint8_t              err;
            uint8_t              errOpcode;
            bool                 isLocalErr;
        } cliErr;
        struct {
            uint16_t             handle;
            bool                 needsAck;
            sg                   data;
        } cliIndNotif;
    };
};

#define WORK_ATT_MTU_INFO                0
#define WORK_ATT_SYNC                    1
#define WORK_SRV_READ_CALL               2
#define WORK_SRV_WRITE_CALL              3
#define WORK_SRV_EXEC_WRITE_CALL         4
#define WORK_SRV_IND_RESULT              5
#define WORK_CLI_FIND_INFO_CALL          6
#define WORK_CLI_FIND_BY_TYPE_VAL_CALL   7
#define WORK_CLI_READ_BY_TYPE_CALL       8
#define WORK_CLI_READ_CALL               9 /* or read blob */
#define WORK_CLI_READ_BY_GRP_TYPE_CALL   10
#define WORK_CLI_WRITE_CALL              11
#define WORK_CLI_ERR_CALL                12
#define WORK_CLI_IND_NOTIF_CALL          13


/* our state */
static pthread_mutex_t mAttLock = PTHREAD_MUTEX_INITIALIZER;
static struct attSrvRange *mRangesHead;
static struct attSrvRange *mRangesTail;

static attSrvTxCbk mTxCbk;
static attMtuCbk mSrvMtuCbk;
static attSrvIndResultCbk mIndCbk;
static attSrvValueExecWriteCbk mExecCbk;
static attSrvValueReadCbk mReadCbk;
static attSrvValueWriteCbk mWriteCbk;

static attMtuCbk mCliMtuCbk;
static attCliReadCbk mCliReadF;
static attCliWriteCbk mCliWriteF;
static attCliError mCliErrF;
static attCliIndNotif mCliIndNotifF;
static attCliFindInfoCbk mCliFindInfoCbk;
static attCliFindByTypeValCbk mCliFindByTypeValCbk;

static struct attConn *mConns;
static struct workQueue *mWorkQ;
static pthread_t mWorker;
static unsigned mNumUsers = 0; /* of ATT itself */




/*
 * FUNCTION: attConnFindByL2cConn
 * USE:      Find a per-connection state given an l2cap connection handle
 * PARAMS:   who - l2cap connection handle
 * RETURN:   struct attConn or NULL if not found
 * NOTES:    plase call while holding mAttLock
 */
static struct attConn* attConnFindByL2cConn(l2c_handle_t who)
{
    struct attConn *conn = mConns;

    while (conn && conn->conn != who)
        conn = conn->next;

    return conn;
}

/*
 * FUNCTION: attConnFindBySrvCid
 * USE:      Find a per-connection state given a server "cid" value (used by android if sadly)
 * PARAMS:   srvCid - the cid
 * RETURN:   struct attConn or NULL if not found
 * NOTES:    plase call while holding mAttLock
 */
static struct attConn* attConnFindBySrvCid(att_cid_t srvCid)
{
    struct attConn *conn = mConns;

    while (conn && conn->srv.cid != srvCid)
        conn = conn->next;

    return conn;
}

/*
 * FUNCTION: attConnListFree
 * USE:      Free a conn-list
 * PARAMS:   listP - where list head is stored
 * RETURN:   NONE
 * NOTES:    call while holding mAttLock
 */
static void attConnListFree(struct attConnListNode **listP)
{
    while (*listP) {
        struct attConnListNode *t = (*listP)->next;
        free(*listP);
        *listP = t;
    }
}

/*
 * FUNCTION: attConnListIsEmpty
 * USE:      See if a conn-list has items
 * PARAMS:   listP - where list head is stored
 * RETURN:   true if an item is found
 * NOTES:    call while holding mAttLock
 */
static bool attConnListIsEmpty(struct attConnListNode **listP)
{
    return !*listP;
}

/*
 * FUNCTION: attConnListDel
 * USE:      Delete a given connection from a conn-list
 * PARAMS:   listP - where list head is stored
 *           conn - the connection to remove
 * RETURN:   NONE
 * NOTES:    call while holding mAttLock
 */
static void attConnListDel(struct attConnListNode **listP, l2c_handle_t conn)
{
    struct attConnListNode *c = *listP, *p = NULL;

    while (c && c->conn != conn) {
        p = c;
        c = c->next;
    }

    if (c) {
        if (p)
            p->next = c->next;
        else
            *listP = c->next;

        free(c);
    }
}

/*
 * FUNCTION: attWorkItemAlloc
 * USE:      Allocate a work item of a given type
 * PARAMS:   type - the type
 *           extraSz - the extra size to allocate
 * RETURN:   success
 * NOTES:
 */
static struct attWorkItem* attWorkItemAlloc(uint8_t type, uint32_t extraSz)
{
    struct attWorkItem *wi = (struct attWorkItem*)calloc(1, sizeof(struct attWorkItem) + extraSz);
    if (wi)
        wi->type = type;

    return wi;
}

/*
 * FUNCTION: attSrvSchedCbkGetNextTid
 * USE:      Get the transaction ID to use
 * PARAMS:   conn - the per-connection data
 * RETURN:   the transaction ID to use
 * NOTES:    call with mAttLock held
 */
static att_trans_t attSrvSchedCbkGetNextTid(struct attConn* conn)
{
    return conn->srv.expectedTransId = uniqGetNext();
}

/*
 * FUNCTION: attCliScheduleErrorCbk
 * USE:      Schedule a call to the error callback
 * PARAMS:   trans - the transaction
 *           who - the peer connection handle
 *           handle - the handle value (ignored if local stack error)
 *           err - error number (ignored if local stack error)
 *           errOpcode - the opcode that caused the error
 *           isLocalErr - local error?
 * RETURN:   false on immediate failure
 * NOTES:
 */
static bool attCliScheduleErrorCbk(uniq_t trans, l2c_handle_t who, uint16_t handle, uint8_t err, uint8_t errOpcode, bool isLocalErr)
{
    struct attWorkItem *wi;

    wi = attWorkItemAlloc(WORK_CLI_ERR_CALL, 0);
    if (!wi)
        return false;

    wi->who = who;
    wi->cli.trans = trans;
    wi->cliErr.handle = handle;
    wi->cliErr.err = err;
    wi->cliErr.errOpcode = errOpcode;
    wi->cliErr.isLocalErr = isLocalErr;

    if (workQueuePut(mWorkQ, wi))
        return true;

    free(wi);
    return false;
}

/*
 * FUNCTION: attSrvSchedReadCbk
 * USE:      Schedule a call to the read callback

 * PARAMS:   range - the handle range
 *           val - the value struct
 *           conn - the per-connection structure
 *           reason - reason value to pass to read callback
 *           byteOfst - byte offset to pass to read callback
 *           maxLen - maxLength to read
 * RETURN:   true if we should expect callback. false on immediate failute
 * NOTES:    call with mAttLock held Do not release the lock until all your state in conn->penOp is set up
 */
static bool attSrvSchedReadCbk(struct attSrvRange *range, struct attSrvVal* val, struct attConn* conn, uint8_t reason, uint16_t byteOfst, uint16_t maxLen)
{
    struct attWorkItem *wi;

    wi = attWorkItemAlloc(WORK_SRV_READ_CALL, 0);
    if (!wi)
        return false;

    wi->who = conn->conn;
    wi->srv.cid = conn->srv.cid;
    wi->srvRead.range = range->rangeRef;
    wi->srvRead.ofst = val->offset;
    wi->srvRead.transId = attSrvSchedCbkGetNextTid(conn);
    wi->srvRead.byteOfst = byteOfst;
    wi->srvRead.maxLen = maxLen;
    wi->srvRead.reason = reason;

    if (workQueuePut(mWorkQ, wi))
        return true;

    free(wi);
    return false;
}

/*
 * FUNCTION: attSrvSchedWriteCbk
 * USE:      Schedule a call to the write callback
 * PARAMS:   range - the handle range
 *           val - the value struct
 *           conn - the per-connection structure
 *           reason - reason value to pass to write callback
 *           replace - repalce the existing slot (else will fail if slot not empty)
 *           byteOfst - byte offset to pass to write callback
 *           data - the sg with the data to write
 * RETURN:   true if we should expect callback. false on immediate failute
 * NOTES:    call with mAttLock held  Do not release the lock until all state in conn->penOp is set up. WILL NOT FREE "data". Caller must!
 */
static bool attSrvSchedWriteCbk(struct attSrvRange *range, struct attSrvVal* val, struct attConn* conn, uint8_t reason, uint16_t byteOfst, sg data)
{
    uint16_t len = sgLength(data);
    struct attWorkItem *wi;

    wi = attWorkItemAlloc(WORK_SRV_WRITE_CALL, len);
    if (!wi)
        return false;

    sgSerialize(data, 0, len, wi + 1);

    wi->who = conn->conn;
    wi->srv.cid = conn->srv.cid;
    wi->srvWrite.range = range->rangeRef;
    wi->srvWrite.ofst = val->offset;
    wi->srvWrite.transId = attSrvSchedCbkGetNextTid(conn);
    wi->srvWrite.byteOfst = byteOfst;
    wi->srvWrite.len = len;
    wi->srvWrite.reason = reason;

    if (workQueuePut(mWorkQ, wi)) {
        sgFree(data);
        return true;
    }

    free(wi);
    return false;
}

/*
 * FUNCTION: attSrvSchedExecCbk
 * USE:      Schedule a call to the execute-write callback
 * PARAMS:   conn - the per-connection structure
 *           exec - true to execute, false to clear state
 * RETURN:   true if we should expect callback. false on immediate failute
 * NOTES:    call with mAttLock held  Do not release the lock until all state in conn->penOp is set up. WILL NOT FREE "data". Caller must!
 */
static bool attSrvSchedExecCbk(struct attConn* conn, bool exec)
{
    struct attWorkItem *wi;

    wi = attWorkItemAlloc(WORK_SRV_EXEC_WRITE_CALL, 0);
    if (!wi)
        return false;

    wi->who = conn->conn;
    wi->srv.cid = conn->srv.cid;
    wi->srvExecWrite.transId = attSrvSchedCbkGetNextTid(conn);
    wi->srvExecWrite.exec = exec;

    if (workQueuePut(mWorkQ, wi))
        return true;

    free(wi);
    return false;
}

/*
 * FUNCTION: attSrvSchedIndResultCbk
 * USE:      Schedule a call to the indication result callback
 * PARAMS:   rangeRef - the range reference
 *           offst - the value offset in the range
 *           conn - the per-connection structure
 *           evt - what happened?
 *           ref - the reference value provided by the higher layer
 * RETURN:   success
 * NOTES:    call with mAttLock held Do not release the lock until all state in conn->penOp is set up
 */
static bool attSrvSchedIndResultCbk(att_range_t rangeRef, uint16_t offst, struct attConn* conn, uint8_t evt, uint64_t ref)
{
    struct attWorkItem *wi;

    wi = attWorkItemAlloc(WORK_SRV_IND_RESULT, 0);
    if (!wi)
        return false;

    wi->who = conn->conn;
    wi->srv.cid = conn->srv.cid;
    wi->srvIndResult.range = rangeRef;
    wi->srvIndResult.ofst = offst;
    wi->srvIndResult.ref = ref;
    wi->srvIndResult.evt = evt;

    if (workQueuePut(mWorkQ, wi))
        return true;

    free(wi);
    return false;
}

/*
 * FUNCTION: attSrvSchedMtuCbk
 * USE:      Schedule a call to the MTU callback
 * PARAMS:   conn - the per-connection structure
 *           mtu - the new mtu
 *           asServer - are we acting as server for this negotiation
 * RETURN:   success
 * NOTES:    call with mAttLock held Do not release the lock until all state in conn->penOp is set up
 */
static bool attSrvSchedMtuCbk(struct attConn* conn, uint32_t mtu, bool asServer)
{
    struct attWorkItem *wi;

    wi = attWorkItemAlloc(WORK_ATT_MTU_INFO, 0);
    if (!wi)
        return false;

    wi->who = conn->conn;
    wi->srv.cid = conn->srv.cid;
    wi->mtuInfo.mtu = mtu;
    wi->mtuInfo.asServer = asServer;

    if (workQueuePut(mWorkQ, wi))
        return true;

    free(wi);
    return false;
}

/*
 * FUNCTION: attSync
 * USE:      Verifies all pending att work before now is finished. Use this after deleting things to make sure all refs to them are gone
 * PARAMS:   NONE
 * RETURN:   success
 * NOTES:    blocks till done
 */
bool attSync(void)
{
    struct attWorkItem *wi;
    sem_t sem;

    wi = attWorkItemAlloc(WORK_ATT_SYNC, 0);
    if (!wi)
        goto fail_alloc;

    if (sem_init(&sem, 0, 0))
        goto fail_sem;

    wi->sync.sem = &sem;

    if (!workQueuePut(mWorkQ, wi))
        goto fail_enq;

    r_sem_wait(&sem);
    sem_destroy(&sem);
    return true;

fail_enq:
    sem_destroy(&sem);

fail_sem:
    free(wi);

fail_alloc:
    return false;
}

/*
 * FUNCTION: attConnListAddIfNew
 * USE:      Add a given connection to a connection list, if it is not yet present there
 * PARAMS:   l2cConn - the l2c connection handle
 * RETURN:   false on error
 * NOTES:    call with mAttLock held
 */
static bool attConnListAddIfNew(l2c_handle_t l2cConn)
{
    struct attConn *conn;
    struct bt_addr peer;

    /* check for existence & alloc as needed */
    if (attConnFindByL2cConn(l2cConn))
        return true;
    conn = calloc(1, sizeof(struct attConn));
    if (!conn)
        return false;

    /* grab the peer address */
    conn->conn = l2cConn;
    if (!l2cApiGetBtAddr(l2cConn, &peer)) {
        loge("Failed to get peer address\n");
        free(conn);
        return false;
    }

    /* get initial encr and mitm state */
    conn->isEncr = l2cApiIsConnEncrypted(conn->conn);
    conn->isMitmProtected = l2cApiIsConnMitmSafe(conn->conn);
    conn->isLE = BT_ADDR_IS_LE(peer);

    /* find a free server CID */
    conn->srv.cid = uniqGetNext();

    /* link it in */
    conn->next = mConns;
    if (mConns)
        mConns->prev = conn;
    mConns = conn;

    return true;
}

/*
 * FUNCTION: attEncrAuthUpdate
 * USE:      Update the ATT state about a change in a connection to a client pertaining to auth/encr
 * PARAMS:   who - the connection to the client
 *           encr - is it now encrypted?
 *           mitmSafe - is it now mitm-safe?
 * RETURN:   success
 * NOTES:
 */
bool attEncrAuthUpdate(l2c_handle_t who, bool encr, bool mitmSafe)
{
    struct attConn *conn;
    bool ret = false;

    pthread_mutex_lock(&mAttLock);
    attConnListAddIfNew(who);
    conn = attConnFindByL2cConn(who);
    if (conn) {
        conn->isEncr = encr;
        conn->isMitmProtected = mitmSafe;
        ret = true;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attSrvInit
 * USE:      Init our ATT server
 * PARAMS:   txF - callback to use to TX data to clients
 *           srvMtuF - callback to tell higher-leyer of new MTU
 *           indF - callback to tell higher-layer of ind TX progress
 *           execF - callback to execute or cancel pending writes
 *           readF - read callback
 *           writeF - write callback
 * RETURN:   NONE
 * NOTES:
 */
void attSrvInit(attSrvTxCbk txF, attMtuCbk srvMtuF, attSrvIndResultCbk indF, attSrvValueExecWriteCbk execF, attSrvValueReadCbk readF, attSrvValueWriteCbk writeF)
{
    pthread_mutex_lock(&mAttLock);
    mTxCbk = txF;
    mSrvMtuCbk = srvMtuF;
    mIndCbk = indF;
    mExecCbk = execF;
    mReadCbk = readF;
    mWriteCbk = writeF;
    pthread_mutex_unlock(&mAttLock);
}

/*
 * FUNCTION: attSrvDeinit
 * USE:      Deinit our ATT server
 * PARAMS:   NONE
 * RETURN:   NONE
 * NOTES:
 */
void attSrvDeinit(void)
{
    struct attSrvRange *range;
    struct attSrvVal *val;
    struct attConn *conn;

    pthread_mutex_lock(&mAttLock);
    for (conn = mConns; conn; conn = conn->next) {
        if (conn->srv.indTimer) {
            if (timerCancel(conn->srv.indTimer))
                attSrvSchedIndResultCbk(conn->srv.indRangeRef, conn->srv.indOffset, conn, ATT_SRV_EVT_IND_SRV_DESTROYED, conn->srv.indRef);
            conn->srv.indTimer = 0;
        }
    }
    /* all uncancelled timers need to be run before we destroy state, so we let them */
    pthread_mutex_unlock(&mAttLock);
    timerSync();
    pthread_mutex_lock(&mAttLock);

    for (range = mRangesHead; range; range = range->next) {
        for (val = range->valsHead; val; ) {
            struct attSrvVal *t = val;
            val = val->next;
            free(t);
        }
        attConnListFree(&range->seenBy);
    }

    pthread_mutex_unlock(&mAttLock);

    mTxCbk = NULL;
    mSrvMtuCbk = NULL;
    mIndCbk = NULL;
}

/*
 * FUNCTION: attSrvRangeDelete
 * USE:      delete all values in a given range
 * PARAMS:   range - the range
 * RETURN:   NONE
 * NOTES:    call with server's write lock held
 */
static void attSrvRangeDeleteAllVals(struct attSrvRange *range)
{
    struct attSrvVal *val, *t;

    val = range->valsHead;
    while (val) {
        t = val;
        val = val->next;
        free(t);
    }
    range->valsHead = NULL;
    range->valsTail = NULL;
}

/*
 * FUNCTION: attSrvRangeDelete
 * USE:      delete a given att range struct
 * PARAMS:   range - the range
 * RETURN:   NONE
 * NOTES:    call with server's write lock held
 */
static void attSrvRangeDelete(struct attSrvRange *range)
{

    if (range->prev)
        range->prev->next = range->next;
    else
        mRangesHead = range->next;

    if (range->next)
        range->next->prev = range->prev;
    else
        mRangesTail = range->prev;

    attSrvRangeDeleteAllVals(range);
    if (!attConnListIsEmpty(&range->seenBy))
        logw("Deleted range 0x%04x+0x%04x has been seen\n", range->start, range->len);
    attConnListFree(&range->seenBy);
    free(range);
}

/*
 * FUNCTION: attNotifConnClose
 * USE:      tell the ATT code about a closed connection (in case it cares)
 * PARAMS:   l2cConn - the l2c connection handle
 * RETURN:   NONE
 * NOTES:    if said connection substribed to notifications, allows us to unsubstribe
 *           them proactively instead of waiting for TX errors
 */
void attNotifConnClose(l2c_handle_t l2cConn)
{
    struct attSrvRange *range, *t;
    struct attConn *conn;

    pthread_mutex_lock(&mAttLock);
    for (range = mRangesHead; range;) {
        attConnListDel(&range->seenBy, l2cConn);
        t = range;
        range = range->next;
        if (attConnListIsEmpty(&t->seenBy) && !t->rangeRef) /* delete a disused range after all who knew about it are gone */
            attSrvRangeDelete(t);
    }

    conn = attConnFindByL2cConn(l2cConn);
    if (conn) {
        if (conn->prev)
            conn->prev->next = conn->next;
        else
            mConns = conn->next;
        if (conn->next)
             conn->next->prev = conn->prev;

        //TODO: XXX: what other cleanup is needed?
        free(conn);
    }
    else
        logi("ATT: notified of a connection closure for a connection we never knew about\n");

    pthread_mutex_unlock(&mAttLock);
}

/*
 * FUNCTION: attSrvHandleRangeReserve
 * USE:      reserve a range of handles in the ATT server
 * PARAMS:   len - the wanted handle range length
 * RETURN:   a reference to the handle range or 0 on failure
 * NOTES:    by default both LE and EDR accesses are disabled until a call to aapiSrvHandleRangeSetAllowedTransports() is amde
 */
att_range_t attSrvHandleRangeReserve(uint16_t len)
{
    uint32_t searchH = ATT_FIRST_VALID_HANDLE;
    struct attSrvRange *next, *prev = NULL, *newRange;
    att_range_t ret = 0;

    pthread_mutex_lock(&mAttLock);
    next = mRangesHead;
    while (searchH <= ATT_LAST_VALID_HANDLE && next) {
        if (next->start - searchH >= len)
            break;
        else {
            searchH = next->start + next->len;
            prev = next;
            next = next->next;
        }
    }
    if (searchH + len - 1 > ATT_LAST_VALID_HANDLE)
        goto out;

    /* next is currently the next item for us, or NULL if we're the new last */
    /* prev is currently the prev item for us, or NULL if we're the new first */

    newRange = (struct attSrvRange*)calloc(1, sizeof(struct attSrvRange));
    if (!newRange)
        goto out;

    newRange->start = searchH;
    newRange->len = len;
    newRange->rangeRef = uniqGetNext();
    newRange->prev = prev;
    newRange->next = next;
    if (next)
        next->prev = newRange;
    else
        mRangesTail = newRange;
    if (prev)
        prev->next = newRange;
    else
        mRangesHead = newRange;

    ret = newRange->rangeRef;
out:
    pthread_mutex_unlock(&mAttLock);
    return ret;
}

/*
 * FUNCTION: attSrvRangeFind
 * USE:      find a range structure for a given range reference in a given ATT server
 * PARAMS:   rangeRef - the range reference
 * RETURN:   the range struct or NULL if not found
 * NOTES:    call with mAttLock held

 */
static struct attSrvRange* attSrvRangeFind(att_range_t rangeRef)
{
    struct attSrvRange *range;

    for (range = mRangesHead; range && range->rangeRef != rangeRef; range = range->next);

    return range;
}

/*
 * FUNCTION: aapiSrvHandleRangeSetAllowedTransports
 * USE:      Set which transports may access a range
 * PARAMS:   rangeRef - the range reference
 *           allowLE - accessible by LE?
 *           allowEDR - accessible by EDR?
 * RETURN:   a reference to the handle range or 0 on failure
 * NOTES:
 */
bool aapiSrvHandleRangeSetAllowedTransports(att_range_t rangeRef, bool allowLE, bool allowEDR)
{
    struct attSrvRange *range;

    pthread_mutex_lock(&mAttLock);
    range = attSrvRangeFind(rangeRef);
    if (!range)
        logw("Attempt to delete a non-existent range\n");
    else {
        range->allowLE = allowLE;
        range->allowEDR = allowEDR;
    }
    pthread_mutex_unlock(&mAttLock);

    return !!range;
}

/*
 * FUNCTION: attSrvValFind
 * USE:      find a value structure for a given range structure and a given offset
 * PARAMS:   range - the range
 *           offset - the offset
 * RETURN:   the value struct or NULL if not found
 * NOTES:    call with mAttLock held
 */
static struct attSrvVal* attSrvValFind(struct attSrvRange *range, uint16_t offset)
{
    struct attSrvVal *val;

    for (val = range->valsHead; val && val->offset != offset; val = val->next);

    return val;
}

/*
 * FUNCTION: attSrvValRangeFind
 * USE:      find a value structure and a range structure for a ATT server, a range handle, and an offset
 * PARAMS:   rangeRef - the range reference
 *           offset - the offset
 *           rangeP - range gets stored here
 * RETURN:   the value struct or NULL if not found
 * NOTES:    call with mAttLock held
 */
static struct attSrvVal* attSrvValRangeFind(att_range_t rangeRef, uint16_t offset, struct attSrvRange **rangeP)
{
    *rangeP = attSrvRangeFind(rangeRef);
    if (*rangeP)
        return  attSrvValFind(*rangeP, offset);
    return NULL;
}

/*
 * FUNCTION: attSrvHandleRangeRelease
 * USE:      release a range of handles in the ATT server
 * PARAMS:   rangeRef - the range reference
 * RETURN:   NONE
 * NOTES:
 */
void attSrvHandleRangeRelease(att_range_t rangeRef)
{
    struct attSrvRange *range;

    pthread_mutex_lock(&mAttLock);
    range = attSrvRangeFind(rangeRef);
    if (!range)
        logw("Attempt to delete a non-existent range\n");
    else {
        if (attConnListIsEmpty(&range->seenBy))
            attSrvRangeDelete(range);
        else {
            attSrvRangeDeleteAllVals(range);
            range->rangeRef = 0;
        }
    }
    pthread_mutex_unlock(&mAttLock);
}

/*
 * FUNCTION: attSrvHandleRangeGetBase
 * USE:      Get the actual handle value of the first handle in a range
 * PARAMS:   rangeRef - the range reference
 * RETURN:   handle value or 0 on error
 * NOTES:
 */
uint16_t attSrvHandleRangeGetBase(att_range_t rangeRef)
{
    struct attSrvRange *range;
    uint16_t ret;

    pthread_mutex_lock(&mAttLock);
    range = attSrvRangeFind(rangeRef);
    ret = range ? range->start : 0;
    pthread_mutex_unlock(&mAttLock);
    return ret;
}

/*
 * FUNCTION: attSrvHandleRangeGetLen
 * USE:      Get the actual length (in handled) of a range
 * PARAMS:   rangeRef - the range reference
 * RETURN:   length or 0 on error
 * NOTES:
 */
uint16_t attSrvHandleRangeGetLen(att_range_t rangeRef)
{
    struct attSrvRange *range;
    uint16_t ret;

    pthread_mutex_lock(&mAttLock);
    range = attSrvRangeFind(rangeRef);
    ret = range ? range->len : 0;
    pthread_mutex_unlock(&mAttLock);
    return ret;
}

/*
 * FUNCTION: attSrvValueRegister
 * USE:      Register a given value in a given range
 * PARAMS:   rangeRef - the range reference
 *           offset - handle's offset from start of the range
 *           type - the type of the registered value
 *           perms - permissions (ATT_PERM_*)
 * RETURN:   success
 * NOTES:
 */
bool attSrvValueRegister(att_range_t rangeRef, uint16_t offset, const struct uuid *type, uint8_t perms)
{
    struct attSrvVal *next, *prev = NULL, *val;
    struct attSrvRange *range;
    bool ret = false;


    pthread_mutex_lock(&mAttLock);
    range = attSrvRangeFind(rangeRef);
    if (!range) {
        logw("Attempt to add a value to a non-existent range\n");
        goto out;
    }

    if (offset >= range->len) {
        logw("Value or group end out of range\n");
        goto out;
    }

    for (next = range->valsHead; next && next->offset < offset; prev = next, next = next->next);
    /*
     * prev is our prev or NULL if we're first
     * next is our next or NULL if we're last
     * If this is a duplication, next is the item we're trying to duplicate
     */

    if (next && next->offset == offset) {
        logw("Attempt to create duplicate-offset value (0x%04X+0x%04X)\n", range->start, offset);
        goto out;
    }

    val = (struct attSrvVal*)calloc(1, sizeof(struct attSrvVal));
    if (!val)
        goto out;

    memcpy(&val->type, type, sizeof(val->type));
    val->offset = offset;
    val->perms = perms;
    val->next = next;
    val->prev = prev;
    if (next)
        next->prev = val;
    else
        range->valsTail = val;
    if (prev)
        prev->next = val;
    else
        range->valsHead = val;
    ret = true;

out:
    pthread_mutex_unlock(&mAttLock);
    return ret;
}

/*
 * FUNCTION: attSrvValueGetGrpLen
 * USE:      Get a given value's "group length" parameter
 * PARAMS:   rangeRef - the range reference
 *           offset - handle's offset from start of the range)
 *           grpLenP - the group length gets stored here
 * RETURN:   success
 * NOTES:
 */
bool attSrvValueGetGrpLen(att_range_t rangeRef, uint16_t offset, uint16_t *grpLenP)
{
    struct attSrvRange *range;
    struct attSrvVal *val;
    bool ret = false;

    pthread_mutex_lock(&mAttLock);
    val = attSrvValRangeFind(rangeRef, offset, &range);
    if (!range) {
        logw("Attempt to set group len on a value from a non-existent range\n");
        goto out;
    }
    if (!val) {
        logw("Attempt to set group len on a non-existent value from a non-existent range (0x%04X+0x%04X)\n", range->start, offset);
        goto out;
    }

    if (grpLenP)
        *grpLenP = val->grpLen;
    ret = true;

out:
    pthread_mutex_unlock(&mAttLock);
    return ret;
}
/*
 * FUNCTION: attSrvValueSetGrpLen
 * USE:      Set a given value's "group length" parameter
 * PARAMS:   rangeRef - the range reference
 *           offset - handle's offset from start of the range)
 *           grpLen - the group length to set
 * RETURN:   success
 * NOTES:
 */
bool attSrvValueSetGrpLen(att_range_t rangeRef, uint16_t offset, uint16_t grpLen)
{
    struct attSrvRange *range;
    struct attSrvVal *val;
    bool ret = false;

    pthread_mutex_lock(&mAttLock);
    val = attSrvValRangeFind(rangeRef, offset, &range);
    if (!range) {
        logw("Attempt to set group len on a value from a non-existent range\n");
        goto out;
    }
    if (!val) {
        logw("Attempt to set group len on a non-existent value from a non-existent range (0x%04X+0x%04X)\n", range->start, offset);
        goto out;
    }

    if (offset + grpLen > range->len) {
        logw("Group end out of range\n");
        goto out;
    }

    val->grpLen = grpLen;
    ret = true;

out:
    pthread_mutex_unlock(&mAttLock);
    return ret;
}

/*
 * FUNCTION: attSrvValueUnregister
 * USE:      Unregister a given value in a given range
 * PARAMS:   rangeRef - the range reference
 *           offset - handle's offset from start of the range)
 * RETURN:   success
 * NOTES:
 */
bool attSrvValueUnregister(att_range_t rangeRef, uint16_t offset)
{
    struct attSrvRange *range;
    struct attSrvVal *val;
    bool ret = false;

    pthread_mutex_lock(&mAttLock);
    val = attSrvValRangeFind(rangeRef, offset, &range);
    if (!range) {
        logw("Attempt to remove a value from a non-existent range\n");
        goto out;
    }
    if (!val) {
        logw("Attempt to remove a non-existent value from a non-existent range (0x%04X+0x%04X)\n", range->start, offset);
        goto out;
    }

    if (val->next)
        val->next->prev = val->prev;
    else
        range->valsTail = val->prev;
    if (val->prev)
        val->prev->next = val->next;
    else
        range->valsHead = val->next;
    free(val);
    ret = true;

out:
    pthread_mutex_unlock(&mAttLock);
    return ret;
}

/*
 * FUNCTION: attConnMtuGetByConn
 * USE:      Get the MTU to someone
 * PARAMS:   conn - per-connection structure
 *           tryDefaults - try to find the default to use?
 * RETURN:   the mtu to use or 0 on error
 * NOTES:    call with mAttLock held
 */
static uint32_t attConnMtuGetByConn(struct attConn *conn, bool tryDefaults)
{
    uint32_t mtu = 0;

    if (!(mtu = conn->mtu) && tryDefaults) {
        struct bt_addr peer;

        if (!l2cApiGetBtAddr(conn->conn, &peer)) {
            logw("Failed to get peer address\n");
            return 0;
        }
        mtu = BT_ADDR_IS_EDR(peer) ? ATT_MTU_MIN_EDR : ATT_MTU_MIN_LE;
    }

    return mtu;
}
/*
 * FUNCTION: attConnMtuGetByL2c
 * USE:      Get the MTU to someone
 * PARAMS:   to - whom to
 *           tryDefaults - try to find the default to use?
 * RETURN:   the mtu to use or 0 on error
 * NOTES:    call with mAttLock held
 */
static uint32_t attConnMtuGetByL2c(l2c_handle_t to, bool tryDefaults)
{
    struct attConn *conn = attConnFindByL2cConn(to);
    uint32_t mtu = 0;

    if ((!conn || !(mtu = conn->mtu)) && tryDefaults) {
        struct bt_addr peer;

        if (!l2cApiGetBtAddr(to, &peer)) {
            logw("Failed to get peer address\n");
            return 0;
        }
        mtu = BT_ADDR_IS_EDR(peer) ? ATT_MTU_MIN_EDR : ATT_MTU_MIN_LE;
    }

    return mtu;
}

/*
 * FUNCTION: attConnMtuSet
 * USE:      Set the MTU to someone
 * PARAMS:   to - whom to
 *           mtu - the MTU to set
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attConnMtuSet(l2c_handle_t to, uint32_t mtu)
{
    struct attConn *conn = attConnFindByL2cConn(to);

    if (!conn) {
        logw("Setting MTU for unknown connection\n");
        return false;
    }

    conn->mtu = mtu;
    return true;
}

/*
 * FUNCTION: attSrvTimerCbk
 * USE:      Called when a timeout for a confirmation for a sent notification comes
 * PARAMS:   which - the timer
 *           userData - unused
 * RETURN:   NONE
 * NOTES:    XXX: penOp interaction with this should be explored
 */
static void attSrvTimerCbk(uniq_t which,  uint64_t userData)
{
    struct attConn *conn = NULL;

    pthread_mutex_lock(&mAttLock);

    /* find the relant conn */
    for (conn = mConns; conn && conn->srv.indTimer != which; conn = conn->next);

    /* if we found it, send the callback */
    if (conn)
        attSrvSchedIndResultCbk(conn->srv.indRangeRef, conn->srv.indOffset, conn, ATT_SRV_EVT_IND_TIMEOUT, conn->srv.indRef);

    pthread_mutex_unlock(&mAttLock);
}


/*
 * FUNCTION: attSendPacketRaw
 * USE:      Sends an assembled packet to the peer
 * PARAMS:   to - whom the data is to be sent to
 *           preData - first part of the packet or NULL
 *           preLen - length of fais data
 *           data - the middle of the packet or NULL
 *           postData - last part of the packet or NULL
 *           postLen - length of said data
 * RETURN:   ATT_TX_RET_*
 * NOTES:
 */
static uint8_t attSendPacketRaw(l2c_handle_t to, const void *preData, uint32_t preLen, sg data, const void *postData, uint32_t postLen)
{
    uint8_t ret;
    sg tmpData = NULL;

    if (!data) {
        tmpData = data = sgNew();
        if (!tmpData)
            return ATT_TX_RET_OOM;
    }

    if (preLen && !sgConcatFrontCopy(data, preData, preLen)) {
        if (tmpData)
            sgFree(tmpData);
        return ATT_TX_RET_OOM;
    }

    if (postLen && !sgConcatBackCopy(data, postData, postLen)) {
        if (tmpData)
            sgFree(tmpData);
        else
            sgTruncFront(data, preLen);
        return ATT_TX_RET_OOM;
    }

    ret = mTxCbk(to, data);
    if (ret == ATT_TX_RET_ACCEPTED)
        return ret;

    if (tmpData)
        sgFree(tmpData);
    else {
        sgTruncBack(data, postLen);
        sgTruncFront(data, preLen);
    }
    return ret;
}

/*
 * FUNCTION: attSrvSendPacketNotif
 * USE:      Send notifications to all clients who wanted them for this value
 * PARAMS:   range - the range
 *           val - the value struct
 *           conn - the per-connection structure
 *           data - the value
 *           notify - send notification (as opposed to indication)
 *           ref - pased to callbacks so you know which notif/ind they are tellking you about
 * RETURN:   L2C_TX_*
 * NOTES:    call with mAttLock held
 */
static uint8_t attSrvSendPacketNotif(struct attSrvRange *range, struct attSrvVal *val, struct attConn* conn, sg data, bool notify, uint64_t ref)
{
    uint8_t hdrBuf[sizeof(struct attHdr) + sizeof(struct attPduHandleValueNotif) + sizeof(struct attPduHandleValueInd)]; /* definitely big enoguh to fit the fist and either second or third */
    struct attHdr *hdr = (struct attHdr*)hdrBuf;
    struct attPduHandleValueNotif *notifH = (struct attPduHandleValueNotif*)(hdr + 1);
    struct attPduHandleValueInd *indH = (struct attPduHandleValueInd*)(hdr + 1);
    uint8_t hdrLen = sizeof(*hdr);
    uint32_t mtu;

    if (notify) {
        utilSetLE8(&hdr->opcode, ATT_OPCODE_HANDLE_VALUE_NOTIF);
        utilSetLE16(&notifH->handle, val->offset + range->start);
        hdrLen += sizeof(*notifH);
    } else {

        if (conn->srv.indTimer)
            return ATT_TX_RET_ATT_BUSY;

        utilSetLE8(&hdr->opcode, ATT_OPCODE_HANDLE_VALUE_IND);
        utilSetLE16(&indH->handle, val->offset + range->start);
        hdrLen += sizeof(*indH);
    }

    mtu = attConnMtuGetByConn(conn, true);
    if (!mtu)
        return ATT_TX_RET_ATT_ERROR;

    mtu -= hdrLen;
    if (sgLength(data) > mtu) {
        logd("Truncating wanted notif/ind data to %ub\n", mtu);
        sgTruncBack(data, sgLength(data) - mtu);
    }

    if (!notify) {
        conn->srv.indRangeRef = range->rangeRef;
        conn->srv.indOffset = val->offset;
        conn->srv.indTimer = timerSet(ATT_IND_TIMEOUT, attSrvTimerCbk, 0);
    }

    return attSendPacketRaw(conn->conn, hdrBuf, hdrLen, data, NULL, 0);
}

/*
 * FUNCTION: attSrvSendPacketErrorReply
 * USE:      Sends an error to the client
 * PARAMS:   to - whom to send to
 *           err - the error
 *           opcode - opcode for which the error happened
 *           handle - the pertinent handle
 * RETURN:   success
 * NOTES:
 */
static bool attSrvSendPacketErrorReply(l2c_handle_t to, uint8_t errNo, uint8_t opcode, uint16_t handle)
{
    struct attPduError err;
    struct attHdr hdr;

    utilSetLE8(&hdr.opcode, ATT_OPCODE_ERROR);
    utilSetLE8(&err.reqOpcode, opcode);
    utilSetLE8(&err.err, errNo);
    utilSetLE16(&err.handle, handle);

    return attSendPacketRaw(to, &hdr, sizeof(hdr), NULL, &err, sizeof(err)) == ATT_TX_RET_ACCEPTED;
}

/*
 * FUNCTION: attSendPacket
 * USE:      Sends a packet to a client
 * PARAMS:   to - whom to send to
 *           opcode - opcode to send
 *           hdr - a header to prepend
 *           hdrLen - length of said header
 *           data - the data to send (may be NULL)
 * RETURN:   success
 * NOTES:
 */
static bool attSendPacket(l2c_handle_t to, uint8_t opcode, const void *hdr, uint32_t hdrLen, sg data)
{
    struct attHdr attHdr;
    bool freeData = false;

    if (!data) {
        data = sgNew();
        if (!data)
            return false;
        freeData = true;
    }

    utilSetLE8(&attHdr.opcode, opcode);

    if (hdr && !sgConcatFrontCopy(data, hdr, hdrLen))
        goto out;

    if (attSendPacketRaw(to, &attHdr, sizeof(attHdr), data, NULL, 0) == ATT_TX_RET_ACCEPTED)
        return true;

    sgTruncFront(data, hdrLen);
    /* fallthough */

out:
    if (freeData)
        sgFree(data);
    return false;
}

/*
 * FUNCTION: attSendPacketEmptyPacket
 * USE:      Sends an empy packet to a client
 * PARAMS:   to - whom to send to
 *           opcode - opcode to send
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attSendPacketEmptyPacket(l2c_handle_t to, uint8_t opcode)
{
    return attSendPacket(to, opcode, NULL, 0, NULL);
}

/*
 * FUNCTION: attSrvValueNotifyChanged
 * USE:      Sen a notification or an indication
 * PARAMS:   rangeRef - the range reference
 *           offset - handle's offset from start of the range
 *           cid - the connection id
 *           data - the data to send
 *           notify - send notification (as opposed to indication)
 *           ref - pased to callbacks so you know which notif/ind they are tellking you about
 * RETURN:   ATT_TX_RET_*
 * NOTES:
 */
uint8_t attSrvValueNotifyChanged(att_range_t rangeRef, uint16_t offset, att_cid_t cid, sg data, bool notify, uint64_t ref)
{
    uint8_t ret = ATT_TX_RET_ATT_ERROR;
    struct attSrvRange *range;
    struct attSrvVal *val;
    struct attConn *conn;

    pthread_mutex_lock(&mAttLock);
    conn = attConnFindBySrvCid(cid);
    if (!conn) {
        loge("Got notif request reply for unknown connection\n");
        goto out;
    }

    val = attSrvValRangeFind(rangeRef, offset, &range);
    if (!range) {
        logw("Attempt to notify on a value from a non-existent range\n");
        goto out;
    }
    if (!val) {
        logw("Attempt to notify on a non-existent value from an existent range (0x%04X+0x%04X)\n", range->start, offset);
        goto out;
    }

    ret = attSrvSendPacketNotif(range, val, conn, data, notify, ref);

out:
    pthread_mutex_unlock(&mAttLock);
    return ret;
}

/*
 * FUNCTION: attSrvCidResolve
 * USE:      Attempt to resolve a CID to a L2C connection handle
 * PARAMS:   srvCid - the server cid
 * RETURN:   L2C connection handle or 0 on failure
 * NOTES:    this is used externally
 */
l2c_handle_t attSrvCidResolve(att_cid_t srvCid)
{
    struct attConn* conn;
    l2c_handle_t ret = 0;

    pthread_mutex_lock(&mAttLock);
    conn = attConnFindBySrvCid(srvCid);
    if (conn)
        ret = conn->conn;
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attSetMtu
 * USE:      Called to set the MTU for an ATT server to a given client directly and with no negotiation
 * PARAMS:   to - whom the MTU is to
 *           mtu - the mtu
 * RETURN:   NONE
 * NOTES:    used by EDR only. LE does its own negotiation of this over special ATT packets
 */
void attSetMtu(l2c_handle_t to, uint32_t mtu)
{
    pthread_mutex_lock(&mAttLock);
    attConnListAddIfNew(to);
    attConnMtuSet(to, mtu);
    pthread_mutex_unlock(&mAttLock);
}

/*
 * FUNCTION: attReadUuid
 * USE:      Read a UUID-128 or a UUID16 from an sg, if it is the only thing there
 * PARAMS:   dst - we store the read UUID here
 *           s - the data
 * RETURN:   success
 * NOTES:
 */
bool attReadUuid(struct uuid *dst, sg s)
{
    uint8_t buf[16];
    struct uuid *ru = (struct uuid*)buf;

    if (sgLength(s) == sizeof(uint16_t)) {
        sgSerialize(s, 0, sizeof(uint16_t), buf);
        uuidFromUuid16(dst, utilGetLE16(buf));
    } else if (sgLength(s) == sizeof(struct uuid)) {
        sgSerialize(s, 0, sizeof(struct uuid), buf);
        uuidReadLE(dst, ru);
    } else
        return false;

    return true;
}

/*
 * FUNCTION: attSrvIsValReadableBy
 * USE:      Decide if a given value is readable by a given connection
 * PARAMS:   range -the value's range
 *           val - the value
 *           conn - per-connection state for this connection
 * RETURN:   ATT_ERROR_*
 * NOTES:    call with mAttLock held
 */
static uint8_t attSrvIsValReadableBy(struct attSrvRange *range, struct attSrvVal *val, struct attConn *conn)
{
    if (val->perms & ATT_PERM_READ)
        return ATT_ERROR_NONE;
    if (val->perms & ATT_PERM_READ_ENCR)
        return conn->isEncr ? ATT_ERROR_NONE : ATT_ERROR_INSUFFICIENT_ENCR;
    if (val->perms & ATT_PERM_READ_ENCR_MITM) {
        if (!conn->isEncr)
            return ATT_ERROR_INSUFFICIENT_ENCR;
        else if (!conn->isMitmProtected)
            return ATT_ERROR_INSUFFICIENT_AUTH;
        else
            return ATT_ERROR_NONE;
    }

    return ATT_ERROR_UNLIKELY_ERROR; /* ?? */
}

/*
 * FUNCTION: attSrvIsValWriteableBy
 * USE:      Decide if a given value is writeable by a given connection
 * PARAMS:   range -the value's range
 *           val - the value
 *           conn - per-connection state for this connection
 *           isSigned - is this a signed write?
 * RETURN:   ATT_ERROR_*
 * NOTES:    call with mAttLock held
 */
static uint8_t attSrvIsValWriteableBy(struct attSrvRange *range, struct attSrvVal *val, struct attConn *conn, bool isSigned)
{
    if (val->perms & ATT_PERM_WRITE)
        return ATT_ERROR_NONE;
    if (isSigned)
        return ((val->perms & ATT_PERM_WRITE_SIGNED) && !conn->isEncr) ? ATT_ERROR_NONE : ATT_ERROR_WRITE_NOT_ALLOWED;
    if (val->perms & ATT_PERM_WRITE_ENCR)
        return conn->isEncr ? ATT_ERROR_NONE  : ATT_ERROR_INSUFFICIENT_ENCR;
    if (val->perms & ATT_PERM_WRITE_ENCR_MITM) {
        if (!conn->isEncr)
            return ATT_ERROR_INSUFFICIENT_ENCR;
        else if (!conn->isMitmProtected)
            return ATT_ERROR_INSUFFICIENT_AUTH;
        else
            return ATT_ERROR_NONE;
    }

    return ATT_ERROR_WRITE_NOT_ALLOWED;
}

/*
 * FUNCTION: attRangeIsVisibleBy
 * USE:      Decide if a given range is visibile to a given connection
 * PARAMS:   range - the range
 *           conn - per-connection state for this connection
 * RETURN:   true if visible, false else
 * NOTES:    call with mAttLock held
 */
static bool attSrvIsRangeVisibleTo(struct attSrvRange *range, struct attConn *conn)
{
    return (conn->isLE && range->allowLE) || (!conn->isLE && range->allowEDR);
}

/*
 * FUNCTION: attSrvOpFindInfo
 * USE:      Perform a find info request
 * PARAMS:   to - whom to reply to
 *           mtu - the mtu to use
 *           startHandle - first handle the client cares about
 *           endHandle - last handle the client cares about
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpFindInfo(l2c_handle_t to, uint32_t mtu, uint16_t startHandle, uint16_t endHandle)
{
    struct attConn *conn = attConnFindByL2cConn(to);
    struct attPduFindInfoRsp rsp;
    bool allUuidsSmall = true;
    struct attSrvRange *range;
    struct attSrvVal *val;
    sg results = NULL;
    bool err = false;

    if (!conn) {
        loge("No connection found\n");
        return attSrvSendPacketErrorReply(to, ATT_ERROR_UNLIKELY_ERROR, ATT_OPCODE_FIND_INFO_REQ, startHandle);
    }

    if (!startHandle || startHandle > endHandle)
        return attSrvSendPacketErrorReply(to, ATT_ERROR_INVALID_HANDLE, ATT_OPCODE_FIND_INFO_REQ, startHandle);

    results = sgNew();

    if (!results)
        return attSrvSendPacketErrorReply(to, ATT_ERROR_INSUFFICIENT_RSRCS, ATT_OPCODE_FIND_INFO_REQ, startHandle);

    mtu -= sizeof(struct attPduFindInfoRsp) + sizeof(struct attHdr); /* mtu is now how many bytes we can produce */

    for (range = mRangesHead; range; range = range->next) {
        if (!attSrvIsRangeVisibleTo(range, conn))
            continue;
        for (val = range->valsHead; val; val = val->next) {
            uint16_t uuid16, handle = range->start + val->offset;

            if (handle < startHandle)
                continue;
            if (handle > endHandle)
                goto out;

            if (allUuidsSmall && uuidToUuid16(&uuid16, &val->type)) {
                struct attPduFindInfoData16 result;

                utilSetLE16(&result.handle, handle);
                utilSetLE16(&result.uuid16, uuid16);
                if (!sgConcatBackCopy(results, &result, sizeof(result))) {
                    err = true;
                    goto out;
                }
            } else {
                struct attPduFindInfoData128 result;
                if (allUuidsSmall) { /* need to convert to all-large */
                    uint32_t numResults = sgLength(results) / sizeof(struct attPduFindInfoData16);
                    struct attPduFindInfoData16 result16;
                    struct uuid uuid;

                    while(numResults--) {
                        if (!sgSerializeCutFront(results, &result16, sizeof(result16)))
                            goto unrecoverable;
                        utilSetLE16(&result.handle, utilGetLE16(&result16.handle));
                        uuidFromUuid16(&uuid, utilGetLE16(&result16.uuid16));
                        uuidWriteLE(&result.uuid128, &uuid);
                        if (!sgConcatBackCopy(results, &result, sizeof(result)))
                            goto unrecoverable;
                    }
                    allUuidsSmall = false;
                }
                utilSetLE16(&result.handle, handle);
                uuidWriteLE(&result.uuid128, &val->type);
                if (!sgConcatBackCopy(results, &result, sizeof(result))) {
                    err = true;
                    goto out;
                }
            }

            /* keep length in check */
            if (sgLength(results) >= mtu)
                goto out;
        }
    }

out:
    /* if we have results AND an error, favour sending results */
    if (!sgLength(results) && err)
        goto unrecoverable;

    /* make sure we do not send too much */
    while (sgLength(results) > mtu)
        sgTruncBack(results, allUuidsSmall ? sizeof(struct attPduFindInfoData16) : sizeof(struct attPduFindInfoData128));

    /* a lack of results is reported thusly */
    if (!sgLength(results)) {
        sgFree(results);
        return attSrvSendPacketErrorReply(to, ATT_ERROR_ATTRIBUTE_NOT_FOUND, ATT_OPCODE_FIND_INFO_REQ, startHandle);
    }

    /* we're ready to send a reply */
    utilSetLE8(&rsp.format, allUuidsSmall ? ATT_FIND_INFO_RSP_FMT_16 : ATT_FIND_INFO_RSP_FMT_128);
    if (attSendPacket(to, ATT_OPCODE_FIND_INFO_RSP, &rsp, sizeof(rsp), results))
        return true;

    /* if we fall though to here, try to send an error (even if it is unlikely to work) */

unrecoverable:
    if (results)
        sgFree(results);
    return attSrvSendPacketErrorReply(to, ATT_ERROR_UNLIKELY_ERROR, ATT_OPCODE_FIND_INFO_REQ, 0);
}

/*
 * FUNCTION: attSrvOpFindByTypeValContinue
 * USE:      Continue a find by type value request
 * PARAMS:   conn - the per-connection struct
 *           lastReadData - return from the READ call
 *           leastReadLen - length last read result produced
 *           lastReadRet - last read's result
 * RETURN:   false to fail immediately, true if more work will be done
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpFindByTypeValContinue(struct attConn *conn, const void *lastReadData, uint16_t leastReadLen, uint8_t lastReadRet)
{
    uint8_t err = ATT_ERROR_UNLIKELY_ERROR;
    struct attSrvRange *range;
    struct attSrvVal *val;
    uint16_t startHandle;
    uint16_t endHandle;
    uint32_t mtu;
    sg results;

    if (conn->srv.penOp.origOpcode != ATT_OPCODE_FIND_BY_TYPE_VAL_REQ)
        return false;

    startHandle = conn->srv.penOp.startHandle;
    endHandle = conn->srv.penOp.endHandle;
    mtu = conn->srv.penOp.mtu;
    results = conn->srv.penOp.replyInProgress;

    mtu -= sizeof(struct attHdr); /* mtu is now how many bytes we can produce */

    if (lastReadRet == ATT_ERROR_NONE && leastReadLen == conn->srv.penOp.findByTypeValue.wantedLen && !memcmp(lastReadData, conn->srv.penOp.findByTypeValue.wantedVal, leastReadLen)) {

        /* if the last read succeeded, append the result if it is a result */
        struct attPduFindByTypeValRspItem result;

        utilSetLE16(&result.firstHandle, startHandle);
        utilSetLE16(&result.groupEndHandle, startHandle + conn->srv.penOp.findByTypeValue.valGrpLen - 1);

        if (!sgConcatBackCopy(results, &result, sizeof(result)))
            goto done;

        if (sgLength(results) >= mtu)
            goto done;

    } else if (lastReadRet != ATT_FIRST_CONTINUE_CALL) {
        /* if the last read failed - stop searching */
        goto done;
    }

    if (startHandle == endHandle)
        goto done;
    startHandle++;

    for (range = mRangesHead; range; range = range->next) {
        if (!attSrvIsRangeVisibleTo(range, conn))
            continue;
        for (val = range->valsHead; val; val = val->next) {
            uint16_t handle = range->start + val->offset;
            uint16_t effectiveGrpLen = val->grpLen ? val->grpLen : 1;


            /* range check */
            if (handle < startHandle)
                continue;
            if (handle > endHandle)
                goto done;

            /* must be readable */
            if (ATT_ERROR_NONE != attSrvIsValReadableBy(range, val, conn))
                continue;

            /* must be of a given type */
            if (!uuidCmp(&val->type, &conn->srv.penOp.findByTypeValue.uuid))
                continue;

            /* we found a falue to read - schedule it */
            conn->srv.penOp.startHandle = handle;
            conn->srv.penOp.findByTypeValue.valGrpLen = effectiveGrpLen;
            if (!attSrvSchedReadCbk(range, val, conn, ATT_READ_FOR_FIND_BY_TYPE_VAL, 0, conn->srv.penOp.findByTypeValue.wantedLen + 1))
                break;

            return false;
        }
    }

done:
    conn->srv.penOp.origOpcode = 0;
    free(conn->srv.penOp.findByTypeValue.wantedVal);

    /* make sure we do not send too much */
    while (sgLength(results) > mtu)
        sgTruncBack(results, sizeof(struct attPduFindByTypeValRspItem));

    /* a lack of results is reported via error */
    if (!sgLength(results)) {
        err = ATT_ERROR_ATTRIBUTE_NOT_FOUND;
        startHandle = conn->srv.penOp.origStartHandle;
    } else if (attSendPacket(conn->conn, ATT_OPCODE_FIND_BY_TYPE_VAL_RSP, NULL, 0, results))
        return true;

    /* if we fall though to here, try to send an error */
    sgFree(results);
    return attSrvSendPacketErrorReply(conn->conn, err, ATT_OPCODE_FIND_BY_TYPE_VAL_REQ, startHandle);
}

/*
 * FUNCTION: attSrvOpFindByTypeValStart
 * USE:      Start a find by type value request
 * PARAMS:   to - whom to reply to
 *           mtu - the mtu to use
 *           startHandle - first handle the client cares about
 *           endHandle - last handle the client cares about
 *           uuid - the uuid to find
 *           s - the value to find
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpFindByTypeValStart(l2c_handle_t to, uint32_t mtu, uint16_t startHandle, uint16_t endHandle, const struct uuid *uuid, sg s)
{
    struct attConn *conn = attConnFindByL2cConn(to);
    uint8_t err = ATT_ERROR_INSUFFICIENT_RSRCS;
    sg results = NULL;
    bool ret;

    if (!startHandle || startHandle > endHandle) {
        ret = attSrvSendPacketErrorReply(to, ATT_ERROR_INVALID_HANDLE, ATT_OPCODE_FIND_BY_TYPE_VAL_REQ, startHandle);
        goto out;
    }

    if (!conn)
        loge("No connection found\n");
    else if (conn->srv.penOp.origOpcode)
        err = ATT_ERROR_UNLIKELY_ERROR;
    else {

        results = sgNew();
        if (results) {

            conn->srv.penOp.findByTypeValue.wantedVal = malloc(sgLength(s));
            if (conn->srv.penOp.findByTypeValue.wantedVal) {

                sgSerialize(s, 0, sgLength(s), conn->srv.penOp.findByTypeValue.wantedVal);

                conn->srv.penOp.origOpcode = ATT_OPCODE_FIND_BY_TYPE_VAL_REQ;
                conn->srv.penOp.replyInProgress = results;
                conn->srv.penOp.origStartHandle = startHandle;
                conn->srv.penOp.startHandle = startHandle - 1;
                conn->srv.penOp.endHandle = endHandle;
                conn->srv.penOp.mtu = mtu;
                memcpy(&conn->srv.penOp.findByTypeValue.uuid, uuid, sizeof(conn->srv.penOp.findByTypeValue.uuid));
                conn->srv.penOp.findByTypeValue.wantedLen = sgLength(s);
                conn->srv.penOp.findByTypeValue.valGrpLen = 0;

                if (attSrvOpFindByTypeValContinue(conn, NULL, 0, ATT_FIRST_CONTINUE_CALL)) {
                    sgFree(s);
                    return true;
                }

                err = ATT_ERROR_UNLIKELY_ERROR;
                conn->srv.penOp.origOpcode = 0;

                free(conn->srv.penOp.findByTypeValue.wantedVal);
            }
            sgFree(results);
        }
    }

    ret = attSrvSendPacketErrorReply(to, err, ATT_OPCODE_FIND_BY_TYPE_VAL_REQ, startHandle);

out:
    if (ret)
        sgFree(s);
    return ret;
}

/*
 * FUNCTION: attSrvOpReadByTypeContinue
 * USE:      Continue a read by type / read by group type request
 * PARAMS:   conn - the per-connection structure
 *           lastReadData - return from the READ call
 *           lastReadLen - length last read result produced
 *           lastReadRet - last read's result
 * RETURN:   false to fail immediately, true if more work will be done
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpReadByTypeContinue(struct attConn *conn, const void *lastReadData, uint16_t lastReadLen, uint8_t lastReadRet)
{
    uint8_t err = ATT_ERROR_NONE;
    struct attSrvRange *range;
    struct attSrvVal *val;
    uint16_t packetHdrSz;
    uint16_t startHandle;
    uint16_t itemMaxLen;
    uint16_t endHandle;
    uint8_t readReason;
    uint8_t itemHdrSz;
    uint8_t reqOpcode;
    uint8_t rspOpcode;
    uint16_t mtu;
    bool grpType;
    sg results;


    grpType = conn->srv.penOp.readByType.grpType;
    packetHdrSz = grpType ? sizeof(struct attPduReadByGrpTypeRsp) : sizeof(struct attPduReadByTypeRsp);
    itemHdrSz = grpType ? sizeof(struct attGrpValuePair) : sizeof(struct attHandleValuePair);
    itemMaxLen = grpType ? ATT_MAX_LEN_FOR_RD_BY_GRP_TYP : ATT_MAX_LEN_FOR_RD_BY_TYPE;
    readReason = grpType ? ATT_READ_FOR_READ_BY_GRP_TYPE : ATT_READ_FOR_READ_BY_TYPE;
    reqOpcode = grpType ? ATT_OPCODE_READ_BY_GRP_TYPE_REQ : ATT_OPCODE_READ_BY_TYPE_REQ;
    rspOpcode = grpType ? ATT_OPCODE_READ_BY_GRP_TYPE_RSP : ATT_OPCODE_READ_BY_TYPE_RSP;

    if (conn->srv.penOp.origOpcode != reqOpcode)
        return false;

    startHandle = conn->srv.penOp.startHandle;
    endHandle = conn->srv.penOp.endHandle;
    mtu = conn->srv.penOp.mtu;
    results = conn->srv.penOp.replyInProgress;

    mtu -= sizeof(struct attHdr) + packetHdrSz; /* mtu is now how many bytes we can produce */
    if (itemMaxLen > mtu - itemHdrSz)
        itemMaxLen = mtu - itemHdrSz;

    if (lastReadRet == ATT_ERROR_NONE) {
        sg thisResult;
        uint16_t perResultSize;

        /* only items of the same size shall be provided, so the first result sets the size */
        if (sgLength(results) && lastReadLen != conn->srv.penOp.readByType.itemLen)
            goto done;
        conn->srv.penOp.readByType.itemLen = lastReadLen;

        /* prepare the per-item header */
        if (grpType) {
            struct attGrpValuePair gvp;
            utilSetLE16(&gvp.handle, startHandle);
            utilSetLE16(&gvp.groupEndHadle, startHandle + conn->srv.penOp.readByType.valGrpLen - 1);

            thisResult = sgNewWithCopyData(&gvp, sizeof(gvp));
        } else {
            struct attHandleValuePair hvp;
            utilSetLE16(&hvp.handle, startHandle);

            thisResult = sgNewWithCopyData(&hvp, sizeof(hvp));
        }

        if (!thisResult) {
            err = ATT_ERROR_INSUFFICIENT_RSRCS;
            goto done;
        }

        if (!sgConcatBackCopy(thisResult, lastReadData, lastReadLen)) {
            sgFree(thisResult);
            err = ATT_ERROR_INSUFFICIENT_RSRCS;
            goto done;
        }

        perResultSize = sgLength(thisResult);

        /* append */
        sgConcat(results, thisResult);

        /*
         * If we cannot fit another result (since they are all the same size), get out.
         * One result is guaranteed to fit!
         */
        if (sgLength(results) + perResultSize > mtu)
            goto done;

    } else if (lastReadRet != ATT_FIRST_CONTINUE_CALL) {
        /* if the last read failed - stop searching */
        err = lastReadRet;
        goto done;
    }

    if (startHandle == endHandle)
        goto done;
    startHandle++;

    for (range = mRangesHead; range; range = range->next) {
        if (!attSrvIsRangeVisibleTo(range, conn))
            continue;
        for (val = range->valsHead; val; val = val->next) {
            uint16_t handle = range->start + val->offset;
            uint16_t effectiveGrpLen = val->grpLen ? val->grpLen : 1;

            /* range check */
            if (handle < startHandle)
                continue;
            if (handle > endHandle)
                goto done;

            /* must be readable */
            err = attSrvIsValReadableBy(range, val, conn);
            if (err != ATT_ERROR_NONE) {
                startHandle = handle;
                goto done;
            }

            /* must be of a given type */
            if (!uuidCmp(&val->type, &conn->srv.penOp.readByType.uuid))
                continue;

            /* we found a falue to read - schedule it */
            conn->srv.penOp.startHandle = handle;
            conn->srv.penOp.readByType.valGrpLen = effectiveGrpLen;
            if (attSrvSchedReadCbk(range, val, conn, readReason, 0, itemMaxLen))
                return true;

            err = ATT_ERROR_UNLIKELY_ERROR;
            goto done;
        }
    }

done:
    conn->srv.penOp.origOpcode = 0;

    if (sgLength(results) > mtu) {
        /* make sure we do not send too much */
        logw("Impossible result length %u over mtu %u in read by [grp] type\n", sgLength(results), mtu);
        startHandle = conn->srv.penOp.origStartHandle;
     } else if (!sgLength(results)) {

        /* a lack of results is reported thusly */
        if (err == ATT_ERROR_NONE) {
            err = ATT_ERROR_ATTRIBUTE_NOT_FOUND;
            startHandle = conn->srv.penOp.origStartHandle;
        }
    } else {
        struct attPduReadByTypeRsp rbt;
        struct attPduReadByGrpTypeRsp gtr;
        void *hdr;

        if (grpType) {
            hdr = &gtr;
            utilSetLE8(&gtr.attGrpValuePairSz, conn->srv.penOp.readByType.itemLen + sizeof(struct attGrpValuePair));
        } else {
            hdr = &rbt;
            utilSetLE8(&rbt.handleValuePairSz, conn->srv.penOp.readByType.itemLen + sizeof(struct attHandleValuePair));
        }

        if (attSendPacket(conn->conn, rspOpcode, hdr, packetHdrSz, results))
            return true;
        err = ATT_ERROR_UNLIKELY_ERROR;
    }

    /* if we fall though to here, try to send an error (even if it is unlikely to work) */
    sgFree(results);
    return attSrvSendPacketErrorReply(conn->conn, err, reqOpcode, startHandle);
}

/*
 * FUNCTION: attSrvOpReadByTypeStart
 * USE:      Start a read by type / read by group type request
 * PARAMS:   to - whom to reply to
 *           mtu - the mtu to use
 *           startHandle - first handle the client cares about
 *           endHandle - last handle the client cares about
 *           uuid - the uuid to find
 *           grpType - is this a "read by group type" request ?
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpReadByTypeStart(l2c_handle_t to, uint32_t mtu, uint16_t startHandle, uint16_t endHandle, const struct uuid *uuid, bool grpType)
{
    const uint8_t reqOpcode = grpType ? ATT_OPCODE_READ_BY_GRP_TYPE_REQ : ATT_OPCODE_READ_BY_TYPE_REQ;
    struct attConn *conn = attConnFindByL2cConn(to);
    uint8_t err = ATT_ERROR_INSUFFICIENT_RSRCS;
    sg results = NULL;

    if (!startHandle || startHandle > endHandle)
        return attSrvSendPacketErrorReply(to, ATT_ERROR_INVALID_HANDLE, reqOpcode, startHandle);

    if (!conn)
        loge("No connection found\n");
    else if (conn->srv.penOp.origOpcode)
        err = ATT_ERROR_UNLIKELY_ERROR;
    else {
        results = sgNew();
        if (results) {

            conn->srv.penOp.origOpcode = reqOpcode;
            conn->srv.penOp.replyInProgress = results;
            conn->srv.penOp.origStartHandle = startHandle;
            conn->srv.penOp.startHandle = startHandle - 1;
            conn->srv.penOp.endHandle = endHandle;
            conn->srv.penOp.mtu = mtu;
            memcpy(&conn->srv.penOp.readByType.uuid, uuid, sizeof(conn->srv.penOp.readByType.uuid));
            conn->srv.penOp.readByType.grpType = grpType;
            conn->srv.penOp.readByType.valGrpLen = 0;
            conn->srv.penOp.readByType.itemLen = 0;

            if (attSrvOpReadByTypeContinue(conn, NULL, 0, ATT_FIRST_CONTINUE_CALL))
                return true;

            err = ATT_ERROR_UNLIKELY_ERROR;
            conn->srv.penOp.origOpcode = 0;

            sgFree(results);
        }
    }

    return attSrvSendPacketErrorReply(to, err, reqOpcode, startHandle);
}

/*
 * FUNCTION: attSrvOpReadContinue
 * USE:      Continue a read / read blob request
 * PARAMS:   conn - the per-connection structure
 *           lastReadData - return from the READ call
 *           leastReadLen - length last read result produced
 *           lastReadRet - last read's result
 * RETURN:   false to fail immediately, true if more work will be done
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpReadContinue(struct attConn *conn, const void *lastReadData, uint16_t leastReadLen, uint8_t lastReadRet)
{
    uint8_t err = lastReadRet;
    uint16_t wantedHandle;
    uint8_t opc, rspOpc;
    sg result;


    if (conn->srv.penOp.origOpcode == ATT_OPCODE_READ_REQ)
        rspOpc = ATT_OPCODE_READ_RSP;
    else if (conn->srv.penOp.origOpcode == ATT_OPCODE_READ_BLOB_REQ)
        rspOpc = ATT_OPCODE_READ_BLOB_RSP;
    else
        return false;

    wantedHandle = conn->srv.penOp.startHandle;
    opc = conn->srv.penOp.origOpcode;
    conn->srv.penOp.origOpcode = 0;

    if (err == ATT_ERROR_NONE) {
        result = sgNewWithCopyData(lastReadData, leastReadLen);
        if (!result)
            err = ATT_ERROR_INSUFFICIENT_RSRCS;
        else if (!attSendPacket(conn->conn, rspOpc, NULL, 0, result)) {
            err = ATT_ERROR_UNLIKELY_ERROR;
            sgFree(result);
        } else
            return true;
    }

    return attSrvSendPacketErrorReply(conn->conn, err, opc, wantedHandle);
}

/*
 * FUNCTION: attSrvOpReadStart
 * USE:      Start a read/readBlob request
 * PARAMS:   to - whom to reply to
 *           mtu - the mtu to use
 *           wantedHandle - the handle the client cares about
 *           offset - offset to start at (if needed for the opcode)
 *           opcode - the opcode we were called with
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpReadStart(l2c_handle_t to, uint32_t mtu, uint16_t wantedHandle, uint16_t offset, uint8_t opcode)
{
    struct attConn *conn = attConnFindByL2cConn(to);
    uint8_t err = ATT_ERROR_INSUFFICIENT_RSRCS;
    struct attSrvRange *range;
    struct attSrvVal *val;


    if (!wantedHandle)
        err = ATT_ERROR_INVALID_HANDLE;
    else if (!conn) {
        err = ATT_ERROR_UNLIKELY_ERROR;
        wantedHandle = 0;
        loge("No connection found\n");
    } else if (conn->srv.penOp.origOpcode)
        err = ATT_ERROR_UNLIKELY_ERROR;
    else {
        for (range = mRangesHead; range; range = range->next) {
            if (!attSrvIsRangeVisibleTo(range, conn))
                continue;
            for (val = range->valsHead; val; val = val->next) {
                uint8_t readReason = opcode == ATT_OPCODE_READ_REQ ? ATT_READ_FOR_READ : ATT_READ_FOR_READ_BLOB;
                uint16_t handle = range->start + val->offset;

                /* range check */
                if (handle < wantedHandle)
                    continue;
                if (handle > wantedHandle) {
                    err = ATT_ERROR_ATTRIBUTE_NOT_FOUND;
                    goto done;
                }

                /* must be readable */
                err = attSrvIsValReadableBy(range, val, conn);
                if (err != ATT_ERROR_NONE)
                    goto done;

                /* do a read */
                conn->srv.penOp.origOpcode = opcode;
                conn->srv.penOp.mtu = mtu;
                conn->srv.penOp.startHandle = wantedHandle;
                conn->srv.penOp.read.offset = offset;

                if (attSrvSchedReadCbk(range, val, conn, readReason, offset, mtu - sizeof(struct attHdr)))
                    return true;

                conn->srv.penOp.origOpcode = 0;
                err = ATT_ERROR_UNLIKELY_ERROR;
                goto done;
            }
        }
    }
done:

    return attSrvSendPacketErrorReply(to, err, opcode, wantedHandle);
}

/*
 * FUNCTION: attSrvOpReadMultContinue
 * USE:      Continue a read multiple request
 * PARAMS:   conn - per-connection structure
 *           lastReadData - return from the READ call
 *           leastReadLen - length last read result produced
 *           lastReadRet - last read's result
 * RETURN:   false to fail immediately, true if more work will be done
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpReadMultContinue(struct attConn *conn, const void *lastReadData, uint16_t leastReadLen, uint8_t lastReadRet)
{
    uint8_t err = ATT_ERROR_NONE;
    struct attSrvRange *range;
    struct attSrvVal *val;
    uint16_t wantedHandle = 0;
    sg results, handles;
    uint16_t mtu;


    if (conn->srv.penOp.origOpcode != ATT_OPCODE_READ_MULT_REQ)
        return false;

    mtu = conn->srv.penOp.mtu;
    results = conn->srv.penOp.replyInProgress;
    handles = conn->srv.penOp.readMult.handles;

    mtu -= sizeof(struct attHdr); /* mtu is now how many bytes we can produce */

    if (lastReadRet == ATT_ERROR_NONE) {

        if (!sgConcatBackCopy(results, lastReadData, leastReadLen)) {
            err = ATT_ERROR_INSUFFICIENT_RSRCS;
            goto error;
        }

        /* if no more handles to read, stop */
        if (!sgLength(handles))
            goto done;

       /* even if we go way over mtu, we keep reading because as per spec we need to generate errors correctly */

    } else if (lastReadRet != ATT_FIRST_CONTINUE_CALL) {
        /* if the last read failed - stop searching */
        err = lastReadRet;
        wantedHandle = conn->srv.penOp.readMult.lastReadHandle;
        goto error;
    }

    if (!sgSerializeCutFront(handles, &wantedHandle, sizeof(wantedHandle)))
        goto done;
    wantedHandle = utilGetLE16(&wantedHandle);

    for (range = mRangesHead; range; range = range->next) {
        if (!attSrvIsRangeVisibleTo(range, conn))
            continue;
        for (val = range->valsHead; val; val = val->next) {
            uint16_t handle = range->start + val->offset;

            /* range check */
            if (handle < wantedHandle)
                continue;
            if (handle > wantedHandle) {
                err = ATT_ERROR_INVALID_HANDLE;
                goto error;
            }

            conn->srv.penOp.readMult.lastReadHandle = wantedHandle;

            /* must be readable */
            err = attSrvIsValReadableBy(range, val, conn);
            if (err != ATT_ERROR_NONE) {
                wantedHandle = handle;
                goto error;
            }

            /* we found the value to read - schedule it */
            conn->srv.penOp.startHandle = handle;
            if (attSrvSchedReadCbk(range, val, conn, ATT_READ_FOR_READ_MULT, 0, mtu))
                return true;

            err = ATT_ERROR_UNLIKELY_ERROR;
            goto error;
        }
    }
    /* if we get here, we did not find the value */
    err = ATT_ERROR_INVALID_HANDLE;
    goto error;

done:
    sgFree(handles);
    handles = NULL;
    /* mind the length */
    if (sgLength(results) > mtu)
        sgTruncBack(results, sgLength(results) - mtu);

    if (attSendPacket(conn->conn, ATT_OPCODE_READ_MULT_RSP, NULL, 0, results))
        return true;

    /* uh oh */
    err = ATT_ERROR_UNLIKELY_ERROR;

error:
    conn->srv.penOp.origOpcode = 0;
    sgFree(results);
    if (handles)
        sgFree(handles);
    return attSrvSendPacketErrorReply(conn->conn, err, ATT_OPCODE_READ_MULT_REQ, wantedHandle);
}

/*
 * FUNCTION: attSrvOpReadMultStart
 * USE:      Start a read multiple request
 * PARAMS:   to - whom to reply to
 *           mtu - the mtu to use
 *           s - sg with uint16_t list of handles
 * RETURN:   success
 * NOTES:    call with mAttLock held. WILL FREE "handles" eventually, if true is returned
 */
static bool attSrvOpReadMultStart(l2c_handle_t to, uint32_t mtu, sg handles)
{
    struct attConn *conn = attConnFindByL2cConn(to);
    uint8_t err = ATT_ERROR_UNLIKELY_ERROR;

    if (!conn)
        loge("No connection found\n");
    else if (!conn->srv.penOp.origOpcode) {

        conn->srv.penOp.replyInProgress = sgNew();
        if (!conn->srv.penOp.replyInProgress)
            err = ATT_ERROR_INSUFFICIENT_RSRCS;
        else {

            conn->srv.penOp.origOpcode = ATT_OPCODE_READ_MULT_REQ;
            conn->srv.penOp.readMult.handles = handles;
            conn->srv.penOp.mtu = mtu;

            if (attSrvOpReadContinue(conn, NULL, 0, ATT_FIRST_CONTINUE_CALL))
                return true;

            sgFree(conn->srv.penOp.replyInProgress);
        }
    }

    if (attSrvSendPacketErrorReply(to, err, ATT_OPCODE_READ_MULT_REQ, 0)) {
        sgFree(handles);
        return true;
    }
    return false;
}

/*
 * FUNCTION: attSrvWriteContinue
 * USE:      Continue a [signed] write request / command
 * PARAMS:   conn - per-connection structure
 *           lastWriteData - return from the READ call
 *           leastWriteLen - length last read result produced
 *           lastWriteRet - last read's result
 * RETURN:   false to fail immediately, true if more work will be done
 * NOTES:    call with mAttLock held
 */
static bool attSrvWriteContinue(struct attConn *conn, const void *lastWriteData, uint16_t leastWriteLen, uint8_t lastWriteRet)
{
    if (conn->srv.penOp.origOpcode != ATT_OPCODE_WRITE_REQ && conn->srv.penOp.origOpcode != ATT_OPCODE_SIGNED_WRITE_CMD &&
         conn->srv.penOp.origOpcode != ATT_OPCODE_WRITE_REQ && conn->srv.penOp.origOpcode != ATT_OPCODE_PREPARE_WRITE_REQ)
        return false;

    if (conn->srv.penOp.origOpcode == ATT_OPCODE_WRITE_REQ) {
        conn->srv.penOp.origOpcode = 0;
        return attSendPacketEmptyPacket(conn->conn, ATT_OPCODE_WRITE_RSP);
    }
    if (conn->srv.penOp.origOpcode == ATT_OPCODE_PREPARE_WRITE_REQ) {
        conn->srv.penOp.origOpcode = 0;
        return attSendPacket(conn->conn, ATT_OPCODE_PREPARE_WRITE_RSP, lastWriteData, leastWriteLen, NULL);
    }

    return true;
}

/*
 * FUNCTION: attSrvWriteStart
 * USE:      Start a [signed] write request / command
 * PARAMS:   to - whom to reply to
 *           mtu - the mtu to use
 *           wantedHandle - the handle to write
 *           data - sg with the data to write
 *           byteOfst - offset into the attribute to write
 *           opcode - the opcode the brought us here
 *           writeReason - the write reason to pass to write callback
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attSrvWriteStart(l2c_handle_t to, uint32_t mtu, uint16_t wantedHandle, sg data, uint16_t byteOfst, uint8_t opcode, uint8_t writeReason)
{
    struct attConn *conn = attConnFindByL2cConn(to);
    uint8_t err = ATT_ERROR_UNLIKELY_ERROR;
    struct attSrvRange *range;
    struct attSrvVal *val;

    if (!conn)
        loge("No connection found\n");
    else if (!conn->srv.penOp.origOpcode) {

        for (range = mRangesHead; range; range = range->next) {
            if (!attSrvIsRangeVisibleTo(range, conn))
                continue;
            for (val = range->valsHead; val; val = val->next) {
                uint16_t handle = range->start + val->offset;

                if (handle > wantedHandle)
                    val = NULL;
                if (handle < wantedHandle)
                    continue;
                goto out;
            }
        }
out:
        if (!val)
            err = ATT_ERROR_INVALID_HANDLE;
        else if ((err = attSrvIsValWriteableBy(range, val, conn, writeReason == ATT_WRITE_FOR_SIGNED_WRITE_CMD)) != ATT_ERROR_NONE) {
            /* actully all is done in the if clause */
        } else {
            conn->srv.penOp.origOpcode = opcode;
            conn->srv.penOp.mtu = mtu;
            conn->srv.penOp.startHandle = wantedHandle;
            if (attSrvSchedWriteCbk(range, val, conn, writeReason, 0, data))
                return true;
            conn->srv.penOp.origOpcode = 0;
        }
    }

    if (attSrvSendPacketErrorReply(to, err, ATT_OPCODE_WRITE_REQ, wantedHandle)) {
        sgFree(data);
        return true;
    }
    return false;
}

/*
 * FUNCTION: attSrvOpSignedWrite
 * USE:      Perform a signed write command
 * PARAMS:   to - whom to reply to
 *           mtu - the mtu to use
 *           handle - the handle to write
 *           rxedSig - the SIG we got
 *           data - sg with the data to write
 * RETURN:   success
 * NOTES:    call with mAttLock held  WILL NOT FREE "data". Caller must!
 */
static bool attSrvOpSignedWrite(l2c_handle_t to, uint32_t mtu, uint16_t handle, const uint8_t *rxedSig, sg data)
{
    uint8_t hdr[sizeof(struct attHdr) + sizeof(struct attPduSignedWriteCmd)];
    struct attHdr *attHdr = (struct attHdr*)hdr;
    struct attPduSignedWriteCmd *cmd = (struct attPduSignedWriteCmd*)(hdr + 1);
    uint8_t calcedSig[ATT_SIG_LEN];
    uint8_t k[SM_BLOCK_LEN];
    struct bt_addr addr;

    if (!l2cApiGetBtAddr(to, &addr)) {
        logw("Cannot get address for signed write. Dropping\n");
        goto out;
    }

    /* XXX: may need to resolve address first */
    if (!persistGetDevKey(&addr, KEY_TYPE_CSRK, k)) {
        logw("Cannot get CSRK for signed write. Dropping\n");
        goto out;
    }

    /* Signature is over packet header too, but we stripped it. Luckily it is easy to reconstruct temporarily */
    utilSetLE8(&attHdr->opcode, ATT_OPCODE_SIGNED_WRITE_CMD);
    utilSetLE16(&cmd->handle, handle);
    if (!sgConcatFrontCopy(data, hdr, sizeof(hdr)))
        return false;

    smSignatureCalc(data, k, calcedSig);
    sgTruncFront(data, sizeof(hdr));

    if (memcmp(calcedSig, rxedSig, ATT_SIG_LEN)) {
        logw("Sig check failed. Dropping\n");
        goto out;
    }

    return attSrvWriteStart(to, mtu, handle, data, 0, ATT_OPCODE_SIGNED_WRITE_CMD, ATT_WRITE_FOR_SIGNED_WRITE_CMD);

out:
    sgFree(data);
    return true;
}


/*
 * FUNCTION: attSrvOpExecuteWriteContinue
 * USE:      Continue an execute write request
 * PARAMS:   conn - per-connection structure
 *           to - the connection handle
 *           execResult - the result of the execution attempt
 *           errorHandle - in case of error stores the handle the caused it
 * RETURN:   false to fail immediately, true if more work will be done
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpExecuteWriteContinue(struct attConn *conn, uint8_t execResult, uint16_t errorHandle)
{
    if (conn->srv.penOp.origOpcode != ATT_OPCODE_EXECUTE_WRITE_REQ)
        return false;

    conn->srv.penOp.origOpcode = 0;

    if (!execResult) {
        if (attSendPacketEmptyPacket(conn->conn, ATT_OPCODE_EXECUTE_WRITE_RSP))
            return true;
        execResult = ATT_ERROR_UNLIKELY_ERROR;
    }

    return attSrvSendPacketErrorReply(conn->conn, execResult, ATT_OPCODE_EXECUTE_WRITE_REQ, errorHandle);
}

/*
 * FUNCTION: attSrvOpExecuteWriteStart
 * USE:      Start an execute write request
 * PARAMS:   to - whom to reply to
 *           mtu - the mtu to use
 *           flags - ATT_EXECUTE_WRITE_FLG_*
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpExecuteWriteStart(l2c_handle_t to, uint32_t mtu, uint8_t flags)
{
    uint8_t err = ATT_ERROR_UNLIKELY_ERROR;
    struct attConn* conn = attConnFindByL2cConn(to);

    if (!conn) {
        /* not much to do here - nothing we CAN do */
    } else if (flags == ATT_EXECUTE_WRITE_FLG_CANCEL || flags == ATT_EXECUTE_WRITE_FLG_EXECUTE) {
       return attSrvSchedExecCbk(conn, flags == ATT_EXECUTE_WRITE_FLG_EXECUTE) && attSendPacketEmptyPacket(to, ATT_OPCODE_EXECUTE_WRITE_RSP);
    } else {
        err = ATT_ERROR_INVALID_PDU;
    }

    return attSrvSendPacketErrorReply(to, err, ATT_OPCODE_EXECUTE_WRITE_REQ, 0);
}

/*
 * FUNCTION: attSrvOpHandleValueConf
 * USE:      Handle a value confirmation
 * PARAMS:   to - whom to reply to (if any)
 *           mtu - the mtu to use
 * RETURN:   success
 * NOTES:    call with mAttLock held
 */
static bool attSrvOpHandleValueConf(l2c_handle_t to, uint32_t mtu)
{
    struct attConn *conn;

    conn = attConnFindByL2cConn(to);
    if (!conn)
        loge("No connection found\n");
    else if (conn->srv.indTimer) { /* we're not late */
        attSrvSchedIndResultCbk(conn->srv.indRangeRef, conn->srv.indOffset, conn, ATT_SRV_EVT_IND_ACKED, conn->srv.indRef);
        timerCancel(conn->srv.indTimer);
        conn->srv.indTimer = 0;
    } else /* we are late */
        logw("Confirmation is late\n");

    pthread_mutex_lock(&mAttLock);
    return true;
}

/*
 * FUNCTION: attCliTransTimeout
 * USE:      Timer callback for ATT trasnaction timer
 * PARAMS:   timer - the timer
 *           cbkData - the L2C connection handle
 * RETURN:   NONE
 * NOTES:
 */
static void attCliTransTimeout(uniq_t timer,  uint64_t cbkData)
{
    l2c_handle_t to = (l2c_handle_t)cbkData;
    struct attConn* conn;
    pthread_mutex_lock(&mAttLock);
    conn = attConnFindByL2cConn(to);
    if (!conn)
        logw("Timer for transaction to for unknown connection\n");
    else if (!conn->cli.ongoingTrans)
        logw("Stale timer for transaction fired\n");
    else if (conn->cli.ongoingTrans != timer)
        logw("Wrong timer for transaction fired\n");
    else {
        if (!attCliScheduleErrorCbk(conn->cli.ongoingTrans, to, 0, 0, 0, true))
            loge("Failed to enqueue a timeout\n");
        conn->cli.ongoingTrans = 0;
    }
    pthread_mutex_unlock(&mAttLock);
}

/*
 * FUNCTION: attCliReqStart
 * USE:      Prepare to send a request that we expect a response for
 * PARAMS:   to - whom to
 * RETURN:   non-zero transaction ID or 0 on failure
 * NOTES:    call with mAttLock held
 */
static uniq_t attCliReqStart(l2c_handle_t to)
{
    struct attConn* conn;

    attConnListAddIfNew(to);
    conn = attConnFindByL2cConn(to);

    if (!conn)
        loge("Cannot find connection for new ATT transaction\n");
    else if (conn->cli.ongoingTrans)
        logw("Refusing to start ATT transaction while another inflight\n");
    else {
        conn->cli.ongoingTrans = timerSet(ATT_REQ_TIMOUT, attCliTransTimeout, (uint64_t)to);
        return conn->cli.ongoingTrans;
    }

    return 0;
}

/*
 * FUNCTION: attCliReqStop
 * USE:      Clean up state for a sent transaction for ATT client
 * PARAMS:   to - whom to
 * RETURN:   transaction ID that was in-progress or 0 if none
 * NOTES:    call with mAttLock held
 */
static uniq_t attCliReqStop(l2c_handle_t to)
{
    struct attConn* conn;
    uniq_t ret = 0;

    attConnListAddIfNew(to);
    conn = attConnFindByL2cConn(to);

    if (!conn)
        loge("Cannot find connection for new ATT transaction\n");
    else if (!conn->cli.ongoingTrans)
        logw("Refusing to stop ATT transaction while none inflight\n");
    else {
        ret = conn->cli.ongoingTrans;
        timerCancel(conn->cli.ongoingTrans);
        conn->cli.ongoingTrans = 0;
    }

    return ret;
}

/*
 * FUNCTION: attSrvDataRx
 * USE:      Called when data arrives from a given connection
 * PARAMS:   from - whom the data arived from
 *           s - the data
 * RETURN:   NONE
 * NOTES:
 */
void attSrvDataRx(l2c_handle_t from, sg s)
{
    struct attPduFindByTypeValReq findByTypeValReq;
    struct attPduPrepareWriteReq prepareWriteReq;
    struct attPduReadByGrpTypeReq readByGrpType;
    struct attPduSignedWriteCmd signedWriteCmd;
    struct attPduExecuteWriteReq execWriteReq;
    struct attPduReadByTypeReq readByTypeReq;
    struct attPduFindInfoReq findInfoReq;
    struct attPduReadBlobReq readBlobReq;
    struct attPduHandleValueNotif notif;
    struct attPduWriteReq writeReq;
    struct attPduWriteCmd writeCmd;
    struct attPduReadReq readReq;
    uint8_t opcode, wiType = 0;
    struct attPduError errRsp;
    struct attPduMtu mtuExch;
    struct attWorkItem *wi;
    struct uuid uuid;
    struct attHdr hdr;
    bool ret = false;
    uint32_t newMtu;
    uint32_t mtu;
    uniq_t trans;

    if (!sgSerializeCutFront(s, &hdr, sizeof(hdr))) {
        loge("ATT cannot find header\n");
        sgFree(s);
        return;
    }

    opcode = utilGetLE8(&hdr.opcode);

    /* add to known client list */
    pthread_mutex_lock(&mAttLock);
    attConnListAddIfNew(from);

    logd("ATT opcode RXed: 0x%02x\n", opcode);

    switch (opcode) {
    case ATT_OPCODE_ERROR:
        if (!sgSerializeCutFront(s, &errRsp, sizeof(errRsp)))
            logw("Invalid error packet gotten: too short\n");
        else if (sgLength(s))
            logw("Invalid error packet gotten: too long (by %ub)\n", sgLength(s));
        else if (!(trans = attCliReqStop(from)))
            logw("Got reply from no transaction in progress\n");
        else if (!attCliScheduleErrorCbk(trans, from, utilGetLE16(&errRsp.handle), utilGetLE16(&errRsp.err), utilGetLE16(&errRsp.reqOpcode), false))
            loge("Failed to schedule an error callback\n");
        else
            ret = true;
        break;

    case ATT_OPCODE_MTU_EXCH_REQ:
    case ATT_OPCODE_MTU_EXCH_RSP:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &mtuExch, sizeof(mtuExch)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (sgLength(s))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else {
            struct attConn* conn = attConnFindByL2cConn(from);

            newMtu = utilGetLE16(&mtuExch.mtu);
            mtu = attConnMtuGetByL2c(from, false);
            if (!mtu || mtu > newMtu)
                mtu = newMtu;
            attConnMtuSet(from, mtu);
            if (opcode == ATT_OPCODE_MTU_EXCH_REQ) { /* it was a request - we should reply */
                utilSetLE16(&mtuExch.mtu, mtu); /* we unconditionally accept */
                ret = attSendPacket(from, ATT_OPCODE_MTU_EXCH_RSP, &mtuExch, sizeof(mtuExch), NULL);
            }
            else
                ret = true;
            if (conn)
                attSrvSchedMtuCbk(conn, mtu, opcode == ATT_OPCODE_MTU_EXCH_REQ);
        }
        break;

    case ATT_OPCODE_FIND_INFO_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &findInfoReq, sizeof(findInfoReq)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (sgLength(s))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else
            ret = attSrvOpFindInfo(from, mtu, utilGetLE16(&findInfoReq.startHandle), utilGetLE16(&findInfoReq.endHandle));
        break;

    case ATT_OPCODE_FIND_INFO_RSP:
        if (!wiType)
            wiType = WORK_CLI_FIND_INFO_CALL;
        /* fall through */

    case ATT_OPCODE_FIND_BY_TYPE_VAL_RSP:
        if (!wiType)
            wiType = WORK_CLI_FIND_BY_TYPE_VAL_CALL;
        /* fall through */

    case ATT_OPCODE_READ_BY_TYPE_RSP:
        if (!wiType)
            wiType = WORK_CLI_READ_BY_TYPE_CALL;
        /* fall through */

    case ATT_OPCODE_READ_RSP:
    case ATT_OPCODE_READ_BLOB_RSP:
        if (!wiType)
            wiType = WORK_CLI_READ_CALL;
        /* fall through */

    case ATT_OPCODE_READ_BY_GRP_TYPE_RSP:
        if (!wiType)
            wiType = WORK_CLI_READ_BY_GRP_TYPE_CALL;

        /* common code for all client-mode response packets */
        if (!(trans = attCliReqStop(from)))
            logw("Got reply from no transaction in progress\n");
        else if (!(wi = attWorkItemAlloc(wiType, 0)))
            loge("Failed to make a work item\n");
        else {
            wi->who = from;
            wi->cli.trans = trans;
            wi->cliJustData.data = s;
            if (workQueuePut(mWorkQ, wi)) {
                s = NULL;
                ret = true;
            }
            else {
                free(wi);
                loge("Failed to enqueue work item\n");
            }
        }
        break;

    case ATT_OPCODE_FIND_BY_TYPE_VAL_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &findByTypeValReq, sizeof(findByTypeValReq)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else {
            uuidFromUuid16(&uuid, utilGetLE16(&findByTypeValReq.uuid16));
            if (attSrvOpFindByTypeValStart(from, mtu, utilGetLE16(&findByTypeValReq.startHandle), utilGetLE16(&findByTypeValReq.endHandle), &uuid, s)) {
                ret = true;
                s = NULL;
            }
        }
        break;

    case ATT_OPCODE_READ_BY_TYPE_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &readByTypeReq, sizeof(readByTypeReq)) || !attReadUuid(&uuid, s))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else
            ret = attSrvOpReadByTypeStart(from, mtu, utilGetLE16(&readByTypeReq.startHandle), utilGetLE16(&readByTypeReq.endHandle), &uuid, false);
        break;

    case ATT_OPCODE_READ_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &readReq, sizeof(readReq)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (sgLength(s))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else
            ret = attSrvOpReadStart(from, mtu, utilGetLE16(&readReq.handle), 0, opcode);
        break;

    case ATT_OPCODE_READ_BLOB_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &readBlobReq, sizeof(readBlobReq)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (sgLength(s))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else
            ret = attSrvOpReadStart(from, mtu, utilGetLE16(&readBlobReq.handle), utilGetLE16(&readBlobReq.offset), opcode);
        break;

    case ATT_OPCODE_READ_MULT_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if ((sgLength(s) % sizeof(uint16_t)) || sgLength(s) < sizeof(uint16_t[ATT_MIN_HANDLES_IN_READ_MULT]))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (attSrvOpReadMultStart(from, mtu, s)) {
            ret = true;
            s = NULL;
        }
        break;

    case ATT_OPCODE_READ_BY_GRP_TYPE_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &readByGrpType, sizeof(readByGrpType)) || !attReadUuid(&uuid, s))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else
            ret = attSrvOpReadByTypeStart(from, mtu, utilGetLE16(&readByGrpType.startHandle), utilGetLE16(&readByGrpType.endHandle), &uuid, true);
        break;

    case ATT_OPCODE_WRITE_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &writeReq, sizeof(writeReq)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (attSrvWriteStart(from, mtu, utilGetLE16(&writeReq.handle), s, 0, opcode, ATT_WRITE_FOR_WRITE_REQ)) {
            ret = true;
            s = NULL;
        }
        break;

    case ATT_OPCODE_WRITE_RSP:
        if (!(trans = attCliReqStop(from)))
            logw("Got reply from no transaction in progress\n");
        else if (!(wi = attWorkItemAlloc(WORK_CLI_WRITE_CALL, 0)))
            loge("Failed to make a work item\n");
        else {
            wi->who = from;
            wi->cli.trans = trans;
            if (workQueuePut(mWorkQ, wi)) {
                s = NULL;
                ret = true;
            }
            else {
                free(wi);
                loge("Failed to enqueue work item\n");
            }
        }
        break;

    case ATT_OPCODE_PREPARE_WRITE_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &prepareWriteReq, sizeof(prepareWriteReq)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (attSrvWriteStart(from, mtu, utilGetLE16(&prepareWriteReq.handle), s, utilGetLE16(&prepareWriteReq.offset), opcode, ATT_WRITE_FOR_PREPARE)) {
            ret = true;
            s = NULL;
        }
        break;

    case ATT_OPCODE_EXECUTE_WRITE_REQ:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &execWriteReq, sizeof(execWriteReq)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (sgLength(s))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else
            ret = attSrvOpExecuteWriteStart(from, mtu, utilGetLE16(&execWriteReq.flags));
        break;

    case ATT_OPCODE_HANDLE_VALUE_NOTIF:
    case ATT_OPCODE_HANDLE_VALUE_IND:
        if (!sgSerializeCutFront(s, &notif, sizeof(notif)))
            loge("Failed to get notification header\n");
        if (!(wi = attWorkItemAlloc(WORK_CLI_IND_NOTIF_CALL, 0)))
            loge("Failed to make a work item\n");
        else {
            wi->who = from;
            wi->cliIndNotif.needsAck = opcode == ATT_OPCODE_HANDLE_VALUE_IND;
            wi->cliIndNotif.data = s;
            wi->cliIndNotif.handle = utilGetLE16(&notif.handle);
            if (workQueuePut(mWorkQ, wi)) {
                s = NULL;
                ret = true;
            }
            else {
                free(wi);
                loge("Failed to enqueue work item\n");
            }
        }
        break;

    case ATT_OPCODE_HANDLE_VALUE_CONF:
        mtu = attConnMtuGetByL2c(from, true);
        if (sgLength(s))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else
            ret = attSrvOpHandleValueConf(from, mtu);
        break;

    case ATT_OPCODE_WRITE_CMD:
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &writeCmd, sizeof(writeCmd)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (attSrvWriteStart(from, mtu, utilGetLE16(&writeReq.handle), s, 0, opcode, ATT_WRITE_FOR_WRITE_CMD)) {
            ret = true;
            s = NULL;
        }
        break;

    case ATT_OPCODE_SIGNED_WRITE_CMD:
        if (l2cApiIsConnEncrypted(from)) {
            /* ignore signed writes on encrypted connections as per spec */
            ret = true;
            break;
        }
        mtu = attConnMtuGetByL2c(from, true);
        if (!sgSerializeCutFront(s, &signedWriteCmd, sizeof(signedWriteCmd)))
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else if (sgLength(s) < ATT_SIG_LEN)
            ret = attSrvSendPacketErrorReply(from, ATT_ERROR_INVALID_PDU, opcode, 0);
        else {
            uint8_t sig[ATT_SIG_LEN];
            sgSerialize(s, sgLength(s) - ATT_SIG_LEN, ATT_SIG_LEN, sig);
            sgTruncBack(s, ATT_SIG_LEN);
            if (attSrvOpSignedWrite(from, mtu, utilGetLE16(&signedWriteCmd.handle), sig, s)) {
                ret = true;
                s = NULL;
            }
        }
        break;

    default:
        logw("Unexpected ATT opcode 0x%02X\n", opcode);
        ret = attSrvSendPacketErrorReply(from, ATT_ERROR_REQ_NOT_SUPPORTED, opcode, 0);
        break;
    }

    pthread_mutex_unlock(&mAttLock);
    if (!ret)
        loge("ATT failed to handle this message\n");
    if (s)
        sgFree(s);
}

/*
 * FUNCTION: attSrvCbkReply
 * USE:      Called by higher layer when a callback we made to them completes
 * PARAMS:   cid - the connection ID in android-gatt terms
 *           transId - the transaction Id we originally passed to the higher layer
 *           handle - the handle value (if relevant -> only in exec write)
 *           err - ATT_ERROR_*
 *           data - the read data
 *           len - read length
 * RETURN:   unused
 * NOTES:
 */
void attSrvCbkReply(att_cid_t cid, att_trans_t transId, uint16_t handle, uint8_t err, const void *data, uint16_t len)
{
    struct attConn* conn;
    bool ret = false;
    uint8_t opcode;

    pthread_mutex_lock(&mAttLock);
    conn = attConnFindBySrvCid(cid);
    if (!conn)
        loge("Got callback reply for unknown connection\n");
    else if (conn->srv.expectedTransId != transId)
        loge("Got callback reply for unknown transaction id "ATT_TRANS_FMT"u\n", ATT_TRANS_CONV(transId));
    else {
        switch ((opcode = conn->srv.penOp.origOpcode)) {
        case ATT_OPCODE_FIND_BY_TYPE_VAL_REQ:
            ret = attSrvOpFindByTypeValContinue(conn, data, len, err);
            break;
        case ATT_OPCODE_READ_BY_TYPE_REQ:
        case ATT_OPCODE_READ_BY_GRP_TYPE_REQ:
            ret = attSrvOpReadByTypeContinue(conn, data, len, err);
            break;
        case ATT_OPCODE_READ_REQ:
        case ATT_OPCODE_READ_BLOB_REQ:
            ret = attSrvOpReadContinue(conn, data, len, err);
            break;
        case ATT_OPCODE_READ_MULT_REQ:
            ret = attSrvOpReadMultContinue(conn, data, len, err);
            break;
        case ATT_OPCODE_WRITE_REQ:
        case ATT_OPCODE_SIGNED_WRITE_CMD:
        case ATT_OPCODE_WRITE_CMD:
        case ATT_OPCODE_PREPARE_WRITE_REQ:
            ret = attSrvWriteContinue(conn, data, len, err);
            break;
        case ATT_OPCODE_EXECUTE_WRITE_REQ:
            ret = attSrvOpExecuteWriteContinue(conn, err, handle);
            break;
        default:
            loge("Unknown original opcode\n");
            conn->srv.penOp.origOpcode = 0;
            ret = true; // to avoid re-logging the error
        }
        if (!ret)
            logw("Error handling reply for opcode %u\n", opcode);
    }
    pthread_mutex_unlock(&mAttLock);
}

/*
 * FUNCTION: attWorker
 * USE:      ATT worker thread
 * PARAMS:   unused - unused
 * RETURN:   unused
 * NOTES:
 */
static void* attWorker(void *unused)
{
    uint8_t format, length;
    struct attWorkItem *wi;
    bool keepGoing = true;
    struct uuid uuid;
    bool haveMore;
    int status;

    pthread_setname_np(pthread_self(), "att_worker");

    while(1) {
        status = workQueueGet(mWorkQ, (void**)&wi);

        /* The only one thing we use the work queue status for - exiting */
        if (status)
            break;

        switch (wi->type) {
        case WORK_ATT_MTU_INFO:
            (wi->mtuInfo.asServer ? mSrvMtuCbk : mCliMtuCbk)(wi->who, wi->mtuInfo.mtu);
            break;

        case WORK_ATT_SYNC:
            sem_post(wi->sync.sem);
            break;

        case WORK_SRV_READ_CALL:
            if (!mReadCbk(wi->who, wi->srv.cid, wi->srvRead.range, wi->srvRead.ofst, wi->srvRead.transId, wi->srvRead.byteOfst, wi->srvRead.reason, wi->srvRead.maxLen))
                attSrvCbkReply(wi->srv.cid, wi->srvRead.transId, 0, ATT_ERROR_UNLIKELY_ERROR, NULL, 0);
            break;

        case WORK_SRV_WRITE_CALL:
            if (!mWriteCbk(wi->who, wi->srv.cid, wi->srvWrite.range, wi->srvWrite.ofst, wi->srvWrite.transId, wi->srvWrite.byteOfst, wi->srvWrite.reason, wi->srvWrite.len, wi + 1))
                attSrvCbkReply(wi->srv.cid, wi->srvWrite.transId, 0, ATT_ERROR_UNLIKELY_ERROR, NULL, 0);
            break;

        case WORK_SRV_EXEC_WRITE_CALL:
            if (!mExecCbk(wi->who, wi->srv.cid, wi->srvExecWrite.transId, wi->srvExecWrite.exec))
                attSrvCbkReply(wi->srv.cid, wi->srvExecWrite.transId, 0, ATT_ERROR_UNLIKELY_ERROR, NULL, 0);
            break;

        case WORK_SRV_IND_RESULT:
            mIndCbk(wi->who, wi->srv.cid, wi->srvIndResult.range, wi->srvIndResult.ofst, wi->srvIndResult.evt, wi->srvIndResult.ref);
            break;

        case WORK_CLI_FIND_INFO_CALL:
            if (!sgSerializeCutFront(wi->cliJustData.data, &format, sizeof(format)))
                logw("Failed to get format from received data for Find\n");
            else if (format != ATT_FIND_INFO_RSP_FMT_16 && format != ATT_FIND_INFO_RSP_FMT_128)
                logw("Format %u unknown for Find\n", format);
            else {
                do {
                    uint16_t handle;

                    if (format == ATT_FIND_INFO_RSP_FMT_16) {
                        uint8_t buf[sizeof(uint16_t)];

                        if (!sgSerializeCutFront(wi->cliJustData.data, buf, sizeof(handle)))
                            break;
                        handle = utilGetLE16(buf);
                        if (!sgSerializeCutFront(wi->cliJustData.data, buf, sizeof(buf)))
                            break;
                        uuidFromUuid16(&uuid, utilGetLE16(buf));
                        haveMore = sgLength(wi->cliJustData.data) >= sizeof(buf) + sizeof(handle);
                    } else {
                        uint8_t buf[sizeof(struct uuid)];

                        if (!sgSerializeCutFront(wi->cliJustData.data, buf, sizeof(handle)))
                            break;
                        handle = utilGetLE16(buf);
                        if (!sgSerializeCutFront(wi->cliJustData.data, &buf, sizeof(buf)))
                            break;
                        uuidReadLE(&uuid, buf);
                        haveMore = sgLength(wi->cliJustData.data) >= sizeof(buf) + sizeof(handle);
                    }
                    keepGoing = mCliFindInfoCbk(wi->cli.trans, wi->who, handle, &uuid, haveMore);
                } while (haveMore && keepGoing);
                if (sgLength(wi->cliJustData.data) && keepGoing)
                    logw("Unexpected leftover data for Find: %ub\n", sgLength(wi->cliJustData.data));
            }
            sgFree(wi->cliJustData.data);
            break;

        case WORK_CLI_FIND_BY_TYPE_VAL_CALL:
            do {
                uint16_t attrH, grpEndH;
                uint8_t buf[sizeof(uint16_t) * 2];

                if (!sgSerializeCutFront(wi->cliJustData.data, buf, sizeof(buf)))
                    break;

                haveMore = sgLength(wi->cliJustData.data) >= sizeof(buf);
                attrH = utilGetLE16(buf);
                grpEndH = utilGetLE16(buf + sizeof(attrH));

                keepGoing = mCliFindByTypeValCbk(wi->cli.trans, wi->who, attrH, grpEndH, haveMore);
            } while (haveMore && keepGoing);
            if (sgLength(wi->cliJustData.data) && keepGoing)
                logw("Unexpected leftover data for FindByTypeValue: %ub\n", sgLength(wi->cliJustData.data));
            sgFree(wi->cliJustData.data);
            break;


        case WORK_CLI_READ_BY_TYPE_CALL:
            if (!sgSerializeCutFront(wi->cliJustData.data, &length, sizeof(length)))
                logw("Failed to get length from received data for ReadByType\n");
            else if (length < sizeof(uint16_t))
                logw("Length %u impossible for ReadByType\n", length);
            else if (sgLength(wi->cliJustData.data) < length)
                logw("Sg length %u impossible for ReadByType (expected %u+)\n", sgLength(wi->cliJustData.data), length);
            else {
                uint8_t buf[sizeof(uint16_t)];
                uint16_t handle;
                sg s;

                do {
                    if (!sgSerializeCutFront(wi->cliJustData.data, buf, sizeof(buf)))
                        break;
                    handle = utilGetLE16(buf);

                    s = sgSplit(wi->cliJustData.data, length - sizeof(buf));
                    if (!s)
                        break;
                    sgSwap(wi->cliJustData.data, s);

                    haveMore = sgLength(wi->cliJustData.data) >= length;
                    keepGoing = mCliReadF(wi->cli.trans, wi->who, &handle, NULL, s, haveMore);
                } while(haveMore && keepGoing);
            }
            if (sgLength(wi->cliJustData.data) && keepGoing)
                logw("Unexpected leftover data for ReadByGroupType: %ub\n", sgLength(wi->cliJustData.data));
            sgFree(wi->cliJustData.data);
            break;

        case WORK_CLI_READ_CALL:
            mCliReadF(wi->cli.trans, wi->who, NULL, NULL, wi->cliJustData.data, false);
            break;

        case WORK_CLI_READ_BY_GRP_TYPE_CALL:
            if (!sgSerializeCutFront(wi->cliJustData.data, &length, sizeof(length)))
                logw("Failed to get length from received data for ReadByGroupType\n");
            else if (length < sizeof(uint16_t) * 2)
                logw("Length %u impossible for ReadByGroupType\n", length);
            else if (sgLength(wi->cliJustData.data) < length)
                logw("Sg length %u impossible for ReadByGroupType (expected %u+)\n", sgLength(wi->cliJustData.data), length);
            else {
                uint8_t buf[sizeof(uint16_t)];
                uint16_t handle, grpEndHandle;
                sg s;

                do {
                    if (!sgSerializeCutFront(wi->cliJustData.data, buf, sizeof(buf)))
                        break;
                    handle = utilGetLE16(buf);

                    if (!sgSerializeCutFront(wi->cliJustData.data, buf, sizeof(buf)))
                        break;
                    grpEndHandle = utilGetLE16(buf);

                    s = sgSplit(wi->cliJustData.data, length - sizeof(buf) * 2);
                    if (!s)
                        break;
                    sgSwap(wi->cliJustData.data, s);

                    haveMore = sgLength(wi->cliJustData.data) >= length;
                    keepGoing = mCliReadF(wi->cli.trans, wi->who, &handle, &grpEndHandle, s, haveMore);
                } while(haveMore && keepGoing);
            }
            if (sgLength(wi->cliJustData.data) && keepGoing)
                logw("Unexpected leftover data for ReadByGroupType: %ub\n", sgLength(wi->cliJustData.data));
            sgFree(wi->cliJustData.data);
            break;

        case WORK_CLI_WRITE_CALL:
            mCliWriteF(wi->cli.trans, wi->who);
            break;

        case WORK_CLI_ERR_CALL:
            mCliErrF(wi->cli.trans, wi->who, wi->cliErr.isLocalErr ? NULL : &wi->cliErr.handle, wi->cliErr.isLocalErr ? NULL : &wi->cliErr.err, wi->cliErr.isLocalErr ? NULL : &wi->cliErr.errOpcode);
            break;

        case WORK_CLI_IND_NOTIF_CALL:
            mCliIndNotifF(wi->who, wi->cliIndNotif.needsAck, wi->cliIndNotif.handle, wi->cliIndNotif.data);
            break;

        default:
            loge("Unknown work type %d\n", wi->type);
            break;
        }
        free(wi);
    }

    logd("ATT worker exiting\n");
    return NULL;
}

/*
 * FUNCTION: attWorkItemFree
 * USE:      Free an ATT work item at time of work quque destruction
 * PARAMS:   NONE
 * RETURN:   success
 * NOTES:
 */
static void attWorkItemFree(void *item)
{
    struct attWorkItem *wi = (struct attWorkItem*)item;

    /* future clean steps here */

    free(wi);
}

/*
 * FUNCTION: attInit
 * USE:      Called to init all of ATT
 * PARAMS:   NONE
 * RETURN:   success
 * NOTES:    internally ref-counted as multiple users exist
 */
bool attInit(void)
{
    bool ret = false;

    pthread_mutex_lock(&mAttLock);
    if (!mNumUsers) {

        mConns = NULL;
        mWorkQ = workQueueAlloc(ATT_WORK_Q_SIZE);
        if (!mWorkQ)
            loge("Failed to create work Q\n");
        else if (pthread_create(&mWorker, NULL, attWorker, NULL)) {
            loge("Failed to create worker\n");
            workQueueFree(mWorkQ, attWorkItemFree);
        } else {
            ret = true;
        }
    } else
        ret = true;

    if (ret)
        mNumUsers++;

    pthread_mutex_unlock(&mAttLock);
    return ret;
}

/*
 * FUNCTION: attDeinit
 * USE:      Called to deinit all of ATT
 * PARAMS:   NONE
 * RETURN:   NONE
 * NOTES:    internally ref-counted as multiple users exist
 */
void attDeinit(void)
{
    pthread_mutex_lock(&mAttLock);
    if (!mNumUsers)
        loge("too many ATT closures!\n");
    else if (!--mNumUsers) {
        workQueueWakeAll(mWorkQ, 1);
        pthread_join(mWorker, NULL);
        workQueueFree(mWorkQ, attWorkItemFree);
        while (mConns) {
            struct attConn *t = mConns->next;
            free(mConns);
            mConns = t;
        }
    }
    pthread_mutex_unlock(&mAttLock);
}

/*
 * FUNCTION: attCliRequestMtu
 * USE:      As a client request an MTU value from the server
 * PARAMS:   to - the server l2c connection
 *           mtu - the mtu to request
 * RETURN:   false on error, true if will try
 * NOTES:
 */
bool attCliRequestMtu(l2c_handle_t to, uint32_t mtu)
{
    struct attPduMtu mtuExch;

    utilSetLE16(&mtuExch.mtu, mtu);
    return attSendPacket(to, ATT_OPCODE_MTU_EXCH_REQ, &mtuExch, sizeof(mtuExch), NULL);
}

/*
 * FUNCTION: attCliInit
 * USE:      Init ATT client code (by providing callbacks)
 * PARAMS:   cliMtuF - calback about MTU negotiation results
 *           cliReadF - read callback for clients
 *           cliWriteF - write callabck for clients
 *           cliErrF - error callback for clients
 * RETURN:   NONE
 * NOTES:
 */
void attCliInit(attMtuCbk cliMtuF, attCliFindInfoCbk cliFindInfoCbk, attCliFindByTypeValCbk cliFindByTypeValCbk, attCliReadCbk cliReadF, attCliWriteCbk cliWriteF, attCliError cliErrF, attCliIndNotif cliIndNotifF)
{
    pthread_mutex_lock(&mAttLock);
    mCliMtuCbk = cliMtuF;
    mCliFindInfoCbk = cliFindInfoCbk;
    mCliFindByTypeValCbk = cliFindByTypeValCbk;
    mCliReadF = cliReadF;
    mCliWriteF = cliWriteF;
    mCliErrF = cliErrF;
    mCliIndNotifF = cliIndNotifF;
    pthread_mutex_unlock(&mAttLock);
}

/*
 * FUNCTION: attCliDeinit
 * USE:      Deinit ATT client code
 * PARAMS:   NONE
 * RETURN:
 * NOTES:
 */
void attCliDeinit(void)
{
    //TODO: maybe?
}

/*
 * FUNCTION: attCliSendIndicationAck
 * USE:      Send a value confirmation (an ack to a value indication)
 * PARAMS:   to - whom to
 * RETURN:   false on error
 * NOTES:
 */
bool attCliSendIndicationAck(l2c_handle_t to)
{
    return attSendPacketEmptyPacket(to, ATT_OPCODE_HANDLE_VALUE_CONF);
}

/*
 * FUNCTION: attCliFindInformation
 * USE:      Send a find-information request to the server
 * PARAMS:   to - whom to
 *           hStart - start handle
 *           hEnd - end handle
 * RETURN:   non-zero transaction ID or 0 on failure
 * NOTES:    find or error callbacks passed to attCliInit may be called
 */
uniq_t attCliFindInformation(l2c_handle_t to, uint16_t hStart, uint16_t hEnd)
{
    struct attPduFindInfoReq req;
    uniq_t ret;

    utilSetLE16(&req.startHandle, hStart);
    utilSetLE16(&req.endHandle, hEnd);

    pthread_mutex_lock(&mAttLock);
    ret = attCliReqStart(to);
    if (ret && !attSendPacket(to, ATT_OPCODE_FIND_INFO_REQ, &req, sizeof(req), NULL)) {
        attCliReqStop(to);
        ret = 0;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attCliFindByTypeValue
 * USE:      Send a find-by-type-value request to the server
 * PARAMS:   to - whom to
 *           hStart - start handle
 *           hEnd - end handle
 *           typeUuid16 - type (must be a uuid16)
 *           value - the value to look for
 * RETURN:   non-zero transaction ID or 0 on failure
 * NOTES:    find or error callbacks passed to attCliInit may be called
 */
uniq_t attCliFindByTypeValue(l2c_handle_t to, uint16_t hStart, uint16_t hEnd, uint16_t typeUuid16, sg value)
{
    struct attPduFindByTypeValReq req;
    uint32_t mtu;
    uniq_t ret;

    utilSetLE16(&req.startHandle, hStart);
    utilSetLE16(&req.endHandle, hEnd);
    utilSetLE16(&req.uuid16, typeUuid16);

    pthread_mutex_lock(&mAttLock);
    mtu = attConnMtuGetByL2c(to, true);
    if (sizeof(req) + sizeof(struct attHdr) + sgLength(value) > mtu) {
        logw("Truncating value in FindByTypeValue to fit into mtu %u -> %u\n", (unsigned)sgLength(value), (unsigned)(mtu - sizeof(req) - sizeof(struct attHdr)));
        sgTruncBack(value, sgLength(value) + sizeof(req) + sizeof(struct attHdr) - mtu);
    }

    ret = attCliReqStart(to);
    if (ret && !attSendPacket(to, ATT_OPCODE_FIND_BY_TYPE_VAL_REQ, &req, sizeof(req), value)) {
        attCliReqStop(to);
        ret = 0;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attCliReadByType
 * USE:      Send a read-by-type request to the server
 * PARAMS:   to - whom to
 *           hStart - start handle
 *           hEnd - end handle
 *           type - the type of values to read
 * RETURN:   non-zero transaction ID or 0 on failure
 * NOTES:    read or error callbacks passed to attCliInit may be called
 */
uniq_t attCliReadByType(l2c_handle_t to, uint16_t hStart, uint16_t hEnd, const struct uuid *type)
{
    uint8_t hdrBuf[sizeof(struct attPduReadByTypeReq) + sizeof(struct uuid) + sizeof(uint16_t)]; /* definitely big enoguh to fit both formats */
    struct attPduReadByTypeReq *req = (struct attPduReadByTypeReq*)hdrBuf;
    struct uuid *uuid128 = (struct uuid*)(req + 1);
    uint16_t *uuid16 = (uint16_t*)(req + 1);
    uint16_t tmpUuid;
    unsigned uuidSz;
    uniq_t ret;

    utilSetLE16(&req->startHandle, hStart);
    utilSetLE16(&req->endHandle, hEnd);

    if (uuidToUuid16(&tmpUuid, type)) {
        utilSetLE16(uuid16, tmpUuid);
        uuidSz = sizeof(uint16_t);
    } else {
        uuidWriteLE(uuid128, type);
        uuidSz = sizeof(struct uuid);
    }

    pthread_mutex_lock(&mAttLock);
    ret = attCliReqStart(to);
    if (ret && !attSendPacket(to, ATT_OPCODE_READ_BY_TYPE_REQ, hdrBuf, sizeof(struct attPduReadByTypeReq) + uuidSz, NULL)) {
        attCliReqStop(to);
        ret = 0;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attCliReadByGroupType
 * USE:      Send a read-by-group-type request to the server
 * PARAMS:   to - whom to
 *           hStart - start handle
 *           hEnd - end handle
 *           type - the group type of values to read
 * RETURN:   non-zero transaction ID or 0 on failure
 * NOTES:    read or error callbacks passed to attCliInit may be called
 */
uniq_t attCliReadByGroupType(l2c_handle_t to, uint16_t hStart, uint16_t hEnd, const struct uuid *type)
{
    uint8_t hdrBuf[sizeof(struct attPduReadByGrpTypeReq) + sizeof(struct uuid) + sizeof(uint16_t)]; /* definitely big enoguh to fit both formats */
    struct attPduReadByGrpTypeReq *req = (struct attPduReadByGrpTypeReq*)hdrBuf;
    struct uuid *uuid128 = (struct uuid*)(req + 1);
    uint16_t *uuid16 = (uint16_t*)(req + 1);
    uint16_t tmpUuid;
    unsigned uuidSz;
    uniq_t ret;

    utilSetLE16(&req->startHandle, hStart);
    utilSetLE16(&req->endHandle, hEnd);

    if (uuidToUuid16(&tmpUuid, type)) {
        utilSetLE16(uuid16, tmpUuid);
        uuidSz = sizeof(uint16_t);
    } else {
        uuidWriteLE(uuid128, type);
        uuidSz = sizeof(struct uuid);
    }

    pthread_mutex_lock(&mAttLock);
    ret = attCliReqStart(to);
    if (ret && !attSendPacket(to, ATT_OPCODE_READ_BY_GRP_TYPE_REQ, hdrBuf, sizeof(struct attPduReadByTypeReq) + uuidSz, NULL)) {
        attCliReqStop(to);
        ret = 0;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attCliRead
 * USE:      Send a read request to the server
 * PARAMS:   to - whom to
 *           handle - the handle
 * RETURN:   non-zero transaction ID or 0 on failure
 * NOTES:    read or error callbacks passed to attCliInit may be called
 */
uniq_t attCliRead(l2c_handle_t to, uint16_t handle)
{
    struct attPduReadReq req;
    uniq_t ret;

    utilSetLE16(&req.handle, handle);

    pthread_mutex_lock(&mAttLock);
    ret = attCliReqStart(to);
    if (ret && !attSendPacket(to, ATT_OPCODE_READ_REQ, &req, sizeof(req), NULL)) {
        attCliReqStop(to);
        ret = 0;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attCliReadBlob
 * USE:      Send a read-blob request to the server
 * PARAMS:   to - whom to
 *           handle - the handle
 *           offset - the offset to request into the value
 * RETURN:   non-zero transaction ID or 0 on failure
 * NOTES:    read or error callbacks passed to attCliInit may be called
 */
uniq_t attCliReadBlob(l2c_handle_t to, uint16_t handle, uint16_t offset)
{
    struct attPduReadBlobReq req;
    uniq_t ret;

    utilSetLE16(&req.handle, handle);
    utilSetLE16(&req.offset, offset);

    pthread_mutex_lock(&mAttLock);
    ret = attCliReqStart(to);
    if (ret && !attSendPacket(to, ATT_OPCODE_READ_BLOB_REQ, &req, sizeof(req), NULL)) {
        attCliReqStop(to);
        ret = 0;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}


/*
 * FUNCTION: attCliWriteInt
 * USE:      Send a write request/command to the server
 * PARAMS:   to - whom to
 *           handle - the handle
 *           data - the data
 *           cmd - use a write command? (else we'll use request)
 * RETURN:   non-zero transaction ID or 0 on failure (transaction ID returned is fake for write command)
 * NOTES:    write or error callbacks passed to attCliInit may be called in case of request.
 *           none will be for command. Passed-in SG may be truncated to MTU-3 even in cases of failure
 */
uniq_t attCliWriteInt(l2c_handle_t to, uint16_t handle, sg data, bool cmd)
{
    struct attPduWriteCmd req;
    uint32_t mtu;
    uniq_t ret;

    utilSetLE16(&req.handle, handle);

    pthread_mutex_lock(&mAttLock);
    mtu = attConnMtuGetByL2c(to, true);
    if (sizeof(req) + sizeof(struct attHdr) + sgLength(data) > mtu) {
        logw("Truncating value in Write to fit into mtu %u -> %u\n", (unsigned)sgLength(data), (unsigned)(mtu - sizeof(req) - sizeof(struct attHdr)));
        sgTruncBack(data, sgLength(data) + sizeof(req) + sizeof(struct attHdr) - mtu);
    }

    ret = cmd ? 1 : attCliReqStart(to);
    if (ret && !attSendPacket(to, cmd ? ATT_OPCODE_WRITE_CMD : ATT_OPCODE_WRITE_REQ, &req, sizeof(req), data)) {
        if (!cmd)
            attCliReqStop(to);
        ret = 0;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attCliWrite
 * USE:      Send a write request to the server
 * PARAMS:   to - whom to
 *           handle - the handle
 *           data - the data
 * RETURN:   non-zero transaction ID or 0 on failure
 * NOTES:    write or error callbacks passed to attCliInit may be called
 */
uniq_t attCliWrite(l2c_handle_t to, uint16_t handle, sg data)
{
    return attCliWriteInt(to, handle, data, false);
}

/*
 * FUNCTION: attCliWrite
 * USE:      Send a write command to the server
 * PARAMS:   to - whom to
 *           handle - the handle
 *           data - the data
 * RETURN:   false on failure
 * NOTES:    no callbacks will be called.
 */
bool attCliWriteNoAck(l2c_handle_t to, uint16_t handle, sg data)
{
    return !!attCliWriteInt(to, handle, data, true);
}

/*
 * FUNCTION: attCliSignedWriteNoAck
 * USE:      Send a signed write command to the server
 * PARAMS:   to - whom to
 *           handle - the handle
 *           data - the data
 * RETURN:   false on failure
 * NOTES:    no callbacks will be called.
 */
bool attCliSignedWriteNoAck(l2c_handle_t to, uint16_t handle, sg data)
{
    uint8_t hdr[sizeof(struct attHdr) + sizeof(struct attPduSignedWriteCmd)];
    struct attHdr *attHdr = (struct attHdr*)hdr;
    struct attPduSignedWriteCmd *cmd = (struct attPduSignedWriteCmd*)(hdr + 1);
    uint8_t sig[ATT_SIG_LEN];
    uint8_t k[SM_BLOCK_LEN];
    bool ret = false;
    uint32_t mtu;

    utilSetLE8(&attHdr->opcode, ATT_OPCODE_SIGNED_WRITE_CMD);
    utilSetLE16(&cmd->handle, handle);

    if (!persistGetDevKey(NULL, KEY_TYPE_CSRK, k)) {
        logw("Cannot get ownCSRK for signed write\n");
        return false;
    }

    pthread_mutex_lock(&mAttLock);
    mtu = attConnMtuGetByL2c(to, true);
    if (sizeof(hdr) + sizeof(sig) + sgLength(data) > mtu) {
        logw("Truncating value in SignedWrite to fit into mtu %u -> %u\n", (unsigned)sgLength(data), (unsigned)(mtu - sizeof(hdr) - sizeof(sig)));
        sgTruncBack(data, sgLength(data) + sizeof(hdr) + sizeof(sig) - mtu);
    }

    if (!sgConcatFrontCopy(data, hdr, sizeof(hdr)))
        loge("Failed to concat SG for signed write\n");
    else {
        smSignatureCalc(data, k, sig);

        ret = attSendPacketRaw(to, NULL, 0, data, sig, sizeof(sig)) == ATT_TX_RET_ACCEPTED;
        if (!ret)
            sgTruncFront(data, sizeof(hdr));
    }

    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attCliPrepareWrite
 * USE:      Send a prepare-write request to the server
 * PARAMS:   to - whom to
 *           handle - the handle
 *           offset - the offset into the data to write
 *           data - the data
 * RETURN:   transaction id or 0 on failure
 * NOTES:    write or error callbacks passed to attCliInit may be called
 */
uniq_t attCliPrepareWrite(l2c_handle_t to, uint16_t handle, uint16_t offset, sg data)
{
    struct attPduPrepareWriteReq req;
    uint32_t mtu;
    uniq_t ret;

    utilSetLE16(&req.handle, handle);
    utilSetLE16(&req.offset, offset);

    pthread_mutex_lock(&mAttLock);
    mtu = attConnMtuGetByL2c(to, true);
    if (sizeof(req) + sizeof(struct attHdr) + sgLength(data) > mtu) {
        logw("Truncating value in PrepareWrite to fit into mtu %u -> %u\n", (unsigned)sgLength(data), (unsigned)(mtu - sizeof(req) - sizeof(struct attHdr)));
        sgTruncBack(data, sgLength(data) + sizeof(req) + sizeof(struct attHdr) - mtu);
    }

    ret = attCliReqStart(to);
    if (ret && !attSendPacket(to, ATT_OPCODE_PREPARE_WRITE_REQ, &req, sizeof(req), data)) {
        attCliReqStop(to);
        ret = 0;
    }

    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attCliExecuteStagedWrites
 * USE:      Send a execute-write request to the server
 * PARAMS:   to - whom to
 *           commit - commit data or destroy it?
 * RETURN:   transaction id or 0 on failure
 * NOTES:    write or error callbacks passed to attCliInit may be called
 */
uniq_t attCliExecuteStagedWrites(l2c_handle_t to, bool commit)
{
    struct attPduExecuteWriteReq req;
    uniq_t ret;

    utilSetLE8(&req.flags, commit ? ATT_EXECUTE_WRITE_FLG_EXECUTE : ATT_EXECUTE_WRITE_FLG_CANCEL);

    pthread_mutex_lock(&mAttLock);
    ret = attCliReqStart(to);
    if (ret && !attSendPacket(to, ATT_OPCODE_EXECUTE_WRITE_REQ, &req, sizeof(req), NULL)) {
        attCliReqStop(to);
        ret = 0;
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}

/*
 * FUNCTION: attClientInvalidateCache
 * USE:      Invalidate the cache for a given connection
 * PARAMS:   to - whom to
 * RETURN:   success?
 * NOTES:
 */
bool attClientInvalidateCache(l2c_handle_t to)
{
    struct attConn* conn;
    bool ret = true;

    pthread_mutex_lock(&mAttLock);
    conn = attConnFindByL2cConn(to);
    if (!conn)
        logw("Caches of nonexistent AATT connections are by definition always clean :)\n");
    else {
        //TODO: this
    }
    pthread_mutex_unlock(&mAttLock);

    return ret;
}





