/*
 * 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 "config.h"
#include "l2cap.h"
#include "sendQ.h"
#include "uniq.h"
#include "uuid.h"
#include "util.h"
#include "gatt.h"
#include "att.h"
#include "log.h"
#include "mt.h"
#include "bt.h"

// TODO: if multiple clients stage writes/try to commit them, we do not arbitrate that. Depending on the desired use of this, we may have to

/* A NOTE ABOUT LOCKS:
 * we call callbacks with locks dropped. This is on purpose, since the
 * callbacks can call back into GATT. We need the locks held to use the various
 * data structures though. This leads to the common structure you'll see here
 * as lock -> work -> unlock -> callback -> relock -> more work. How do we make
 * sure that nothing changes while the lock is dropped? We do not and cannot.
 * So what do we do? There are two things we care about. One is the connection
 * itself going away. We solve this easily by again looking it up when we
 * re-take the locks. If we do not find it, it went away and we can stop
 * whatever we were doing. Now, about that. We keep track of what we were doing
 * using a "ToDo item" structure. When a connection is torn down, all of its
 * associated ToDo items are freed. But, this may happen in a thread different
 * from the one currently in the callback. How do we avoid this race? Two
 * solutions exist. One is to have a per-todo-item lock. That would not be fun
 * as we'd be constantly creating and deleting locks. Another is simpler - a
 * flag in the connection saying "do not free *current* ToDo item". We set this
 * flag before dropping the locks, and clear it when we re-take them. If a
 * connection is closed and this flag is set, the cleanup code will not free
 * the *current* ToDo item. This makes sure the code after lock re-acquisition
 * can continue to run. When it fails to find the connection, it knows that
 * it itself must free the ToDo item it was working on. Thus: no memory leak
 * and no use-after-free.
 */


#define GATT_ITEM_TYPE_INCLUDE     1
#define GATT_ITEM_TYPE_CHAR_DECL   2
#define GATT_ITEM_TYPE_CHAR_VAL    3
#define GATT_ITEM_TYPE_CHAR_DESCR  4

#define GATT_HDR_HANDLES           1 /* handles required for a service header */
struct gattService;
struct gattCliNotif;

struct gattIncludeDefHdr {
    uint16_t startHandle;
    uint16_t endHandle;
    /* uuid here IFF it is a uuid-16 */
} __packed;

struct gattCharDefHdr {
    uint8_t charProps;
    uint16_t valHandle;
    /* uuid here 16 or 128 bits */
} __packed;

// we can have one ATT transaction outstanding per connection. This list serializes them
struct gattCliTodoItem {
    struct gattCliTodoItem            *next;
    gatt_client_conn_t                 connId;       // higher level ID - unused by us

    uint8_t                            type;         // what sort of an ATT request is it? GATT_CLI_TODO_*
    uint8_t                            purpose;      // why are we doing it? GATT_INTENT_*
    bool                               enqueued;     // for error checking

    // per-type info (selectively used for various types of requests)
    bool                               execute;
    uint16_t                           handle;
    uint16_t                           endHandle;
    uint16_t                           auxHandle[2]; // sometimes we need to store some handle values temporarily in a todo's state. eg for enum included svcs, when reading 128 bit uuid, it stores {next incl handle to search, end of cur handle }
    union {
        uint16_t                       offset;       // for some reads and writes
        uint16_t                       mtu;          // for MTU negotiations
    };
    struct uuid                        uuid;         // uuid16 for find-by-type-value, any uuid for read-by-type, read-by-group-type
    bool                               commit;       // for write-execute
    uint8_t                            authReq;      // for some reads and writes
    sg                                 data;         // sometimes we actually need data
    uniq_t                             notifLocator; // used to find a notif rec for cccd writes

    uniq_t                             clientTrans;  // unused by us. set and given to clients for state tracking

    struct uuid                        desiredUuid;  // find-service-by-uuid will save the desired uuid here as else we'll lose it

    // callbacks
    union {
        gattCliSvcEnumCbk              enumSvcsCbk;
        gattCliEnumCharacteristicsCbk  enumCharsCbk;
        gattCliEnumCharDescrsCbk       enumCharDscrsCbk;
        gattCliStagedWriteExecuteCb    executeCbk;
        gattCliEnumIncludedSvcsCbk     enumIncludedSvcsCbk;
        gattCliReadCbk                 readCbk;
        gattCliWriteCbk                writeCbk;
    };
};

#define GATT_CLI_TODO_FIND_INFO          0
#define GATT_CLI_TODO_FIND_BY_TYPE_VAL   1
#define GATT_CLI_TODO_READ_BY_TYPE       2
#define GATT_CLI_TODO_READ               3
#define GATT_CLI_TODO_READ_BLOB          4
#define GATT_CLI_TODO_READ_BY_GRP_TYPE   5
#define GATT_CLI_TODO_WRITE              6
#define GATT_CLI_TODO_WRITE_NO_ACK       7
#define GATT_CLI_TODO_SIGNED_WRITE       8
#define GATT_CLI_TODO_PREPARE_WRITE      9
#define GATT_CLI_TODO_WRITE_EXEC         10
#define GATT_CLI_TODO_SEND_MTU_REQ       11
#define GATT_CLI_TODO_WRITE_CCCD         12 // special case that will devolve into a write once we resolve what to write

#define GATT_INTENT_INTERNAL             0
#define GATT_INTENT_FIND_SVC             1
#define GATT_INTENT_ENUM_SVCS            2
#define GATT_INTENT_ENUM_INCL_SVCS       3
#define GATT_INTENT_ENUM_CHARS           4
#define GATT_INTENT_ENUM_CHAR_DESCRS     5
#define GATT_INTENT_READ                 6
#define GATT_INTENT_WRITE                7
#define GATT_INTENT_EXECUTE              8
#define GATT_INTENT_NOTIF_SUB_UNSUB      9
#define GATT_INTENT_MTU_XCHG             10


#define GATT_CONN_STATE_CONNECTING       0  /* only if initiating */
#define GATT_CONN_STATE_RUNNING          1

struct GattEnqueuedWrite {
    struct GattEnqueuedWrite *next;
    att_range_t rangeRef;
    uint16_t handleOfst;
    sg data;
};

struct gattConnState {
    struct gattConnState     *next;
    struct gattConnState     *prev;
    uniq_t                    gattConnId;

    struct gattCliNotif      *cliNotifs; // things we as a client are subscribed to
    struct bt_addr            addr;
    l2c_handle_t              conn;
    uint32_t                  mtu;
    uint8_t                   state;
    bool                      encr;

    uint32_t                  queuedLength; // how much we've buffered so far
    struct GattEnqueuedWrite *queuedWrites;

    struct gattCliTodoItem   *todoListH;
    struct gattCliTodoItem   *todoListT;
    struct gattCliTodoItem   *todoCurr; // or null if none
    bool                      doNotFreeTodoCurr; // used to synchronize who frees "todoCurr". See "A NOTE ABOUT LOCKS"
};

struct gattItem { /* a list of these exists in a a gatt service */
    struct gattItem    *next;
    struct gattItem    *prev;
    uint8_t             type;
    union {
        struct{
            struct gattService *incl;
        } include;
        struct {
            struct uuid         uuid;
            uint8_t             charProps;
        } charDecl;
        struct {
            uint32_t            valPerms;
        } charVal;
        struct {
            struct uuid         uuid;
            uint32_t            descrValPerms;
        } descriptor;
    };
};

struct gattService {
    struct gattService  *next;
    struct gattService  *prev;
    struct uuid          uuid;
    att_range_t          attRange;
    uint16_t             numItems;
    uint16_t             maxItems;
    gatt_service_t       svcRef;

    gattSrvValueReadCbk  readF;
    gattSrvValueWriteCbk writeF;
    gattSrvIndCbk        indF;
    gattSrvDisconnectCbk discF;

    struct gattItem     *itemsHead;
    struct gattItem     *itemsTail;
    uint16_t             useCount; /* how many services include this one */
    bool                 primary;
    bool                 online;
    bool                 allowLE;
    bool                 allowEDR;
};

struct gattCliNotif { /* keeps track of all notifications all clients are subscribed to */
    struct gattCliNotif     *prev;
    struct gattCliNotif     *next;
    uint32_t                 refCtInd;         // how many clients want indication
    uint32_t                 refCtNotif;       // how many clients want notification
    uniq_t                   locator;          // used to locate this cli-notif structure
    uint8_t                  curState;         // NOTIF_C_STATE_*

    /* cache of relevant values for speed and convenience. spec promises these can never change */
    uint16_t                 charHeaderHandle; /* first handle for this characteristic */
    uint16_t                 charValueHandle;  /* characteristic's actual value's handle */
    uint16_t                 charConfigHandle; /* characteristic's "config" handle for unsubscribing */
};

#define NOTIF_C_STATE_NOT_SUBBED         0
#define NOTIF_C_STATE_SUBBED_TO_IND      1
#define NOTIF_C_STATE_SUBBED_TO_NOTIF    2


struct gattCliNotifRec { /* used to keep track of all notifications that a client is subscribed to */
    struct gattCliNotifRec       *next;
    struct gattCliNotifRec       *prev;
    struct gattCliNotif          *notif;
    bool                          wantInd;       // else we'll ask for notif
    bool                          subCallMade;   // set once we have sent the notif sub status callback (to make sure we only do once)
    bool                          unsubCallMade; // set once we have sent the notif unsub status callback (to make sure we only do once)

    gattCliNotifArrivedCbk        arrivedCbk;
    gattCliNotifSubscribeStateCbk stateCbk;      // only set if we haven't yet called it
};

struct gattClientConnection {
    struct gattClientConnection  *next;
    struct gattClientConnection  *prev;
    uniq_t                        gattConnId;
    struct gattCliNotifRec       *notifs;
    gatt_client_conn_t            connId; // used by our callers
    gattCliConnectResultCbk       connCbk;
};

struct gattWorkItem {
    uint8_t type;
    union {
        struct {
            l2c_handle_t             who;
            union {
                gattSrvValueReadCbk  readF;
                gattSrvValueWriteCbk writeF;
            };
            gatt_service_t           svcRef;
            att_cid_t                cid;
            att_trans_t              transId;
            uint16_t                 handle;
            uint16_t                 byteOfst;
            uint16_t                 len;
            uint8_t                  reason;
            /* data here, if write */
        } srvRwCall;
        struct {
            uint64_t                 ref;
            l2c_handle_t             who;
            gattSrvIndCbk            indF;
            gatt_service_t           svcRef;
            att_cid_t                cid;
            uint16_t                 handle;
            uint8_t                  evt;
        } srvIndCall;
        struct {
            l2c_handle_t             who;
            gattSrvDisconnectCbk     discF;
            gatt_service_t           svcRef;
        } srvDiscCall;
        struct {
            l2c_handle_t             who;
            att_cid_t                cid;
            struct GattEnqueuedWrite *q;
            att_trans_t              transId;
        } srvWriteExec;
        struct {
            gattCliConnectResultCbk  cbk;
            gatt_client_conn_t       connId;
            uint8_t                  status;
        } cliConnStateNotif;
        struct {
            l2c_handle_t             conn;
            struct gattCliTodoItem  *todo;
        } cliDoNext;
        struct {
            gattCliNotifArrivedCbk   cbk;
            gatt_client_conn_t       conn;
            uint16_t                 handle;
            bool                     ind;
            sg                       data;
        } cliIndCall;
        struct {
            gattCliNotifSubscribeStateCbk  cbk;
            gatt_client_conn_t       conn;
            uint16_t                 handle;
            bool                     forSub;
            uint8_t                  stat;
        } cliSubUnsubCall;
    };
};

struct GattCliUtilSvcTraverseState {
    struct GattCliUtilSvcTraverseState *next;
    struct GattCliUtilSvcTraverseState *prev;
    uniq_t curTrans, clientTrans;
    struct GattTraversedService res;
    uint32_t numChars, numDescrs, numInclSvcs;
    struct GattTraversedServiceChar *allChars;
    struct GattTraversedServiceCharDescr* allDescrs;
    struct GattTraversedServiceInclSvc *allInclSvcs;
    gattCliUtilSvcTraversedCbk cbk;
};

struct GattCliUtilLongReadState {
    struct GattCliUtilLongReadState *next;
    struct GattCliUtilLongReadState *prev;
    uniq_t curTrans, clientTrans;
    uint16_t handle;
    uint8_t authReq;
    sg dataSoFar;
    gattCliUtilLongReadCompletedCbk cbk;
};

#define GATT_WORK_SRV_READ_CALL          0
#define GATT_WORK_SRV_WRITE_CALL         1
#define GATT_WORK_SRV_IND_CALL           2
#define GATT_WORK_SRV_DISC_CALL          3
#define GATT_WORK_SRV_WRITE_EXEC         4
#define GATT_WORK_CLI_CONN_STATE_NOTIF   5
#define GATT_WORK_CLI_DO_NEXT            6 // run the next todo item, if none in flight currently
#define GATT_WORK_CLI_IND_CALL           7
#define GATT_WORK_CLI_SUB_UNSUB_CALL     8


/* our state */
static struct sendQ* mSendQ;
static struct workQueue* mWorkQ;
static pthread_t mWorker;

static pthread_mutex_t mGattLock = PTHREAD_MUTEX_INITIALIZER;
static struct gattConnState *mConns = NULL; /* one per L2C conn (max one per peer) */
static struct gattService *mSvcs = NULL;
static struct gattClientConnection *mClientConns = NULL; /* one per client's idea of a connection */

static pthread_mutex_t mGattUtilLock = PTHREAD_MUTEX_INITIALIZER;
static struct GattCliUtilSvcTraverseState *mUtilSvcEnumStates;
static struct GattCliUtilLongReadState *mUtilLongReadStates;

/* fwd decls */
static struct gattCliTodoItem* gattCliTodoMakeWrite(gatt_client_conn_t connId, uint8_t purpose, uint8_t writeType, uint16_t handle, uint8_t authReq, uint16_t offset, sg data);
static void gattCliTodoEnqItem(struct gattConnState *conn, struct gattCliTodoItem *todo, bool inFront);
static void gattCliTodoNext(l2c_handle_t conn, struct gattCliTodoItem *now);
static void gattCliTodoItemFree(struct gattCliTodoItem *todo);
static void gattWorkItemFree(struct gattWorkItem *wi);
static struct gattCliTodoItem* gattCliTodoMakeMtuReq(struct gattConnState* conn, uint16_t mtu, uint8_t purpose);
static uint8_t gattClientUtilLongReadScheduleNextChunk(gatt_client_conn_t conn, uint32_t curTrans, bool needCallback);


/*
 * FUNCTION: gattConnFindByL2cConn
 * USE:      find a per-connection structure for a given l2c handle
 * PARAMS:   conn - the l2c connection handle
 * RETURN:   connection structure or NULL if not found
 * NOTES:    call with mGattLock held
 */
static struct gattConnState* gattConnFindByL2cConn(l2c_handle_t conn)
{
    struct gattConnState *state;

    for (state = mConns; state && state->conn != conn; state = state->next);

    return state;
}

/*
 * FUNCTION: gattConnFindByAddr
 * USE:      find a per-connection structure for a given address
 * PARAMS:   addr - the address
 * RETURN:   connection structure or NULL if not found
 * NOTES:    call with mGattLock held
 */
static struct gattConnState* gattConnFindByAddr(const struct bt_addr *addr)
{
    struct gattConnState *state;

    for (state = mConns; state && memcmp(addr, &state->addr, sizeof(struct bt_addr)); state = state->next);

    return state;
}

/*
 * FUNCTION: gattConnFindById
 * USE:      find a per-connection structure for a given gatt connection id
 * PARAMS:   gattConnId - the connection id
 * RETURN:   connection structure or NULL if not found
 * NOTES:    call with mGattLock held
 */
static struct gattConnState* gattConnFindById(uniq_t gattConnId)
{
    struct gattConnState *state;

    for (state = mConns; state && state->gattConnId != gattConnId; state = state->next);

    return state;
}

/*
 * FUNCTION: gattNotifFindByLocatorInConn
 * USE:      find a notification record structure given a connection it belongs to and its locator value
 * PARAMS:   conn - connection structure
 *           notifLocator - unique notif record locator value
 * RETURN:   notif structure or NULL
 * NOTES:    call with mGattLock held
 */
static struct gattCliNotif* gattNotifFindByLocatorInConn(struct gattConnState* conn, uniq_t notifLocator)
{
    struct gattCliNotif *notif;

    for (notif = conn->cliNotifs; notif; notif = notif->next) {
        if (notif->locator == notifLocator)
            return notif;
    }

    return NULL;
}

/*
 * FUNCTION: gattQueuedWriteQueueFree
 * USE:      Free a queued wrote linked list properly
 * PARAMS:   qw - the queued write linked list
 * RETURN:   NONE
 * NOTES:
 */
static void gattQueuedWriteQueueFree(struct GattEnqueuedWrite *qw)
{
    struct GattEnqueuedWrite *t;

    while (qw) {
        t = qw;
        qw = qw->next;
        if (t->data)
            sgFree(t->data);
        free(t);
    }
}

/*
 * FUNCTION: gattConnStructDelete
 * USE:      Delete and unlink a connection struct
 * PARAMS:   state - said struct
 * RETURN:   NONE
 * NOTES:    call with mGattLock held
 */
static void gattConnStructDelete(struct gattConnState *state)
{
    struct gattCliNotif *nC, *nN;
    struct gattCliTodoItem *tC, *tN;

    for (nC = state->cliNotifs; nC; nC = nN) {
        nN = nC->next;
        free(nC);
    }

    for (tC = state->todoListH; tC; tC = tN) {
        tN = tC->next;
        gattCliTodoItemFree(tC);
    }

    if (state->todoCurr && !state->doNotFreeTodoCurr)
        gattCliTodoItemFree(state->todoCurr);

    gattQueuedWriteQueueFree(state->queuedWrites);

    if (state->next)
        state->next->prev = state->prev;
    if (state->prev)
        state->prev->next = state->next;
    else
        mConns = state->next;

    /* future free steps here */
    free(state);
}

/*
 * FUNCTION: gattServiceFindByUuid
 * USE:      Find a gatt service by uuid
 * PARAMS:   uuid - the uuid
 * RETURN:   service struct or NULL if not found
 * NOTES:    call with mGattLock held
 */
static struct gattService* gattServiceFindByUuid(const struct uuid *uuid)
{
    struct gattService *svc = mSvcs;

    while (svc && !uuidCmp(uuid, &svc->uuid))
        svc = svc->next;

    return svc;
}

/*
 * FUNCTION: gattServiceFindBySvcRef
 * USE:      Find a gatt service by service reference
 * PARAMS:   svcRef - the service reference
 * RETURN:   service struct or NULL if not found
 * NOTES:    call with mGattLock held
 */
static struct gattService* gattServiceFindBySvcRef(gatt_service_t svcRef)
{
    struct gattService *svc = mSvcs;

    while (svc && svcRef != svc->svcRef)
        svc = svc->next;

    return svc;
}

/*
 * FUNCTION: gattClientConnFindById
 * USE:      Find a gatt client connection structure by connId
 * PARAMS:   connId - the connection id
 * RETURN:   client connection struct or NULL if not found
 * NOTES:    call with mGattLock held
 */
static struct gattClientConnection* gattClientConnFindById(gatt_client_conn_t connId)
{
    struct gattClientConnection *clicon = mClientConns;

    while (clicon && connId != clicon->connId)
        clicon = clicon->next;

    return clicon;
}

/*
 * FUNCTION: gattServiceFindByRangeRef
 * USE:      Find a gatt service by att range reference
 * PARAMS:   rangeRef - the service range reference
 * RETURN:   service struct or NULL if not found
 * NOTES:    call with mGattLock held
 */
static struct gattService *gattServiceFindByRangeRef(att_range_t rangeRef)
{
    struct gattService *svc = mSvcs;

    while (svc && rangeRef != svc->attRange)
        svc = svc->next;

    return svc;
}

/*
 * FUNCTION: gattAttSrvTxCbk
 * USE:      ATT calls this to TX to a client
 * PARAMS:   who - whom to send to
 *           s - the data to send
 * RETURN:   ATT_TX_RET_*
 * NOTES:
 */
static uint8_t gattAttSrvTxCbk(l2c_handle_t who, sg s)
{
    return sendQueueTx(mSendQ, who, s) ? ATT_TX_RET_ACCEPTED : ATT_TX_RET_L2C_ERR;
}

/*
 * FUNCTION: gattEnqueueSrvRwCall
 * USE:      Enqueue a work item to make a call to the higher layer for a read or a write
 * PARAMS:   workType - read or write?
 *           svc - the relevant service
 *           who - whom the connection is to
 *           cid - ATT's connection ID
 *           transId - ATT's transaction ID
 *           handle - handle
 *           byteOfst - byte offset for the read/write
 *           reason - ATT_READ_FOR_* or ATT_WRITE_FOR_*
 *           len - requested length
 *           data - NULL for read, data for write
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueSrvRwCall(uint8_t workType, struct gattService *svc, l2c_handle_t who, att_cid_t cid, att_trans_t transId, uint16_t handle, uint16_t byteOfst, uint8_t reason, uint16_t len, const void *data)
{
    struct gattWorkItem *wi = (struct gattWorkItem*)calloc(1, sizeof(struct gattWorkItem) + (data ? len : 0));

    if (wi) {
        wi->type = workType;
        wi->srvRwCall.who = who;
        wi->srvRwCall.svcRef = svc->svcRef;
        wi->srvRwCall.cid = cid;
        wi->srvRwCall.transId = transId;
        wi->srvRwCall.handle = handle;
        wi->srvRwCall.byteOfst = byteOfst;
        wi->srvRwCall.len = len;
        wi->srvRwCall.reason = reason;
        if (workType == GATT_WORK_SRV_READ_CALL)
            wi->srvRwCall.readF = svc->readF;
        else {
            wi->srvRwCall.writeF = svc->writeF;
            memcpy(wi + 1, data, len);
        }

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

        free(wi);
    }
    return false;
}

/*
 * FUNCTION: gattEnqueueSrvReadCall
 * USE:      Enqueue a work item to make a call to the higher layer for a read
 * PARAMS:   svc - the relevant service
 *           who - whom the connection is to
 *           cid - ATT's connection ID
 *           transId - ATT's transaction ID
 *           handle - handle
 *           byteOfst - byte offset for the read
 *           reason - ATT_READ_FOR_*
 *           len - requested length
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueSrvReadCall(struct gattService *svc, l2c_handle_t who, att_cid_t cid, att_trans_t transId, uint16_t handle, uint16_t byteOfst, uint8_t reason, uint16_t maxLen)
{
    return gattEnqueueSrvRwCall(GATT_WORK_SRV_READ_CALL, svc, who, cid, transId, handle, byteOfst, reason, maxLen, NULL);
}

/*
 * FUNCTION: gattEnqueueSrvWriteCall
 * USE:      Enqueue a work item to make a call to the higher layer for a write
 * PARAMS:   svc - the relevant service
 *           who - whom the connection is to
 *           cid - ATT's connection ID
 *           transId - ATT's transaction ID
 *           handle - handle
 *           byteOfst - byte offset for the write
 *           reason - ATT_WRITE_FOR_*
 *           len - requested length
 *           data - data to write
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueSrvWriteCall(struct gattService *svc, l2c_handle_t who, att_cid_t cid, att_trans_t transId, uint16_t handle, uint16_t byteOfst, uint8_t reason, uint16_t len, const void *data)
{
    return gattEnqueueSrvRwCall(GATT_WORK_SRV_WRITE_CALL, svc, who, cid, transId, handle, byteOfst, reason, len, data);
}

/*
 * FUNCTION: gattEnqueueSrvIndCall
 * USE:      Enqueue a work item to make a call to the higher layer for a result of sending an indication/notification
 * PARAMS:   svc - the relevant service
 *           who - whom the connection is to
 *           cid - ATT's connection ID
 *           handle - handle
 *           evt - what happened
 *           ref - the value to pass to callback
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueSrvIndCall(struct gattService *svc, l2c_handle_t who, att_cid_t cid, uint16_t handle, uint8_t evt, uint64_t ref)
{
    struct gattWorkItem *wi = (struct gattWorkItem*)calloc(1, sizeof(struct gattWorkItem));

    if (wi) {
        wi->type = GATT_WORK_SRV_IND_CALL;
        wi->srvIndCall.who = who;
        wi->srvIndCall.svcRef = svc->svcRef;
        wi->srvIndCall.cid = cid;
        wi->srvIndCall.handle = handle;
        wi->srvIndCall.evt = evt;
        wi->srvIndCall.ref = ref;
        wi->srvIndCall.indF = svc->indF;

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

        free(wi);
    }
    return false;
}

/*
 * FUNCTION: gattEnqueueSrvDiscCall
 * USE:      Enqueue a work item to make a call to the higher layer for a result of a disconnection
 * PARAMS:   svc - the relevant service
 *           who - whom the connection is to
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueSrvDiscCall(struct gattService *svc, l2c_handle_t who)
{
    struct gattWorkItem *wi = (struct gattWorkItem*)calloc(1, sizeof(struct gattWorkItem));

    if (wi) {
        wi->type = GATT_WORK_SRV_DISC_CALL;
        wi->srvDiscCall.who = who;
        wi->srvDiscCall.svcRef = svc->svcRef;
        wi->srvDiscCall.discF = svc->discF;

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

        free(wi);
    }
    return false;
}

/*
 * FUNCTION: gattEnqueueCliConnStatusCall
 * USE:      Enqueue a work item to make a call to the higher layer for a result of sending a GATT connect/disconnetc
 * PARAMS:   clicon - the client connection structure
 *           status - the status to send
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueCliConnStatusCall(struct gattClientConnection *clicon, uint8_t status)
{
    struct gattWorkItem *wi = (struct gattWorkItem*)calloc(1, sizeof(struct gattWorkItem));

    if (wi) {
        wi->type = GATT_WORK_CLI_CONN_STATE_NOTIF;
        wi->cliConnStateNotif.cbk = clicon->connCbk;
        wi->cliConnStateNotif.connId = clicon->connId;
        wi->cliConnStateNotif.status = status;

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

        free(wi);
    }
    return false;
}

/*
 * FUNCTION: gattEnqueueCliDoNextTodoItem
 * USE:      Enqueue a work item to perform the next todo item if none is currently in flight for this connection
 * PARAMS:   conn - the connection structure
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueCliDoNextTodoItem(struct gattConnState *conn)
{
    struct gattCliTodoItem *now;
    struct gattWorkItem *wi;

    logd("gattEnqueueCliDoNextTodoItem cur=%p next=%p\n", conn->todoCurr, conn->todoListH);

    if (conn->todoCurr) {
        logd("gattEnqueueCliDoNextTodoItem called with an existing transaction running - not necessary\n");
        return true;
    }
    if (!conn->todoListH) {
        logd("gattEnqueueCliDoNextTodoItem called with no todo items - not necessary\n");
        return true;
    }

    wi = (struct gattWorkItem*)calloc(1, sizeof(struct gattWorkItem));
    if (wi) {
        now = conn->todoListH;

        wi->type = GATT_WORK_CLI_DO_NEXT;
        wi->cliDoNext.conn = conn->conn;
        wi->cliDoNext.todo = now;
        now->enqueued = false;

        if (workQueuePut(mWorkQ, wi)) {
            conn->todoListH = conn->todoListH->next;
            if (!conn->todoListH)
                conn->todoListT = NULL;
            conn->todoCurr = now;
            now->next = NULL;

            return true;
        }
        free(wi);
    }

    return false;
}

/*
 * FUNCTION: gattEnqueueCliIndCall
 * USE:      Enqueue a work item to perform a notif/ind callback to the caller
 * PARAMS:   clicon - client connection struct
 *           nr - the notification record
 *           data - the data to send
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueCliIndCall(struct gattClientConnection *clicon, struct gattCliNotifRec *nr, sg data)
{
    struct gattWorkItem *wi;

    wi = (struct gattWorkItem*)calloc(1, sizeof(struct gattWorkItem));
    if (wi) {

        wi->type = GATT_WORK_CLI_IND_CALL;
        wi->cliIndCall.cbk = nr->arrivedCbk;
        wi->cliIndCall.conn = clicon->connId;
        wi->cliIndCall.handle = nr->notif->charValueHandle;
        wi->cliIndCall.ind = nr->wantInd;
        wi->cliIndCall.data = data;

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

        free(wi);
    }

    return false;
}

/*
 * FUNCTION: gattEnqueueCliSubUnsubCall
 * USE:      Enqueue a work item to perform a subscribe/unsubscribe notification to a caller for ind/notifs
 * PARAMS:   clicon - client connection struct
 *           nr - the notification record
 *           cbk - the callback to call (passed directly as it is not always the one in nr that we want to call)
 *           forSub - is this call for a subscribe or an unsubscribe request
 *           stat - the statsu value to send
 * RETURN:   false on immediate failure
 * NOTES:    call with mGattLock held
 */
static bool gattEnqueueCliSubUnsubCall(struct gattClientConnection *clicon, struct gattCliNotifRec *nr, gattCliNotifSubscribeStateCbk cbk, bool forSub, uint8_t stat)
{
    struct gattWorkItem *wi;

    wi = (struct gattWorkItem*)calloc(1, sizeof(struct gattWorkItem));
    if (wi) {

        wi->type = GATT_WORK_CLI_SUB_UNSUB_CALL;
        wi->cliSubUnsubCall.cbk = cbk;
        wi->cliSubUnsubCall.conn = clicon->connId;
        wi->cliSubUnsubCall.handle = nr->notif->charHeaderHandle;
        wi->cliSubUnsubCall.forSub = forSub;
        wi->cliSubUnsubCall.stat = stat;

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

        free(wi);
    }

    return false;
}

/*
 * FUNCTION: gattAttSrvIndCbk
 * USE:      ATT calls this with results of sending an indication/notification
 * PARAMS:   who - who the remote is
 *           cid - the connection Id to pass back to ATT
 *           rangeRef - the range this is related to
 *           offset - the value in the range
 *           evt - ATT_SRV_EVT_NOTIF_*
 *           ref - the reference passed to attSrvValueNotifyChanged() initially
 *           success - did we succeed?
 * RETURN:   NONE
 * NOTES:
 */
static void gattAttSrvIndCbk(l2c_handle_t to, att_cid_t cid, att_range_t rangeRef, uint16_t offset, uint8_t evt, uint64_t ref)
{
    struct gattService *svc;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindByRangeRef(rangeRef);
    if (!svc)
        logw("Failed to find service for read\n");
    else if (!gattEnqueueSrvIndCall(svc, to, cid, offset + attSrvHandleRangeGetBase(svc->attRange), evt, ref))
        loge("Failed to forward notif event up\n");
    pthread_mutex_unlock(&mGattLock);
}

/*
 * FUNCTION: gattAttSvrReadCbk
 * USE:      ATT calls this to read an attribute
 * PARAMS:   who - who the remote is
 *           rangeRef - the range this is related to
 *           cid - the connection Id to pass back to ATT
 *           ofst - the value in the range
 *           transId - transaction ID
 *           byteOfst - how mnay bytes into the characteristic we want to readsrvcre
 *           reason - read reason (ATT_READ_FOR_*)
 *           maxLen - max bytes to return
 * RETURN:   false on immediate failure
 * NOTES:    when read completes, a call to attSrvCbkReply() should be made
 */
static bool gattAttSvrReadCbk(l2c_handle_t who, att_cid_t cid, att_range_t rangeRef, uint16_t ofst, att_trans_t transId, uint16_t byteOfst, uint8_t reason, uint16_t maxLen)
{
    uint8_t err = ATT_ERROR_NONE;
    struct gattService *svc;
    struct gattItem *gi;
    uint8_t *ptr = NULL;
    uint16_t len = 0;
    uint16_t tmp;
    uint8_t buf[32];

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindByRangeRef(rangeRef);
    if (!svc) {
        logw("Failed to find service for read\n");
        err = ATT_ERROR_INVALID_HANDLE;
        goto out;
    }

    if (!ofst) { /* service header */
        if (uuidToUuid16(&tmp, &svc->uuid)) { /* if it fits in 16 bits, do that */
            utilSetLE16(buf, tmp);
            ptr = buf;
            len = sizeof(uint16_t);
        } else {                                 /* else, send the entire 16-bute uuid */
            uuidWriteLE(buf, &svc->uuid);
            ptr = buf;
            len = sizeof(struct uuid);
        }
    } else if (ofst < GATT_HDR_HANDLES) {
        logw("Unexpected offset %u after header and before handles!\n", ofst);
        err = ATT_ERROR_INVALID_HANDLE;
        goto out;
    } else {
        uint16_t ctr = ofst;
        gi = svc->itemsHead;
        ctr -= GATT_HDR_HANDLES;
        while (gi && ctr--)
            gi = gi->next;

        if (!gi) {
            logw("Handle list ended abruptly with %u handles to go\n", ctr);
            err = ATT_ERROR_INVALID_HANDLE;
            goto out;
        }

        if (gi->type == GATT_ITEM_TYPE_INCLUDE) {
            struct gattIncludeDefHdr *hdr = (struct gattIncludeDefHdr*)buf;
            struct gattService *incl = gi->include.incl;
            uint16_t start;

            start = attSrvHandleRangeGetBase(incl->attRange);

            if (!attSrvValueGetGrpLen(incl->attRange, 0, &tmp)) {
                loge("Failed to get service len for included service\n");
                err = ATT_ERROR_UNLIKELY_ERROR;
                goto out;
            }
            utilSetLE16(&hdr->startHandle, start);
            utilSetLE16(&hdr->endHandle, start + tmp - 1);
            ptr = buf;
            len = sizeof(struct gattIncludeDefHdr);

            if (uuidToUuid16(&tmp, &incl->uuid)) { /* fits into a uuid-16 */
                utilSetLE16(hdr + 1, tmp);
                len += sizeof(uint16_t);
            }

        } else if (gi->type == GATT_ITEM_TYPE_CHAR_DECL) {
            struct gattCharDefHdr *hdr = (struct gattCharDefHdr*)buf;

            utilSetLE8(&hdr->charProps, gi->charDecl.charProps);
            utilSetLE16(&hdr->valHandle, ofst + attSrvHandleRangeGetBase(svc->attRange) + 1); /* always next */
            ptr = buf;
            len = sizeof(struct gattCharDefHdr);

            if (uuidToUuid16(&tmp, &gi->charDecl.uuid)) { /* fits into a uuid-16 */
                utilSetLE16(hdr + 1, tmp);
                len += sizeof(uint16_t);
            } else {
                uuidWriteLE(hdr + 1, &gi->charDecl.uuid);
                len += sizeof(struct uuid);
            }

        } else { /* in this case call to the higher layer for the read */
            if (!gattEnqueueSrvReadCall(svc, who, cid, transId, ofst + attSrvHandleRangeGetBase(svc->attRange), byteOfst, reason, maxLen))
                err = ATT_ERROR_UNLIKELY_ERROR;
            goto out;
        }
    }

    if (!ptr) {
        loge("No data to send at end of read callback\n");
        err = ATT_ERROR_UNLIKELY_ERROR;
    } else if (byteOfst > len)
        err = ATT_ERROR_INVALID_OFFSET;
    else {
        len -= byteOfst;
        ptr += byteOfst;
    }

out:
    pthread_mutex_unlock(&mGattLock);

    if (len || err != ATT_ERROR_NONE)
        attSrvCbkReply(cid, transId, 0, err, ptr, len);
    return true;
}

/*
 * FUNCTION: gattAttSrvProcessWriteReq
 * USE:      Handle a prepare write command
 * PARAMS:   who - who the remote is
 *           cid - ATT's connection ID
 *           rangeRef - the ATT range raference
 *           handleOfst - offset of the given handle in the range
 *           byteOfst - how many bytes into the characteristic we want to write
 *           len - bytes to write
 *           data - the data
 * RETURN:   ATT_ERROR_*
 * NOTES:    called with mGattLock held
 */
static uint8_t gattAttSrvProcessPrepareWriteReq(l2c_handle_t who, att_cid_t cid, att_range_t rangeRef, uint16_t handleOfst, uint32_t byteOfst, uint32_t len, const void *data)
{
    struct gattConnState *conn = gattConnFindByL2cConn(who);
    struct GattEnqueuedWrite *qw, *t;
    uint64_t totalBufSz;

    if (!conn)
        return ATT_ERROR_INVALID_HANDLE;

    totalBufSz = conn->queuedLength;
    qw = conn->queuedWrites;

    // verify buffering limits are met
    totalBufSz += len;
    if (totalBufSz >= GATT_SRV_PREPARE_WRITE_MAX_BYTES)
        return ATT_ERROR_PREPARE_QUEUE_FULL;

    // see if this is a continuation of an existing write and if so, append to it
    for (t = qw; t && (t->rangeRef != rangeRef || t->handleOfst != handleOfst); t = t->next);
    if (t) {
        // gaps arent really allowed when doing long writes in GATT, nor are overlaps
        if (sgLength(t->data) != byteOfst)
            return ATT_ERROR_INVALID_OFFSET;
        // also, attribute max len is 65536 bytes
        if (byteOfst + len > 0x10000)
            return ATT_ERROR_INVALID_OFFSET;
        // append
        if (!sgConcatBackCopy(t->data, data, len))
            return ATT_ERROR_UNLIKELY_ERROR;
        // account for it
        conn->queuedLength += len;
        return ATT_ERROR_NONE;
    }

    // new entry - verify sanity (GATT long write must start at zero)
    if (byteOfst)
        return ATT_ERROR_INVALID_OFFSET;

    // new entry - allocate it & data
    t = calloc(1, sizeof(struct GattEnqueuedWrite));
    if (!t)
        return ATT_ERROR_INSUFFICIENT_RSRCS;

    t->data = sgNewWithCopyData(data, len);
    if (!t->data) {
        free(t);
        return ATT_ERROR_INSUFFICIENT_RSRCS;
    }

    // fill in details
    t->rangeRef = rangeRef;
    t->handleOfst = handleOfst;

    // attach it & update totals
    t->next = qw;
    conn->queuedWrites = t;
    conn->queuedLength += len;

    return ATT_ERROR_NONE;
}

/*
 * FUNCTION: gattAttSvrWriteCbk
 * USE:      ATT calls this to write an attribute
 * PARAMS:   who - who the remote is
 *           rangeRef - the range this is related to
 *           cid - the connection Id to pass back to ATT
 *           handleOfst - the value in the range
 *           transId - transaction ID
 *           byteOfst - how mnay bytes into the characteristic we want to write
 *           reason - read reason (ATT_WRITE_FOR_*)
 *           len - bytes to write
 *           data - the data
 * RETURN:   false on immediate failure
 * NOTES:    when write completes, a call to attSrvCbkReply() should be made
 */
static bool gattAttSvrWriteCbk(l2c_handle_t who, att_cid_t cid, att_range_t rangeRef, uint16_t handleOfst, att_trans_t transId, uint16_t byteOfst, uint8_t reason, uint16_t len, const void *data)
{
    /* attributes GATT creates internally for the user {service headers, includes, characteristic headers} are not writeable. All write pass to user */
    bool replyEvenIfNoErr = false;
    uint8_t err = ATT_ERROR_NONE;
    struct gattService *svc;
    uint16_t handle = handleOfst + attSrvHandleRangeGetBase(rangeRef);

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindByRangeRef(rangeRef);
    if (!svc) {
        logw("Failed to find service for read\n");
        err = ATT_ERROR_INVALID_HANDLE;
        goto out;
    }

    if (reason == ATT_WRITE_FOR_PREPARE) {
        err = gattAttSrvProcessPrepareWriteReq(who, cid, rangeRef, handleOfst, byteOfst, len, data);
        replyEvenIfNoErr = true;
        goto out;
    }
    if (!gattEnqueueSrvWriteCall(svc, who, cid, transId, handle, byteOfst, reason, len, data)) {
        err = ATT_ERROR_INSUFFICIENT_RSRCS;
        goto out;
    }

out:
    if (err != ATT_ERROR_NONE || replyEvenIfNoErr)
        attSrvCbkReply(cid, transId, handle, err, data, len);
    pthread_mutex_unlock(&mGattLock);
    return true;
}

/*
 * FUNCTION: gattAttExecWriteCbk
 * USE:      ATT calls this when client asks us to execute a write
 * PARAMS:   who - who the remote is
 *           cid - the connection Id to pass back to ATT
 *           transId - the transaction ID
 *           exec - execute or dump data?
 * RETURN:   NONE
 * NOTES:
 */
static bool gattAttExecWriteCbk(l2c_handle_t who, att_cid_t cid, att_trans_t transId, bool exec)
{
    struct GattEnqueuedWrite *qw = NULL;
    uint8_t err = ATT_ERROR_NONE;
    bool replyEvenIfOk = true;
    struct gattConnState *conn;
    struct gattWorkItem *wi;

    pthread_mutex_lock(&mGattLock);
    conn = gattConnFindByL2cConn(who);

    if (!conn) {
        err = ATT_ERROR_UNLIKELY_ERROR;
        goto out;
    }

    /// if there are writes queued, detach them from the list
    qw = conn->queuedWrites;
    conn->queuedWrites = NULL;

    // if the request was to cancel, and we have writes queued delete them and reply; if request was to apply, and no writes were queued just reply
    if (!exec || !qw)
        goto out;

    // we only get this far if we had queued writes and we were asked to perform them - enqueue a work queue item to do that and only reply in case of failure to do so
    wi = (struct gattWorkItem*)calloc(1, sizeof(struct gattWorkItem));
    if (!wi) {
        err = ATT_ERROR_INSUFFICIENT_RSRCS;
        goto out;
    }

    wi->type = GATT_WORK_SRV_WRITE_EXEC;
    wi->srvWriteExec.who = who;
    wi->srvWriteExec.cid = cid;
    wi->srvWriteExec.q = qw;
    wi->srvWriteExec.transId = transId;

    if (workQueuePut(mWorkQ, wi)) {
        replyEvenIfOk = false;
        qw = NULL;
    }
    else {
        err = ATT_ERROR_UNLIKELY_ERROR;
        free(wi);
    }

out:
    gattQueuedWriteQueueFree(qw);

    pthread_mutex_unlock(&mGattLock);
    if (err != ATT_ERROR_NONE || replyEvenIfOk)
        attSrvCbkReply(cid, transId, 0, err, NULL, 0);
    return true;
}

/*
 * FUNCTION: gattMtuAdjust
 * USE:      Set MTU as per negotiation
 * PARAMS:   gatt - the gatt connection state
 *           mtu - the mtu to set
 * RETURN:   NONE
 * NOTES:    call with mGattLock held
 */
static void gattMtuAdjust(struct gattConnState* gatt, uint32_t mtu)
{
    if (gatt->mtu > mtu)
        loge("MTU decrease not allowed\n");
    else
        gatt->mtu = mtu;
}

/*
 * FUNCTION: gattAttCliMtuCbk
 * USE:      ATT calls this with results of MTU negotiation (if we are client)
 * PARAMS:   who - whom the MTU is to
 *           mtu - the mtu to the client
 * RETURN:   NONE
 * NOTES:
 */
static void gattAttCliMtuCbk(l2c_handle_t who, uint32_t mtu)
{
    struct gattConnState *conn;

    pthread_mutex_lock(&mGattLock);
    conn = gattConnFindByL2cConn(who);
    if (conn) {
        struct gattCliTodoItem *todo = conn->todoCurr;

        if (!todo || todo->type != GATT_CLI_TODO_SEND_MTU_REQ || todo->purpose != GATT_INTENT_MTU_XCHG)
            logw("Unexpected MTU reply\n");
        else {
            gattMtuAdjust(conn, mtu);
        }

        conn->todoCurr = NULL;
        gattCliTodoItemFree(todo);
        gattEnqueueCliDoNextTodoItem(conn);
    }
    pthread_mutex_unlock(&mGattLock);
}

/*
 * FUNCTION: gattAttSrvMtuCbk
 * USE:      ATT calls this with results of MTU negotiation (if we are server)
 * PARAMS:   who - whom the MTU is to
 *           mtu - the mtu to the client
 * RETURN:   NONE
 * NOTES:
 */
static void gattAttSrvMtuCbk(l2c_handle_t who, uint32_t mtu)
{
    struct gattConnState* state;

    pthread_mutex_lock(&mGattLock);
    state = gattConnFindByL2cConn(who);
    if (!state)
        loge("Unknown connection for MTU change event\n");
    else
        gattMtuAdjust(state, mtu);
    pthread_mutex_unlock(&mGattLock);
}

/*
 * FUNCTION: gattAttEdrMtuCbk
 * USE:      ATT calls this with results of MTU negotiation (on EDR)
 * PARAMS:   who - whom the MTU is to
 *           mtu - the mtu to the client
 * RETURN:   NONE
 * NOTES:
 */
static void gattAttEdrMtuCbk(l2c_handle_t who, uint32_t mtu)
{
    struct gattConnState* state;

    pthread_mutex_lock(&mGattLock);
    state = gattConnFindByL2cConn(who);
    if (!state)
        loge("Unknown connection for MTU change event\n");
    else
        gattMtuAdjust(state, mtu);
    pthread_mutex_unlock(&mGattLock);
}

/*
 * FUNCTION: gattNotifyServersOfConnClose
 * USE:      Tell all GATT servers that a connection closed
 * PARAMS:   who - the l2c conn handle for the connection
 * RETURN:   NONE
 * NOTES:
 */
static void gattNotifyServersOfConnClose(l2c_handle_t who)
{
    struct gattService *svc;

    pthread_mutex_lock(&mGattLock);
    for (svc = mSvcs; svc; svc = svc->next) {
        if (!svc->online)
            continue;
        if (!gattEnqueueSrvDiscCall(svc, who))
            loge("cannot notify server of connection closure\n");
    }
    pthread_mutex_unlock(&mGattLock);
}

/*
 * FUNCTION: gattNotifyAllClientsOfConn
 * USE:      Tell all those waiting for a connection open/close that it happened
 * PARAMS:   inst - per-connection instance state (struct gattConnState)
 *           state - the state to notify with
 * RETURN:   NONE
 * NOTES:    call with mGattLock held
 */
static void gattNotifyAllClientsOfConn(struct gattConnState *inst, uint8_t state)
{
    struct gattClientConnection *clicon;

    for (clicon = mClientConns; clicon; clicon = clicon->next) {
        if (clicon->gattConnId != inst->gattConnId)
            continue;
        logd("telling client with gatt conn "GATTHANDLEFMT" about connection open status %u\n", GATTHANDLECNV(clicon->connId), state);
        gattEnqueueCliConnStatusCall(clicon, state);
    }
}

/*
 * FUNCTION: gattConnEvt
 * USE:      L2C calls this with events about connections
 * PARAMS:   userData - unused
 *           instance - per-connection instance state (struct gattConnState)
 *           evt - what event happened
 *           data - the data pertinent to the event
 *           len - the length of said data
 * RETURN:   NONE
 * NOTES:
 */
static void gattConnEvt(void *userData, void *instance, uint8_t evt, const void *data, uint32_t len)
{
    struct gattConnState *state = (struct gattConnState*)instance;
    l2c_handle_t conn;
    uint16_t mtu;
    sg s;

    switch (evt) {
    case L2C_STATE_OPEN:
        if (len != sizeof(l2c_handle_t)) {
            loge("invalid length for open event\n");
            break;
        }
        conn = *(l2c_handle_t*)data;
        pthread_mutex_lock(&mGattLock);
        if (state->state == GATT_CONN_STATE_CONNECTING) { // outbound conenction success

            state->conn = conn;
            logd("GATT outbound connection to "ADDRFMT" success: "HANDLEFMT"\n", ADDRCONV(state->addr), HANDLECNV(conn));
            state->state = GATT_CONN_STATE_RUNNING;
            if (BT_ADDR_IS_LE(state->addr)) { // try to negotiate mtu if LE
                logd("Requesting gatt MTU negotiation\n");
                if (!gattCliTodoMakeMtuReq(state, L2C_MAX_SAFE_MTU, GATT_INTENT_MTU_XCHG))
                    logw("Failed to make MTU request change todo - ATT may be slow\n");
            }
            gattNotifyAllClientsOfConn(state, GATT_CLI_STATUS_OK);
        }
        else if (state->state != GATT_CONN_STATE_RUNNING)
            loge("GATT L2C connection state 'opened' while in state %u\n", state->state);
        else if (state->conn != conn)
            loge("GATT L2C conn handle change is unexpected for inbound connections!!!\n");
        pthread_mutex_unlock(&mGattLock);
        break;

    case L2C_STATE_MTU:
        if (len != sizeof(uint16_t)) {
            loge("invalid length for mtu event\n");
            break;
        }
        mtu = *(uint16_t*)data;
        attSetMtu(state->conn, mtu);
        gattAttEdrMtuCbk(state->conn, mtu);
        break;

    case L2C_STATE_ENCR:
        if (len != sizeof(struct l2cEncrState)) {
            loge("invalid length for encr event\n");
            break;
        }
        attEncrAuthUpdate(state->conn, ((struct l2cEncrState*)data)->isEncr, ((struct l2cEncrState*)data)->isMitmSafe);
        // TODO: tell gatt clients & servers
        break;

    case L2C_STATE_ENCR_KEY_REF:
        if (len != sizeof(struct l2cEncrState)) {
            loge("invalid length for encr key event\n");
            break;
        }
        attEncrAuthUpdate(state->conn, ((struct l2cEncrState*)data)->isEncr, ((struct l2cEncrState*)data)->isMitmSafe);
        break;

    case L2C_STATE_RX:
        if (len != sizeof(sg)) {
            loge("invalid length for RX event\n");
            break;
        }
        s = *(sg*)data;
        attSrvDataRx(state->conn, s);
        break;

    case L2C_STATE_CLOSED:
        gattNotifyServersOfConnClose(state->conn);
        attNotifConnClose(state->conn);
        pthread_mutex_lock(&mGattLock);
        gattNotifyAllClientsOfConn(state, GATT_CLI_STATUS_OTHER_SIDE_DISC);
        sendQueueDelPackets(mSendQ, state->conn);
        gattConnStructDelete(state);
        pthread_mutex_unlock(&mGattLock);
        break;
    default:
        logd("unknown L2C event %u\n", evt);
        break;
    }
}

/*
 * FUNCTION: gattStateAllocLocked
 * USE:      Allocate a GATT state for an L2C link
 * PARAMS:   conn - the connection handle (0 if none yet)
 *           instanceP - we store per-connection instance here
 *           addr - the peer's address
 *           initialState - state to leave the connection in
 * RETURN:   SVC_ALLOC_*
 * NOTES:    call with mGattLock held
 */
static uint8_t gattStateAllocLocked(l2c_handle_t conn, void **instanceP, const struct bt_addr *addr, uint8_t initialState)
{
    struct gattConnState *state = (struct gattConnState*)calloc(1, sizeof(struct gattConnState));

    if (!state)
        return SVC_ALLOC_FAIL_OTHER;

    state->conn = conn;
    state->state = initialState;
    state->gattConnId = uniqGetNext();
    state->mtu = BT_ADDR_IS_LE(*addr) ? ATT_MTU_MIN_LE : ATT_MTU_MIN_EDR;
    memcpy(&state->addr, addr, sizeof(struct bt_addr));
    /* any other init here */

    state->next = mConns;
    if (mConns)
        mConns->prev = state;
    mConns = state;

    *instanceP = state;
    return SVC_ALLOC_SUCCESS;
}

/*
 * FUNCTION: gattStateAlloc
 * USE:      Allocate a GATT state for an L2C link
 * PARAMS:   conn - the connection handle (0 if none yet)
 *           instanceP - we store per-connection instance here
 *           addr - the peer's address
 *           initialState - state to leave the connection in
 * RETURN:   SVC_ALLOC_*
 * NOTES:    just a version of gattStateAllocLocked that takes the lock as needed
 */
static uint8_t gattStateAlloc(l2c_handle_t conn, void **instanceP, const struct bt_addr *addr, uint8_t initialState)
{
    uint8_t ret;

    pthread_mutex_lock(&mGattLock);
    ret = gattStateAllocLocked(conn, instanceP, addr, initialState);
    pthread_mutex_unlock(&mGattLock);

    return ret;
}

/*
 * FUNCTION: gattPsmSvcAlloc
 * USE:      L2C calls this with remote requests to open a PSM-based channel
 * PARAMS:   userData - unused
 *           handle - the connection handle
 *           instanceP - we store per-connection instance here
 * RETURN:   SVC_ALLOC_*
 * NOTES:    if allocate is called, we are being connected to. in that case go right to
 *           GATT_CONN_STATE_RUNNING state
 */
static uint8_t gattPsmSvcAlloc(void *userData, l2c_handle_t handle, void **instanceP)
{
    struct bt_addr peer;

    /* if we cannot get peer address, do not bother with anything else */
    if (!l2cApiGetBtAddr(handle, &peer))
        return SVC_ALLOC_FAIL_OTHER;

    /* we do not support PSM access to GATT over LE */
    if (BT_ADDR_IS_LE(peer))
        return SVC_ALLOC_FAIL_OTHER;

    return gattStateAlloc(handle, instanceP, &peer, GATT_CONN_STATE_RUNNING);
}

/*
 * FUNCTION: gattFixedChSvcAlloc
 * USE:      L2C calls this with requests to open a fixed channel
 * PARAMS:   userData - unused
 *           handle - the connection handle
 *           instanceP - we store per-connection instance here
 * RETURN:   SVC_ALLOC_*
 * NOTES:    if allocate is called, we are being connected to. in that case go right to
 *           GATT_CONN_STATE_RUNNING state
 */
static uint8_t gattFixedChSvcAlloc(void *userData, l2c_handle_t handle, void **instanceP)
{
    struct bt_addr peer;

    /* if we cannot get peer address, do not bother with anything else */
    if (!l2cApiGetBtAddr(handle, &peer))
        return SVC_ALLOC_FAIL_OTHER;

    /* we do not support FixedCh access to GATT over EDR */
    if (BT_ADDR_IS_EDR(peer))
        return SVC_ALLOC_FAIL_OTHER;

    return gattStateAlloc(handle, instanceP, &peer, GATT_CONN_STATE_RUNNING);
}

/*
 * FUNCTION: gattConnectionCreateOrLocate
 * USE:      Make a new gatt L2C connection or find an existing one
 * PARAMS:   to - whom to connect to
 * RETURN:   connection struct or NULL
 * NOTES:    call with mGattLock held
 */
static struct gattConnState* gattConnectionCreateOrLocate(const struct bt_addr *to)
{
    struct gattConnState *gattConn;
    bool connTrying;

    gattConn = gattConnFindByAddr(to);
    if (!gattConn) {

        if (gattStateAllocLocked(0, (void**)&gattConn, to, GATT_CONN_STATE_CONNECTING) != SVC_ALLOC_SUCCESS)
            logw("Failed to allocate a gatt connection instance for an outbound GATT connection to "ADDRFMT"\n", ADDRCONV(*to));
        else {

            if (BT_ADDR_IS_EDR(*to))
                connTrying = l2cApiCreatePsmConnection(GATT_PSM, to, L2C_MAX_SAFE_MTU, gattConnEvt, NULL, gattConn);
            else
                connTrying = l2cApiCreateFixedChConnection(GATT_FIXEDCH, to, gattConnEvt, NULL, gattConn);

            if (!connTrying) {
                logw("Failed to attempt to establish an outbound GATT connection to "ADDRFMT"\n", ADDRCONV(*to));
                gattConnStructDelete(gattConn);
                gattConn = NULL;
            }
        }
    }

    return gattConn;
}

/*
 * FUNCTION: gattClientConnect
 * USE:      Make a new gatt client connection
 * PARAMS:   to - whom to connect to
 *           resultCbk - will be called with results
 * RETURN:   connection id or 0 on failure
 * NOTES:    the callback might be called before this func returnes (talk
 *           to your scheduler about that). This leaves you with a conundrum:
 *           How will you know the callback is for you when you do not yet
*            know thw connection id. Caller solves this themselves. eg: take
 *           a mutex in callback, and also take it before calling this, do
 *           not release it till this func returns.
 */
gatt_client_conn_t gattClientConnect(const struct bt_addr *to, gattCliConnectResultCbk resultCbk)
{
    struct gattClientConnection *clicon;
    struct gattConnState *inst;
    gatt_client_conn_t ret = 0;

    clicon = calloc(1, sizeof(struct gattClientConnection));
    if (!clicon) {
        loge("Out of memory allocating a client connection for GATT\n");
        return 0;
    }

    pthread_mutex_lock(&mGattLock);
    inst = gattConnectionCreateOrLocate(to);
    if (!inst) {
        logw("Failed to create an outbound GATT connection. Client connection process will end\n");
        goto out;
    }

    clicon->next = mClientConns;
    if (mClientConns)
        mClientConns->prev = clicon;
    mClientConns = clicon;

    clicon->gattConnId = inst->gattConnId;
    clicon->connId = uniqGetNext();
    clicon->connCbk = resultCbk;

    // call callback right away?
    if (inst->state == GATT_CONN_STATE_RUNNING)
        gattEnqueueCliConnStatusCall(clicon, GATT_CLI_STATUS_OK);

    // success!
    ret = clicon->connId;
    pthread_mutex_unlock(&mGattLock);
    return ret;

out:
    pthread_mutex_unlock(&mGattLock);
    free(clicon);
    return 0;
}

/*
 * FUNCTION: gattClientDisconnect
 * USE:      Disconnect an actual gatt connection
 * PARAMS:   conn - the connection
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientDisconnect(gatt_client_conn_t conn)
{
    // TODO: can call gattClientConnClose(cliCon, false /* do not notify client -> no need they're about to go away awnyways */);
    return GATT_CLI_STATUS_OK;
}


/*
 * FUNCTION: gattWorkQueueFreeItem
 * USE:      Called to free a workQ item at workQ delete time
 * PARAMS:   item - the work item
 * RETURN:   NONE
 * NOTES:
 */
static void gattWorkQueueFreeItem(void *item)
{
    struct gattWorkItem *wi = (struct gattWorkItem*)item;

    gattWorkItemFree(wi);
}

/*
 * FUNCTION: gattSrvCbkReply
 * USE:      Called from higher layer as a reply to us calling for a read/write
 * PARAMS:   cid - conenction ID from ATT
 *           transId - transaction ID from ATT
 *           handle - handle on which an error occured (unused for read & write)
 *           err - ATT_ERROR_*
 *           data - the read data
 *           len - the read len
 * RETURN:   unused
 * NOTES:
 */
void gattSrvCbkReply(att_cid_t cid, att_trans_t transId, uint16_t handle, uint8_t err, const void *data, uint16_t len)
{
    attSrvCbkReply(cid, transId, handle, err, data, len);
}

/*
 * FUNCTION: gattCliTodoItemFree
 * USE:      Properly free a todo item for GATT
 * PARAMS:   todo - the todo item to free
 * RETURN:   NONE
 * NOTES:
 */
static void gattCliTodoItemFree(struct gattCliTodoItem *todo)
{
    if (todo->data) // data may be NULL if the item had aleady been processed
        sgFree(todo->data);
    free(todo);
}


/*
 * FUNCTION: gattSrvDoOneQueuedWrite
 * USE:      Perform a queued write as the server. Take locks as needed
 * PARAMS:   who - the L2C cnnection
 *           cid - the att connection id
 *           rangeRef - the ATT handle range
 *           handleOfst - the offset of the handle in that range
 *           transId - ATT transaction ID (for reply)
 *           data - the data
 * RETURN:   ATT_ERROR_*
 * NOTES:    called from gatt worker thread. take locks as needed
 */
static uint8_t gattSrvDoOneQueuedWrite(l2c_handle_t who, att_cid_t cid, att_range_t rangeRef, uint16_t handleOfst, att_trans_t transId, sg data)
{
    uint16_t handle = handleOfst + attSrvHandleRangeGetBase(rangeRef);
    uint32_t len = sgLength(data);
    uint8_t err = ATT_ERROR_NONE;
    struct gattService *svc;
    void *buf = NULL;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindByRangeRef(rangeRef);
    if (!svc) {
        logw("Failed to find service for queued write\n");
        err = ATT_ERROR_INVALID_HANDLE;
        goto out;
    }

    // we need to serialize the data here temporarily
    buf = malloc(len);
    if (!buf) {
        err = ATT_ERROR_INSUFFICIENT_RSRCS;
        goto out;
    }

    if (len != sgSerialize(data, 0, len, buf)) {
        err = ATT_ERROR_UNLIKELY_ERROR;
        goto out;
    }

    if (!svc->writeF(svc->svcRef, who, cid, transId, handle, 0, ATT_WRITE_FOR_PREPARE, len, buf)) {
        err = ATT_ERROR_UNLIKELY_ERROR;
        goto out;
    }

    //success? free data
    sgFree(data);

out:
    if (buf)
        free(buf);
    pthread_mutex_unlock(&mGattLock);
    return err;

}

/*
 * FUNCTION: gattSrvQueuedWritesPerformFromWorkerThread
 * USE:      Perform queued writes as the server. Take locks as needed. Send reply either way
 * PARAMS:   who - the L2C cnnection
 *           cid - the att connection id
 *           qw - writes currently queued that we need to execute
 *           transId - ATT transaction ID (for reply)
 * RETURN:   NONE
 * NOTES:    called from gatt worker thread. set "->data" to NULL if sg has been used or handed off
 */
static void gattSrvQueuedWritesPerformFromWorkerThread(l2c_handle_t who, att_cid_t cid, struct GattEnqueuedWrite *qw, att_trans_t transId)
{
    uint8_t err = ATT_ERROR_NONE;

    while (qw) {
        err = gattSrvDoOneQueuedWrite(who, cid, qw->rangeRef, qw->handleOfst, transId, qw->data);
        if (err != ATT_ERROR_NONE)
            break;

        qw->data = NULL;
        qw = qw->next;
    }

    //reply with err...
    attSrvCbkReply(cid, transId, qw ? qw->handleOfst + attSrvHandleRangeGetBase(qw->rangeRef) : 0, err, NULL, 0);
}

/*
 * FUNCTION: gattWorkItemFree
 * USE:      Properly free a work item for GATT
 * PARAMS:   wi - the work item to free
 * RETURN:   NONE
 * NOTES:
 */
static void gattWorkItemFree(struct gattWorkItem *wi)
{
    if (wi->type == GATT_WORK_CLI_DO_NEXT && wi->cliDoNext.todo)
        gattCliTodoItemFree(wi->cliDoNext.todo);
    else if (wi->type == GATT_WORK_CLI_IND_CALL && wi->cliIndCall.data)
        sgFree(wi->cliIndCall.data);
    else if (wi->type == GATT_WORK_SRV_WRITE_EXEC)
        gattQueuedWriteQueueFree(wi->srvWriteExec.q);

    free(wi);
}

/*
 * FUNCTION: gattWorker
 * USE:      Worker thread for calls to higher layer
 * PARAMS:   param - unused
 * RETURN:   unused
 * NOTES:
 */
static void* gattWorker(void *param)
{
    struct gattWorkItem *wi;
    int status;

    pthread_setname_np(pthread_self(), "gatt_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 GATT_WORK_SRV_READ_CALL:
            if (!wi->srvRwCall.readF(wi->srvRwCall.svcRef, wi->srvRwCall.who, wi->srvRwCall.cid, wi->srvRwCall.transId, wi->srvRwCall.handle, wi->srvRwCall.byteOfst, wi->srvRwCall.reason, wi->srvRwCall.len))
                gattSrvCbkReply(wi->srvRwCall.cid, wi->srvRwCall.transId, 0, ATT_ERROR_UNLIKELY_ERROR, NULL, 0);
            break;
        case GATT_WORK_SRV_WRITE_CALL:
            if (!wi->srvRwCall.writeF(wi->srvRwCall.svcRef, wi->srvRwCall.who, wi->srvRwCall.cid, wi->srvRwCall.transId, wi->srvRwCall.handle, wi->srvRwCall.byteOfst, wi->srvRwCall.reason, wi->srvRwCall.len, wi + 1))
                gattSrvCbkReply(wi->srvRwCall.cid, wi->srvRwCall.transId, 0, ATT_ERROR_UNLIKELY_ERROR, NULL, 0);
            break;
        case GATT_WORK_SRV_IND_CALL:
            wi->srvIndCall.indF(wi->srvIndCall.svcRef, wi->srvIndCall.who, wi->srvIndCall.cid, wi->srvIndCall.handle, wi->srvIndCall.evt, wi->srvIndCall.ref);
            break;
        case GATT_WORK_SRV_DISC_CALL:
            wi->srvDiscCall.discF(wi->srvDiscCall.svcRef, wi->srvDiscCall.who);
            break;
        case GATT_WORK_SRV_WRITE_EXEC:
            gattSrvQueuedWritesPerformFromWorkerThread(wi->srvWriteExec.who, wi->srvWriteExec.cid, wi->srvWriteExec.q, wi->srvWriteExec.transId);
            break;
        case GATT_WORK_CLI_CONN_STATE_NOTIF:
            wi->cliConnStateNotif.cbk(wi->cliConnStateNotif.connId, wi->cliConnStateNotif.status);
            break;
        case GATT_WORK_CLI_DO_NEXT:
            gattCliTodoNext(wi->cliDoNext.conn, wi->cliDoNext.todo);
            wi->cliDoNext.todo = NULL; // do not auto-free it
            break;
        case GATT_WORK_CLI_IND_CALL:
            wi->cliIndCall.cbk(wi->cliIndCall.conn, wi->cliIndCall.handle, wi->cliIndCall.ind, wi->cliIndCall.data);
            wi->cliIndCall.data = NULL; // do not auto-free it
            break;
        case GATT_WORK_CLI_SUB_UNSUB_CALL:
            wi->cliSubUnsubCall.cbk(wi->cliSubUnsubCall.conn, wi->cliSubUnsubCall.handle, wi->cliSubUnsubCall.forSub, wi->cliSubUnsubCall.stat);
            break;
        default:
            loge("Unknown work type %d\n", wi->type);
            break;
        }
        gattWorkItemFree(wi);
    }

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

/*
 * FUNCTION: gattAttCbkCheckState
 * USE:      Common code for all GATT ATT client callbacks. Some basic checks mostly
 * PARAMS:   trans - transaction id (or 0 if none)
 *           to - peer's connection handle
 *           expectedWorkItemTypes - list of acceptable work item types (NULL if we have no expectations)
 *           numExpTypes - size of the above list
 *           cbkName - name (used for message printing only)
 * RETURN:   gattConnState if all is OK, NULL else
 * NOTES:    call with mGattLock held
 */
static struct gattConnState* gattAttCbkCheckState(uniq_t trans, l2c_handle_t to, const uint8_t *expectedWorkItemTypes, unsigned numExpTypes, const char* cbkName)
{
    struct gattConnState *conn;
    unsigned i;

    conn = gattConnFindByL2cConn(to);
    if (!conn)
        logw("%s callback on a nonexistent connection\n", cbkName);
    else if (!conn->todoCurr)
        logw("%s callback with no todo item\n", cbkName);
    else {
        if (!numExpTypes)
            return conn;
        for (i = 0; i < numExpTypes; i++)
            if (*expectedWorkItemTypes++ == conn->todoCurr->type)
                return conn;
        logw("%s callback with wrong work type (%u)\n", cbkName, conn->todoCurr->type);
    }

    return NULL;
}

/*
 * FUNCTION: gattAttCliFindInfoCbk
 * USE:      Called by ATT as a reply to our Find request, if results were provided
 * PARAMS:   trans - transaction id
 *           to - peer's connection handle
 *           handle - the handle that was found
 *           uuid - the uuid that was found
 *           haveMore - will there be more calls to this func from the same ATT reply packet?
 * RETURN:   false to receive no more callbacks
 * NOTES:
 */
static bool gattAttCliFindInfoCbk(uniq_t trans, l2c_handle_t to, uint16_t handle, const struct uuid *uuid, bool haveMore)
{
    static const uint8_t expectedWorkTypes[] = {GATT_CLI_TODO_FIND_INFO};
    bool killItem = true, ret = false;
    struct gattConnState *conn;

    pthread_mutex_lock(&mGattLock);
    conn = gattAttCbkCheckState(trans, to, expectedWorkTypes, sizeof(expectedWorkTypes), "Read");
    if (conn) {
        struct gattCliTodoItem *todo = conn->todoCurr;
        bool done = false;

        switch (conn->todoCurr->purpose) {
        case GATT_INTENT_ENUM_CHAR_DESCRS:
            conn->doNotFreeTodoCurr = true;
            pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
            todo->enumCharDscrsCbk(todo->connId, todo->clientTrans, uuid, handle, GATT_CLI_STATUS_OK);
            // if this is the end - signal that now
            if (handle == todo->endHandle) {
                todo->enumCharDscrsCbk(todo->connId, todo->clientTrans, NULL, 0, GATT_CLI_STATUS_OK);
                done = true;
            }
            pthread_mutex_lock(&mGattLock);
            conn = gattConnFindByL2cConn(to);
            if (conn)
                conn->doNotFreeTodoCurr = false;
            else {
                gattCliTodoItemFree(todo);
                logd("Connection went away while processing\n");
            }
            if (conn && !done) {
                ret = true;
                killItem = false;
                todo->handle = handle + 1;
                if (!haveMore)
                    gattCliTodoEnqItem(conn, todo, false);
            }
            break;

        default:
            loge("Unknown reason for getting a find result\n");
            break;
        }

        if (conn) {
            if (!ret || !haveMore) { // either way we expect no more calls from ATT about this item
                conn->todoCurr = NULL;
                if (killItem)
                    gattCliTodoItemFree(todo);
            }
            else if (killItem)
                loge("Cannot kill todo item if we expect more callbacks on it!\n");
            gattEnqueueCliDoNextTodoItem(conn);
        }
    }

    pthread_mutex_unlock(&mGattLock);
    return ret;
}

/*
 * FUNCTION: gattAttCliFindByTypeValCbk
 * USE:      Called by ATT as a reply to our FindByTypeValue request, if results were provided
 * PARAMS:   trans - transaction id
 *           to - peer's connection handle
 *           handle - the handle that was found
 *           grpEndHandle - group end handle that was found
 *           haveMore - will there be more calls to this func from the same ATT reply packet?
 * RETURN:   false to receive no more callbacks
 * NOTES:
 */
static bool gattAttCliFindByTypeValCbk(uniq_t trans, l2c_handle_t to, uint16_t handle, uint16_t grpEndHandle, bool haveMore)
{
    static const uint8_t expectedWorkTypes[] = {GATT_CLI_TODO_FIND_BY_TYPE_VAL};
    bool killItem = true, ret = false;
    struct uuid tempUuid;
    struct gattConnState *conn;

    pthread_mutex_lock(&mGattLock);
    conn = gattAttCbkCheckState(trans, to, expectedWorkTypes, sizeof(expectedWorkTypes), "FindByTypeVal");
    if (conn) {
        struct gattCliTodoItem *todo = conn->todoCurr;

        switch (conn->todoCurr->purpose) {
        case GATT_INTENT_FIND_SVC:
            uuidFromUuid16(&tempUuid, GATT_UUID_SVC_PRIMARY);
            conn->doNotFreeTodoCurr = true;
            pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
            todo->enumSvcsCbk(todo->connId, todo->clientTrans, &todo->desiredUuid, uuidCmp(&tempUuid, &todo->uuid), handle, grpEndHandle - handle + 1, GATT_CLI_STATUS_OK);
            pthread_mutex_lock(&mGattLock);
            conn = gattConnFindByL2cConn(to);
            if (conn)
                conn->doNotFreeTodoCurr = false;
            else {
                gattCliTodoItemFree(todo);
                logd("Connection went away while processing\n");
            }
            ret = true;
            killItem = false;
            break;
        default:
            loge("Unknown reason for getting a find result\n");
            break;
        }

        if (conn) {
            if (!ret || !haveMore) { // either way we expect no more calls from ATT about this item
                conn->todoCurr = NULL;
                if (killItem)
                    gattCliTodoItemFree(todo);
            }
            else if (killItem)
                loge("Cannot kill todo item if we expect more callbacks on it!\n");
            gattEnqueueCliDoNextTodoItem(conn);
        }
    }

    pthread_mutex_unlock(&mGattLock);
    return ret;
}

/*
 * FUNCTION: gattAttCliReadCbk
 * USE:      Called by ATT as a reply to our Read/ReadBlob/ReadByType/ReadByGroupType request, if results were provided
 * PARAMS:   trans - transaction id
 *           to - peer's connection handle
 *           handleP - points to the handle that was found or NULL if none provided for this type of read frequest
 *           endGrpHandleP - points to the group end handle that was found or NULL if none provided for this type of read frequest
 *           data - the data that was read
 *           haveMore - will there be more calls to this func from the same ATT reply packet?
 * RETURN:   false to receive no more callbacks
 * NOTES:
 */
static bool gattAttCliReadCbk(uniq_t trans, l2c_handle_t to, const uint16_t *handleP, const uint16_t *endGrpHandleP, sg data, bool haveMore)
{
    static const uint8_t expectedWorkTypes[] = {GATT_CLI_TODO_READ_BY_TYPE, GATT_CLI_TODO_READ, GATT_CLI_TODO_READ_BLOB, GATT_CLI_TODO_READ_BY_GRP_TYPE};
    bool killItem = true, ret = false;
    struct gattIncludeDefHdr inclDef;
    struct gattCharDefHdr charDef;
    struct uuid uuid, tempUuid;
    struct gattConnState *conn;
    uint16_t tmpHandle;
    bool done = false;


    pthread_mutex_lock(&mGattLock);
    conn = gattAttCbkCheckState(trans, to, expectedWorkTypes, sizeof(expectedWorkTypes), "Read");
    if (conn) {
        struct gattCliTodoItem *todo = conn->todoCurr;

        switch (todo->purpose) {
        case GATT_INTENT_ENUM_SVCS:
            ret = attReadUuid(&uuid, data);
            sgFree(data);
            if (!ret) {
                logw("Read for enum services did not produce a uuid\n");
                break;
            }
            uuidFromUuid16(&tempUuid, GATT_UUID_SVC_PRIMARY);
            conn->doNotFreeTodoCurr = true;
            pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
            todo->enumSvcsCbk(todo->connId, todo->clientTrans, &uuid, uuidCmp(&tempUuid, &todo->uuid), *handleP, *endGrpHandleP - *handleP + 1, GATT_CLI_STATUS_OK);
            // if this is the end - signal that now
            if (*endGrpHandleP == ATT_LAST_VALID_HANDLE) {
                todo->enumSvcsCbk(todo->connId, todo->clientTrans, NULL, uuidCmp(&tempUuid, &todo->uuid), 0, 0, GATT_CLI_STATUS_OK);
                done = true;
            }
            pthread_mutex_lock(&mGattLock);
            conn = gattConnFindByL2cConn(to);
            if (conn)
                conn->doNotFreeTodoCurr = false;
            else {
                gattCliTodoItemFree(todo);
                logd("Connection went away while processing\n");
            }
            if (conn && !done) {
                ret = true;
                killItem = false;
                todo->handle = *endGrpHandleP + 1;
                if (!haveMore)
                    gattCliTodoEnqItem(conn, todo, false);
            }
            break;

        case GATT_INTENT_ENUM_CHARS:
            if (!sgSerializeCutFront(data, &charDef, sizeof(charDef)))
                logw("Invalid char def\n");
            else if (!attReadUuid(&uuid, data))
                logw("Char definition does not end in a uuid\n");
            else {
                tmpHandle = utilGetLE16(&charDef.valHandle);
                logd("Found char @ 0x%04x with props 0x%02x & val @ 0x%04x: "UUIDFMT"\n", *handleP, utilGetLE8(&charDef.charProps), tmpHandle, UUIDCONV(uuid));

                conn->doNotFreeTodoCurr = true;
                pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
                todo->enumCharsCbk(todo->connId, todo->clientTrans, &uuid, *handleP, tmpHandle, utilGetLE8(&charDef.charProps), GATT_CLI_STATUS_OK);
                // if this is the end - signal that now
                if (tmpHandle >= todo->endHandle) {
                    todo->enumCharsCbk(todo->connId, todo->clientTrans, NULL, 0, 0, 0, GATT_CLI_STATUS_OK);
                    done = true;
                }
                pthread_mutex_lock(&mGattLock);
                conn = gattConnFindByL2cConn(to);
                if (conn)
                    conn->doNotFreeTodoCurr = false;
                else {
                    gattCliTodoItemFree(todo);
                    logd("Connection went away while processing\n");
                }
                if (conn && !done) {
                    ret = true;
                    killItem = false;
                    todo->handle = tmpHandle + 1;
                    if (!haveMore)
                        gattCliTodoEnqItem(conn, todo, false);
                }
            }
            sgFree(data);
            break;

        case GATT_INTENT_ENUM_INCL_SVCS:
            if (todo->type == GATT_CLI_TODO_READ_BY_TYPE) { // an include definition
                if (!sgSerializeCutFront(data, &inclDef, sizeof(inclDef)))
                    logw("Invalid include def\n");
                else if (sgLength(data) == sizeof(uint16_t)) { // have uuid16 - report it
                    attReadUuid(&uuid, data);

                    // call up to report found include
                    conn->doNotFreeTodoCurr = true;
                    pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
                    todo->enumIncludedSvcsCbk(todo->connId, todo->clientTrans, &uuid, *handleP, utilGetLE16(&inclDef.startHandle), utilGetLE16(&inclDef.endHandle), GATT_CLI_STATUS_OK);
                    // if this is the end - signal that now
                    if (*handleP >= todo->endHandle) {
                        done = true;
                        todo->enumIncludedSvcsCbk(todo->connId, todo->clientTrans, NULL, 0, 0, 0, GATT_CLI_STATUS_OK);
                    }
                    pthread_mutex_lock(&mGattLock);
                    conn = gattConnFindByL2cConn(to);
                    if (conn)
                        conn->doNotFreeTodoCurr = false;
                    else {
                        gattCliTodoItemFree(todo);
                        logd("Connection went away while processing\n");
                    }

                    if (conn && !done) {
                        ret = true;
                        killItem = false;
                        todo->handle = *handleP + 1;
                        if (!haveMore)
                            gattCliTodoEnqItem(conn, todo, false);
                    }
                }
                else if (sgLength(data))
                    logw("Invalid include def (uuid area)\n");
                else { // do not have uuit16 - read the uuid128 directly
                    todo->auxHandle[0] = *handleP; // save our iteration location
                    todo->auxHandle[1] = utilGetLE16(&inclDef.endHandle); // save group end location
                    todo->handle = utilGetLE16(&inclDef.startHandle);
                    todo->type = GATT_CLI_TODO_READ;
                    gattCliTodoEnqItem(conn, todo, false);
                    killItem = false;
                    // keep ret as false - we can only do one of these at a time
                }
            }
            else if (todo->type == GATT_CLI_TODO_READ) { // a service definition (to get a 128-bit uuid)
                if (!attReadUuid(&uuid, data))
                    logw("Cannot read the provided service definition uuid\n");
                else {
                    // call up to report now that we have all the info
                    conn->doNotFreeTodoCurr = true;
                    pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
                    todo->enumIncludedSvcsCbk(todo->connId, todo->clientTrans, &uuid, todo->auxHandle[0], todo->handle, todo->auxHandle[1], GATT_CLI_STATUS_OK);
                    // if this is the end - signal that now
                    if (todo->auxHandle[0] >= todo->endHandle) {
                        done = true;
                        todo->enumIncludedSvcsCbk(todo->connId, todo->clientTrans, NULL, 0, 0, 0, GATT_CLI_STATUS_OK);
                    }
                    pthread_mutex_lock(&mGattLock);
                    conn = gattConnFindByL2cConn(to);
                    if (conn)
                        conn->doNotFreeTodoCurr = false;
                    else {
                        gattCliTodoItemFree(todo);
                        logd("Connection went away while processing\n");
                    }

                    if (conn && !done) {
                        // resume our initial inquiry from where we left off
                        todo->handle = todo->auxHandle[0] + 1;
                        todo->type = GATT_CLI_TODO_READ_BY_TYPE;
                        ret = true;
                        killItem = false;
                        gattCliTodoEnqItem(conn, todo, false);
                    }
                }
            }
            sgFree(data);
            break;

        case GATT_INTENT_READ:
            pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
            todo->readCbk(todo->connId, todo->clientTrans, todo->handle, GATT_CLI_STATUS_OK, data);
            pthread_mutex_lock(&mGattLock);
            conn = gattConnFindByL2cConn(to);
            break;

        default:
            loge("Unknown reason for getting a read result. purpose = %u\n", todo->purpose);
            break;
        }

        if (conn) {
            if (!ret || !haveMore) { // either way we expect no more calls from ATT about this item
                conn->todoCurr = NULL;
                if (killItem)
                    gattCliTodoItemFree(todo);
            }
            else if (killItem)
                loge("Cannot kill todo item if we expect more callbacks on it!\n");
            gattEnqueueCliDoNextTodoItem(conn);
        }
    }

    pthread_mutex_unlock(&mGattLock);
    return ret;
}

/*
 * FUNCTION: gattAttCliWriteCbk
 * USE:      Called by ATT as a reply to our Write requests/commands and PrepareWrite
 * PARAMS:   trans - transaction id
 *           to - peer's connection handle
 * RETURN:   NONE
 * NOTES:    data from PrepareWrite reply is not provided.
 */
static void gattAttCliWriteCbk(uniq_t trans, l2c_handle_t to)
{
    static const uint8_t expectedWorkTypes[] = {GATT_CLI_TODO_WRITE, GATT_CLI_TODO_PREPARE_WRITE, GATT_CLI_TODO_WRITE_EXEC, GATT_CLI_TODO_WRITE_CCCD};
    struct gattClientConnection *clicon;
    struct gattConnState *conn;
    struct gattCliNotif *notif;
    bool somethingDone;

    pthread_mutex_lock(&mGattLock);
    conn = gattAttCbkCheckState(trans, to, expectedWorkTypes, sizeof(expectedWorkTypes), "Write");
    if (conn) {
        struct gattCliTodoItem *todo = conn->todoCurr;

        switch (todo->purpose) {
        case GATT_INTENT_NOTIF_SUB_UNSUB:
            notif = gattNotifFindByLocatorInConn(conn, todo->notifLocator);
            if (!notif)
                break;

            // update the notif rec's state
            switch (todo->offset) {
            default:
                logw("Weird unknown value written by us to CCCD: 0x%04x\n", todo->offset);
                // fallthrough
            case 0:
                notif->curState = NOTIF_C_STATE_NOT_SUBBED;
                break;
            case GATT_CLI_CFG_BIT_NOTIFS:
                notif->curState = NOTIF_C_STATE_SUBBED_TO_NOTIF;
                break;
            case GATT_CLI_CFG_BIT_INDS:
                notif->curState = NOTIF_C_STATE_SUBBED_TO_IND;
                break;
            }

            // tell everyone who needs to know - first iterate all client connections
            do {

                somethingDone = false;
                for (clicon = mClientConns; clicon && !somethingDone; clicon = clicon->next) {
                    struct gattCliNotifRec *nr;

                    // for each, iterate the notifications/indications requested
                    for (nr = clicon->notifs; nr; nr = nr->next) {

                        // for those applicable to this CCCD write, and in proper state, and not yet told we are subscribed, tell them
                        if (nr->notif == notif && !nr->subCallMade && ((nr->wantInd && notif->curState == NOTIF_C_STATE_SUBBED_TO_IND) || (notif->curState == NOTIF_C_STATE_SUBBED_TO_NOTIF))) {

                            gattCliNotifSubscribeStateCbk stateCbk = nr->stateCbk;

                            nr->subCallMade = true;
                            conn->doNotFreeTodoCurr = true;
                            pthread_mutex_unlock(&mGattLock);
                            stateCbk(clicon->connId, todo->auxHandle[0], true, GATT_CLI_STATUS_OK);
                            pthread_mutex_lock(&mGattLock);
                            conn->doNotFreeTodoCurr = false;
                            somethingDone = true;
                            conn = gattConnFindByL2cConn(to);
                            break;
                        }
                    }
                }
            } while (conn && somethingDone);
            break;

        default:
            loge("Unknown reason for getting a write result\n");
            break;
        }

        if (conn) {
            conn->todoCurr = NULL;
            gattCliTodoItemFree(todo);
            gattEnqueueCliDoNextTodoItem(conn);
        }
    }

    pthread_mutex_unlock(&mGattLock);
}

/*
 * FUNCTION: gattAttCliError
 * USE:      Called by ATT as a result of an error occuring
 * PARAMS:   trans - transaction id
 *           to - peer's connection handle
 *           handleP - points to the handle from the error message or NULL on local stack errors
 *           errP - points to the errno from the error message or NULL on local stack errors
 *           errOpcodeP - points to the error opcode from the error message or NULL on local stack errors
 * RETURN:   NONE
 * NOTES:
 */
static void gattAttCliError(uniq_t trans, l2c_handle_t to, const uint16_t *handleP, const uint8_t *errP, const uint8_t *errOpcodeP)
{
    static const uint8_t expectedWorkTypes[] = {GATT_CLI_TODO_FIND_INFO, GATT_CLI_TODO_FIND_BY_TYPE_VAL, GATT_CLI_TODO_READ_BY_TYPE, GATT_CLI_TODO_READ, GATT_CLI_TODO_READ_BLOB,
                                                GATT_CLI_TODO_READ_BY_GRP_TYPE, GATT_CLI_TODO_WRITE, GATT_CLI_TODO_PREPARE_WRITE, GATT_CLI_TODO_WRITE_EXEC, GATT_CLI_TODO_WRITE_CCCD};
    struct gattConnState *conn;
    bool handled = false;
    struct uuid tempUuid;

    logd("att signalled error on handle 0x%04x of type 0x%02x from opcode 0x%02x\n", handleP ? *handleP : -1, errP ? *errP : -1, errOpcodeP ? *errOpcodeP : -1);

    pthread_mutex_lock(&mGattLock);
    conn = gattAttCbkCheckState(trans, to, expectedWorkTypes, sizeof(expectedWorkTypes), "Error");
    if (conn) {
        struct gattCliTodoItem *todo = conn->todoCurr;
        conn->todoCurr = NULL;

        switch (todo->purpose) {
        case GATT_INTENT_ENUM_SVCS:
            if (*errP == ATT_ERROR_ATTRIBUTE_NOT_FOUND ) { // end of enum (we could check handle, but even spec is conflicted on what it should be, so we do not)
                uuidFromUuid16(&tempUuid, GATT_UUID_SVC_PRIMARY);
                pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
                todo->enumSvcsCbk(todo->connId, todo->clientTrans, NULL, uuidCmp(&tempUuid, &todo->uuid), 0, 0, GATT_CLI_STATUS_OK);
                pthread_mutex_lock(&mGattLock);
                conn = gattConnFindByL2cConn(to);
                if (!conn)
                    logd("Connection went away while processing\n");
                handled = true;
            }
            break;

        case GATT_INTENT_ENUM_INCL_SVCS:
            if (*errP == ATT_ERROR_ATTRIBUTE_NOT_FOUND) { // end of enum (we could check handle, but even spec is conflicted on what it should be, so we do not)
                pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
                todo->enumIncludedSvcsCbk(todo->connId, todo->clientTrans, NULL, 0, 0, 0, GATT_CLI_STATUS_OK);
                pthread_mutex_lock(&mGattLock);
                conn = gattConnFindByL2cConn(to);
                if (!conn)
                    logd("Connection went away while processing\n");
                handled = true;
            }
            break;

        case GATT_INTENT_ENUM_CHARS:
            if (*errP == ATT_ERROR_ATTRIBUTE_NOT_FOUND) { // end of enum (we could check handle, but even spec is conflicted on what it should be, so we do not)
                pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
                todo->enumCharsCbk(todo->connId, todo->clientTrans, NULL, 0, 0, 0, GATT_CLI_STATUS_OK);
                pthread_mutex_lock(&mGattLock);
                conn = gattConnFindByL2cConn(to);
                if (!conn)
                    logd("Connection went away while processing\n");
                handled = true;
            }
            break;

        case GATT_INTENT_ENUM_CHAR_DESCRS:
            if (*errP == ATT_ERROR_ATTRIBUTE_NOT_FOUND) { // end of enum (we could check handle, but even spec is conflicted on what it should be, so we do not)
                pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
                todo->enumCharDscrsCbk(todo->connId, todo->clientTrans, NULL, 0, GATT_CLI_STATUS_OK);
                pthread_mutex_lock(&mGattLock);
                conn = gattConnFindByL2cConn(to);
                if (!conn)
                    logd("Connection went away while processing\n");
                handled = true;
            }
            break;

        case GATT_INTENT_READ:
            pthread_mutex_unlock(&mGattLock); // see "A NOTE ABOUT LOCKS" above
            // "invalid offset" or "not long" are not error, just EOFs, so we treat them as not errors.
            todo->readCbk(todo->connId, todo->clientTrans, todo->handle, (*errP == ATT_ERROR_ATTRIBUTE_NOT_LONG || *errP == ATT_ERROR_INVALID_OFFSET) ? GATT_CLI_STATUS_OK : GATT_CLI_STATUS_ERR, NULL);
            pthread_mutex_lock(&mGattLock);
            conn = gattConnFindByL2cConn(to);
            break;

        default:
            loge("Unknown reason for getting a error result\n");
            break;
        }

        if (!handled)
            logw("Unhandled ATT error. Who knows what this might cause?\n");

        gattCliTodoItemFree(todo);

        if (conn)
            gattEnqueueCliDoNextTodoItem(conn);
    }
    pthread_mutex_unlock(&mGattLock);
}

/*
 * FUNCTION: gattAttCliIndNotif
 * USE:      Called by ATT as a result of getting a notification or indication
 * PARAMS:   to - peer's connection handle
 *           needsAck - set for indications
 *           handle - the handle value that changed
 *           data - the data that was sent by the server
 * RETURN:   NONE
 * NOTES:
 */
static void gattAttCliIndNotif(l2c_handle_t to, bool needsAck, uint16_t handle, sg data)
{
    struct gattConnState *conn;

    pthread_mutex_lock(&mGattLock);
    conn = gattConnFindByL2cConn(to);
    if (!conn)
        logw("Notif callback on a nonexistent connection\n");
    else {
        struct gattCliNotif *n;

        /* find the per-connection notif structure */
        for (n = conn->cliNotifs; n && n->charValueHandle != handle; n = n->next);
        if (!n)
            logw("Got notif/ind which we have no record of\n");
        else {

            struct gattClientConnection *clicon;
            struct gattCliNotifRec *nr;
            sg dataCopy;

            /* find all clients who are subscribed and notify them */
            for (clicon = mClientConns; clicon; clicon = clicon->next) {
                /* skip all clients not connected to this connection */
                if (clicon->gattConnId != conn->gattConnId)
                    continue;

                /* skip all clients who are not subscribed to this notif */
                for (nr = clicon->notifs; nr && nr->notif != n; nr = nr->next);
                if (!nr)
                    continue;

                /* now we have a client who cares, tell them about this glorious event */
                dataCopy = sgDup(data);
                if (!dataCopy)
                    logw("Failed to copy data for ind/notif\n");
                else if (!gattEnqueueCliIndCall(clicon, nr, dataCopy)) {
                    logw("Failed to schedule a call for notif/ind\n");
                    sgFree(dataCopy);
                }
            }

        }
    }

    pthread_mutex_unlock(&mGattLock);

    sgFree(data);

    /* since multiple (or no) clients may be subscribedat this very moment, we generate the ACK ourselves */
    if (needsAck)
        attCliSendIndicationAck(to);
}

/*
 * FUNCTION: gattProfileInit
 * USE:      Initialize GATT
 * PARAMS:   NONE
 * RETURN:   success
 * NOTES:
 */
bool gattProfileInit(void)
{
    static const struct l2cServicePsmDescriptor gattPsm = {
        .serviceInstanceAlloc = gattPsmSvcAlloc,
        .serviceInstanceStateCbk = gattConnEvt,
        .mtu = L2C_MAX_SAFE_MTU,
    };
    static const struct l2cServiceFixedChDescriptor gattFixedCh = {
        .serviceFixedChAlloc = gattFixedChSvcAlloc,
        .serviceFixedChStateCbk = gattConnEvt,
    };

    attSrvInit(gattAttSrvTxCbk, gattAttSrvMtuCbk, gattAttSrvIndCbk, gattAttExecWriteCbk, gattAttSvrReadCbk, gattAttSvrWriteCbk);
    attCliInit(gattAttCliMtuCbk, gattAttCliFindInfoCbk, gattAttCliFindByTypeValCbk, gattAttCliReadCbk, gattAttCliWriteCbk, gattAttCliError, gattAttCliIndNotif);

    mWorkQ = workQueueAlloc(GATT_WORK_Q_SIZE);
    if (!mWorkQ) {
        loge("Failed create a workQ\n");
        goto out_workq;
    }

    if (pthread_create(&mWorker, NULL, gattWorker, NULL)) {
        loge("Failed create worker\n");
        goto out_thread;
    }

    mSendQ = sendQueueAlloc(8);
    if (!mSendQ) {
        loge("Failed create a sendQ\n");
        goto out_sendq;
    }

    if (!l2cApiServicePsmRegister(GATT_PSM, &gattPsm)) {
        loge("Failed to register GATT PSM\n");
        goto out_psm;
    }

    if (!l2cApiServiceFixedChRegister(GATT_FIXEDCH, &gattFixedCh)) {
        loge("Failed to register GATT FixedCh\n");
        goto out_fixed;
    }


    return true;


out_fixed:
    l2cApiServicePsmUnregister(GATT_PSM, NULL, 0);

out_psm:
    sendQueueFree(mSendQ);

out_sendq:
    workQueueWakeAll(mWorkQ, 1);
    pthread_join(mWorker, NULL);

out_thread:
    workQueueFree(mWorkQ, gattWorkQueueFreeItem);

out_workq:
    attSrvDeinit();
    attCliDeinit();

    return false;
}

/*
 * FUNCTION: gattProfileDeinit
 * USE:      Deinitialize GATT
 * PARAMS:   NONE
 * RETURN:   NONE
 * NOTES:
 */
void gattProfileDeinit(void)
{
    l2cApiServiceFixedChUnregister(GATT_FIXEDCH, NULL, 0);
    l2cApiServicePsmUnregister(GATT_PSM, NULL, 0);
    attSrvDeinit();
    workQueueWakeAll(mWorkQ, 1);
    pthread_join(mWorker, NULL);
    workQueueFree(mWorkQ, gattWorkQueueFreeItem);
    sendQueueFree(mSendQ);
}

/*
 * FUNCTION: gattServiceCreate
 * USE:      Create a public-facing GATT service
 * PARAMS:   uuid - the uuid to use
 *           primary - primary or secondary service?
 *           numHandles - how many handles we expect this service to occupy
 *           readF - read callback for the values
 *           writeF - write callback for the values
 *           indF - callback to be notified of confirmations of indications
 *           discF - callback to be notified of disconnects
 * RETURN:   service reference or 0 on error
 * NOTES:
 */
gatt_service_t gattServiceCreate(const struct uuid *uuid, bool primary, uint16_t numHandles, gattSrvValueReadCbk readF, gattSrvValueWriteCbk writeF, gattSrvIndCbk indF, gattSrvDisconnectCbk discF)
{
    struct gattService *svc;
    gatt_service_t svcRef = 0;

    if (numHandles < GATT_HDR_HANDLES) {
        loge("Service with %u handles is impossible (%u min)\n", numHandles, GATT_HDR_HANDLES);
        return 0;
    }

    pthread_mutex_lock(&mGattLock);
    if (gattServiceFindByUuid(uuid)) {
        loge("Service ("UUIDFMT") already exists!\n", UUIDCONV(*uuid));
        goto out;
    }
    svc = (struct gattService*)calloc(1, sizeof(struct gattService));
    if (!svc)
        goto out;

    /* get a handle */
    svc->svcRef = uniqGetNext();

    /* grab a range */
    svc->attRange = attSrvHandleRangeReserve(numHandles);
    if (!svc->attRange) {
        loge("Failed to reserve %u-handle range\n", numHandles);
        goto out_att;
    }

    memcpy(&svc->uuid, uuid, sizeof(svc->uuid));
    svc->readF = readF;
    svc->writeF = writeF;
    svc->indF = indF;
    svc->discF = discF;

    svc->maxItems = numHandles;
    svc->primary = primary;
    svcRef = svc->svcRef;

    svc->next = mSvcs;
    if (mSvcs)
        mSvcs->prev = svc;
    mSvcs = svc;

    goto out;

out_att:
    free(svc);

out:
    pthread_mutex_unlock(&mGattLock);
    return svcRef;
}

/*
 * FUNCTION: gattPermToAttPerm
 * USE:      Convert our 32-bit permissions mask to something we can pass to att with its simple 2-flag setup
 * PARAMS:   gattPerms - bitmask of GATT_PERM_*
 * RETURN:   bitmask of ATT_PERM_*
 * NOTES:
 */
static uint8_t gattPermToAttPerm(uint32_t gattPerms)
{
    uint8_t ret = 0;

    if (gattPerms & GATT_PERM_READ)
        ret |= ATT_PERM_READ;
    if (gattPerms & GATT_PERM_READ_ENCR)
        ret |= ATT_PERM_READ_ENCR;
    if (gattPerms & GATT_PERM_READ_ENCR_MITM)
        ret |= ATT_PERM_READ_ENCR_MITM;
    if (gattPerms & GATT_PERM_WRITE)
        ret |= ATT_PERM_WRITE;
    if (gattPerms & GATT_PERM_WRITE_ENCR)
        ret |= ATT_PERM_WRITE_ENCR;
    if (gattPerms & GATT_PERM_WRITE_ENCR_MITM)
        ret |= ATT_PERM_WRITE_ENCR_MITM;
    if (gattPerms & (GATT_PERM_WRITE_SIGNED | GATT_PERM_WRITE_SIGNED_MITM))
        ret |= ATT_PERM_WRITE_SIGNED;

    return ret;
}

/*
 * FUNCTION: gattServiceOnline
 * USE:      Online a service
 * PARAMS:   svc - the service struct
 *           supportLE - does this service support LE
 *           supportEDR - does this service support EDR
 * RETURN:   success
 * NOTES:    call with mGattLock held
 */
static bool gattServiceOnline(struct gattService *svc, bool supportLE, bool supportEDR)
{
    static const uint8_t attAllReadPerms = ATT_PERM_READ | ATT_PERM_READ_ENCR | ATT_PERM_READ_ENCR_MITM;
    uint16_t ofst = 0, charOfst = 0;
    struct gattItem *gi;
    struct uuid uuid;
    uint8_t perms = 0;

    if (svc->online) {
        logw("Cannot online an online service\n");
        goto out;
    }

    svc->allowLE = supportLE;
    svc->allowEDR = supportEDR;
    if (!aapiSrvHandleRangeSetAllowedTransports(svc->attRange, supportLE, supportEDR)) {
        logw("Failed to set ATT transport perms\n");
        goto out;
    }

    uuidFromUuid16(&uuid, svc->primary ? GATT_UUID_SVC_PRIMARY : GATT_UUID_SVC_SECONDARY);
    if (!attSrvValueRegister(svc->attRange, ofst++, &uuid, attAllReadPerms)) {
        loge("Failed to add service header\n");
        goto out;
    }

    gi = svc->itemsHead;
    while (gi) {
        bool updateGrp = false;

        switch (gi->type) {
        case GATT_ITEM_TYPE_INCLUDE:
            uuidFromUuid16(&uuid, GATT_UUID_INCLUDE);
            perms = attAllReadPerms;
            break;
        case GATT_ITEM_TYPE_CHAR_DECL:
            uuidFromUuid16(&uuid, GATT_UUID_CHARACTERISTIC);
            perms = attAllReadPerms;
            charOfst = ofst;
            break;
        case GATT_ITEM_TYPE_CHAR_VAL:
            if (gi->prev && gi->prev->type == GATT_ITEM_TYPE_CHAR_DECL)
                memcpy(&uuid, &gi->prev->charDecl.uuid, sizeof(uuid));
            else {
                loge("Char value not following a char descr\n");
                goto out_dereg;
            }
            perms = gattPermToAttPerm(gi->charVal.valPerms);
            updateGrp = true;
            break;
        case GATT_ITEM_TYPE_CHAR_DESCR:
            memcpy(&uuid, &gi->descriptor.uuid, sizeof(uuid));
            perms = gattPermToAttPerm(gi->descriptor.descrValPerms);
            updateGrp = true;
            break;
        default:
            loge("Unknown item type %u\n", gi->type);
            goto out_dereg;
        }

        if (!attSrvValueRegister(svc->attRange, ofst, &uuid, perms)) {
            loge("Failed to item at offset %u\n", ofst - 1);
            goto out_dereg;
        }
        ofst++;
        if (updateGrp && !attSrvValueSetGrpLen(svc->attRange, charOfst, ofst - charOfst)) {
            loge("Failed to set group length for characteristic\n");
            goto out_dereg;
        }
        gi = gi->next;
    }

    if (!attSrvValueSetGrpLen(svc->attRange, 0, ofst)) {
        loge("Failed to set group length for service\n");
        goto out_dereg;
    }

    svc->online = true;
    return true;

out_dereg:
    while (ofst)
        attSrvValueUnregister(svc->attRange, --ofst);

out:
    return false;
}

/*
 * FUNCTION: gattServiceOffline
 * USE:      Offline a service
 * PARAMS:   svc - the service struct
 * RETURN:   NONE
 * NOTES:    call with mGattLock held
 */
static void gattServiceOffline(struct gattService *svc)
{
    uint16_t i;

    if (!svc->online) {
        loge("Cannot offline an offlined service\n");
        return;
    }
    svc->online = false;

    for (i = 0; i < svc->numItems; i++)
        if (!attSrvValueUnregister(svc->attRange, i + GATT_HDR_HANDLES))
            logw("Failed to unregister a value (ofst %u) for offlining!\n", i + GATT_HDR_HANDLES);

    if (!attSrvValueUnregister(svc->attRange, 0))
        logw("Failed to unregister a header value for offlining!\n");
}

/*
 * FUNCTION: gattServiceDelete
 * USE:      Delete a service
 * PARAMS:   svc - the service struct
 * RETURN:   NONE
 * NOTES:    call with mGattLock held
 */
static void gattServiceDelete(struct gattService *svc)
{
    struct gattItem *gi, *t;

    if (svc->online) {
        loge("Cannot delete an online service\n");
        return;
    }

    attSrvHandleRangeRelease(svc->attRange);
    if (svc->prev)
        svc->prev->next = svc->next;
    else
        mSvcs = svc->next;
    if (svc->next)
        svc->next->prev = svc->prev;

    gi = svc->itemsHead;
    while (gi) {
        t = gi;
        gi = gi->next;

        if (t->type == GATT_ITEM_TYPE_INCLUDE)
            t->include.incl->useCount--;

        free(t);
    }
    free(svc);
}

/*
 * FUNCTION: gattServiceDestroy
 * USE:      Destroy a public-facing GATT service
 * PARAMS:   svcRef - the service reference
 * RETURN:   success
 * NOTES:
 */
bool gattServiceDestroy(gatt_service_t svcRef)
{
    struct gattService *svc;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (svc) {
        if (svc->useCount)
            loge("Refusing to destroy service included elsewhere (%u times)\n", svc->useCount);
        else {
            if (svc->online) {
                logw("Destroying an online service\n");
                gattServiceOffline(svc);
            }
            gattServiceDelete(svc);
        }
    }
    pthread_mutex_unlock(&mGattLock);

    return !!svc;
}

/*
 * FUNCTION: gattServiceStart
 * USE:      Online a service
 * PARAMS:   svcRef - the service reference
 *           supportLE - does this service support LE
 *           supportEDR - does this service support EDR
 * RETURN:   success
 * NOTES:
 */
bool gattServiceStart(gatt_service_t svcRef, bool supportLE, bool supportEDR)
{
    struct gattService *svc;
    bool ret = false;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (svc)
        ret = gattServiceOnline(svc, supportLE, supportEDR);
    pthread_mutex_unlock(&mGattLock);

    return ret;
}

/*
 * FUNCTION: gattServiceStop
 * USE:      Offline a service
 * PARAMS:   svcRef - the service reference
 * RETURN:   success
 * NOTES:
 */
bool gattServiceStop(gatt_service_t svcRef)
{
    struct gattService *svc;
    bool ret = false;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (svc) {
        gattServiceOffline(svc);
        ret = true;
    }
    pthread_mutex_unlock(&mGattLock);

    return ret;
}

/*
 * FUNCTION: gattServiceIsRunning
 * USE:      Check if a service is online
 * PARAMS:   svcRef - the service reference
 * RETURN:   true if service exists and is running
 * NOTES:
 */
bool gattServiceIsRunning(gatt_service_t svcRef)
{
    struct gattService *svc;
    bool ret = false;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (svc)
        ret = svc->online;
    pthread_mutex_unlock(&mGattLock);

    return ret;
}

/*
 * FUNCTION: gattServiceGetUuid
 * USE:      Get a service's UUID
 * PARAMS:   svcRef - the service reference
 *           dst - store UUID here
 * RETURN:   true if service exists and UUID was gotten
 * NOTES:
 */
bool gattServiceGetUuid(gatt_service_t svcRef, struct uuid *dst)
{
    struct gattService *svc;
    bool ret = false;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (svc) {
        memcpy(dst, &svc->uuid, sizeof(struct uuid));
        ret = true;
    }
    pthread_mutex_unlock(&mGattLock);

    return ret;
}

/*
 * FUNCTION: gattServiceGetHandleBaseByUuid
 * USE:      Get the base handle for a service given its UUID. Only works for online services
 * PARAMS:   uuid - the desired uuid
 * RETURN:   handle value or 0 on error
 * NOTES:
 */
uint16_t gattServiceGetHandleBaseByUuid(const struct uuid *uuid)
{
    struct gattService *svc;
    uint16_t handle = 0;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindByUuid(uuid);
    if (!svc)
        loge("Cannot get base for not-found service\n");
    else if (!svc->online)
        loge("Non-online services have no base\n");
    else
        handle = attSrvHandleRangeGetBase(svc->attRange);
    pthread_mutex_unlock(&mGattLock);

    return handle;
}

/*
 * FUNCTION: gattServiceGetHandleBaseBySvc
 * USE:      Get the base handle for a service given its service ref
 * PARAMS:   uuid - the desired uuid
 * RETURN:   handle value or 0 on error
 * NOTES:
 */
uint16_t gattServiceGetHandleBaseBySvc(gatt_service_t svcRef)
{
    struct gattService *svc;
    uint16_t handle = 0;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (!svc)
        loge("Cannot get base for not-found service\n");
    else
        handle = attSrvHandleRangeGetBase(svc->attRange);
    pthread_mutex_unlock(&mGattLock);

    return handle;
}

/*
 * FUNCTION: gattServiceFindByHandle
 * USE:      Find the svcRef of a service by handle
 * PARAMS:   handle - the handle
 *           firstOnly - if set only search by start of range, else serach by anything IN range
 * RETURN:   srvcRef or 0 on error
 * NOTES:
 */
gatt_service_t gattServiceFindByHandle(uint16_t handle, bool firstOnly)
{
    struct gattService *svc;
    gatt_service_t ret = 0;

    pthread_mutex_lock(&mGattLock);
    svc = mSvcs;
    while (svc) {
       uint16_t base = attSrvHandleRangeGetBase(svc->attRange);
       uint16_t len = attSrvHandleRangeGetLen(svc->attRange);

       if (firstOnly && base == handle)
           break;

       if (base <= handle && base + len > handle)
           break;

       svc = svc->next;
    }

    if (svc)
        ret = svc->svcRef;
    pthread_mutex_unlock(&mGattLock);

    return ret;
}

/*
 * FUNCTION: gattSeerviceItemAppend
 * USE:      Append an item to a service
 * PARAMS:   svc - service struct
 *           gi - the item
 * RETURN:   offset from range start
 * NOTES:    probably want to tall this with the lock held
 */
static uint16_t gattServiceItemAppend(struct gattService *svc, struct gattItem *gi)
{
    gi->prev = svc->itemsTail;
    if (svc->itemsTail)
        svc->itemsTail->next = gi;
    else
        svc->itemsHead = gi;
    svc->itemsTail = gi;
    return svc->numItems++;
}

/*
 * FUNCTION: gattServiceAddIncludedService
 * USE:      Append an "included service" to a service
 * PARAMS:   svcRef - the service we're operating on
 *           uuid - the service to include
 * RETURN:   handle or 0 on error
 * NOTES:
 */
uint16_t gattServiceAddIncludedService(gatt_service_t svcRef, const struct uuid *uuid)
{
    struct gattService *svc, *included;
    struct gattItem *gi;
    uint16_t handle = 0;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (!svc) {
        loge("Failed to find service "GATTHANDLEFMT"\n", GATTHANDLECNV(svcRef));
        goto out;
    }
    included = gattServiceFindByUuid(uuid);
    if (!included) {
        loge("Failed to find included service "UUIDFMT"n", UUIDCONV(*uuid));
        goto out;
    }
    if (svc->numItems >= svc->maxItems - GATT_HDR_HANDLES) {
        loge("No space left in the service\n");
        goto out;
    }

    gi = (struct gattItem*)calloc(1, sizeof(struct gattItem));
    if (!gi) {
        loge("Failed to allocate new item for include\n");
        goto out;
    }

    gi->type = GATT_ITEM_TYPE_INCLUDE;
    gi->include.incl = included;
    handle = gattServiceItemAppend(svc, gi) + attSrvHandleRangeGetBase(svc->attRange) + GATT_HDR_HANDLES;
    included->useCount++;

out:
    pthread_mutex_unlock(&mGattLock);
    return handle;
}

/*
 * FUNCTION: gattServiceAddChar
 * USE:      Append a "characteristic" to a service
 * PARAMS:   svcRef - the service we're operating on
 *           uuid - the uuid of the value
 *           props - the value properties to show
 *           perms - actual permissions for the value
 * RETURN:   handle of the value attribute (not of the descriptor attribute which is first) or 0 on error
 * NOTES:
 */
uint16_t gattServiceAddChar(gatt_service_t svcRef, const struct uuid *uuid, uint8_t props, uint32_t perms)
{
    struct gattItem *giDecl, *giVal;
    struct gattService *svc;
    uint16_t handle = 0;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (!svc) {
        loge("Failed to find service "GATTHANDLEFMT"\n", GATTHANDLECNV(svcRef));
        goto out;
    }
    if (svc->numItems + 1 >= svc->maxItems - GATT_HDR_HANDLES) {
        loge("No space left in the service\n");
        goto out;
    }

    giDecl = (struct gattItem*)calloc(1, sizeof(struct gattItem));
    if (!giDecl) {
        loge("Failed to allocate new item for chat decl\n");
        goto out;
    }

    giVal = (struct gattItem*)calloc(1, sizeof(struct gattItem));
    if (!giVal) {
        free(giDecl);
        loge("Failed to allocate new item for char val\n");
        goto out;
    }

    giDecl->type = GATT_ITEM_TYPE_CHAR_DECL;
    giDecl->charDecl.charProps = props;
    memcpy(&giDecl->charDecl.uuid, uuid, sizeof(giDecl->charDecl.uuid));

    giVal->type = GATT_ITEM_TYPE_CHAR_VAL;
    giVal->charVal.valPerms = perms;

    gattServiceItemAppend(svc, giDecl);
    handle = gattServiceItemAppend(svc, giVal) + attSrvHandleRangeGetBase(svc->attRange) + GATT_HDR_HANDLES;

out:
    pthread_mutex_unlock(&mGattLock);
    return handle;
}

/*
 * FUNCTION: gattServiceAddCharDescr
 * USE:      Append a "characteristic descriptor" to a service
 * PARAMS:   svcRef - the service we're operating on
 *           uuid - the uuid of the descriptor
 *           perms - actual permissions for the descriptor's value
 * RETURN:   handle or 0 on error
 * NOTES:
 */
uint16_t gattServiceAddCharDescr(gatt_service_t svcRef, const struct uuid *uuid, uint32_t perms)
{
    struct gattService *svc;
    struct gattItem *gi;
    uint16_t handle = 0;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (!svc) {
        loge("Failed to find service "GATTHANDLEFMT"\n", GATTHANDLECNV(svcRef));
        goto out;
    }
    if (svc->numItems >= svc->maxItems - GATT_HDR_HANDLES) {
        loge("No space left in the service\n");
        goto out;
    }
    gi = (struct gattItem*)calloc(1, sizeof(struct gattItem));
    if (!gi) {
        loge("Failed to allocate new item for char descriptor\n");
        goto out;
    }

    gi->type = GATT_ITEM_TYPE_CHAR_DESCR;
    memcpy(&gi->descriptor.uuid, uuid, sizeof(gi->descriptor.uuid));
    gi->descriptor.descrValPerms = perms;
    handle = gattServiceItemAppend(svc, gi) + attSrvHandleRangeGetBase(svc->attRange) + GATT_HDR_HANDLES;

out:
    pthread_mutex_unlock(&mGattLock);
    return handle;
}

/*
 * FUNCTION: gattServiceSendInd
 * USE:      Send an indication or a notification
 * PARAMS:   svcRef - the reference to a service
 *           cid - ATT's connection Id
 *           handle - the handle to notify/indicate on
 *           buf - the data to send
 *           len - length of said data
 *           withConfirm - use an indication?
 *           ref - passed to callback later. unused by GATT
 * RETURN:   false on immediate failure
 * NOTES:
 */
bool gattServiceSendInd(gatt_service_t svcRef, att_cid_t cid, uint16_t handle, const void *buf, uint16_t len, bool withConfirm, uint64_t ref)
{
    uint8_t ret = L2C_TX_ERROR;
    struct gattService *svc;
    uint16_t base;
    sg data;

    pthread_mutex_lock(&mGattLock);
    svc = gattServiceFindBySvcRef(svcRef);
    if (!svc) {
        loge("Failed to find service "GATTHANDLEFMT"\n", GATTHANDLECNV(svcRef));
        goto out;
    }

    base = attSrvHandleRangeGetBase(svc->attRange);
    if (handle < base || handle >= base + svc->maxItems) {
        logd("Refusing to send notif for handle 0x%04X not in range 0x%04X+0x%04X\n", handle, base, svc->maxItems);
        goto out;
    }

    data = sgNewWithCopyData(buf, len);
    if (!data) {
        loge("Failed to contrust an SG\n");
        goto out;
    }

    ret = attSrvValueNotifyChanged(svc->attRange, handle - base, cid, data, !withConfirm, ref);
    if (ret == L2C_TX_ACCEPTED) {
        if (!withConfirm && !gattEnqueueSrvIndCall(svc, attSrvCidResolve(cid), cid, handle, ATT_SRV_EVT_NOTIF_SENT, ref))
            loge("Failed to notify caller of notif TX\n");
    } else
        sgFree(data);

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

/*
 * FUNCTION: gattCliHandleCccdWriteRequestIfNeeded
 * USE:      Figure out of a CCCD write is needed, and enqueue it if so
 * PARAMS:   conn - the conection handle
 *           now - the todo item
 * RETURN:   att transaction ID if we start a transaction, 0 else
 * NOTES:    called from the worker thread with mGattLock NOT held!
 */
static uniq_t gattCliHandleCccdWriteRequestIfNeeded(l2c_handle_t conn, struct gattCliTodoItem *now)
{
    uint8_t writeData[sizeof(uint16_t)];
    struct gattConnState *connState;
    struct gattCliNotif *notif;
    uint16_t cccdVal;
    uniq_t trans = 0;
    sg writeDataSg;

    pthread_mutex_lock(&mGattLock);
    connState = gattConnFindByL2cConn(conn);
    if (!connState)
        goto out;

    //find the notif by locator;
    notif = gattNotifFindByLocatorInConn(connState, now->notifLocator);
    if (!notif)
        goto out;

    //figure out what (if anything) to do with it
    if (notif->refCtInd && notif->curState == NOTIF_C_STATE_SUBBED_TO_IND)
        goto out;
    if (!notif->refCtInd && notif->refCtNotif && notif->curState == NOTIF_C_STATE_SUBBED_TO_NOTIF)
        goto out;

    if(!notif->refCtInd && !notif->refCtNotif && notif->curState != NOTIF_C_STATE_NOT_SUBBED)
        goto out;

    //we now know we need a CCCD write - figure out the value
    if (notif->refCtInd)
        cccdVal = GATT_CLI_CFG_BIT_INDS;
    else if (notif->refCtNotif)
        cccdVal = GATT_CLI_CFG_BIT_NOTIFS;
    else
        cccdVal = 0;
    utilSetLE16(writeData, cccdVal);

    //store the data into the todo and the value we're writing into offset (so we can know what we wrote when the ACK comes)
    writeDataSg = sgNewWithCopyData(writeData, sizeof(writeData));
    if (!writeDataSg)
        goto out;
    now->offset = cccdVal;

    //try to issue the write
    trans = attCliWrite(conn, now->handle, writeDataSg);
    if (!trans)
        sgFree(writeDataSg);

out:
    pthread_mutex_unlock(&mGattLock);
    return trans;
}

/*
 * FUNCTION: gattCliTodoNext
 * USE:      Start on the next to-do item for the connection
 * PARAMS:   conn - the conection handle
 *           now - the todo item
 * RETURN:   NONE
 * NOTES:    This should ONLY be called from the worker thread with mGattLock NOT held!
 */
static void gattCliTodoNext(l2c_handle_t conn, struct gattCliTodoItem *now)
{
    struct gattConnState *connState;
    uniq_t trans = 0;
    uint16_t uuid16;

    /* actually start it */
    logd("Current gatt cli todo command being sent: %u\n", now->type);
    switch (now->type) {
    case GATT_CLI_TODO_FIND_INFO:
        trans = attCliFindInformation(conn, now->handle, now->endHandle);
        if (!trans)
            logw("FindInfo failed\n");
        break;

    case GATT_CLI_TODO_FIND_BY_TYPE_VAL:
        if (!uuidToUuid16(&uuid16, &now->uuid)) {
            loge("Cannot do find-by-type-value with a non-16-bit-uuid. You're about to have a Bad Time (tm)\n");
            uuid16 = 0;
        }
        trans = attCliFindByTypeValue(conn, now->handle, now->endHandle, uuid16, now->data);
        if (!trans) {
            sgFree(now->data);
            now->data = NULL;
            logw("FindByTypeValue failed\n");
         }
        break;

    case GATT_CLI_TODO_READ_BY_TYPE:
        trans = attCliReadByType(conn, now->handle, now->endHandle, &now->uuid);
        if (!trans)
            logw("ReadByType failed\n");
        break;

    case GATT_CLI_TODO_READ:
        trans = attCliRead(conn, now->handle);
        if (!trans)
            logw("Read failed\n");
        break;

    case GATT_CLI_TODO_READ_BLOB:
        trans = attCliReadBlob(conn, now->handle, now->offset);
        if (!trans)
            logw("ReadBlob failed\n");
        break;

    case GATT_CLI_TODO_READ_BY_GRP_TYPE:
        trans = attCliReadByGroupType(conn, now->handle, now->endHandle, &now->uuid);
        if (!trans)
            logw("ReadByGroupType failed\n");
        break;

    case GATT_CLI_TODO_WRITE:
        trans = attCliWrite(conn, now->handle, now->data);
        if (!trans) {
            sgFree(now->data);
            now->data = NULL;
            logw("Write with confirm failed\n");
        }
        break;

    case GATT_CLI_TODO_WRITE_NO_ACK:
        if (!attCliWriteNoAck(conn, now->handle, now->data)) {
            sgFree(now->data);
            now->data = NULL;
            logi("Write with no confirm failed\n");
        }
        break;

    case GATT_CLI_TODO_SIGNED_WRITE:
        if (!attCliSignedWriteNoAck(conn, now->handle, now->data)) {
            sgFree(now->data);
            now->data = NULL;
            logi("Write with signature failed\n");
        }
        break;

    case GATT_CLI_TODO_PREPARE_WRITE:
        trans = attCliPrepareWrite(conn, now->handle, now->offset, now->data);
        if (!trans) {
            sgFree(now->data);
            now->data = NULL;
            logw("PrepareWrite failed\n");
        }
        break;

    case GATT_CLI_TODO_WRITE_EXEC:
        trans = attCliExecuteStagedWrites(conn, now->commit);
        if (!trans)
            logw("ExecWrite failed\n");
        break;

    case GATT_CLI_TODO_SEND_MTU_REQ:
        trans = attCliRequestMtu(conn, now->mtu);
        break;

    case GATT_CLI_TODO_WRITE_CCCD:
        trans = gattCliHandleCccdWriteRequestIfNeeded(conn, now);
        break;
    }

    pthread_mutex_lock(&mGattLock);
    connState = gattConnFindByL2cConn(conn);
    if (!connState)
        logd("ToDo item we just did no longer has a connection. Oops\n");
    else if (connState->todoCurr != now)
        loge("Inconsistent idea of what the current todo item is!\n");
    else if (!trans) { /* a transaction is NOT ongoing */
        gattCliTodoItemFree(now);
        if (connState) {
            connState->todoCurr = NULL;
            gattEnqueueCliDoNextTodoItem(connState);
        }
    }
    pthread_mutex_unlock(&mGattLock);
}

/*
 * FUNCTION: gattCliNotifSubUnsubIssueWriteIfNeededNewTodo
 * USE:      Issue a write to the notif/ind subscription descriptor if needed
 * PARAMS:   conn - the connection structure
 *           notif - the notif struct
 * RETURN:   false on immediate error
 * NOTES:    call with mGattLock held. When is a write needed? If all clients we
 *           have need a different subscription model than we currently have, or
 *           all clients go away.
 */
static bool gattCliNotifSubUnsubIssueWriteIfNeededNewTodo(struct gattConnState *conn, struct gattCliNotif *notif)
{
    struct gattCliTodoItem *todo;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return false;

    todo->purpose = GATT_INTENT_NOTIF_SUB_UNSUB;
    todo->type = GATT_CLI_TODO_WRITE_CCCD;
    todo->handle = notif->charConfigHandle;
    todo->auxHandle[0] = notif->charValueHandle;
    todo->notifLocator = notif->locator;

    gattCliTodoEnqItem(conn, todo, false);

    return true;
}

/*
 * FUNCTION: gattCliNotifRecDelete
 * USE:      Delete a gattCliNotifRec. If needed, schedule a deletion for gattCliNotif as well
 * PARAMS:   clicon - the client connection structure
 *           nr - the notif rec
 * RETURN:   NONE
 * NOTES:    call with mGattLock held. "nr" WILL be invalid after this call, "notif" may be too
 */
static void gattCliNotifRecDelete(struct gattClientConnection *clicon, struct gattCliNotifRec *nr)
{
    struct gattConnState* conn = gattConnFindById(clicon->gattConnId);
    struct gattCliNotif *notif = nr->notif;

    if (!conn)
        return;

    /* adjust refcount */
    if (nr->wantInd)
        notif->refCtInd--;
    else
        notif->refCtNotif--;

    /* delete the notif rec itself */
    if (nr->next)
        nr->next->prev = nr->prev;
    if (nr->prev)
        nr->prev->next = nr->next;
    else
        clicon->notifs = nr->next;

    free(nr);

    /* see if notif itself needs deletion */
    if (!notif->refCtInd && !notif->refCtNotif) {
        if (conn->cliNotifs == notif)
            conn->cliNotifs = notif->next;
        else
            notif->prev->next = notif->next;
        if (notif->next)
            notif->next->prev = notif->prev;

        free(notif);
    }
}

/*
 * FUNCTION: gattClientNotifUnsubscribe
 * USE:      Unsubscribe fron a notification/indication
 * PARAMS:   clicon - the client connection structure
 *           nr - the gattCliNotifRec
 * RETURN:   NONE
 * NOTES:    call with mGattLock held
 */
static void gattClientNotifUnsubscribe(struct gattClientConnection *clicon, struct gattCliNotifRec *nr)
{
    struct gattConnState *conn = gattConnFindById(clicon->gattConnId);
    struct gattCliNotif *notif = nr->notif;

    gattCliNotifRecDelete(clicon, nr);

    /* if needed, do [another] char descr write */
    if (!conn || !gattCliNotifSubUnsubIssueWriteIfNeededNewTodo(conn, notif)) {
        loge("Unnotif write enqueue failed\n");
    }
}

/*
 * FUNCTION: gattClientConnClose
 * USE:      Close a client's connection (optionally notify said client)
 * PARAMS:   clicon - the client connection structure
 *           status - status to notify client with (if GATT_CLI_STATUS_OK, no notification will be sent)
 * RETURN:   NONE
 * NOTES:    call with mGattLock held
 */
static void gattClientConnClose(struct gattClientConnection *clicon, uint8_t status)
{
    struct gattConnState* conn = gattConnFindById(clicon->gattConnId);
    struct gattCliTodoItem *tC, *tN, *tP = NULL;

    /* notify client if needed */
    if (status != GATT_CLI_STATUS_OK && !gattEnqueueCliConnStatusCall(clicon, status))
        logw("Failed to notify client about connection closure. Pity.\n");

    /* enumerate all notifications this client had and unsubscribe from them. */
    while (clicon->notifs)
        gattClientNotifUnsubscribe(clicon, clicon->notifs);

    if (conn) {
        /*
         * Remove all todo list items that are in client's name. If one is
         * in flight, it will gracefully fail when it fails to find a client
         * on completion, so we need not do much for that case. In reality
         * this is all an optimization. We could leave all these items here
         * and let them all fail safely. But since it is easy to get rid of
         * them, we do.
         */
        for (tC = conn->todoListH; tC; tC = tN) {
            tN = tC->next;
            if (tC->connId == clicon->connId) {
                if (tC == conn->todoListH)
                    conn->todoListH = tN;
                else
                    tP->next = tN;
                if (tC == conn->todoListT)
                    conn->todoListT = tP;
                free(tC);
            } else
                tP = tC;
        }
    }

    /* destroy the structure(s) */
    if (clicon->next)
        clicon->next->prev = clicon->prev;
    if (clicon->prev)
        clicon->prev->next = clicon->next;
    else
        mClientConns = clicon->next;
    free(clicon);
}

/*
 * FUNCTION: gattClientInvalidateCache
 * USE:      Invalidate cache and repopulate it
 * PARAMS:   whomTo - cache of what device to invalidate
 * RETURN:   false on immediate failure
 * NOTES:
 */
bool gattClientInvalidateCache(const struct bt_addr *whomTo)
{
    struct gattConnState *conn;
    bool ret = true;

    pthread_mutex_lock(&mGattLock);
    conn = gattConnFindByAddr(whomTo);
    if (!conn)
        logw("Caches of nonexistent GATT connections are by definition always clean :)\n");
    else
        ret = attClientInvalidateCache(conn->conn);

    pthread_mutex_unlock(&mGattLock);
    return ret;
}

/*
 * FUNCTION: gattCliTodoEnqItem
 * USE:      Enqueue a gatt to-do item in front or back of list
 * PARAMS:   conn - the connection structure
 *           todo - the item
 *           inFront - add it in front (instead of in order) this is used for confirmations
 * RETURN:   NONE
 * NOTES:    Call with mGattLock held
 */
static void gattCliTodoEnqItem(struct gattConnState *conn, struct gattCliTodoItem *todo, bool inFront)
{
    if (todo->enqueued) {
        loge("Cannot enqueue an item that is already in the list!\n");
        return;
    }
    todo->enqueued = true;

    logd("Enqueuing item %p with handle range 0x%04x-0x%04x in %s\n", todo, todo->handle, todo->endHandle, inFront ? "front" : "rear");

    if (conn->todoListH) { /* have items in list already? */
        if (inFront) {
            todo->next = conn->todoListH;
            conn->todoListH = todo;
        } else {
            todo->next = NULL;
            conn->todoListT->next = todo;
            conn->todoListT = todo;
        }
    } else {
        conn->todoListT = todo;
        conn->todoListH = todo;
        if (!conn->todoCurr) /* if no current task, start one */
            gattEnqueueCliDoNextTodoItem(conn);
    }
}

/*
 * FUNCTION: gattCliTodoMakeReadByGroupType
 * USE:      Enqueue a read-by-group-type todo item
 * PARAMS:   connId - the connection id
 *           type - the type of attribute to read (uuid16)
 *           purpose - the intent of this request
 *           firstHandle - first handle to consider
 *           lastHandle - last handle to consider
 * RETURN:   todo item or NULL.
 * NOTES:    call with mGattLock held, item WILL be added to the queue, but since the queue will
 *           not advance while mGattLock is held by you, you can customize the item safely after
 *           this func gives it to you and until you release mGattLock
 */
static struct gattCliTodoItem* gattCliTodoMakeReadByGroupType(gatt_client_conn_t connId, uint16_t type, uint8_t purpose, uint16_t firstHandle, uint16_t lastHandle)
{
    struct gattClientConnection *clicon;
    struct gattCliTodoItem *todo;
    struct gattConnState *conn;

    clicon = gattClientConnFindById(connId);
    if (!clicon)
        return NULL;

    conn = gattConnFindById(clicon->gattConnId);
    if (!conn)
        return NULL;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return NULL;

    todo->type = GATT_CLI_TODO_READ_BY_GRP_TYPE;
    uuidFromUuid16(&todo->uuid, type);
    todo->handle = firstHandle;
    todo->endHandle = lastHandle;
    todo->purpose = purpose;
    todo->connId = clicon->connId;
    gattCliTodoEnqItem(conn, todo, false);

    return todo;
}

/*
 * FUNCTION: gattCliTodoMakeFindByTypeValue
 * USE:      Enqueue a find-by-type-value todo item
 * PARAMS:   connId - the connection id
 *           type - the type of attribute to find (uuid16)
 *           value - the value we want to find (a copy is made)
 *           valueLen - length of the above value
 *           purpose - the intent of this request
 *           firstHandle - first handle to consider
 *           lastHandle - last handle to consider
 * RETURN:   todo item or NULL.
 * NOTES:    call with mGattLock held, item WILL be added to the queue, but since the queue will
 *           not advance while mGattLock is held by you, you can customize the item safely after
 *           this func gives it to you and until you release mGattLock
 */
static struct gattCliTodoItem* gattCliTodoMakeFindByTypeValue(gatt_client_conn_t connId, uint16_t type, const void* value, uint32_t valueLen, uint8_t purpose, uint16_t firstHandle, uint16_t lastHandle)
{
    struct gattClientConnection *clicon;
    struct gattCliTodoItem *todo;
    struct gattConnState *conn;
    sg val;

    clicon = gattClientConnFindById(connId);
    if (!clicon)
        return NULL;

    conn = gattConnFindById(clicon->gattConnId);
    if (!conn)
        return NULL;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return NULL;

    val = sgNewWithCopyData(value, valueLen);
    if (!val) {
        free(todo);
        return NULL;
    }

    todo->type = GATT_CLI_TODO_FIND_BY_TYPE_VAL;
    uuidFromUuid16(&todo->uuid, type);
    todo->handle = firstHandle;
    todo->endHandle = lastHandle;
    todo->purpose = purpose;
    todo->connId = clicon->connId;
    todo->data = val;
    gattCliTodoEnqItem(conn, todo, false);

    return todo;
}

/*
 * FUNCTION: gattCliTodoMakeReadByType
 * USE:      Enqueue a read-by-type todo item
 * PARAMS:   connId - the connection id
 *           type - the type of attribute to read (uuid16)
 *           purpose - the intent of this request
 *           firstHandle - first handle to consider
 *           lastHandle - last handle to consider
 * RETURN:   todo item or NULL.
 * NOTES:    call with mGattLock held, item WILL be added to the queue, but since the queue will
 *           not advance while mGattLock is held by you, you can customize the item safely after
 *           this func gives it to you and until you release mGattLock
 */
static struct gattCliTodoItem* gattCliTodoMakeReadByType(gatt_client_conn_t connId, uint16_t type, uint8_t purpose, uint16_t firstHandle, uint16_t lastHandle)
{
    struct gattClientConnection *clicon;
    struct gattCliTodoItem *todo;
    struct gattConnState *conn;

    clicon = gattClientConnFindById(connId);
    if (!clicon)
        return NULL;

    conn = gattConnFindById(clicon->gattConnId);
    if (!conn)
        return NULL;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return NULL;

    todo->type = GATT_CLI_TODO_READ_BY_TYPE;
    uuidFromUuid16(&todo->uuid, type);
    todo->handle = firstHandle;
    todo->endHandle = lastHandle;
    todo->purpose = purpose;
    todo->connId = clicon->connId;
    gattCliTodoEnqItem(conn, todo, false);

    return todo;
}

/*
 * FUNCTION: gattCliTodoMakeFindInfo
 * USE:      Enqueue a find-info todo item
 * PARAMS:   connId - the connection id
 *           purpose - the intent of this request
 *           firstHandle - first handle to consider
 *           lastHandle - last handle to consider
 * RETURN:   todo item or NULL.
 * NOTES:    call with mGattLock held, item WILL be added to the queue, but since the queue will
 *           not advance while mGattLock is held by you, you can customize the item safely after
 *           this func gives it to you and until you release mGattLock
 */
static struct gattCliTodoItem* gattCliTodoMakeFindInfo(gatt_client_conn_t connId, uint8_t purpose, uint16_t firstHandle, uint16_t lastHandle)
{
    struct gattClientConnection *clicon;
    struct gattCliTodoItem *todo;
    struct gattConnState *conn;

    clicon = gattClientConnFindById(connId);
    if (!clicon)
        return NULL;

    conn = gattConnFindById(clicon->gattConnId);
    if (!conn)
        return NULL;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return NULL;

    todo->type = GATT_CLI_TODO_FIND_INFO;
    todo->handle = firstHandle;
    todo->endHandle = lastHandle;
    todo->purpose = purpose;
    todo->connId = clicon->connId;
    gattCliTodoEnqItem(conn, todo, false);

    return todo;
}

/*
 * FUNCTION: gattCliTodoMakeRead
 * USE:      Enqueue a read todo item
 * PARAMS:   connId - the connection id
 *           purpose - the intent of this request
 *           handle - handle to consider
 *           authReq - the authentication requirements
 * RETURN:   todo item or NULL.
 * NOTES:    call with mGattLock held, item WILL be added to the queue, but since the queue will
 *           not advance while mGattLock is held by you, you can customize the item safely after
 *           this func gives it to you and until you release mGattLock
 */
static struct gattCliTodoItem* gattCliTodoMakeRead(gatt_client_conn_t connId, uint8_t purpose, uint16_t handle, uint8_t authReq)
{
    struct gattClientConnection *clicon;
    struct gattCliTodoItem *todo;
    struct gattConnState *conn;

    clicon = gattClientConnFindById(connId);
    if (!clicon)
        return NULL;

    conn = gattConnFindById(clicon->gattConnId);
    if (!conn)
        return NULL;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return NULL;

    todo->type = GATT_CLI_TODO_READ;
    todo->handle = handle;
    todo->purpose = purpose;
    todo->connId = clicon->connId;
    todo->authReq = authReq;
    gattCliTodoEnqItem(conn, todo, false);

    return todo;
}

/*
 * FUNCTION: gattCliTodoMakeReadBlob
 * USE:      Enqueue a read blob todo item
 * PARAMS:   connId - the connection id
 *           purpose - the intent of this request
 *           handle - handle to consider
 *           authReq - the authentication requirements
 *           offset - offset to read at
 * RETURN:   todo item or NULL.
 * NOTES:    call with mGattLock held, item WILL be added to the queue, but since the queue will
 *           not advance while mGattLock is held by you, you can customize the item safely after
 *           this func gives it to you and until you release mGattLock
 */
static struct gattCliTodoItem* gattCliTodoMakeReadBlob(gatt_client_conn_t connId, uint8_t purpose, uint16_t handle, uint8_t authReq, uint16_t offset)
{
    struct gattClientConnection *clicon;
    struct gattCliTodoItem *todo;
    struct gattConnState *conn;

    clicon = gattClientConnFindById(connId);
    if (!clicon)
        return NULL;

    conn = gattConnFindById(clicon->gattConnId);
    if (!conn)
        return NULL;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return NULL;

    todo->type = GATT_CLI_TODO_READ_BLOB;
    todo->handle = handle;
    todo->purpose = purpose;
    todo->offset = offset;
    todo->connId = clicon->connId;
    todo->authReq = authReq;
    gattCliTodoEnqItem(conn, todo, false);

    return todo;
}

/*
 * FUNCTION: gattCliTodoMakeWrite
 * USE:      Enqueue a write todo item (specific type given by param)
 * PARAMS:   connId - the connection id
 *           purpose - the intent of this request
 *           writeType - the actual write type
 *           handle - handle to consider
 *           authReq - the authentication requirements
 *           offset - offset to write at
 *           data - the data to write
 * RETURN:   todo item or NULL.
 * NOTES:    call with mGattLock held, item WILL be added to the queue, but since the queue will
 *           not advance while mGattLock is held by you, you can customize the item safely after
 *           this func gives it to you and until you release mGattLock
 */
static struct gattCliTodoItem* gattCliTodoMakeWrite(gatt_client_conn_t connId, uint8_t purpose, uint8_t writeType, uint16_t handle, uint8_t authReq, uint16_t offset, sg data)
{
    struct gattClientConnection *clicon;
    struct gattCliTodoItem *todo;
    struct gattConnState *conn;

    clicon = gattClientConnFindById(connId);
    if (!clicon)
        return NULL;

    conn = gattConnFindById(clicon->gattConnId);
    if (!conn)
        return NULL;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return NULL;

    todo->type = writeType;
    todo->handle = handle;
    todo->purpose = purpose;
    todo->offset = offset;
    todo->connId = clicon->connId;
    todo->authReq = authReq;
    todo->data = data;
    gattCliTodoEnqItem(conn, todo, false);

    return todo;
}

/*
 * FUNCTION: gattCliTodoMakeMtuReq
 * USE:      Create a MTU request todo
 * PARAMS:   conn - the connection structure
 *           mtu - the mtu to ask for
 *           purpose - the stated purpose
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
static struct gattCliTodoItem* gattCliTodoMakeMtuReq(struct gattConnState* conn, uint16_t mtu, uint8_t purpose)
{
    struct gattCliTodoItem *todo;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        return NULL;

    todo->type = GATT_CLI_TODO_SEND_MTU_REQ;
    todo->purpose = purpose;
    todo->mtu = mtu;
    gattCliTodoEnqItem(conn, todo, false);

    return todo;
}

/*
 * FUNCTION: gattClientFindService
 * USE:      Find all services with a given uuid on a server
 * PARAMS:   conn - the connection id
 *           primary - search for primary services
 *           searchForThis - uuid of service to find
 *           trans - transaction ID (unused, passed to callback)
 *           cbk - the callback to call with results (we'll call it with NULL after all results have been returned)
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientFindService(gatt_client_conn_t conn, bool primary, const struct uuid *searchForThis, uniq_t trans, gattCliSvcEnumCbk cbk)
{
    uint8_t buf[sizeof(struct uuid)];
    struct gattCliTodoItem *todo;
    uint32_t uuidLen;
    uint16_t uuid16;

    // convert uuid to uuid16 bit if possible, either way write it to buffer and keep track of length
    if (uuidToUuid16(&uuid16, searchForThis)) {
        utilSetLE16(buf, uuid16);
        uuidLen = sizeof(uint16_t);
    }
    else {
        uuidWriteLE(buf, searchForThis);
        uuidLen = sizeof(struct uuid);
    }

    pthread_mutex_lock(&mGattLock);
    todo = gattCliTodoMakeFindByTypeValue(conn, primary ? GATT_UUID_SVC_PRIMARY : GATT_UUID_SVC_SECONDARY, buf, uuidLen, GATT_INTENT_FIND_SVC, ATT_FIRST_VALID_HANDLE, ATT_LAST_VALID_HANDLE);
    if (todo) {
        todo->enumSvcsCbk = cbk;
        todo->desiredUuid = *searchForThis;
        todo->clientTrans = trans;
    }
    pthread_mutex_unlock(&mGattLock);

    return todo ? GATT_CLI_STATUS_OK : GATT_CLI_STATUS_ERR;
}

/*
 * FUNCTION: gattClientEnumServices
 * USE:      Find all services on a server
 * PARAMS:   conn - the connection id
 *           primary - search for primary services
 *           trans - transaction ID (unused, passed to callback)
 *           cbk - the callback to call with results (we'll call it with NULL after all results have been returned)
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientEnumServices(gatt_client_conn_t conn, bool primary, uniq_t trans, gattCliSvcEnumCbk cbk)
{
    struct gattCliTodoItem *todo;

    pthread_mutex_lock(&mGattLock);
    todo = gattCliTodoMakeReadByGroupType(conn, primary ? GATT_UUID_SVC_PRIMARY : GATT_UUID_SVC_SECONDARY, GATT_INTENT_ENUM_SVCS, ATT_FIRST_VALID_HANDLE, ATT_LAST_VALID_HANDLE);
    if (todo) {
        todo->enumSvcsCbk = cbk;
        todo->clientTrans = trans;
    }
    pthread_mutex_unlock(&mGattLock);

    return todo ? GATT_CLI_STATUS_OK : GATT_CLI_STATUS_ERR;
}

/*
 * FUNCTION: gattClientEnumIncludedServices
 * USE:      Find included services in a service
 * PARAMS:   conn - the connection id
 *           fromHandle - first handle to search
 *           toHandle - last handle to search
 *           trans - transaction ID (unused, passed to callback)
 *           cbk - the callback to call with results (UUID will be passed as NULL if no more were found)
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientEnumIncludedServices(gatt_client_conn_t conn, uint16_t fromHandle, uint16_t toHandle, uniq_t trans, gattCliEnumIncludedSvcsCbk cbk)
{
    struct gattCliTodoItem *todo;

    pthread_mutex_lock(&mGattLock);
    todo = gattCliTodoMakeReadByType(conn, GATT_UUID_INCLUDE, GATT_INTENT_ENUM_INCL_SVCS, fromHandle, toHandle);
    if (todo) {
        todo->enumIncludedSvcsCbk = cbk;
        todo->clientTrans = trans;
    }
    pthread_mutex_unlock(&mGattLock);

    return todo ? GATT_CLI_STATUS_OK : GATT_CLI_STATUS_ERR;
}

/*
 * FUNCTION: gattClientEnumCharacteristics
 * USE:      Enumerate characteristics in a service
 * PARAMS:   conn - the connection id
 *           fromHandle - first handle to search
 *           toHandle - last handle to search
 *           trans - transaction ID (unused, passed to callback)
 *           cbk - the callback to call with results (UUID will be passed as NULL if no more were found)
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:    will call callback with each char found
 */
uint8_t gattClientEnumCharacteristics(gatt_client_conn_t conn, uint16_t fromHandle, uint16_t toHandle, uniq_t trans, gattCliEnumCharacteristicsCbk cbk)
{
    struct gattCliTodoItem *todo;

    pthread_mutex_lock(&mGattLock);
    todo = gattCliTodoMakeReadByType(conn, GATT_UUID_CHARACTERISTIC, GATT_INTENT_ENUM_CHARS, fromHandle, toHandle);
    if (todo) {
        todo->enumCharsCbk = cbk;
        todo->clientTrans = trans;
    }
    pthread_mutex_unlock(&mGattLock);

    return todo ? GATT_CLI_STATUS_OK : GATT_CLI_STATUS_ERR;
}

/*
 * FUNCTION: gattClientEnumCharDescriptors
 * USE:      Find the next characteristic descriptor in a characteristic
 * PARAMS:   conn - the connection id
 *           fromHandle - first handle to search (value handle plus one)
 *           toHandle - last handle to search
 *           trans - transaction ID (unused, passed to callback)
 *           cbk - the callback to call with results (UUID will be passed as NULL if no more were found)
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientEnumCharDescriptors(gatt_client_conn_t conn, uint16_t fromHandle, uint16_t toHandle, uniq_t trans, gattCliEnumCharDescrsCbk cbk)
{
    struct gattCliTodoItem *todo;

    pthread_mutex_lock(&mGattLock);
    todo = gattCliTodoMakeFindInfo(conn, GATT_INTENT_ENUM_CHAR_DESCRS, fromHandle, toHandle);
    if (todo) {
        todo->enumCharDscrsCbk = cbk;
        todo->clientTrans = trans;
    }
    pthread_mutex_unlock(&mGattLock);

    return todo ? GATT_CLI_STATUS_OK : GATT_CLI_STATUS_ERR;
}

/*
 * FUNCTION: gattClientVerifyAuthReq
 * USE:      Verify an authReq param given to us is valid (simply numerically)
 * PARAMS:   authReq - said param
 * RETURN:   true if it is a valid value
 * NOTES:
 */
static bool gattClientVerifyAuthReq(uint8_t authReq)
{
    switch (authReq) {
    case GATT_CLI_AUTH_REQ_NONE:
    case GATT_CLI_AUTH_REQ_NO_MITM:
    case GATT_CLI_AUTH_REQ_MITM:
    case GATT_CLI_AUTH_REQ_SIGNED_NO_MITM:
    case GATT_CLI_AUTH_REQ_SIGNED_MITM:
        return true;
    default:
        return false;
    }
}

/*
 * FUNCTION: gattClientRead
 * USE:      Read an attribute (usually a characteristic or a descriptor)
 * PARAMS:   conn - the connection id
 *           handle - the handle to read
 *           authReq - authentication requirements (// TODO)
 *           offset - offset to start reading at
 *           trans - transaction ID (unused, passed to callback)
 *           cbk - the callback to call with results
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientRead(gatt_client_conn_t conn, uint16_t handle, uint8_t authReq, uint16_t offset, uniq_t trans, gattCliReadCbk cbk)
{
    struct gattCliTodoItem *todo;

    if (!gattClientVerifyAuthReq(authReq))
        return GATT_CLI_STATUS_ERR;

    pthread_mutex_lock(&mGattLock);
    if (offset)
        todo = gattCliTodoMakeReadBlob(conn, GATT_INTENT_READ, handle, authReq, offset);
    else
        todo = gattCliTodoMakeRead(conn, GATT_INTENT_READ, handle, authReq);
    if (todo) {
        todo->readCbk = cbk;
        todo->clientTrans = trans;
    }
    pthread_mutex_unlock(&mGattLock);

    return todo ? GATT_CLI_STATUS_OK : GATT_CLI_STATUS_ERR;
}

/*
 * FUNCTION: gattClientCharWrite
 * USE:      Write a characteristic
 * PARAMS:   conn - the connection id
 *           handle - the handle to read
 *           authReq - authentication requirements (// TODO)
 *           writeType - cmd? req? prepare? (GATT_CLI_WRITE_TYPE_*)
 *           ofst - write offset (used only for prepare write)
 *           data  -the data to write
 *           trans - transaction ID (unused, passed to callback)
 *           cbk - the callback to call with results
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientWrite(gatt_client_conn_t conn, uint16_t handle, uint8_t authReq, uint8_t writeType, uint16_t ofst, sg data, uniq_t trans, gattCliWriteCbk cbk)
{
    struct gattCliTodoItem *todo;
    uint8_t type;

    if (!gattClientVerifyAuthReq(authReq))
        return GATT_CLI_STATUS_ERR;

    switch (writeType) {
    case GATT_CLI_WRITE_TYPE_SIGNED:
        type = GATT_CLI_TODO_SIGNED_WRITE;
        break;
    case GATT_CLI_WRITE_TYPE_WRITE_NO_RSP:
        type = GATT_CLI_TODO_WRITE_NO_ACK;
        break;
    case GATT_CLI_WRITE_TYPE_WRITE:
        type = GATT_CLI_TODO_WRITE;
        break;
    case GATT_CLI_WRITE_TYPE_PREPARE:
        type = GATT_CLI_TODO_PREPARE_WRITE;
        break;
    default:
        return GATT_CLI_STATUS_ERR;
    }

    pthread_mutex_lock(&mGattLock);
    todo = gattCliTodoMakeWrite(conn, GATT_INTENT_WRITE, type, handle, authReq, ofst, data);
    if (todo) {
        todo->writeCbk = cbk;
        todo->clientTrans = trans;
    }
    pthread_mutex_unlock(&mGattLock);

    return todo ? GATT_CLI_STATUS_OK : GATT_CLI_STATUS_ERR;
}

/*
 * FUNCTION: gattClientStagedWritesExecute
 * USE:      Execute or abandon previously staged writes
 * PARAMS:   connId - the connection id
 *           execute - true to commit them, false to abandon
 *           trans - transaction ID (unused, passed to callback)
 *           cbk - the callback to call with results
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientStagedWritesExecute(gatt_client_conn_t connId, bool execute, uniq_t trans, gattCliStagedWriteExecuteCb cbk)
{
    struct gattClientConnection *clicon;
    uint8_t ret = GATT_CLI_STATUS_ERR;
    struct gattCliTodoItem *todo;
    struct gattConnState *conn;

    pthread_mutex_lock(&mGattLock);
    clicon = gattClientConnFindById(connId);
    if (!clicon)
        goto out;

    conn = gattConnFindById(clicon->gattConnId);
    if (!conn)
        goto out;

    todo = calloc(1, sizeof(struct gattCliTodoItem));
    if (!todo)
        goto out;

    todo->type = GATT_CLI_TODO_WRITE_EXEC;
    todo->execute = execute;
    todo->executeCbk = cbk;
    todo->clientTrans = trans;

    todo->connId = clicon->connId;
    gattCliTodoEnqItem(conn, todo, false);

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

/*
 * FUNCTION: gattClientNotifsSubscribe
 * USE:      Subscribe to a notification or indication
 * PARAMS:   connId - the connection id
 *           charHandle - the handle of the characteristic (header)
 *           charValueHandle - the handle of the characteristic value
 *           cccdHandle - the handle of the cccd
 *           reliable - use reliable delivery?
 *           stateCbk - callback to call when subscription state changes
 *           arrivedCbk - callback to call when notif/ind arrives
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientNotifsSubscribe(gatt_client_conn_t connId, uint16_t charHandle, uint16_t charValueHandle, uint16_t cccdHandle, bool reliable, gattCliNotifSubscribeStateCbk stateCbk, gattCliNotifArrivedCbk arrivedCbk)
{
    struct gattClientConnection *clicon;
    uint8_t sta = GATT_CLI_STATUS_ERR;
    struct gattCliNotifRec *nr;
    struct gattCliNotif *notif;
    struct gattConnState *conn;
    bool callStateCbk = false;

    pthread_mutex_lock(&mGattLock);
    clicon = gattClientConnFindById(connId);
    if (!clicon)
        logw("No client connection for subscribe\n");
    else {

        conn = gattConnFindById(clicon->gattConnId);
        if (!conn) {
           logw("No gatt for subscribe\n");
           goto out;
        }

        /* find the notif record, if one exists */
        for (nr = clicon->notifs; nr; nr = nr->next) {

            if (nr->notif->charHeaderHandle != charHandle)
                continue;
            if (nr->notif->charValueHandle != charValueHandle)
                continue;
            if (nr->notif->charConfigHandle != cccdHandle)
                continue;
            break;
        }
        if (nr) {
            logw("Duplicate subscribe\n");
            sta = GATT_CLI_STATUS_OK;
            goto out;
        }

        nr = calloc(1, sizeof(struct gattCliNotifRec));
        if (!nr) {
            loge("Allocation error of a notif rec\n");
            goto out;
        }
        nr->wantInd = reliable;
        nr->stateCbk = stateCbk;
        nr->arrivedCbk = arrivedCbk;

        /* find the notif structure, if it exists */
        for (notif = conn->cliNotifs; notif; notif = notif->next) {

            if (notif->charHeaderHandle != charHandle)
                continue;
            if (notif->charValueHandle != charValueHandle)
                continue;
            if (notif->charConfigHandle != cccdHandle)
                continue;
            break;
        }
        if (!notif) {

            logd("Nobody was previously subscribed to char at 0x%04x - making new struct\n", charHandle);

            /* no structure? create it */
            notif = calloc(1, sizeof(struct gattCliNotif));
            if (!notif) {
                free(nr);
                loge("Allocation error of a notif struct\n");
                goto out;
            }
            notif->charHeaderHandle = charHandle;
            notif->charValueHandle = charValueHandle;
            notif->charConfigHandle = cccdHandle;
            notif->curState = NOTIF_C_STATE_NOT_SUBBED;
            notif->locator = uniqGetNext();
            sta = GATT_CLI_STATUS_OK;
            notif->next = conn->cliNotifs;
            conn->cliNotifs = notif;
            if (notif->next)
                notif->next->prev = notif;
        } else {

            logd("Somebody was previously subscribed to char at 0x%04x - reusing struct\n", charHandle);

            /* see if we can already tell them it's ready */
            if (notif->curState == NOTIF_C_STATE_SUBBED_TO_IND || (!reliable && notif->curState == NOTIF_C_STATE_SUBBED_TO_NOTIF)) {
                callStateCbk = true;
                nr->subCallMade = true;
                sta = GATT_CLI_STATUS_OK;
            }
        }

        /* if needed, do [another] char descr write */
        if (!gattCliNotifSubUnsubIssueWriteIfNeededNewTodo(conn, notif)) {
            sta = GATT_CLI_STATUS_ERR;
            loge("Notif write enqueue failed\n");
            free(nr);
            nr = NULL;
            callStateCbk = false;
        }

        if (nr) {
            nr->notif = notif;
            if (reliable)
                notif->refCtInd++;
            else
                notif->refCtNotif++;

            nr->next = clicon->notifs;
            clicon->notifs = nr;
            if (nr->next)
                nr->next->prev = nr;
        }
    }

out:
    pthread_mutex_unlock(&mGattLock);

    if (callStateCbk)
        stateCbk(connId, charValueHandle, true, sta);

    return sta;
}

/*
 * FUNCTION: gattClientNotifsUnsubscribe
 * USE:      Unsubscribe from a notification or indication
 * PARAMS:   conn - the connection id
 *           inThisService - in what service?
 *           thisChar - what characteristic?
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
uint8_t gattClientNotifsUnsubscribe(gatt_client_conn_t conn, uint16_t charValueHandle)
{
    gattCliNotifSubscribeStateCbk stateCbk = NULL;
    struct gattClientConnection *clicon;
    uint8_t sta = GATT_CLI_STATUS_ERR;
    struct gattCliNotifRec *nr;

    pthread_mutex_lock(&mGattLock);
    clicon = gattClientConnFindById(conn);
    if (!clicon)
        logw("No connection for unsubscribe\n");
    else {

        /* find the notif record, if one exists */
        for (nr = clicon->notifs; nr; nr = nr->next) {

            if (nr->notif->charValueHandle != charValueHandle)
                continue;
            break;
        }
        if (!nr)
            logw("NotifRec not found for unsub\n");
        else {
            if (!nr->unsubCallMade)
                stateCbk = nr->stateCbk;
            nr->unsubCallMade = true;

            gattClientNotifUnsubscribe(clicon, nr);
            sta = GATT_CLI_STATUS_OK;
        }
    }
    pthread_mutex_unlock(&mGattLock);

    if (stateCbk)
        stateCbk(conn, charValueHandle, false, sta);

    return sta;
}

/*
 * FUNCTION: gattClientUtilSvcTraversalStructFindByTransId
 * USE:      find a service traversal state structure by a transaction id
 * PARAMS:   trans - the transaction Id to look for
 * RETURN:   structure pointer or NULL
 * NOTES:    call with mGattUtilLock held
 */
static struct GattCliUtilSvcTraverseState* gattClientUtilSvcTraversalStructFindByTransId(uniq_t trans)
{
    struct GattCliUtilSvcTraverseState* t;

    for (t = mUtilSvcEnumStates; t; t = t->next) {
        if (t->curTrans == trans)
            break;
    }

    return t;
}

/*
 * FUNCTION: gattClientUtilSvcTraversalStructUnlink
 * USE:      Unlink a service traversal state struct from the list
 * PARAMS:   state the service traversal state structure
 * RETURN:   NONE
 * NOTES:    call with mGattUtilLock held
 */
static void gattClientUtilSvcTraversalStructUnlink(struct GattCliUtilSvcTraverseState* state)
{
    // unlink from list
    if (state->prev)
        state->prev->next = state->next;
    else
        mUtilSvcEnumStates = state->next;
    if (state->next)
        state->next->prev = state->prev;
}

/*
 * FUNCTION: gattClientUtilSvcTraversalStructFreeData
 * USE:      Properly free a service traversal state structure's data
 * PARAMS:   state the service traversal state structure
 * RETURN:   NONE
 * NOTES:    call with mGattUtilLock held
 */
static void gattClientUtilSvcTraversalStructFreeData(struct GattCliUtilSvcTraverseState* state)
{
    uint32_t i;

    // free constituent parts & itself
    for (i = 0; i < state->res.numChars; i++)
        free(state->res.chars[i].descrs);
    free(state->res.inclSvcs);
    free(state->res.chars);
    free(state);
}

/*
 * FUNCTION: gattClientUtilSvcTraversalStructFree
 * USE:      Properly unlink & then free a service traversal state structure
 * PARAMS:   state the service traversal state structure
 * RETURN:   NONE
 * NOTES:    call with mGattUtilLock held
 */
static void gattClientUtilSvcTraversalStructFree(struct GattCliUtilSvcTraverseState* state)
{
    gattClientUtilSvcTraversalStructUnlink(state);
    gattClientUtilSvcTraversalStructFreeData(state);
}

/*
 * FUNCTION: gattClientUtilFindAndTraversePrimaryServiceDescrEnumCbk
 * USE:      Called by GATT code when we find a descriptor (or another attribute that looks like it)
 * PARAMS:   conn - the connection id
 *           trans - out transaction ID (matches to "->curTrans")
 *           uuid - the found uuid of the descriptor or NULL at end
 *           handle - the handle of the descriptor
 *           status - GATT status for this search
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
static void gattClientUtilFindAndTraversePrimaryServiceDescrEnumCbk(gatt_client_conn_t conn, uniq_t trans, const struct uuid *uuid, uint16_t handle, uint8_t status)
{
    struct GattCliUtilSvcTraverseState* st;
    gattCliUtilSvcTraversedCbk cbk = NULL;
    uniq_t clientTrans;

    pthread_mutex_lock(&mGattUtilLock);
    st = gattClientUtilSvcTraversalStructFindByTransId(trans);
    if (!st)
        logi("state for this transaction not found\n");
    else {
        if (status != GATT_CLI_STATUS_OK)
            logi("error finding descriptors");
        else if (uuid) { // a descriptor is potentially found

            struct GattTraversedServiceChar *inChr = NULL;
            bool discard;
            uint32_t i;

            logd("GATT util svc traversal: descr search produces "UUIDFMT" @ 0x%04x\n", UUIDCONV(*uuid), handle);

            // verify it is not something else (here we'll get "characteristic" declarations, characteristic values, "include service" declarations, and our actual "service" declaration)
            discard = handle == st->res.firstHandle;
            for (i = 0; i < st->res.numInclSvcs && !discard; i++) {
                discard = handle == st->res.inclSvcs[i].includeDefHandle;
            }
            // while doing that also find what char it is in
            for (i = 0; i < st->res.numChars && !discard; i++) {
                discard = handle == st->res.chars[i].firstHandle || handle == st->res.chars[i].valHandle;
                if (handle > st->res.chars[i].firstHandle && handle <= st->res.chars[i].lastHandle)
                    inChr = &st->res.chars[i];
            }
            if (discard) {
                logd("GATT util svc traversal: descr discarded\n");
                pthread_mutex_unlock(&mGattUtilLock);
                return;
            }

            if (!inChr)
                logi("This descriptor not in a characteristic!\n");
            else {
                struct GattTraversedServiceCharDescr *t = realloc(inChr->descrs, sizeof(struct GattTraversedServiceCharDescr) * (inChr->numDescrs + 1));

                if (!t)
                    logi("mem error\n");
                else {
                    inChr->descrs = t;
                    inChr->descrs[inChr->numDescrs].uuid = *uuid;
                    inChr->descrs[inChr->numDescrs].handle = handle;
                    inChr->numDescrs++;
                    pthread_mutex_unlock(&mGattUtilLock);
                    return;
                }
            }
        }
        else { // enum of descrs is done - tell user & then free data
            logd("GATT util svc traversal: descr search complete\n");

            // we unlink it from the list so we can drop the lock. We do not want to hold the lock during a callback. Once unliked it CANNOT disappear from under us
            gattClientUtilSvcTraversalStructUnlink(st);
            pthread_mutex_unlock(&mGattUtilLock);
            st->cbk(conn, st->clientTrans, &st->res);
            gattClientUtilSvcTraversalStructFreeData(st);
            return;
        }
        // an error happened - clean up and tell user
        if (st) {
            clientTrans = st->clientTrans;
            cbk = st->cbk;
            gattClientUtilSvcTraversalStructFree(st);
        }
        pthread_mutex_unlock(&mGattUtilLock);
        if (cbk)
            cbk(conn, clientTrans, NULL);
    }
}

/*
 * FUNCTION: gattClientUtilFindAndTraversePrimaryServiceCharEnumCbk
 * USE:      Called by GATT code when we find a characteristic
 * PARAMS:   conn - the connection id
 *           trans - out transaction ID (matches to "->curTrans")
 *           uuid - the found uuid of the characteristic or NULL at end
 *           charHandle - the handle of the "characteristic" definition
 *           valHandle - the handle of the characteristic's "value" attribute
 *           props - character properties as per GATT
 *           status - GATT status for this search
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
static void gattClientUtilFindAndTraversePrimaryServiceCharEnumCbk(gatt_client_conn_t conn, uniq_t trans, const struct uuid *uuid, uint16_t charHandle, uint16_t valHandle, uint8_t props, uint8_t status)
{
    struct GattCliUtilSvcTraverseState* st;
    gattCliUtilSvcTraversedCbk cbk = NULL;
    uniq_t clientTrans;
    uint32_t i, j;

    pthread_mutex_lock(&mGattUtilLock);
    st = gattClientUtilSvcTraversalStructFindByTransId(trans);
    if (!st)
        logi("state for this transaction not found\n");
    else {
        if (status != GATT_CLI_STATUS_OK)
            logi("error finding characteristics");
        else if (uuid) { // a characteristic is found
            logd("GATT util svc traversal: char search produces "UUIDFMT" {0x%04x,0x%04x,0x%02x}\n", UUIDCONV(*uuid), charHandle, valHandle, props);

            struct GattTraversedServiceChar *t = realloc(st->res.chars, sizeof(struct GattTraversedServiceChar) * (st->res.numChars + 1));
            if (!t)
                logi("mem error\n");
            else {
                st->res.chars = t;
                st->res.chars[st->res.numChars].uuid = *uuid;
                st->res.chars[st->res.numChars].charProps = props;
                st->res.chars[st->res.numChars].firstHandle = charHandle;
                st->res.chars[st->res.numChars].valHandle = valHandle;
                st->res.chars[st->res.numChars].lastHandle = st->res.lastHandle; // we'll calculate this properly later, but all chars DO end where service ends
                st->res.chars[st->res.numChars].numDescrs = 0;
                st->res.chars[st->res.numChars].descrs = NULL;
                st->res.numChars++;
                pthread_mutex_unlock(&mGattUtilLock);
                return;
            }
        }
        else { // enum of chars is done
            uint16_t firstHandle, lastHandle;

            logd("GATT util svc traversal: char search complete\n");

            // calculate char ends (this is N^2, but there are never too many chars so we can live with it). a char ends where next begins. last one ends where service ends
            for (i = 0; i < st->res.numChars; i++) {
                for (j = 0; j < st->res.numChars; j++) {
                    if (st->res.chars[i].firstHandle < st->res.chars[j].firstHandle && st->res.chars[i].lastHandle >= st->res.chars[j].firstHandle)
                        st->res.chars[i].lastHandle = st->res.chars[j].firstHandle - 1;
                }
                logd("GATT util svc traversal: char "UUIDFMT" range determined to be 0x%04x-0x%04x\n", UUIDCONV(st->res.chars[i].uuid), st->res.chars[i].firstHandle, st->res.chars[i].lastHandle);
            }

            // enum descriptors (doing it all at once is simpler, but we need to filter out non-descriptor things)

            st->curTrans = trans = uniqGetNext();
            firstHandle = st->res.firstHandle;
            lastHandle = st->res.lastHandle;
            pthread_mutex_unlock(&mGattUtilLock);
            status = gattClientEnumCharDescriptors(conn, firstHandle, lastHandle, trans, gattClientUtilFindAndTraversePrimaryServiceDescrEnumCbk);
            if (status == GATT_CLI_STATUS_OK)
                return;
            pthread_mutex_lock(&mGattUtilLock);
            st = gattClientUtilSvcTraversalStructFindByTransId(trans);
        }
        // an error happened - clean up and tell user
        if (st) {
            clientTrans = st->clientTrans;
            cbk = st->cbk;
            gattClientUtilSvcTraversalStructFree(st);
        }
        pthread_mutex_unlock(&mGattUtilLock);
        if (cbk)
            cbk(conn, clientTrans, NULL);
    }
}

/*
 * FUNCTION: gattClientUtilFindAndTraversePrimaryServiceInclSvcEnumCbk
 * USE:      Called by GATT code when we find an included service
 * PARAMS:   conn - the connection id
 *           trans - out transaction ID (matches to "->curTrans")
 *           uuid - the found uuid of the included service or NULL at end
 *           includeDefHandle - the handle of the "include" definition
 *           firstHandle - the start of this included service's handle range
 *           lastHandle - the ed of this included service's handle range
 *           status - GATT status for this search
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
static void gattClientUtilFindAndTraversePrimaryServiceInclSvcEnumCbk(gatt_client_conn_t conn, uniq_t trans, const struct uuid *uuid, uint16_t includeDefHandle, uint16_t firstHandle, uint16_t lastHandle, uint8_t status)
{
    struct GattCliUtilSvcTraverseState* st;
    gattCliUtilSvcTraversedCbk cbk = NULL;
    uniq_t clientTrans;

    pthread_mutex_lock(&mGattUtilLock);
    st = gattClientUtilSvcTraversalStructFindByTransId(trans);
    if (!st)
        logi("state for this transaction not found\n");
    else {
        logd("GATT util svc traversal: include search produces return with status %u and uuid is %sNULL\n", status, uuid ? "non-" : "");

        if (status != GATT_CLI_STATUS_OK)
            logi("error finding included services");
        else if (uuid) { // an included service is found
            struct GattTraversedServiceInclSvc *t = realloc(st->res.inclSvcs, sizeof(struct GattTraversedServiceInclSvc) * (st->res.numInclSvcs + 1));
            if (!t)
                logi("mem error\n");
            else {
                st->res.inclSvcs = t;
                st->res.inclSvcs[st->res.numInclSvcs].uuid = *uuid;
                st->res.inclSvcs[st->res.numInclSvcs].includeDefHandle = includeDefHandle;
                st->res.inclSvcs[st->res.numInclSvcs].firstHandle = firstHandle;
                st->res.inclSvcs[st->res.numInclSvcs].lastHandle = lastHandle;
                st->res.numInclSvcs++;
                pthread_mutex_unlock(&mGattUtilLock);
                return;
            }
        }
        else { // enum of included services is done
            st->curTrans = trans = uniqGetNext();
            firstHandle = st->res.firstHandle;
            lastHandle = st->res.lastHandle;
            pthread_mutex_unlock(&mGattUtilLock);
            status = gattClientEnumCharacteristics(conn, firstHandle, lastHandle, trans, gattClientUtilFindAndTraversePrimaryServiceCharEnumCbk);
            if (status == GATT_CLI_STATUS_OK)
                return;
            pthread_mutex_lock(&mGattUtilLock);
            st = gattClientUtilSvcTraversalStructFindByTransId(trans);
        }
        // an error happened - clean up and tell user
        if (st) {
            clientTrans = st->clientTrans;
            cbk = st->cbk;
            gattClientUtilSvcTraversalStructFree(st);
        }
        pthread_mutex_unlock(&mGattUtilLock);
        if (cbk)
            cbk(conn, clientTrans, NULL);
    }
}

/*
 * FUNCTION: gattClientUtilFindAndTraversePrimaryServiceSvcEnumCbk
 * USE:      Called by GATT code when we find the desired service (or find it does not exist)
 * PARAMS:   conn - the connection id
 *           trans - out transaction ID (matches to "->curTrans")
 *           uuid - the found uuid (should match "->res.uuid") or NULL at end
 *           primary - is it a primary service (we expect yes)
 *           firstHandle - the start of this service's handle range
 *           numHandles - how many handles the service contains
 *           status - GATT status for this search
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
static void gattClientUtilFindAndTraversePrimaryServiceSvcEnumCbk(gatt_client_conn_t conn, uniq_t trans, const struct uuid *uuid, bool primary, uint16_t firstHandle, uint16_t numHandles, uint8_t status)
{
    uint16_t lastHandle = firstHandle + numHandles - 1;
    struct GattCliUtilSvcTraverseState* st;
    gattCliUtilSvcTraversedCbk cbk = NULL;
    uniq_t clientTrans;

    pthread_mutex_lock(&mGattUtilLock);
    st = gattClientUtilSvcTraversalStructFindByTransId(trans);
    if (!st)
        logi("state for this transaction not found\n");
    else {
        if (status == GATT_CLI_STATUS_OK && uuid && uuidCmp(uuid, &st->res.uuid) && primary) {

            st->res.firstHandle = firstHandle;
            st->res.lastHandle = lastHandle;
            st->curTrans = trans = uniqGetNext();
            pthread_mutex_unlock(&mGattUtilLock);
            logd("GATT util svc traversal: service found at 0x%04x-0x%04x. Enumerating includes\n", firstHandle, lastHandle);
            status = gattClientEnumIncludedServices(conn, firstHandle, lastHandle, trans, gattClientUtilFindAndTraversePrimaryServiceInclSvcEnumCbk);
            if (status == GATT_CLI_STATUS_OK)
                return;
            pthread_mutex_lock(&mGattUtilLock);
            st = gattClientUtilSvcTraversalStructFindByTransId(trans);
        }

        // an error happened - clean up and tell user
        if (st) {
            clientTrans = st->clientTrans;
            cbk = st->cbk;
            gattClientUtilSvcTraversalStructFree(st);
        }
        pthread_mutex_unlock(&mGattUtilLock);
        if (cbk)
            cbk(conn, clientTrans, NULL);
    }
}

/*
 * FUNCTION: gattClientUtilFindAndTraversePrimaryService
 * USE:      Perform all the work needed to completely traverse a service
 * PARAMS:   conn - the connection id
 *           svcUuid - the service uuid to find
 *           clientTrans - transaction ID (unused, passed to callback)
 *           cbk - callback to call with results
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:    if more than service with a given uuid exists, first is returned
 */
uint8_t gattClientUtilFindAndTraversePrimaryService(gatt_client_conn_t conn, const struct uuid *svcUuid, uniq_t clientTrans, gattCliUtilSvcTraversedCbk cbk)
{
    struct GattCliUtilSvcTraverseState* st = (struct GattCliUtilSvcTraverseState*)calloc(1, sizeof(struct GattCliUtilSvcTraverseState));
    uniq_t trans;
    uint8_t ret;

    if (!st)
        return GATT_CLI_STATUS_ERR;

    st->res.uuid = *svcUuid;
    st->clientTrans = clientTrans;
    st->curTrans = trans = uniqGetNext();
    st->cbk = cbk;

    pthread_mutex_lock(&mGattUtilLock);
    st->next = mUtilSvcEnumStates;
    mUtilSvcEnumStates = st;
    if (st->next)
        st->next->prev = st;
    pthread_mutex_unlock(&mGattUtilLock);
    ret = gattClientFindService(conn, true, svcUuid, trans, gattClientUtilFindAndTraversePrimaryServiceSvcEnumCbk);
    if (ret != GATT_CLI_STATUS_OK) {
        pthread_mutex_lock(&mGattUtilLock);
        st = gattClientUtilSvcTraversalStructFindByTransId(trans);
        if(st)
            gattClientUtilSvcTraversalStructFree(st);
        pthread_mutex_unlock(&mGattUtilLock);
    }
    return ret;
}

/*
 * FUNCTION: gattClientUtilLongReadStructFindByTransId
 * USE:      find a long read state structure by a transaction id
 * PARAMS:   trans - the transaction id to look for
 * RETURN:   structure pointer or NULL
 * NOTES:    call with mGattUtilLock held
 */
static struct GattCliUtilLongReadState* gattClientUtilLongReadStructFindByTransId(uniq_t trans)
{
    struct GattCliUtilLongReadState* t;

    for (t = mUtilLongReadStates; t; t = t->next) {
        if (t->curTrans == trans)
            break;
    }

    return t;
}

/*
 * FUNCTION: gattClientUtilLongReadStructUnlink
 * USE:      Unlink a long read state state struct from the list
 * PARAMS:   state the long read state state structure
 * RETURN:   NONE
 * NOTES:    call with mGattUtilLock held
 */
static void gattClientUtilLongReadStructUnlink(struct GattCliUtilLongReadState* state)
{
    // unlink from list
    if (state->prev)
        state->prev->next = state->next;
    else
        mUtilLongReadStates = state->next;
    if (state->next)
        state->next->prev = state->prev;
}

/*
 * FUNCTION: gattClientUtilLongReadStructFreeData
 * USE:      Properly free a long read state state structure's data
 * PARAMS:   state the long read state state structure
 * RETURN:   NONE
 * NOTES:    call with mGattUtilLock held
 */
static void gattClientUtilLongReadStructFreeData(struct GattCliUtilLongReadState* state)
{
    // free constituent parts & itself
    if (state->dataSoFar)
        sgFree(state->dataSoFar);
    free(state);
}

/*
 * FUNCTION: gattClientUtilLongReadReadCbk
 * USE:      Called by GATT code when a reach chunk arrives
 * PARAMS:   conn - the connection id
 *           curTrans - current transaction ID used to look up this long read operation
 *           handle - the handle that was read
 *           status - GATT status of thie read
 *           data - the data we got or NULL on EOF
 * RETURN:
 * NOTES:
 */
static void gattClientUtilLongReadReadCbk(gatt_client_conn_t conn, uniq_t curTrans, uint16_t handle, uint8_t status, sg data)
{
    struct GattCliUtilLongReadState* st;

    pthread_mutex_lock(&mGattUtilLock);
    st = gattClientUtilLongReadStructFindByTransId(curTrans);
    if (!st) {
        logi("state for this transaction not found\n");
        pthread_mutex_unlock(&mGattUtilLock);
        if (data)
            sgFree(data);
        return;
    }

    // unlikely, but why not check?
    if (handle != st->handle)
        logw("Handle mismatch is impossible with transaction match!\n");

    // if error, discard all data and tell user NO
    if (status != GATT_CLI_STATUS_OK) {
        if (st->dataSoFar)
            sgFree(st->dataSoFar);
        st->dataSoFar = NULL;
    }
    else if (data) { // some data in reply
        uint32_t rxedLen = sgLength(data);

        sgConcat(st->dataSoFar, data);
        if (rxedLen) {  // got data? ask for more
            pthread_mutex_unlock(&mGattUtilLock);
            (void)gattClientUtilLongReadScheduleNextChunk(conn, curTrans, true);
            return;
        }
    }

    // done? tell caller
    gattClientUtilLongReadStructUnlink(st);
    pthread_mutex_unlock(&mGattUtilLock);
    st->cbk(conn, st->clientTrans, st->dataSoFar);
    st->dataSoFar = NULL; // callback owns it
    gattClientUtilLongReadStructFreeData(st);
}

/*
 * FUNCTION: gattClientUtilLongReadScheduleNextChunk
 * USE:      Schedule the next read chunk for a long read operation
 * PARAMS:   conn - the connection id
 *           curTrans - current transaction ID used to look up this long read operation
 *           needCallback - set to send callback in cases of error
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:
 */
static uint8_t gattClientUtilLongReadScheduleNextChunk(gatt_client_conn_t conn, uint32_t curTrans, bool needCallback)
{
    struct GattCliUtilLongReadState* st;
    uint8_t ret, authReq;
    uint32_t offset;
    uint16_t handle;

    pthread_mutex_lock(&mGattUtilLock);
    st = gattClientUtilLongReadStructFindByTransId(curTrans);
    if (!st) {
        logi("state for this transaction not found\n");
        pthread_mutex_unlock(&mGattUtilLock);
        return GATT_CLI_STATUS_ERR;
    }

    handle = st->handle;
    authReq = st->authReq;
    offset = sgLength(st->dataSoFar);
    st->curTrans = curTrans = uniqGetNext();
    pthread_mutex_unlock(&mGattUtilLock);

    if (offset != (uint16_t)offset) {
        logi("GATT util long read: offset too large\n");
        ret = GATT_CLI_STATUS_ERR;
    }
    else {
        ret = gattClientRead(conn, handle, authReq, offset, curTrans, gattClientUtilLongReadReadCbk);
        if (ret == GATT_CLI_STATUS_OK)
            return GATT_CLI_STATUS_OK;
        logi("GATT util long read: failed to schedule a read: 0x%02x\n", ret);
    }

    //if we ge this far, we failed - cleanup
    pthread_mutex_lock(&mGattUtilLock);
    st = gattClientUtilLongReadStructFindByTransId(curTrans);
    if (!st) {
        logi("Failed to delete struct since there is no more struct\n");
        pthread_mutex_unlock(&mGattUtilLock);
        return ret;
    }
    gattClientUtilLongReadStructUnlink(st);
    pthread_mutex_unlock(&mGattUtilLock);
    if (needCallback)
        st->cbk(conn, st->clientTrans, NULL);
    gattClientUtilLongReadStructFreeData(st);
    return ret;
}

/*
 * FUNCTION: gattClientUtilLongRead
 * USE:      Perform all the work needed to completely read a handle
 * PARAMS:   conn - the connection id
 *           handle - the handle to read
 *           authReq - the authentication requirements
 *           clientTrans - transaction ID (unused, passed to callback)
 *           cbk - callback to call with results
 * RETURN:   GATT_CLI_STATUS_*
 * NOTES:    even handles cases of MTU changing during the read. Pessimistically does one extra read at end to avoid caring about MTUs
 */
uint8_t gattClientUtilLongRead(gatt_client_conn_t conn, uint16_t handle, uint8_t authReq, uniq_t clientTrans, gattCliUtilLongReadCompletedCbk cbk)
{
    struct GattCliUtilLongReadState* st = (struct GattCliUtilLongReadState*)calloc(1, sizeof(struct GattCliUtilLongReadState));
    uniq_t trans;

    if (!st)
        return GATT_CLI_STATUS_ERR;

    st->dataSoFar = sgNew();
    if (!st->dataSoFar) {
        free(st);
        return GATT_CLI_STATUS_ERR;
    }

    st->handle = handle;
    st->authReq = authReq;
    st->clientTrans = clientTrans;
    st->curTrans = trans = uniqGetNext();
    st->cbk = cbk;

    pthread_mutex_lock(&mGattUtilLock);
    st->next = mUtilLongReadStates;
    mUtilLongReadStates = st;
    if (st->next)
        st->next->prev = st;
    pthread_mutex_unlock(&mGattUtilLock);
    return gattClientUtilLongReadScheduleNextChunk(conn, trans, false); // no need for callback this first time as we're sync
}

