/*
 * 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.
 */
//todo: only one LE connection attempt can exist at a time
//our "extra" param for event filtering canhandle other events to as long as we're willing to have a giant switch-case... and check against it in all structs
//todo: always request remote versions & features before using them (eg: le encrypt support) and before telling anyone a link is up!
//todo: always set flush timout to infinite
//todo: since only one LE connection attempt can exist at a time, enqueue others...
//todo: when link up do not upcall to l2cap until we have all features and versions from the other side gotten already!
//todo: The LE_Create_Connection_Cancel command is used to cancel the LE_Create_Connection command. This command shall only be issued after the LE_Create_Connection command has been issued, a Command Status event has been received for the LE Create Connection command and before the LE Connection Complete event

#define _INCLUDED_FROM_HCI_H_
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include "newblue-macros.h"
#include "workQueue.h"
#include "vendorLib.h"
#include "hci_int.h"
#include "persist.h"
#include "config.h"
#include "timer.h"
#include "l2cap.h"
#include "aapi.h"
#include "util.h"
#include "uniq.h"
#include "hci.h"
#include "log.h"
#include "mt.h"


#define MAX_FTR_PAGES         4 /* we'll not get any more than this */
#define HCI_STAT_GOING_DOWN   0xFF


struct hciCmdHdr {
    uint16_t opcode;
    uint8_t paramLen;
} __packed;
#define CMD_MAKE_OPCODE(ogf, ocf) ((((uint16_t)((ogf) & 0x3f)) << 10) | ((ocf) & 0x03ff))
#define CMD_GET_OGF(opcode)       (((opcode) >> 10) & 0x3f)
#define CMD_GET_OCF(opcode)       ((opcode) & 0x03ff)


struct hciAclHdr {
    uint16_t hdr;
    uint16_t len;
} __packed;
#define ACL_HDR_MASK_CONN_ID      0x0FFF
#define ACL_HDR_MASK_PB           0x3000
#define ACL_HDR_MASK_BC           0xC000
#define ACL_HDR_PB_FIRST_NONAUTO  0x0000
#define ACL_HDR_PB_CONINUED       0x1000
#define ACL_HDR_PB_FIRST_AUTO     0x2000
#define ACL_HDR_PB_COMPLETE       0x3000

struct hciScoHdr {
    uint16_t hdr;
    uint8_t len;
} __packed;
#define SCO_HDR_MASK_CONN_ID      0x0FFF
#define SCO_HDR_MASK_STATUS       0x3000
#define SCO_STATUS_ALL_OK         0x0000
#define SCO_STATUS_UNKNOWN        0x1000
#define SCO_STATUS_NO_DATA        0x2000
#define SCO_STATUS_SOME_DATA      0x3000

struct hciEvtHdr {
    uint8_t code;
    uint8_t len;
} __packed;

#define ACL_CONN_ID_INVALID       (ACL_HDR_MASK_CONN_ID + 2)

/* returns true if this is the event we wanted, false else. Do not block! If evt is passed as NULL, stack is shutting down. Do not try to enqueue/dequeue handlers here either */
typedef bool (*hciEvtCbk)(const struct hciEvtHdr *evt, uint32_t evtSz, void *cbkData, uniq_t evtWaitStateID, uniq_t forCmdID);
typedef void (*hciSimpleCbk)(void* cbkData1, void* cbkData2, bool stackGoingDown, struct hciEvtHdr *evt);

struct hciEvtWaitState {
    uniq_t                  evtWaitStateID; /* used to cancel THIS waiter */
    uniq_t                  forCmdID; /* used to cancel ALL waiters for this CMD */

    struct hciEvtWaitState *next;
    struct hciEvtWaitState *prev;

    hciEvtCbk               cbk;
    void                   *cbkData;

    uint16_t                extra; /* cmd for cmd complete/statue, subevent for LE */
    uint8_t                 evtType;

    bool                    persistent; /* do not delete when it fires */
};

struct hciEvtWaitDescr {
    uint8_t    evtType; /* == 0 -> not valid/not enabled */
    uint16_t   extra;
    hciEvtCbk  cbk;
    void      *cbkData;
    bool       persistent;
};

struct hciEvtWaitDescrWithID {
    struct hciEvtWaitDescr descr;
    uniq_t id;
};

struct hciCmdSubmitWithCompleteSyncData {
    sem_t   *sem;
    void    *evtBuf;
    uint8_t  evtBufSz;
    bool     goingDown;
};

struct hciCmdSendWorkItem {
    uniq_t cmdID;
    uint8_t numEventWaiters;
    sg cmd;

    /* even handlers */
    struct hciEvtWaitDescrWithID ewds[];
};

#define CBK_WORK_ITEM_DONE_CBK      0
#define CBK_WORK_ITEM_SIMPLE_CBK    1
#define CBK_WORK_LE_DISC_DEV        2
#define CBK_WORK_FLUSH              3
#define CBK_WORK_CONN_UP            4
#define CBK_WORK_CONN_DOWN          5
#define CBK_WORK_PARAMS_CHANGE      6
#define CBK_WORK_ENCR_CHANGE        7
#define CBK_WORK_ACL_DATA           8
#define CBK_WORK_LE_KEY_REQ         9
#define CBK_WORK_ENCR_KEY_REFRESH   10
#define CBK_WORK_MAKE_NEXT_LE_CONN  11
#define CBK_WORK_ACL_RX             12

struct hciCbkWorkItem {
    uint8_t       cbkWorkItemType;

    union {
        struct {
            hciOpDoneCbk                  cbk;
            void                         *cbkData;
            uint8_t                       status;
        } done;

        struct {
            hciSimpleCbk                  cbk;
            void                         *cbkData1;
            void                         *cbkData2;
            bool                          stackGoingDown;
            bool                          haveEvt;
        } simple;

        struct {
            struct bt_addr                addr;
            uint8_t                       advType;
            int8_t                        rssi;
            uint8_t                       advLen;
            uint8_t                       adv[];
        } leDev;

        struct {
            sem_t                        *sem;
        } flush;

        struct {
            hci_conn_t                    conn;
            struct bt_addr                peerAddr;
            struct bt_addr                selfAddr;
            bool                          isMaster;
            bool                          isEncrypted;
            bool                          isMitmSafe;
        } connUp;

        struct {
            hci_conn_t                    conn;
            uint8_t                       reason;
        } connDown;

        struct {
            hci_conn_t                    conn;
            bool                          success;
            uint16_t                      interval;
            uint16_t                      latency;
            uint16_t                      timeout;
        } leParamChange;

        struct {
            hci_conn_t                    conn;
            bool                          nowEncrypted;
            bool                          isMitmSafe;
        } encrChange;

        struct {
            hci_conn_t                    conn;
            bool                          nowEncrypted;
            bool                          isMitmSafe;
        } encrKeyRefresh;

        struct {
            hci_conn_t                    conn;
            sg                            packet;
            bool                          first;
        } aclDataRx;

        struct {
            hci_conn_t                    conn;
            uint64_t                      randomNum;
            uint16_t                      diversifier;
        } leKeyReq;

        struct {
            uint16_t                      hdr;
            sg                            packet;
        } aclRx;
    };
};

struct hciBacklogItemHdr {
    uint32_t len;
    uint16_t aclHdr;
} __packed;

struct hciSimpleCbkData {
    hciSimpleCbk  cbk; /* may be null */
    void         *cbkData1;
    void         *cbkData2;
    uint8_t       expectedParamLenMin;
    uint8_t       expectedParamLenMax;
    uint8_t       wantEventItself  :1;
    uint8_t       complete         :1;
};

struct hciAclConn {
    struct hciAclConn *next;
    struct hciAclConn *prev;
    struct bt_addr     peerAddr;
    struct bt_addr     selfAddr;
    hci_conn_t         handle;

    uint16_t           id;
    bool               isMaster;
    bool               encrypted;
    bool               mitmSafe;
    uint8_t            state; /* CONN_STATE_* */
    sg                 rxBacklog; /* data we RXed during configuration stage */
    uint32_t           outstandingPackets;

    union {
        struct {
            uint64_t       ftrs;
            uint16_t       interval;
            uint16_t       latency;
            uint16_t       timeout;
            uint8_t        mca;
            hci_adv_set_t  advSet;
        } le;
        //EDR struct here if needed
    };
};

struct hciAdvSet {
    /* bookkeeping */
    struct hciAdvSet  *next;
    struct hciAdvSet  *prev;
    hci_adv_set_t      handle;

    /* hw state */
    uint16_t           hwSetNum;
    bool               hwEnabled;
    int8_t             hwPowerLevel; /* if hw supports power setting, must be populated when enabled */

    /* user data */
    uint32_t           advDataLen;
    uint32_t           scanRspDataLen;
    uint8_t            advData[HCI_ADV_DATA_MAX_LEN];
    uint8_t            scanRspData[HCI_SCAN_RSP_DATA_MAX_LEN];
    uint16_t           intervalMin;
    uint16_t           intervalMax;
    uint8_t            advType;
    uint8_t            ownAddressType;
    struct bt_addr     ownRandomAddr; //only used if random addr selected
    struct bt_addr     directAddr;
    uint8_t            channelMap;
    uint8_t            filterPolicy;
    int8_t             powerLevel;
};

struct hciLeConnReq {
    struct hciLeConnReq *next;
    hci_conn_t aclConn;
    uint16_t scanInt;
    uint16_t scanWindow;
    uint16_t intMin;
    uint16_t intMax;
    uint16_t latency;
    uint16_t timeout;
    bool useRandomAddr;
    uint8_t selfRandomAddr[BT_MAC_LEN];
};

#define CONN_STATE_WAIT            0
#define CONN_STATE_TRYING          1
#define CONN_STATE_ADV_SET_BLAMING 2
#define CONN_STATE_CFG             3
#define CONN_STATE_RUNNING         4
#define CONN_STATE_DELETING        5

#define CONN_CFG_STEP_LE           0x0000

#define ADV_SET_BLAME_TIMEOUT_ANDROID_VENDOR    100 /* 100ms is as good a number as any */

#define STACK_STATE_DOWN           0 //down and not ready for up
#define STACK_STATE_READY_FOR_UP   1 //ready to be brought up
#define STACK_STATE_COMING_UP      2 //on the way up
#define STACK_STATE_UP             3 //working
#define STACK_STATE_GOING_DOWN     4 //on the way down

/* useful constants */
static const char *mBtVers[] = {"1.0b", "1.1", "1.2", "2.0", "2.1", "3.0", "4.0", "4.1", "4.2", "5.0"};

/* our state */

static pthread_mutex_t mCmdWaitLock = PTHREAD_MUTEX_INITIALIZER;
static struct hciEvtWaitState *mEvtWaitHead = NULL;
static struct hciEvtWaitState *mEvtWaitTail = NULL;

static pthread_mutex_t mCmdLock = PTHREAD_MUTEX_INITIALIZER;
static sem_t mCmdSendSem;
static struct workQueue* mCmdsSendWork;
static pthread_t mCmdsSendThread;
static uint8_t mStackState = STACK_STATE_DOWN;
static hciReadyForUpCbk mReadyForUpCbk;
static void *mReadyForUpData;

static struct workQueue* mCallbackWork;
static pthread_t mCallbackThread;

static pthread_mutex_t mConnsLock = PTHREAD_MUTEX_INITIALIZER;
static struct hciAclConn *mConns = NULL;
static struct hciLeConnReq *mLeConnReqsHead = NULL;
static struct hciLeConnReq *mLeConnReqsTail = NULL;
static bool mLeConnInProgress = false;

static pthread_mutex_t mAdvSetsLock = PTHREAD_MUTEX_INITIALIZER;
static struct hciAdvSet *mAdvSets = NULL;

static pthread_mutex_t mDiscoveryStateLock = PTHREAD_MUTEX_INITIALIZER;

static hciDeviceDiscoveredLeCbk mDiscoverLeCbk;
static void *mDiscoverLeData;
static uniq_t mDiscoverLeHandle = 0;



/* read from chip */
static uint8_t mBtVer = 0; /* HCI_VERSION_* */
static uint64_t mLocalFtrs[MAX_FTR_PAGES] = {0, };
static uint64_t mLocalLeFtrs = 0;
static uint16_t mScoBufSz = 0;
static uint16_t mAclBufSzEdr = 0;
static uint16_t mAclBufSzLe = 0;
static uint16_t mScoBufNum = 0;
static uint16_t mAclBufNumEdr = 0;
static uint16_t mAclBufNumLe = 0;
static bool mBtJointBuffers = true; /* use EDR buffers for LE */
static sem_t mAclPacketsLe;
static sem_t mAclPacketsEdr;
static uint8_t mLocalAddr[BT_MAC_LEN];
static uint16_t mMaxAdvSets;
static bool mCanSetAdvTxPower;


/* fwd declarations */
static bool hciBtStackUp(void);
static bool hciScheduleMakeProgressOnLeConnectionReqs(void); //necessary if we are in evt rx thread
static void hciMakeProgressOnLeConnectionReqs(void);
static bool hciScheduleConnUpNotif(hci_conn_t conn, const struct bt_addr *peerAddr, const struct bt_addr *selfAddr, bool isMaster, bool isEncrypted, bool isMitmSafe);
static bool hciScheduleConnDownNotif(hci_conn_t conn, uint8_t reason);
static bool hciScheduleConnDataRx(hci_conn_t conn, sg packet, bool first);
static bool hciCmdSubmitSimpleWithStatusWithDoneCbk(uint8_t ogf, uint16_t ocf, const void* paramData, uint8_t paramLen, hciOpDoneCbk cbk, void *cbkData);
static bool hciCmdSubmitSimpleWithCompleteSync(uint8_t ogf, uint16_t ocf, const void* paramData, uint8_t paramLen, void* evtBuf, uint8_t evtBufSz);
static bool hciCmdSubmitSimpleWithStatusSync(uint8_t ogf, uint16_t ocf, const void *paramData, uint8_t paramLen, struct hciEvtCmdStatus *dstEvt);
static void hciHandleConnAclDown(uint16_t cid, uint8_t reason);
static bool hciHandleConnAclLeUp(uint8_t status, uint16_t id, bool isMaster, const uint8_t *mac, bool addrRandom, uint16_t interval, uint16_t latency, uint16_t timeout, uint8_t mca);
static bool hciHandleConnAclEncr(uint16_t cid, bool encrOn);
static bool hciHandleConnAclAuth(uint16_t cid, bool authOn);
static bool hciHandleConnAclEncrKeyRefresh(uint16_t cid, bool encrOn);
static bool hciHandleConnAclLeUpdate(uint8_t status, uint16_t cid, uint16_t interval, uint16_t latency, uint16_t timeout);
static bool hciHandleConnLeLtkReq(uint16_t cid, uint64_t randomNum, uint16_t diversifier);
static bool hciConnUpdate(uint16_t cid, uint16_t minInt, uint16_t maxInt, uint16_t latency, uint16_t timeout);
static void hciCmdStatusCbk(void *cbkData, uint8_t status);
static bool hciConnDisconnect(uint16_t cid);
static bool hciConnLeCancel(void);
static void hciConnCfg(struct hciAclConn *c, uint32_t step, uint32_t aux);
static bool hciRxAclForRunningConn(struct hciAclConn* conn, uint16_t hdr, sg packet);
static void hciRxAcl(uint16_t hdr, sg packet);
static bool hciScheduleAclRx(uint16_t hdr, sg packet);
static void hciConnAclStructDel(struct hciAclConn* conn);
static bool hciSetupResetEventHandler(bool cmdWaitLockHeld);
static void hciAdvSetGetCurAdvAddrLocked(struct hciAdvSet *set, struct bt_addr *ownAddr);

/* adv indirection function pointers. Called with mAdvSetsLock held*/
static bool (*mHciAdvSetEnable)(struct hciAdvSet *set, bool enable);
static bool (*mHciAdvSetHandleAndBlameNewConn)(struct hciAclConn *conn); //return true if done, false if not yet. if false is returned, you MUST later call hciConnCfg(c, CONN_CFG_STEP_LE, 0); and set state to CFG when decided



/* templated commands - they need the above vars hence include here */
#include "hci_templated_commands.h"


/*
 * FUNCTION: hciConnFindById
 * USE:      Find a connection struct given an ID
 * PARAMS:   id - the id
 * RETURN:   connection struct or NULL if not found
 * NOTES:    call with mConnsLock held
 */
static struct hciAclConn* hciConnFindById(uint16_t id)
{
    struct hciAclConn *c = mConns;

    while (c && c->id != id)
        c = c->next;

    return c;
}

/*
 * FUNCTION: hciConnFindByHandle
 * USE:      Find a connection struct given a handle
 * PARAMS:   addr - the address
 * RETURN:   connection struct or NULL if not found
 * NOTES:    call with mConnsLock held
 */
static struct hciAclConn* hciConnFindByHandle(hci_conn_t handle)
{
    struct hciAclConn *c = mConns;

    while (c && c->handle != handle)
        c = c->next;

    return c;
}

/*
 * FUNCTION: hciConnFindByAddr
 * USE:      Find a connection struct given an address
 * PARAMS:   addr - the address
 * RETURN:   connection struct or NULL if not found
 * NOTES:    call with mConnsLock held
 */
static struct hciAclConn* hciConnFindByAddr(const struct bt_addr *addr)
{
    struct hciAclConn *c = mConns;

    while (c && memcmp(&c->peerAddr, addr, sizeof(c->peerAddr)))
        c = c->next;

    return c;
}

/*
 * FUNCTION: hciEvtWaitDequeueInt
 * USE:      Dequeue a handler for an event we expect
 * PARAMS:   ws - the handler struct
 * RETURN:   NONE
 * NOTES:    call with mCmdWaitLock held
 */
static void hciEvtWaitDequeueInt(struct hciEvtWaitState *ws)
{
    if (ws->next)
        ws->next->prev = ws->prev;
    else
        mEvtWaitTail = ws->prev;

    if (ws->prev)
        ws->prev->next = ws->next;
    else
        mEvtWaitHead = ws->next;

    free(ws);
}

/*
 * FUNCTION: hciEvtWaitDequeue
 * USE:      Dequeue a handler for an event we expect
 * PARAMS:   evtWaitStateID - wait state ID from hciEvtWaitEnqueue()
 * RETURN:   true if dequeued, false if not found (already fired or never existed)
 * NOTES:
 */
static bool hciEvtWaitDequeue(uniq_t evtWaitStateID)
{
    struct hciEvtWaitState *ws;
    bool found = true;

    pthread_mutex_lock(&mCmdWaitLock);

    ws = mEvtWaitHead;
    while (ws && ws->evtWaitStateID != evtWaitStateID)
        ws = ws->next;

    if (ws)
        hciEvtWaitDequeueInt(ws);
    else
        found = false;

    pthread_mutex_unlock(&mCmdWaitLock);

    return found;
}
/*
 * FUNCTION: hciEvtWaitDequeueAllForCmd
 * USE:      Dequeue all handler for a given command ID
 * PARAMS:   forCmdID - command ID as passed to hciEvtWaitEnqueue();
 * RETURN:   how many handlers were dequeued
 * NOTES:
 */
static uint8_t hciEvtWaitDequeueAllForCmd(uniq_t forCmdID)
{
    struct hciEvtWaitState *ws, *t;
    uint8_t found = 0;

    pthread_mutex_lock(&mCmdWaitLock);

    ws = mEvtWaitHead;
    while (ws) {
        t = ws;
        ws = ws->next;

        if (t->forCmdID == forCmdID) {
            hciEvtWaitDequeueInt(ws);
            found++;
        }
    }

    pthread_mutex_unlock(&mCmdWaitLock);

    return found;
}

/*
 * FUNCTION: hciEvtWaitEnqueueUnlocked
 * USE:      Enqueue a handler for an event we expect
 * PARAMS:   ewd - the event wait descriptor
 *           forCmdID - the commandID this is for
 * RETURN:   uniq_t identifying this event wait object or 0 on failure
 * NOTES:    must be called with mCmdWaitLock held
 */
static uniq_t hciEvtWaitEnqueueUnlocked(const struct hciEvtWaitDescr *ewd, uniq_t forCmdID)
{
    struct hciEvtWaitState *ws = (struct hciEvtWaitState*)malloc(sizeof(struct hciEvtWaitState));
    uniq_t ret;

    if (!ws) {
        loge("Failed to enqueue handler for event 0x%02X.%04X\n", ewd->evtType, ewd->extra);
        return 0;
    }

    ret = uniqGetNext();

    ws->cbk = ewd->cbk;
    ws->cbkData = ewd->cbkData;
    ws->evtType = ewd->evtType;
    ws->extra = ewd->extra;
    ws->persistent = ewd->persistent;
    ws->next = NULL;
    ws->evtWaitStateID = ret;
    ws->forCmdID = forCmdID;

    ws->prev = mEvtWaitTail;
    mEvtWaitTail = ws;
    if (ws->prev)
        ws->prev->next = ws;
    else
        mEvtWaitHead = ws;

    return ret;
}

/*
 * FUNCTION: hciEvtWaitEnqueue
 * USE:      Enqueue a handler for an event we expect
 * PARAMS:   ewd - the event wait descriptor
 *           forCmdID - the commandID this is for
 * RETURN:   uniq_t identifying this event wait object or 0 on failure
 * NOTES:
 */
static uniq_t hciEvtWaitEnqueue(const struct hciEvtWaitDescr *ewd, uniq_t forCmdID)
{
    uniq_t ret;

    pthread_mutex_lock(&mCmdWaitLock);
    ret = hciEvtWaitEnqueueUnlocked(ewd, forCmdID);
    pthread_mutex_unlock(&mCmdWaitLock);

    return ret;
}

/*
 * FUNCTION: hciCbkChipHwUp
 * USE:      Called when the chip hw or fw are up
 * PARAMS:   cbkData - unused
 *           fw - true if fw status, false if hw
 *           up - success of bringing said component up
 * RETURN:   true on success, false else
 * NOTES:
 */
static void hciCbkChipHwUp(void *cbkData, bool fw, bool up)
{
    logi("BT %cW %s!\n", fw ? 'F' : 'H', up ? "UP" : "DOWN");
}

/*
 * FUNCTION: hciRxAclForRunningConn
 * USE:      Called with a valid ACL packet/fragment for a running connection
 * PARAMS:   conn - the connection this is for
 *           hdr - packet header
 *           packet - the packet we got
 * RETURN:   NONE
 * NOTES:    call with mConnsLock held
 */
static bool hciRxAclForRunningConn(struct hciAclConn* conn, uint16_t hdr, sg packet)
{
    uint16_t pb = hdr & ACL_HDR_MASK_PB;

    if (pb == ACL_HDR_PB_FIRST_NONAUTO || pb == ACL_HDR_PB_COMPLETE) {
        logw("Invalid acl.pb flag from chp: 0x%04X. Dropped\n", pb);
        return false;
    }

    return hciScheduleConnDataRx(conn->handle, packet, pb == ACL_HDR_PB_FIRST_AUTO);
}

/*
 * FUNCTION: hciRxAcl
 * USE:      Called with a valid ACL packet/fragment
 * PARAMS:   hdr - packet header
 *           packet - the packet we got
 * RETURN:   NONE
 * NOTES:
 */
static void hciRxAcl(uint16_t hdr, sg packet)
{
    uint16_t cid = hdr & ACL_HDR_MASK_CONN_ID;
    struct hciAclConn* conn;


    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindById(cid);
    if (!conn) {
        logi("Dropping packet for unknown acl link %d\n", cid);
        sgFree(packet);
    } else if (conn->state == CONN_STATE_CFG) {
        struct hciBacklogItemHdr itemHdr = {.len = sgLength(packet), .aclHdr = hdr};

        if (!conn->rxBacklog)
            conn->rxBacklog = sgNew();

        if (conn->rxBacklog && sgConcatFrontCopy(packet, &itemHdr, sizeof(itemHdr)) && sgLength(conn->rxBacklog) + sgLength(packet) <= HCI_CONN_CFG_DATA_BACKLOG_MAX) {
            sgConcat(conn->rxBacklog, packet);
            logd("Added packet to RX backlog\n");
        } else {
            logi("Dropping connection -> we're unable to save RX in backlog\n");
            hciConnDisconnect(conn->id);
            sgFree(packet);
        }
    } else if (conn->state != CONN_STATE_RUNNING) {
        logi("Dropping arrived data for connection in state %u\n", conn->state);
        sgFree(packet);
    } else if (!hciRxAclForRunningConn(conn, hdr, packet)) {
        logi("Failed to enqueue packet RX for link %d\n", cid);
        sgFree(packet);
    }
    pthread_mutex_unlock(&mConnsLock);
}

/*
 * FUNCTION: hciRxEvt
 * USE:      Called with a valid EVT packet
 * PARAMS:   packet - the packet we got
 * RETURN:   NONE
 * NOTES:
 */
static void hciRxEvt(sg packet)
{
    struct hciEvtWaitState *ws = NULL, *cur = NULL;
    bool handled = false, addCredit = false;
    const struct hciEvtCmdComplete *cmdComplete;
    const struct hciEvtCmdStatus *cmdStatus;
    const struct hciEvtLeMeta *leMeta;
    const struct hciEvtVendor *vendor;
    const struct hciEvtHdr *evt;
    uint8_t evtType, len;
    uint32_t i, evtLen;
    void* sgiter;


    /*
     * The SG may or may not be contiguous on the inside. If it is not, we'll alloc a new buffer
     * and serialize the SG into it. If it is, we can just use the SG's internal buffer. How do
     * we check? Iterate SG of course... Why? To save a copy and a malloc() & a free()
     */
    sgiter = sgIterStart(packet);
    evtLen = sgLength(packet);
    if (sgiter && sgIterCurLen(sgiter) == evtLen)
        evt = (const struct hciEvtHdr*)sgIterCurData(sgiter);
    else {
        evt = malloc(evtLen);
        if (!evt) {
            loge("Failed to alloc flat event representation\n");
            sgFree(packet);
        }
        sgSerialize(packet, 0, evtLen, (struct hciEvtHdr*)evt);
        sgiter = NULL;
        sgFree(packet);
    }

    leMeta = (struct hciEvtLeMeta*)(evt + 1);
    vendor = (struct hciEvtVendor*)(evt + 1);
    cmdComplete = (struct hciEvtCmdComplete*)(evt + 1);
    cmdStatus = (struct hciEvtCmdStatus*)(evt + 1);

    evtType = utilGetLE8(&evt->code);
    len = utilGetLE8(&evt->len);

    /* handle the cases of credits: command complete */
    if (evtType == HCI_EVT_Command_Complete && utilGetLE8(&cmdComplete->numCmdCredits))
        addCredit = true;

    /* handle the cases of credits: command status */
    if (evtType == HCI_EVT_Command_Status && utilGetLE8(&cmdStatus->numCmdCredits))
        addCredit = true;

    /* handle data credits */
    if (evtType == HCI_EVT_Number_Of_Completed_Packets) {
        bool hadLeCreds = false, hadEdrCreds = false;
        uint16_t newCreditsEdr = 0, newCreditsLe = 0;
        struct hciAclConn* conn;
        struct hciEvtNumCompletedPackets *ncp = (struct hciEvtNumCompletedPackets*)(evt + 1);
        struct hciEvtNumCompletedPacketsItem *items = ncp->items;

        pthread_mutex_lock(&mConnsLock);
        for (i = 0; i < utilGetLE8(&ncp->numHandles); i++, items++) {
            uint16_t connID = utilGetLE16(&items->conn);
            uint16_t numPackets = utilGetLE16(&items->numPackets);
            uint8_t acceptCredits = 0;

            conn = hciConnFindById(connID);
            if (!conn) {
                loge("Unknown conn 0x%04X in %d packets completed.\n", connID, numPackets);
            } else {
                if (conn->outstandingPackets >= numPackets) {
                    acceptCredits = numPackets;
                    conn->outstandingPackets -= numPackets;
                } else {
                    loge("Conn %u has %u outstanding packets but got %u credits back.\n", (unsigned)conn->id, conn->outstandingPackets, numPackets);
                    acceptCredits = conn->outstandingPackets;
                    conn->outstandingPackets = 0;
                }
            }
            if (HCI_TAKE_CREDS_FOR_UNKNOWN_CONNS && acceptCredits != numPackets) {
                logw("Accepting %d credits for unknown packets\n", numPackets - acceptCredits);
                acceptCredits = numPackets;
            }
            if (BT_ADDR_IS_LE(conn->peerAddr) && !mBtJointBuffers) {
                hadLeCreds = true;
                newCreditsLe += acceptCredits;
            } else {
                hadEdrCreds = true;
                newCreditsEdr += acceptCredits;
            }
        }
        pthread_mutex_unlock(&mConnsLock);
        while (newCreditsLe--)
            sem_post(&mAclPacketsLe);
        while (newCreditsEdr--)
            sem_post(&mAclPacketsEdr);
        if (hadLeCreds || (hadEdrCreds && mBtJointBuffers))
            l2cAclCreditAvail(true);
        handled = true;
    }

    /* handle command complete with ocf == 0 and ogf == 0 by ignoring it as per spec */
    if (evtType == HCI_EVT_Command_Complete && !utilGetLE16(&cmdComplete->opcode))
        handled = true;

    /* handle HW failure */
    if (evtType == HCI_EVT_Hardware_Error) {
        struct hciEvtHwError *hwErr = (struct hciEvtHwError*)(evt + 1);
        loge("Chip reported HW failure, code %d -> catastropic stack failure\n", utilGetLE8(&hwErr->errCode));
        abort();
    }

    if (!handled) {

        pthread_mutex_lock(&mCmdWaitLock);
        ws = mEvtWaitHead;
        while (ws && !handled) {
            cur = ws;
            ws = ws->next;

            /* type match? If no, do not go on */
            if (evtType != cur->evtType)
                continue;

            /* if LE & Vendor events, check code and skip handler if wrong */
            if (evtType == HCI_EVT_LE_Meta) {
                if(len < sizeof(struct hciEvtLeMeta)) {
                    logw("Got LE meta event of len %ub\n", len);
                    break;
                }
                if (utilGetLE8(&leMeta->subevent) != cur->extra)
                    continue;
            }
            if (evtType == HCI_EVT_Vendor) {
                if(len < sizeof(struct hciEvtVendor)) {
                    logw("Got vendor event of len %ub\n", len);
                    break;
                }
                if (utilGetLE8(&vendor->subevent) != cur->extra)
                    continue;
            }

            /* same for command complete */
            if (evtType == HCI_EVT_Command_Complete) {
                if(len < sizeof(struct hciEvtCmdComplete)) {
                    logw("Got command complete event of len %ub\n", len);
                    break;
                }
                if (utilGetLE16(&cmdComplete->opcode) != cur->extra)
                    continue;
            }

            /* same for command status */
            if (evtType == HCI_EVT_Command_Status) {
                if(len < sizeof(struct hciEvtCmdStatus)) {
                    logw("Got command status event of len %ub\n", len);
                    break;
                }
                if (utilGetLE16(&cmdStatus->opcode) != cur->extra)
                    continue;
            }

            /* if we're here, this handler matches - let's see what it says */
            handled = cur->cbk(evt, evtLen, cur->cbkData, cur->evtWaitStateID, cur->forCmdID);
        }

        if (handled && cur && !cur->persistent)
            hciEvtWaitDequeueInt(cur);
        if (mStackState == STACK_STATE_GOING_DOWN) {
            //if we are now in reset, delete all waiters. reset handler code cannot do it as we still hold the lock
            while (mEvtWaitHead)
                 hciEvtWaitDequeueInt(mEvtWaitHead);
            hciSetupResetEventHandler(true);
            mStackState = STACK_STATE_DOWN;
        }
        pthread_mutex_unlock(&mCmdWaitLock);
    }

    if (addCredit) {
        sem_post(&mCmdSendSem);
        if (mStackState == STACK_STATE_DOWN) {
            mStackState = STACK_STATE_READY_FOR_UP;
            if (mReadyForUpCbk)
                mReadyForUpCbk(mReadyForUpData);
        }
    }

    if (!handled)
        logw("Unhandled HCI event code 0x%02X with %ub of params\n", evtType, len);

    if (sgiter)
        sgFree(packet);
    else
        free((struct hciEvtHdr*)evt);
}

/*
 * FUNCTION: hciRx
 * USE:      Called when the chip gives us data/events
 * PARAMS:   cbkData - unused
 *           typ - type of thing we're getting
 *           packet - the packet we got
 * RETURN:   true on success, false else
 * NOTES:    we must free the "data" buffer at some point in time - we own it now
 */
static void hciRx(void *cbkData, uint8_t typ, sg packet)
{
    struct hciAclHdr hdrAcl;
    struct hciEvtHdr hdrEvt;
    uint32_t datalen = sgLength(packet);
    uint32_t len;
    uint16_t hdr;

    switch (typ){
    case HCI_PKT_TYP_ACL:
        if (datalen < sizeof(struct hciAclHdr)) {
            loge("Got ACL packet of %ub\n", datalen);
            break;
        }
        datalen -= sizeof(struct hciAclHdr);
        sgSerialize(packet, 0, sizeof(struct hciAclHdr), &hdrAcl);
        hdr = utilGetLE16(&hdrAcl.hdr);
        len = utilGetLE16(&hdrAcl.len);
        if (len != datalen) {
            loge("ACL packet claims %ub but had %ub\n", len, datalen);
            break;
        }
        sgTruncFront(packet, sizeof(struct hciAclHdr));
        if (hciScheduleAclRx(hdr, packet))
            packet = NULL;
        else
            logw("Dropping data packet\n");
        break;
    case HCI_PKT_TYP_SCO:
        loge("Got SCO packet\n");
        break;
    case HCI_PKT_TYP_EVT:
        if (datalen < sizeof(struct hciEvtHdr)) {
            loge("Got EVT packet of %ub\n", datalen);
            break;
        }
        datalen -= sizeof(struct hciEvtHdr);
        sgSerialize(packet, 0, sizeof(struct hciEvtHdr), &hdrEvt);
        len = utilGetLE8(&hdrEvt.len);
        if (len != datalen) {
            loge("EVT packet claims %ub but had %ub\n", len, datalen);
            break;
        }
        hciRxEvt(packet);
        packet = NULL;
        break;
    default:
        loge("Dropping unknown packet with type %d\n", typ);
        break;
    }

    if (packet)
        sgFree(packet);
}

/*
 * FUNCTION: hciCallbackWorkDeallocator
 * USE:      Called to cleanup each item of callback workqueue at deinit time
 * PARAMS:   workItem - a work item
 * RETURN:   NONE
 * NOTES:
 */
static void hciCallbackWorkDeallocator(void *workItem)
{
    struct hciCbkWorkItem *w = (struct hciCbkWorkItem*)workItem;


    if (w->cbkWorkItemType == CBK_WORK_ACL_DATA)
        sgFree(w->aclDataRx.packet);
    else if (w->cbkWorkItemType == CBK_WORK_ACL_RX)
        sgFree(w->aclRx.packet);

    free(workItem);
}

/*
 * FUNCTION: hciCallbackWorkDeallocator
 * USE:      Called to cleanup each item of command send workqueue at deinit time
 * PARAMS:   workItem - a work item
 * RETURN:   NONE
 * NOTES:
 */
static void hciCmdSendWorkDeallocator(void *workItem)
{
    struct hciCmdSendWorkItem *w = (struct hciCmdSendWorkItem*)workItem;

    sgFree(w->cmd);
    free(workItem);
}

/*
 * FUNCTION: hciCbkWorkLeLtkReq
 * USE:      Called in worker thread - request key from someone
 * PARAMS:   aclConn - the connection
 *           randomNum - provied by other side
 *           diversifier - provied by other side
 * RETURN:   none
 * NOTES:    caller should soon call hciLeProvideLtk() with reply
 */
static void hciCbkWorkLeLtkReq(hci_conn_t aclConn, uint64_t randomNum, uint16_t diversifier)
{
    struct hciAclConn* conn;

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindByHandle(aclConn);
    if (!conn)
        logd("Conn for key req not found\n");
    else if (!l2cAclLeLtkRequest(aclConn, randomNum, diversifier)) {
        logd("LTK key req from L2C failed - assuming no key\n");
        struct hciLeLtkRequestNegativeReply cmd;
        utilSetLE16(&cmd.conn, conn->id);
        //we cannot call a sync function in this thread, so do the async thing
        if (!hciCmdSubmitSimpleWithStatusWithDoneCbk(HCI_OGF_LE, HCI_CMD_LE_LTK_Request_Negative_Reply, &cmd, sizeof(cmd), hciCmdStatusCbk, NULL)) {
            logi("Failed to request negative link key reply for acl conn "HCI_CONN_FMT"u (id %u)\n", HCI_CONN_CONV(aclConn), conn->id);
        }
    }
    pthread_mutex_unlock(&mConnsLock);
}

/*
 * FUNCTION: hciLeProvideLtk
 * USE:      Called by higher layer - provide key
 * PARAMS:   aclConn - the connection
 *           key - key to use or NULL if none
 * RETURN:   false on error
 * NOTES:    proper hci reply command will be called
 */
bool hciLeProvideLtk(hci_conn_t aclConn, const uint8_t *key)
{
    struct hciAclConn* conn;
    bool ret = false;

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindByHandle(aclConn);
    if (!conn)
        logd("Conn for key req reply found\n");
    else if (key)
        ret = !hciLeLtkRequestReplySync(conn->id, key);
    else
        ret = !hciLeLtkRequestNegativeReplySync(conn->id);
    pthread_mutex_unlock(&mConnsLock);

    return ret;
}

/*
 * FUNCTION: hciCbkWorker
 * USE:      Worker thread for calling callbacks for HCI completed items
 * PARAMS:   unused - unused
 * RETURN:   unused
 * NOTES:
 */
static void* hciCbkWorker(void *unused)
{
    struct hciCbkWorkItem *w;
    int ret;

    pthread_setname_np(pthread_self(), "bt_hci_callbacks");

    while (1) {

        ret = workQueueGet(mCallbackWork, (void**)&w);
        if (ret)
            break;

        switch (w->cbkWorkItemType){
        case CBK_WORK_ITEM_DONE_CBK:
            w->done.cbk(w->done.cbkData, w->done.status);
            break;
        case CBK_WORK_ITEM_SIMPLE_CBK:
            w->simple.cbk(w->simple.cbkData1, w->simple.cbkData2, w->simple.stackGoingDown, w->simple.haveEvt ? (struct hciEvtHdr*)(w + 1) : NULL);
            break;
        case CBK_WORK_LE_DISC_DEV:
            mDiscoverLeCbk(mDiscoverLeData, &w->leDev.addr, w->leDev.rssi, w->leDev.advType, w->leDev.adv, w->leDev.advLen);
            break;
        case CBK_WORK_FLUSH:
            sem_post(w->flush.sem);
            break;
        case CBK_WORK_CONN_UP:
            l2cAclLinkUp(w->connUp.conn, &w->connUp.peerAddr, &w->connUp.selfAddr, w->connUp.isMaster, w->connUp.isEncrypted, w->connUp.isMitmSafe);
            break;
        case CBK_WORK_CONN_DOWN:
            l2cAclLinkDown(w->connDown.conn, w->connDown.reason);
            break;
        case CBK_WORK_PARAMS_CHANGE:
            l2cAclLinkParamsChange(w->leParamChange.conn, w->leParamChange.success, w->leParamChange.interval, w->leParamChange.latency, w->leParamChange.timeout);
            break;
        case CBK_WORK_ENCR_CHANGE:
            l2cAclLinkEncrChange(w->encrChange.conn, w->encrChange.nowEncrypted, w->encrChange.isMitmSafe);
            break;
        case CBK_WORK_ACL_DATA:
            l2cAclDataRx(w->aclDataRx.conn, w->aclDataRx.packet, w->aclDataRx.first);
            break;
        case CBK_WORK_LE_KEY_REQ:
            hciCbkWorkLeLtkReq(w->leKeyReq.conn, w->leKeyReq.randomNum, w->leKeyReq.diversifier);
            break;
        case CBK_WORK_ENCR_KEY_REFRESH:
            l2cAclLinkEncrKeyRefresh(w->encrKeyRefresh.conn, w->encrKeyRefresh.nowEncrypted, w->encrKeyRefresh.isMitmSafe);
            break;
        case CBK_WORK_MAKE_NEXT_LE_CONN:
            hciMakeProgressOnLeConnectionReqs();
            break;
        case CBK_WORK_ACL_RX:
            hciRxAcl(w->aclRx.hdr, w->aclRx.packet);
            break;
        default:
            loge("Unknown callback work type %u\n", w->cbkWorkItemType);
            break;
        }
        free(w);
    }
    logd("HCI callback worker exiting\n");

    return NULL;
}

/*
 * FUNCTION: hciScheduleOpDoneCbk
 * USE:      Enqueue an op_done callback to be called
 * PARAMS:   cbk - the callback to call
 *           cbkData - the data for said callback
 *           status - the status byte
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleOpDoneCbk(hciOpDoneCbk cbk, void *cbkData, uint8_t status)
{
    struct hciCbkWorkItem *w;

    if (!cbk) {
        logw("Not scheduling done callback with a NULL function pointer\n");
        return true;
    }

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_ITEM_DONE_CBK;
    w->done.cbk = cbk;
    w->done.cbkData = cbkData;
    w->done.status = status;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleSimpleCbk
 * USE:      Enqueue simple callback to be called
 * PARAMS:   cbk - the callback to call
 *           cbkData1 - the data for said callback
 *           cbkData2 - the data for said callback
 *           stackGoingDown - as the name implies...
 *           evt - event to provide, or NULL if none
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleSimpleCbk(hciSimpleCbk cbk, void *cbkData1, void *cbkData2, bool stackGoingDown, const struct hciEvtHdr *evt)
{
    uint16_t evtLen = evt ? (sizeof(struct hciEvtHdr) + utilGetLE8(&evt->len)) : 0;
    uint32_t neededLen = sizeof(struct hciCbkWorkItem) + evtLen;
    struct hciCbkWorkItem *w;

    if (!cbk) {
        logw("Not scheduling simple callback with a NULL function pointer\n");
        return true;
    }

    w = (struct hciCbkWorkItem*)malloc(neededLen);
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_ITEM_SIMPLE_CBK;
    w->simple.cbk = cbk;
    w->simple.cbkData1 = cbkData1;
    w->simple.cbkData2 = cbkData2;
    w->simple.stackGoingDown = stackGoingDown;
    w->simple.haveEvt = evt != NULL;

    if (evt)
        memcpy(w + 1, evt, evtLen);

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciWorkFlush
 * USE:      Flush the workQueue
 * PARAMS:   NONE
 * RETURN:   true if success, false else
 * NOTES:    blocks till all existing work items have been finished
 */
static bool hciWorkFlush(void)
{
    struct hciCbkWorkItem *w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    bool ret = false;
    sem_t sem;

    if (!w) {
        loge("Failed to alloc workQ flush cmd\n");
        return false;
    }

    if (sem_init(&sem, 0, 0)) {
        free(w);
        loge("Failed to alloc workQ flush sem\n");
        return false;
    }

    w->cbkWorkItemType = CBK_WORK_FLUSH;
    w->flush.sem = &sem;

    if (workQueuePut(mCallbackWork, w)) {
        r_sem_wait(&sem);
        ret = true;
    } else
        free(w);

    sem_destroy(&sem);

    return ret;
}

/*
 * FUNCTION: hciScheduleConnUpNotif
 * USE:      Enqueue a call to the ACL link up notif
 * PARAMS:   conn - the connection
 *           peerAddr - peer address
 *           selfAddr - whom we were being when we made the connection
 *           isMaster - are we master on the link
 *           isEncrypted - is the link encrypted
 *           isMitmSafe - is th elink MITM-safe?
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleConnUpNotif(hci_conn_t conn, const struct bt_addr *peerAddr, const struct bt_addr *selfAddr, bool isMaster, bool isEncrypted, bool isMitmSafe)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_CONN_UP;
    w->connUp.conn = conn;
    w->connUp.isMaster = isMaster;
    w->connUp.isEncrypted = isEncrypted;

    w->connUp.peerAddr = *peerAddr;
    w->connUp.selfAddr = *selfAddr;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleConnDownNotif
 * USE:      Enqueue a call to the ACL link down notif
 * PARAMS:   conn - the connection handle
 *           reason - the reason to pass to upper layers
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleConnDownNotif(hci_conn_t conn, uint8_t reason)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_CONN_DOWN;
    w->connDown.conn = conn;
    w->connDown.reason = reason;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleConnParamChange
 * USE:      Enqueue a call to the connection param change notif
 * PARAMS:   conn - the conenction
 *           success - success?
 *           interval - new interval
 *           latency - new latency
 *           timeout - new timeout
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleConnParamChange(hci_conn_t conn, bool success, uint16_t interval, uint16_t latency, uint16_t timeout)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_PARAMS_CHANGE;
    w->leParamChange.conn = conn;
    w->leParamChange.success = success;
    w->leParamChange.interval = interval;
    w->leParamChange.latency = latency;
    w->leParamChange.timeout = timeout;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleLeLtkRequest
 * USE:      Enqueue a call to the connection key request notif
 * PARAMS:   conn - the connection
 *           randomNum - provied by other side
 *           diversifier - provied by other side
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleLeLtkRequest(hci_conn_t conn, uint64_t randomNum, uint16_t diversifier)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_LE_KEY_REQ;
    w->leKeyReq.conn = conn;
    w->leKeyReq.randomNum = randomNum;
    w->leKeyReq.diversifier = diversifier;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleConnEncrChange
 * USE:      Enqueue a call to the connection encr change notif
 * PARAMS:   conn - the connection
 *           nowEncrypted - are we now encrypted?
 *           isMitmSafe - are we now MITM-safe?
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleConnEncrChange(hci_conn_t conn, bool nowEncrypted, bool isMitmSafe)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_ENCR_CHANGE;
    w->encrChange.conn = conn;
    w->encrChange.nowEncrypted = nowEncrypted;
    w->encrChange.isMitmSafe = isMitmSafe;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleConnEncrKeyRefresh
 * USE:      Enqueue a call to the connection encryption key fresh notification
 * PARAMS:   conn - the connection
 *           nowEncrypted - are we now encrypted?
 *           isMitmSafe - are we now MITM-safe?
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleConnEncrKeyRefresh(hci_conn_t conn, bool nowEncrypted, bool isMitmSafe)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_ENCR_KEY_REFRESH;
    w->encrKeyRefresh.conn = conn;
    w->encrKeyRefresh.nowEncrypted = nowEncrypted;
    w->encrKeyRefresh.isMitmSafe = isMitmSafe;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleMakeProgressOnLeConnectionReqs
 * USE:      Enqueue a call to hciMakeProgressOnLeConnectionReqs
 * PARAMS:   NONE
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleMakeProgressOnLeConnectionReqs(void)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_MAKE_NEXT_LE_CONN;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleAclRx
 * USE:      Enqueue a call to hciRxAcl
 * PARAMS:   hdr - packet header
 *           packet - the packet we got
 * RETURN:   true if enqueued, false else
 * NOTES:
 */
static bool hciScheduleAclRx(uint16_t hdr, sg packet)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_ACL_RX;
    w->aclRx.hdr = hdr;
    w->aclRx.packet = packet;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciScheduleConnDataRx
 * USE:      Enqueue a call to the connection RX notif
 * PARAMS:   conn - the conenction
 *           packet - the packet
 *           first - was packet marked as first?
 * RETURN:   true if enqueued, false else
 * NOTES:    data is copied
 */
static bool hciScheduleConnDataRx(hci_conn_t conn, sg packet, bool first)
{
    struct hciCbkWorkItem *w;

    w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem));
    if (!w)
        return false;

    w->cbkWorkItemType = CBK_WORK_ACL_DATA;
    w->aclDataRx.conn = conn;
    w->aclDataRx.packet = packet;
    w->aclDataRx.first = first;

    if (workQueuePut(mCallbackWork, w))
        return true;

    free(w);
    return false;
}

/*
 * FUNCTION: hciCmdSendWorker
 * USE:      Worker thread for sending commands to the chip
 * PARAMS:   unused - unused
 * RETURN:   unused
 * NOTES:
 */
static void* hciCmdSendWorker(void *unused)
{
    struct hciCmdSendWorkItem *w;
    bool weExpectReply = false;
    struct timespec ts;
    int ret, i;

    pthread_setname_np(pthread_self(), "bt_hci_cmds_send");

    while (1) {

        vendorTxDoneWithEvts();
        ret = workQueueGet(mCmdsSendWork, (void**)&w);
        if (ret)
            break;

        clock_gettime(CLOCK_REALTIME, &ts);
        ts.tv_sec += BT_COMMAND_TIMEOUT;
        if (r_sem_timedwait(&mCmdSendSem, &ts)) {
            loge("CHIP DEAD!\n");
            mt_analize_death();
            abort();
        }

        /*
         * This lock makes sure adding a handler for an event and sending the
         * corresponding command are handled as one atomic unit.
         */
        pthread_mutex_lock(&mCmdLock);

        for (i = 0; i < w->numEventWaiters; i++) {
            if (!w->ewds[i].descr.persistent)
                weExpectReply = true;
            w->ewds[i].id = hciEvtWaitEnqueue(&w->ewds[i].descr, w->cmdID);
            if (!w->ewds[i].id) {
                loge("Failed to enqueue handler [%d] \n", i);
                goto failed;
            }
        }

        if (vendorTx(HCI_PKT_TYP_CMD, w->cmd, weExpectReply))
            goto success;

        loge("Failed to TX a cmd\n");
        sgFree(w->cmd);

failed:
        loge("Command not sent\n");
        while (i)
            hciEvtWaitDequeue(w->ewds[--i].id);

success:
        pthread_mutex_unlock(&mCmdLock);
        free(w);
    }
    logd("HCI command send worker exiting\n");

    return NULL;
}

/*
 * FUNCTION: hciUp
 * USE:      Bring up HCI (comms to bt chip)
 * PARAMS:   addr - the BT addr
 *           cbk - callback when stack is ready for up
 *           cbkData - data to be passed to cbk
 * RETURN:   true on success, false else
 * NOTES:    may take a while
 */
bool hciUp(const uint8_t *addr, hciReadyForUpCbk cbk, void *cbkData)
{
    int ret;

    logd("Vendor open\n");
    if (!vendorOpen()) {
        loge("Failed to open vendor lib\n");
        goto out_lib_open;
    }

    logd("Vendor up\n");
    if (!vendorUp(addr, hciCbkChipHwUp, hciRx, NULL)) {
        loge("Failed to bring up the chip\n");
        goto out_chip_up;
    }

    ret = sem_init(&mCmdSendSem, 0, 0);
    if (ret) {
        loge("Sem init failure\n");
        goto out_sem;
    }

    mCmdsSendWork = workQueueAlloc(HCI_NUM_OUTSTANDING_CMDS);
    if (!mCmdsSendWork) {
        loge("Failed to create command send workqueue\n");
        goto out_cmd_workq;
    }

    mCallbackWork = workQueueAlloc(HCI_NUM_OUTSTANDING_CBKS);
    if (!mCallbackWork) {
        loge("Failed to create hci callback workqueue\n");
        goto out_cbk_workq;
    }

    ret = pthread_create(&mCallbackThread, NULL, hciCbkWorker, NULL);
    if (ret) {
        loge("Failed(%d) to create hci callback worker\n", ret);
        goto out_cbk_worker;
    }

    ret = pthread_create(&mCmdsSendThread, NULL, hciCmdSendWorker, NULL);
    if (ret) {
        loge("Failed(%d) to create hci cmd send worker\n", ret);
        goto out_cmd_worker;
    }

    mReadyForUpCbk = cbk;
    mReadyForUpData = cbkData;

    sem_init(&mAclPacketsLe, 0, 0);
    sem_init(&mAclPacketsEdr, 0, 0);

    hciSetupResetEventHandler(false);
    vendorStartRx();

    logd("Stack ready for up...awaiting reset event\n");
    //in a real stack we'd call hciBtStackUp() here. but with splitter, we just wait...
    return true;


out_cmd_worker:
    workQueueWakeAll(mCallbackWork, 1);
    pthread_join(mCallbackThread, NULL);

out_cbk_worker:
    workQueueFree(mCallbackWork, hciCallbackWorkDeallocator);

out_cbk_workq:
    workQueueFree(mCmdsSendWork, hciCmdSendWorkDeallocator);

out_cmd_workq:
    sem_destroy(&mCmdSendSem);

out_sem:
    vendorDown();

out_chip_up:
    vendorClose();

out_lib_open:
    return false;
}

/*
 * FUNCTION: hciDown
 * USE:      Bring down HCI (comms to bt chip)
 * PARAMS:   NONE
 * RETURN:   NONE
 * NOTES:    may take a while, some shutdown actions may go
 *           on after this (in higher layers). does not cleanup
 *           chip state - assumes chip will be reset.
 */
void hciDown(void)
{
    logd("Cancelling all event waiters\n");
    pthread_mutex_lock(&mCmdWaitLock);
    while (mEvtWaitHead) {
        mEvtWaitHead->cbk(NULL, 0, mEvtWaitHead->cbkData, mEvtWaitHead->evtWaitStateID, mEvtWaitHead->forCmdID);
        hciEvtWaitDequeueInt(mEvtWaitHead);
    }
    while (mConns) {
        struct hciAclConn *t = mConns;
        mConns = mConns->next;
        free(t);
    }
    while (mAdvSets) {
        struct hciAdvSet *t = mAdvSets;
        mAdvSets = mAdvSets->next;
        free(t);
    }
    pthread_mutex_unlock(&mCmdWaitLock);

    //more deinit here
    pthread_mutex_lock(&mDiscoveryStateLock);
    mDiscoverLeHandle = 0;
    pthread_mutex_unlock(&mDiscoveryStateLock);

    workQueueWakeAll(mCallbackWork, 1);
    workQueueWakeAll(mCmdsSendWork, 1);
    sem_post(&mCmdSendSem); /* wakes up cmdSend worker if it is waiting on a cmd credit */
    pthread_join(mCallbackThread, NULL);
    pthread_join(mCmdsSendThread, NULL);
    workQueueFree(mCallbackWork, hciCallbackWorkDeallocator);
    workQueueFree(mCmdsSendWork, hciCmdSendWorkDeallocator);
    sem_destroy(&mCmdSendSem);
    vendorDown();
    vendorClose();
}

/*
 * FUNCTION: hciCmdSubmit
 * USE:      Atomically enqueue a command to be sent to the chip and event handlers for
 *           events that will result.
 * PARAMS:   ogf - the command group
 *           ocf - the command code
 *           paramData - command params
 *           paramLen - parameter length
 *           ... - NULL-terminated list of const struct hciEvtWaitDescr* for wanted events
 * RETURN:   success
 * NOTES:    SHALL FINISH QUICKLY AND NOT BLOCK. WILL NOT DEADLOCK YOU! ALWAYS SAFE TO CALL!
 */
static bool hciCmdSubmit(uint8_t ogf, uint16_t ocf, const void* paramData, uint32_t paramLen, ...)
{
    const struct hciEvtWaitDescr *ewd;
    struct hciCmdSendWorkItem *w;
    uint8_t numHandlers = 0;
    struct hciCmdHdr cmdhdr;
    va_list vl;
    sg cmd;

    /* count up the events we want to wait for */
    va_start(vl, paramLen);
    while (va_arg(vl, const struct hciEvtWaitDescr*))
        numHandlers++;
    va_end(vl);

    cmd = sgNew();
    if (!cmd) {
        loge("Failed to alloc cmd sg\n");
        goto out_ret;
    }

    /* allocate the work item */
    w = (struct hciCmdSendWorkItem*)malloc(sizeof(struct hciCmdSendWorkItem) + sizeof(struct hciEvtWaitDescrWithID[numHandlers]));
    if (!w) {
        loge("Failed to alloc command work for cmd 0x%02X.%04X\n", ogf, ocf);
        goto out_sgfree;
    }

    /* copy wait state objects into it */
    numHandlers = 0;
    va_start(vl, paramLen);
    while ((ewd = va_arg(vl, const struct hciEvtWaitDescr*)) != NULL)
        memcpy(&w->ewds[numHandlers++].descr, ewd, sizeof(struct hciEvtWaitDescr));
    va_end(vl);
    w->numEventWaiters = numHandlers;

    /* create the command */
    utilSetLE16(&cmdhdr.opcode, CMD_MAKE_OPCODE(ogf, ocf));
    utilSetLE16(&cmdhdr.paramLen, paramLen);
    if (!sgConcatBackCopy(cmd, &cmdhdr, sizeof(cmdhdr)) || !sgConcatBackCopy(cmd, paramData, paramLen)) {
        loge("Failed to fill command sg\n");
        goto out_wfree;
    }
    w->cmd = cmd;

    /* try to enqueue it */
    if (workQueuePut(mCmdsSendWork, w))
        return true;

    /* in case of failure, free all that we allocated */
    loge("Failed to enqueue command\n");

out_wfree:
    free(w);

out_sgfree:
    sgFree(cmd);

out_ret:
    return false;
}

/*
 * FUNCTION: hciCmdSubmitSimpleCbk
 * USE:      Command callback for hciCmdSubmitSimple
 * PARAMS:   evt - the event
 *           evtSz - event size
 *           cbkData - struct hciSimpleCbkData - our data
 *           evtWaitStateID - event waiterID
 *           forCmdID - commandID
 * RETURN:   true if we handled it, false else
 * NOTES:
 */
static bool hciCmdSubmitSimpleCbk(const struct hciEvtHdr *evt, uint32_t evtSz, void *cbkData, uniq_t evtWaitStateID, uniq_t forCmdID)
{
    struct hciSimpleCbkData *cbkd = (struct hciSimpleCbkData*)cbkData;
    const char* name = cbkd->complete ? "complete" : "status";
    uint8_t paramLen;
    uint8_t evtHdrLen;
    bool ret = false;

    if (!evt)
        return hciScheduleSimpleCbk(cbkd->cbk, cbkd->cbkData1, cbkd->cbkData2, true, NULL);

    paramLen = utilGetLE8(&evt->len);
    evtHdrLen = cbkd->complete ? sizeof(struct hciEvtCmdComplete) : sizeof(struct hciEvtCmdStatus);

    if (paramLen < evtHdrLen) {
        logw("Comand %s event too short @ %ub (wanted %ub+)\n", name, paramLen, evtHdrLen);
        goto out;
    }
    paramLen -= evtHdrLen;

    /* is param length within bounds? */
    if (paramLen < cbkd->expectedParamLenMin || paramLen > cbkd->expectedParamLenMax) {
        logw("Got expected %s event, but wrong size: %u !< %u !< %u\n", name,
            cbkd->expectedParamLenMin, paramLen, cbkd->expectedParamLenMax);
        goto out;
    }

    /* enqueue the callback */
    ret = hciScheduleSimpleCbk(cbkd->cbk, cbkd->cbkData1, cbkd->cbkData2, false, cbkd->wantEventItself ? evt : NULL);

out:
    free(cbkData);
    return ret;
}

/*
 * FUNCTION: hciCmdSubmitSimple
 * USE:      Send a command and setup a handler for a command complete/command status for it
 * PARAMS:   ogf - command group
 *           ocf - command code
 *           paramData - command params
 *           paramLen - length of command params
 *           cbk - callback to call when command complete event arrives
 *           cbkData1 - data1 to pass to that callback
 *           cbkData2 - data2 to pass to that callback
 *           minEvtDataLen - minimum event data length to accept (excluding command complete/status event itself)
 *           maxEvtDataLen - maximum event data length to accept (excluding command complete/status event itself)
 *           wantEvt - pass a copy of the event to callback?
 *           expectComplete - expect command complete event? (else command status)
 * RETURN:   true if we enqueued it, false else
 * NOTES:
 */
static bool hciCmdSubmitSimple(uint8_t ogf, uint16_t ocf, const void* paramData, uint8_t paramLen, hciSimpleCbk cbk, void *cbkData1,
                               void *cbkData2, uint8_t minEvtDataLen, uint8_t maxEvtDataLen, bool wantEvt, bool expectComplete)
{
    struct hciEvtWaitDescr ewd;
    struct hciSimpleCbkData *cbkd = (struct hciSimpleCbkData*)malloc(sizeof(struct hciSimpleCbkData));

    if (!cbkd)
        return false;

    cbkd->cbk = cbk;
    cbkd->cbkData1 = cbkData1;
    cbkd->cbkData2 = cbkData2;
    cbkd->complete = expectComplete ? 1 : 0;
    cbkd->wantEventItself = wantEvt ? 1 : 0;
    cbkd->expectedParamLenMin = minEvtDataLen;
    cbkd->expectedParamLenMax = maxEvtDataLen;

    ewd.evtType = expectComplete ? HCI_EVT_Command_Complete : HCI_EVT_Command_Status;
    ewd.extra = CMD_MAKE_OPCODE(ogf, ocf);
    ewd.cbk = hciCmdSubmitSimpleCbk;
    ewd.cbkData = cbkd;
    ewd.persistent = false;

    if (hciCmdSubmit(ogf, ocf, paramData, paramLen, &ewd, NULL))
        return true;

    free(cbkd);
    return false;
}

/*
 * FUNCTION: hciCmdSubmitWithDoneSimpleCbk
 * USE:      Event callback for command complete event used by hciCmdSubmitSimpleWithCompleteWithDoneCbk()
 * PARAMS:   cbkData1 - 1st callback data (actually the original hciOpDoneCbk)
 *           cbkData2 - 2nd callback data (actually original data for hciOpDoneCbk)
 *           evt - the arrived event
 * RETURN:   true if we handled the event (always yes)
 * NOTES:
 */
static void hciCmdSubmitWithDoneSimpleCbk(void* cbkData1, void* cbkData2, bool goingDown, struct hciEvtHdr *evt)
{
    struct hciEvtCmdComplete *cmpl = (struct hciEvtCmdComplete*)(evt + 1);
    struct hciEvtCmdStatus *stat = (struct hciEvtCmdStatus*)(evt + 1);
    uint8_t *paramP = (uint8_t*)(cmpl + 1); //for compelte
    hciOpDoneCbk cbkF = (hciOpDoneCbk)cbkData1;
    uint8_t status;

    if (goingDown)
        status = HCI_STAT_GOING_DOWN;
    else if (utilGetLE8(&evt->code) == HCI_EVT_Command_Complete)
        status = utilGetLE8(paramP);
    else
        status = utilGetLE8(&stat->status);

    if (!hciScheduleOpDoneCbk(cbkF, cbkData2, status))
        loge("Failed to shedule done callback for simple command complete handler\n");
}

/*
 * FUNCTION: hciCmdSubmitSimpleWithCompleteWithDoneCbk
 * USE:      Send a command and setup a handler for a command complete for it. call DoneCbk
 * PARAMS:   ogf - command group
 *           ocf - command code
 *           paramData - command params
 *           paramLen - length of command params
 *           cbk - doneCbk
 *           cbkData - data1 to pass to doneCbk
 * RETURN:   true if we enqueued it, false else
 * NOTES:    This only works if the first byte of the event is a "status" byte. WATCH OUT FOR THIS!!!
 */
static bool hciCmdSubmitSimpleWithCompleteWithDoneCbk(uint8_t ogf, uint16_t ocf, const void* paramData, uint8_t paramLen, hciOpDoneCbk cbk, void *cbkData)
{
    return hciCmdSubmitSimple(ogf, ocf, paramData, paramLen, hciCmdSubmitWithDoneSimpleCbk, (void*)cbk, cbkData, 1/* status byte required */, 255, true, true);
}

/*
 * FUNCTION: hciCmdSubmitSimpleWithStatusWithDoneCbk
 * USE:      Send a command and setup a handler for a command status for it. call DoneCbk
 * PARAMS:   ogf - command group
 *           ocf - command code
 *           paramData - command params
 *           paramLen - length of command params
 *           cbk - doneCbk
 *           cbkData - data1 to pass to doneCbk
 * RETURN:   true if we enqueued it, false else
 * NOTES:
 */
static bool hciCmdSubmitSimpleWithStatusWithDoneCbk(uint8_t ogf, uint16_t ocf, const void* paramData, uint8_t paramLen, hciOpDoneCbk cbk, void *cbkData)
{
    return hciCmdSubmitSimple(ogf, ocf, paramData, paramLen, hciCmdSubmitWithDoneSimpleCbk, (void*)cbk, cbkData, 0, 255, true, false);
}

/*
 * FUNCTION: hciCmdSubmitCompleteSyncSimpleCbk
 * USE:      Event callback for command complete event used by hciCmdSubmitSimpleWithCompleteSync()
 * PARAMS:   cbkData1 - 1st callback data (struct hciCmdSubmitWithCompleteSyncData*)
 *           cbkData2 - 2nd callback data (unused)
 *           evt - the arrived event
 * RETURN:   NONE
 * NOTES:
 */
static void hciCmdSubmitCompleteSyncSimpleCbk(void* cbkData1, void* cbkData2, bool stackGoingDown, struct hciEvtHdr *evt)
{
    struct hciEvtCmdComplete *cmpl = (struct hciEvtCmdComplete*)(evt + 1);
    struct hciCmdSubmitWithCompleteSyncData *data = (struct hciCmdSubmitWithCompleteSyncData*)cbkData1;
    void* evtData = (void*)(cmpl + 1);
    uint8_t paramLen;

    data->goingDown = stackGoingDown;

    if (stackGoingDown)
        sem_post(data->sem);

    paramLen = utilGetLE8(&evt->len) - sizeof(struct hciEvtCmdComplete);

    if (paramLen > data->evtBufSz) {
        logw("Sync complete event shortened %ud->%ud\n", paramLen, data->evtBufSz);
        paramLen = data->evtBufSz;
    }
    memcpy(data->evtBuf, evtData, paramLen);
    sem_post(data->sem);
}

/*
 * FUNCTION: hciCmdSubmitSimpleWithCompleteSync
 * USE:      Send a command and setup a handler for a command complete for it. Wait for it to complete. Optionally provide resulting event back.
 * PARAMS:   ogf - command group
 *           ocf - command code
 *           paramData - command params
 *           paramLen - length of command params
 *           evtBuf - buffer where to put event (command complete event will be stripped, only params will remain)
 *           evtBufSz - size of said buffer. Event will be truncated if it does not fit
 * RETURN:   true if it happened. false else
 * NOTES:    Will block!
 */
static bool hciCmdSubmitSimpleWithCompleteSync(uint8_t ogf, uint16_t ocf, const void* paramData, uint8_t paramLen, void* evtBuf, uint8_t evtBufSz)
{
    bool ret = true;
    sem_t sem;
    struct hciCmdSubmitWithCompleteSyncData data;

    if (pthread_self() == mCallbackThread) {
        loge("Refusing to issue sync command from callback thread. This WILL deadlock\n");
        return false;
    }

    data.sem = &sem;
    data.evtBuf = evtBuf;
    data.evtBufSz = evtBufSz;

    if (sem_init(&sem, 0, 0)) {
        loge("sem init failed\n");
        return false;
    }

    if (hciCmdSubmitSimple(ogf, ocf, paramData, paramLen, hciCmdSubmitCompleteSyncSimpleCbk, &data, NULL, 0, 255, true, true)) {
        r_sem_wait(&sem);
        if (data.goingDown) {
            logi("going down\n");
            ret = false;
        }
    } else
        ret = false;

    sem_destroy(&sem);

    return ret;
}

/*
 * FUNCTION: hciCmdSubmitStatusSyncSimpleCbk
 * USE:      Event callback for command complete event used by hciCmdSubmitSimpleWithCompleteSync()
 * PARAMS:   cbkData1 - 1st callback data (sem_t* sem)
 *           cbkData2 - 2nd callback data (struct hciEvtCmdStatus* dstEvt)
 *           evt - the arrived event
 * RETURN:   NONE
 * NOTES:
 */
static void hciCmdSubmitStatusSyncSimpleCbk(void* cbkData1, void* cbkData2, bool stackGoingDown, struct hciEvtHdr *evt)
{
    struct hciEvtCmdStatus *stat = (struct hciEvtCmdStatus*)(evt + 1);
    sem_t *sem = (sem_t*)cbkData1;
    struct hciEvtCmdStatus* dstSta = (struct hciEvtCmdStatus*)cbkData2;

    if (stackGoingDown)
        utilSetLE8(&dstSta->status, HCI_STAT_GOING_DOWN);
    else
        memcpy(dstSta, stat, sizeof(struct hciEvtCmdStatus));
    sem_post(sem);
}

/*
 * FUNCTION: hciCmdSubmitSimpleWithStatusSync
 * USE:      Send a command and setup a handler for a command status for it. Wait for it. Provide resulting event back.
 * PARAMS:   ogf - command group
 *           ocf - command code
 *           paramData - command params
 *           paramLen - length of command params
 *           dstEvt - will store event here
 * RETURN:   true if it happened. false else
 * NOTES:    Will block!
 */
static bool hciCmdSubmitSimpleWithStatusSync(uint8_t ogf, uint16_t ocf, const void *paramData, uint8_t paramLen, struct hciEvtCmdStatus *dstEvt)
{
    bool ret = true;
    sem_t sem;

    if (pthread_self() == mCallbackThread) {
        loge("Refusing to issue sync command from callback thread. This WILL deadlock\n");
        return false;
    }

    if (sem_init(&sem, 0, 0)) {
        loge("sem init failed\n");
        return false;
    }

    if (hciCmdSubmitSimple(ogf, ocf, paramData, paramLen, hciCmdSubmitStatusSyncSimpleCbk, &sem, dstEvt, 0, 0, true, false))
        r_sem_wait(&sem);
    else
        ret = false;

    sem_destroy(&sem);

    return ret;
}

/*
 * FUNCTION: hciInquiryUpdatePersistDeviceDb
 * USE:      Update persistent "seen devices" DB with EIR data
 * PARAMS:   addr - the address of the remote device
 *           devClsP - device class or NULL if not known
 *           eir - the provided EIR data (if any)
 *           eirLen - size of the above buffer
 * RETURN:   NONE
 * NOTES:
 */
void hciInquiryUpdatePersistDeviceDb(const struct bt_addr *addr, const uint32_t *devClsP, const void *eir, uint8_t eirLen)
{
    const uint8_t *name = NULL;
    uint32_t nameLen = 0;
    uint32_t eirDevCls;
    bool nameIsFull = false;

    if (eirLen) { /* parse eir to find name */
        const uint8_t *eirP = (const uint8_t*)eir;
        const uint8_t *eirEnd = eirP + eirLen;

        while (eirP < eirEnd) {
            uint8_t type, len = *eirP++;
            if (!len) /* zero length item means end of EIR */
                break;
            type = *eirP++;
            len--;

            if (type == HCI_EIR_TYPE_SHORTENED_NAME || type == HCI_EIR_TYPE_FULL_NAME) {
                name = eirP;
                nameLen = len;
                nameIsFull = type == HCI_EIR_TYPE_FULL_NAME;
            } else if (type == HCI_EIR_DEV_CLS && len == 3) {
                eirDevCls = utilGetLE24(eirP);
                devClsP = &eirDevCls;
            }
            eirP += len;
        }
    }

    persistAddKnownDev(addr, name, name ? &nameLen : NULL, nameIsFull, devClsP);
}

/*
 * FUNCTION: hciInquiryEvtLeSingleItem
 * USE:      Enqueue a callback to discovery LE cbk
 * PARAMS:   addr - the address of the remote device
 *           advType - type of reply
 *           rssi - the RSSI
 *           advData - the provided advertisement data
 *           advDataLen - size of the above buffer
 * RETURN:   NONE
 * NOTES:    a copy of all params is made
 */
static void hciInquiryEvtLeSingleItem(const struct bt_addr *addr, uint8_t advType, int8_t rssi, const void *advData, uint8_t advDataLen)
{
    struct hciCbkWorkItem *w = (struct hciCbkWorkItem*)malloc(sizeof(struct hciCbkWorkItem) + advDataLen);
    if (!w) {
        logw("Dropping LE discovered item due to memory error\n");
        return;
    }

    w->cbkWorkItemType = CBK_WORK_LE_DISC_DEV;
    memcpy(&w->leDev.addr, addr, sizeof(w->leDev.addr));
    memcpy(w->leDev.adv, advData, advDataLen);
    w->leDev.advType = advType;
    w->leDev.advLen = advDataLen;
    w->leDev.rssi = rssi;

    hciInquiryUpdatePersistDeviceDb(addr, NULL, advData, advDataLen);
    if (workQueuePut(mCallbackWork, w))
        return;

    free(w);
    logi("Dropping LE discovered item dues to queue error\n");
}

/*
 * FUNCTION: hciAdvSetTerminatedEventHandle
 * USE:      Called when we know an adv set stopped being advertised (usually due to a connection)
 * PARAMS:   advInstance - the hw instance id of the adv set
 *           aclConnId - the connection this caused (or ACL_CONN_ID_INVALID is none)
 * RETURN:   none
 * NOTES:    will take mAdvSetsLock and mConnsLock (not concurrently). If a connection is found and
 *           it is still in a BLAMING state, it will be adjusted to config state and advSet param
 *           will be filled.
 */
static void hciAdvSetTerminatedEventHandle(uint8_t advInstance, uint16_t aclConnId)
{
    hci_adv_set_t setH = 0;
    struct hciAdvSet *t;
    struct bt_addr self;

    pthread_mutex_lock(&mAdvSetsLock);
    for (t = mAdvSets; t; t = t->next) {
        if (t->hwEnabled && t->hwSetNum == advInstance) {
            hciAdvSetGetCurAdvAddrLocked(t, &self);
            t->hwEnabled = false; //even if conn not found, this set was still fingered for being the cause so it is still already off
            setH = t->handle;
            break;
        }
    }
    pthread_mutex_unlock(&mAdvSetsLock);

    if (!setH)
        logw("Adv id not found for vendor advt change event\n");
    else if (aclConnId != ACL_CONN_ID_INVALID) {

        struct hciAclConn* conn;

        pthread_mutex_lock(&mConnsLock);
        conn = hciConnFindById(aclConnId);
        if (!conn)
            logw("Connection id not found for vendor advt change event\n");
        else if (conn->state != CONN_STATE_ADV_SET_BLAMING)
            logw("Conn is not in blaming state for vendor advt change event\n");
        else {
            conn->le.advSet = setH;
            conn->selfAddr = self;
            conn->state = CONN_STATE_CFG;
            hciConnCfg(conn, CONN_CFG_STEP_LE, 0);
        }
        pthread_mutex_unlock(&mConnsLock);
    }
}

/*
 * FUNCTION: hciConnEvtCbk
 * USE:      Called with connection state events
 * PARAMS:   evt - the event
 *           evtSz - event size
 *           cbkData - callback data
 *           evtWaitStateID - event wait state ID (unused)
 *           forCmdID - event commadn ID (unused)
 * RETURN:   false on error
 * NOTES:
 */
static bool hciConnEvtCbk(const struct hciEvtHdr *evt, uint32_t evtSz, void *cbkData, uniq_t evtWaitStateID, uniq_t forCmdID)
{
    uint8_t evtType;
    if (!evt)
        return false;

    evtType = utilGetLE8(&evt->code);
    if (evtType == HCI_EVT_Disconnection_Complete) {
        struct hciEvtDiscComplete *disc = (struct hciEvtDiscComplete*)(evt + 1);
        uint8_t status = utilGetLE8(&disc->status);
        uint16_t cid = utilGetLE16(&disc->conn);
        uint8_t reason = utilGetLE8(&disc->reason);

        logd("ACL conn %d down for reason %d with status %d\n", cid, reason, status);
        hciHandleConnAclDown(cid, reason);

    } else if (evtType == HCI_EVT_Encryption_Change) {
        struct hciEvtEncrChange *encr = (struct hciEvtEncrChange*)(evt + 1);
        uint8_t status = utilGetLE8(&encr->status);
        uint16_t cid = utilGetLE16(&encr->conn);
        bool encrOn = !status && utilGetLE8(&encr->encrOn);

        logd("ACL conn %d encr %d with status %d\n", cid, encrOn, status);
        if (!hciHandleConnAclEncr(cid, encrOn))
            loge("Failed to handle conn encr\n");
    } else if (evtType == HCI_EVT_Authentication_Complete) {
        struct hciEvtEncrChange *encr = (struct hciEvtEncrChange*)(evt + 1);
        uint8_t status = utilGetLE8(&encr->status);
        uint16_t cid = utilGetLE16(&encr->conn);

        logd("ACL conn %d auth with status %d\n", cid, status);
        if (!hciHandleConnAclAuth(cid, !status))
            loge("Failed to handle conn auth\n");
    } else if (evtType == HCI_EVT_Encryption_Key_Refresh_Complete) {
        struct hciEvtEncrKeyRefreshComplete *encr = (struct hciEvtEncrKeyRefreshComplete*)(evt + 1);
        uint8_t status = utilGetLE8(&encr->status);
        uint16_t cid = utilGetLE16(&encr->conn);
        bool encrOn = !status;

        logd("ACL conn %d encr key refreshed %d with status %d\n", cid, encrOn, status);
        if (!hciHandleConnAclEncrKeyRefresh(cid, encrOn))
            loge("Failed to handle conn encr key refreshed\n");
    } else if (evtType == HCI_EVT_LE_Meta) {
        struct hciEvtLeMeta *meta = (struct hciEvtLeMeta*)(evt + 1);
        evtType = utilGetLE8(&meta->subevent);

        if (evtType == HCI_EVTLE_Connection_Complete) {
            struct hciEvtLeConnectionComplete *conn = (struct hciEvtLeConnectionComplete*)(meta + 1);
            uint8_t status = utilGetLE8(&conn->status);
            uint16_t cid = utilGetLE16(&conn->conn);
            bool amSlave = !!utilGetLE8(&conn->amSlave);
            bool peerAddrRandom = !!utilGetLE8(&conn->peerAddrRandom);
            uint16_t interval = utilGetLE16(&conn->connInterval);
            uint16_t latency = utilGetLE16(&conn->connLatency);
            uint16_t timeout = utilGetLE16(&conn->supervisionTimeout);
            uint8_t mca = utilGetLE8(&conn->masterClockAccuracy);

            logd("ACL LE conn %d up to %c"MACFMT" as %c: {%d,%d,%d,%d}\n", cid, peerAddrRandom ? 'R' : 'P', MACCONV(conn->peerMac), amSlave ? 'S' : 'M', interval, latency, timeout, mca);
            if (!hciHandleConnAclLeUp(status, cid, !amSlave, conn->peerMac, peerAddrRandom, interval, latency, timeout, mca))
                loge("Failed to handle conn LE conn up\n");
        } else if (evtType == HCI_EVTLE_Connection_Update_Complete) {
            struct hciEvtLeConnectionUpdateComplete *updt = (struct hciEvtLeConnectionUpdateComplete*)(meta + 1);
            uint8_t status = utilGetLE8(&updt->status);
            uint16_t cid = utilGetLE16(&updt->conn);
            uint16_t interval = utilGetLE16(&updt->connInterval);
            uint16_t latency = utilGetLE16(&updt->connLatency);
            uint16_t timeout = utilGetLE16(&updt->supervisionTimeout);

            logd("ACL LE conn %d update to {%d,%d,%d}\n", cid, interval, latency, timeout);
            if (!hciHandleConnAclLeUpdate(status, cid, interval, latency, timeout))
                loge("Failed to handle LE conn update\n");
        } else if (evtType == HCI_EVTLE_LTK_Request) {
            struct hciEvtLeLtkRequest *req = (struct hciEvtLeLtkRequest*)(meta + 1);
            uint16_t cid = utilGetLE16(&req->conn);
            uint64_t randomNum = utilGetLE16(&req->randomNum);
            uint16_t diversifier = utilGetLE16(&req->diversifier);

            logd("ACL LE key req for conn 0x%02x with rand 0x"FMT64"x and div 0x%02x\n", cid, CNV64(randomNum), diversifier);
            if (!hciHandleConnLeLtkReq(cid, randomNum, diversifier))
                loge("Failed to handle LE key req\n");
        } else if (evtType == HCI_EVTLE_Adv_Set_Terminated) {
            struct hciEvtLeAdvSetTerminated *req = (struct hciEvtLeAdvSetTerminated*)(meta + 1);

            hciAdvSetTerminatedEventHandle(req->advSetHandle, req->status ? ACL_CONN_ID_INVALID : req->conn);
        } else
            return false;
    } else if (evtType == HCI_EVT_Vendor) {
        struct hciEvtVendor *vendor = (struct hciEvtVendor*)(evt + 1);
        evtType = utilGetLE8(&vendor->subevent);

        if (evtType == HCI_EVTVENDOR_Android_Subevent_Advt_State_Change) {
            struct hciEvtVendorAndroidVendorExtAdvtStateChange *sce = (struct hciEvtVendorAndroidVendorExtAdvtStateChange*)(vendor + 1);

            if (evtSz != sizeof(*evt) + sizeof(*vendor) + sizeof(*sce))
                logw("Invalid event size for vendor subevent for advt change - ignored\n");
            else if (sce->reason != HCI_EVTVENDOR_Android_Subevent_Advt_State_Change_Reason)
                logw("Invalid reason code for vendor subevent for advt change - ignored\n");
            else
                hciAdvSetTerminatedEventHandle(sce->advInstance, sce->connHandle);
        } else
            return false;
    } else
        return false;

    return true;
}

/*
 * FUNCTION: hciInquiryEvtCbk
 * USE:      Called with inquiry events
 * PARAMS:   evt - the event
 *           evtSz - event size
 *           cbkData - callback data
 *           evtWaitStateID - event wait state ID (unused)
 *           forCmdID - event commadn ID (unused)
 * RETURN:   false on error
 * NOTES:
 */
static bool hciInquiryEvtCbk(const struct hciEvtHdr *evt, uint32_t evtSz, void *cbkData, uniq_t evtWaitStateID, uniq_t forCmdID)
{
    uint8_t evtType;
    struct bt_addr addr;
    uint8_t i, num;

    if (!evt)
        return false;

    evtType = utilGetLE8(&evt->code);

    if(evtType == HCI_EVT_LE_Meta) {
        struct hciEvtLeMeta *meta = (struct hciEvtLeMeta*)(evt + 1);
        struct hciEvtLeAdvReport *adv = (struct hciEvtLeAdvReport*)(meta + 1);
        struct hciEvtLeAdvReportItem *item = (struct hciEvtLeAdvReportItem*)(adv + 1);
        uint8_t subevent = utilGetLE8(&meta->subevent);
        uint8_t *rssiP;

        if (subevent != HCI_EVTLE_Advertising_Report) {
            loge("Unexpected LE subevent 0x%02X in discovery event handler\n", subevent);
            return false;
        }

        num = utilGetLE8(&adv->numReports);

        for (i = 0; i < num; i++) {
            uint8_t dataLen = utilGetLE8(&item->dataLen);

            addr.type = utilGetLE8(&item->randomAddr) ? BT_ADDR_TYPE_LE_RANDOM : BT_ADDR_TYPE_LE_PUBLIC;
            memcpy(addr.addr, item->mac, sizeof(addr.addr));
            rssiP = item->data + dataLen;
            hciInquiryEvtLeSingleItem(&addr, utilGetLE8(&item->advType), utilGetLE8(rssiP), item->data, dataLen);
            item = (struct hciEvtLeAdvReportItem*)(rssiP + 1);
        }
    } else {
        loge("Unexpected event 0x%02X in discovery event handler\n", evtType);
        return false;
    }

    return true;
}

/*
 * FUNCTION: hciLeParamChangeRequestEventCbk
 * USE:      Called with remote's requests for parameter changes
 * PARAMS:   evt - the event
 *           evtSz - event size
 *           cbkData - callback data
 *           evtWaitStateID - event wait state ID (unused)
 *           forCmdID - event commadn ID (unused)
 * RETURN:   false on error
 * NOTES:    we deny all such requests. Remote devices have no business telling us what to do and how to live our life. We do what we want!
 */
static bool hciLeParamChangeRequestEventCbk(const struct hciEvtHdr *evt, uint32_t evtSz, void *cbkData, uniq_t evtWaitStateID, uniq_t forCmdID)
{
    const struct hciEvtLeMeta *meta = (const struct hciEvtLeMeta*)(evt + 1);
    const struct hciEvtLeRemoteConnParamRequest *req = (const struct hciEvtLeRemoteConnParamRequest*)(meta + 1);
    struct hciLeRemoteConnParamRequestNegativeReply repl = {.reason = HCI_ERR_Unsupported_Feature_Or_Parameter_Value,};

    if (evtSz != sizeof(struct hciEvtHdr) + sizeof(struct hciEvtLeMeta) + sizeof(struct hciEvtLeRemoteConnParamRequest)) {
        logw("Invalid event size %u\n", evtSz);
        return false;
    }

    utilSetLE16(&repl.conn, utilGetLE16(&req->conn));

    if (!hciCmdSubmitSimpleWithCompleteWithDoneCbk(HCI_OGF_LE, HCI_CMD_LE_Remote_Conn_Param_Request_Negative_Reply, &repl, sizeof(repl), hciCmdStatusCbk, NULL)) {
        logi("Failed to request connection param change denial\n");
        return false;
    }

    return true;
}

/*
 * FUNCTION: hciResetEvtCbk
 * USE:      Called when a reset complete event arrives. Tears down any existing state and sets the in-reset state.
 * PARAMS:   evt - the event (unused)
 *           evtSz - event size
 *           cbkData - callback data (unused)
 *           evtWaitStateID - event wait state ID (unused)
 *           forCmdID - event command ID (unused)
 * RETURN:   false on error
 * NOTES:
 */
static bool hciResetEvtCbk(const struct hciEvtHdr *evt, uint32_t evtSz, void *cbkData, uniq_t evtWaitStateID, uniq_t forCmdID)
{
    //notify everyone that all connections are down


    pthread_mutex_lock(&mConnsLock);
    while (mConns) {
        //for all connections upper layers know of, tell them they are no more
        if (mConns->state == CONN_STATE_CFG || mConns->state == CONN_STATE_RUNNING)
            if (!hciScheduleConnDownNotif(mConns->handle, HCI_ERR_Connection_Terminated_By_Local_Host))
                loge("Failed to schedule conn down notif\n");
        hciConnAclStructDel(mConns);
    }
    pthread_mutex_unlock(&mConnsLock);

    //remove command send authority if it exists (this event may give us a credit or not, that will be handled later)
    while(!sem_trywait(&mCmdSendSem));

    //remember that we're in reset
    mStackState = STACK_STATE_GOING_DOWN;

    return true;
}

/*
 * FUNCTION: hciSetupResetEventHandler
 * USE:      Set up the handler for the "reset" event
 * PARAMS:   cmdWaitLockHeld - set if caller has mCmdWaitLock
 * RETURN:   false on error
 * NOTES:    may be called with mCmdWaitLock held (see params)
 */
static bool hciSetupResetEventHandler(bool cmdWaitLockHeld)
{
    bool ret;
    struct hciEvtWaitDescr ewd = {
        .cbk = hciResetEvtCbk,
        .evtType = HCI_EVT_Command_Complete,
        .extra = CMD_MAKE_OPCODE(HCI_OGF_Controller_and_Baseband, HCI_CMD_Reset),
        .persistent = true,
    };

    if (cmdWaitLockHeld)
         ret = hciEvtWaitEnqueueUnlocked(&ewd, 0);
    else
         ret = hciEvtWaitEnqueue(&ewd, 0);

    return ret;
}

/*
 * FUNCTION: hciIsUp
 * USE:      Ask if chip is ready to be used
 * PARAMS:   none
 * RETURN:   the answer
 * NOTES:
 */
bool hciIsUp(void)
{
    loge(" *X* state = %d\n", mStackState);

    if (mStackState == STACK_STATE_READY_FOR_UP)
        return hciBtStackUp();

    return mStackState == STACK_STATE_UP;
}

/*
 * FUNCTION: hciSetManyEventPersistentHandlers
 * USE:      Set a few identical event handlers for variosu events
 * PARAMS:   evtTypes - event types list (ended with a 0)
 *           evtExtras - event extras array (or NULL if all zeros are to be assumed)
 *           cbk - the handler
 *           cbkData - data for the handler
 * RETURN:   false on error
 * NOTES:
 */
static bool hciSetManyEventPersistentHandlers(const uint8_t *evtTypes, const uint16_t *evtExtras, hciEvtCbk cbk, void *cbkData)
{

    struct hciEvtWaitDescr ewd = {0, };
    uint8_t i;

    ewd.cbk = cbk;
    ewd.cbkData = cbkData;
    ewd.persistent = true;

    for (i = 0; evtTypes[i]; i++) {
        ewd.evtType = evtTypes[i];
        ewd.extra = evtExtras ? evtExtras[i] : 0;

        if (!hciEvtWaitEnqueue(&ewd, 0)) {
            loge("Failed to enqueue handler %d: 0x%02X.%04X\n", i, ewd.evtType, ewd.extra);
            return false;
        }
    }

    return true;
}

/*
 * FUNCTION: hciGetLocalAddress
 * USE:      Get the local static BT addr
 * PARAMS:   addr - the buffer to stash address in. not a bt_addr struct since type is not determinable
 * RETURN:   NONE
 * NOTES:
 */
void hciGetLocalAddress(uint8_t *addr)
{
    memcpy(addr, mLocalAddr, sizeof(mLocalAddr));
}

/*
 * FUNCTION: hciAdvSetEnableDisableMethodAndroidVendorCmds
 * USE:      Enable or disable an adv set on BT4 chips that support android-vendor BT extension
 * PARAMS:   set - the set to operate on
 *           enable - on or off?
 * RETURN:   success
 * NOTES:    called with mAdvSetsLock held
 *           This is one of the few "adv set on/off handlers". This one is used
 *           when the android-vendor methods are available and BT 5.0 is not
 */
static bool hciAdvSetEnableDisableMethodAndroidVendorCmds(struct hciAdvSet *set, bool enable)
{
    struct hciCmplLeReadAdvChannelTxPower pwrLvlEvt;
    int8_t desiredPowerLvl = set->powerLevel;
    struct hciAdvSet *t;
    bool *usedSets;
    uint16_t i;
    int ret;

    /*
     * Some explanation here: Android Vendor Extensions for BT 4 provide for multi-adv,
     * but caveats exist. If the chip says it supports X slots, in reality it supports
     * X - 1 slots with this custom API (indexed at 1) and the default 4.0 API (slot 0).
     * "but," you might say - "default API has no TX power control!" Yes. Slot 0 has no
     * tx power control. But it is even worse. Slot 0 shared the "random address" with
     * any connection attempt we make using a random address, so we cannot really use
     * it to advertise at the same time as we try to connect to anyone. There are some
     * ways to cleverly use it for both, but they are fragile and error-prone. Instead,
     * we'll just use slots 1..N and not use slot 0. This way we can always safely set
     * the chip random address for connection purposes.
     */

    if (!enable) { // disable the set we do not need

        if (set->hwSetNum)
            ret = hciVendorLeMultiAdvSetAdvEnableSync(false, set->hwSetNum);
        else
            ret = hciLeSetAdvEnableSync(false);
        if (ret) {
            logw("Cannot disable adv 0x"HCI_ADV_SET_FMT"x on channel %u because VendorSetAdvEnable command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), set->hwSetNum, ret);
            return false;
        }
        set->hwEnabled = false;
        return true;
    }

    //sanity checks specific to this method
    if (desiredPowerLvl != HCI_ADV_TX_PWR_LVL_DONT_CARE) {
        if (desiredPowerLvl > 20) {
            logi("AndroidVendorExtensions adv does not support adv power level over 20dBm - cutting set 0x"HCI_ADV_SET_FMT"x down to 20dBm from %ddBm\n", HCI_ADV_SET_CONV(set->handle), set->powerLevel);
            desiredPowerLvl = 20;
        }
        if (desiredPowerLvl < -70) {
            logi("AndroidVendorExtensions adv does not support adv power level below -70dBm - raising set 0x"HCI_ADV_SET_FMT"x up to -70dBm from %ddBm\n", HCI_ADV_SET_CONV(set->handle), set->powerLevel);
            desiredPowerLvl = -70;
        }
    }

    //we want to enable: first find a free slot (if any)
    usedSets = alloca(mMaxAdvSets + 1);
    memset(usedSets, 0, mMaxAdvSets + 1);
    for (t = mAdvSets; t; t = t->next) {
        if (t->hwEnabled) {
            if (usedSets[t->hwSetNum])
                logw("It seems that HW adv set %u is used by two advs... this is bad\n", t->hwSetNum);
            else
                usedSets[t->hwSetNum] = true;
        }
    }
    for (i = 1; i < mMaxAdvSets + 1; i++) {
        if (!usedSets[i])
            break;
    }
    if (i == mMaxAdvSets + 1) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x because there are no free slots\n", HCI_ADV_SET_CONV(set->handle));
        return false;
    }
    logd("picked slot %u for adv set 0x"HCI_ADV_SET_FMT"x\n", i, HCI_ADV_SET_CONV(set->handle));

    //if no power level was requested, use max
    if (desiredPowerLvl == HCI_ADV_TX_PWR_LVL_DONT_CARE)
        desiredPowerLvl = 20;

    //configure the slot: number
    set->hwSetNum = i;

    //configure the slot: adv data
    if (set->hwSetNum)
        ret = hciVendorLeMultiAdvSetAdvDataSync(set->advDataLen, set->advData, set->hwSetNum);
    else
        ret = hciLeSetAdvDataSync(set->advDataLen, set->advData);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x on channel %u because VendorSetAdvData command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), set->hwSetNum, ret);
        return false;
    }

    //configure the slot: scan rsp data
    if (set->hwSetNum)
        ret = hciVendorLeMultiAdvSetScanRspDataSync(set->scanRspDataLen, set->scanRspData, set->hwSetNum);
    else
        ret = hciLeSetScanResponseDataSync(set->scanRspDataLen, set->scanRspData);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x on channel %u because VendorSetScanRspData command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), set->hwSetNum, ret);
        return false;
    }

    //configure the slot: adv params
    if (set->hwSetNum)
        ret = hciVendorLeMultiAdvSetAdvParamsSync(set->intervalMin, set->intervalMax, set->advType, set->ownAddressType, set->ownRandomAddr.addr, set->directAddr.type == BT_ADDR_TYPE_LE_RANDOM ? 1 : 0, set->directAddr.addr, set->channelMap, set->filterPolicy, set->hwSetNum, desiredPowerLvl);
    else
        ret = hciLeSetAdvParamsSync(set->intervalMin, set->intervalMax, set->advType, set->ownAddressType, set->directAddr.type == BT_ADDR_TYPE_LE_RANDOM ? 1 : 0, set->directAddr.addr, set->channelMap, set->filterPolicy);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x on channel %u because VendorSetAdvParams command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), set->hwSetNum, ret);
        return false;
    }

    //configure the slot: own random address (if needed)
    if (set->ownAddressType == HCI_ADV_OWN_ADDR_TYPE_RANDOM || set->ownAddressType == HCI_ADV_OWN_ADDR_TYPE_AUTO_RESOLV_ELSE_RANDOM) {
        if (set->hwSetNum)
            ret = hciVendorLeMultiAdvSetRandomAddrSync(set->ownRandomAddr.addr, set->hwSetNum);
        else
            ret = hciLeSetRandomAddressSync(set->ownRandomAddr.addr);
        if (ret) {
            logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x on channel %u because VendorSetRandomAddr command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), set->hwSetNum, ret);
            return false;
        }
    }

    //configure the slot: record/read *actual* TX power level
    if (set->hwSetNum)
        set->hwPowerLevel = desiredPowerLvl;
    else {
        ret = hciLeReadAdvChannelTxPowerSync(&pwrLvlEvt);
        if (ret) {
            logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x on channel %u because GetTxPwrLvl command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), set->hwSetNum, ret);
            return false;
        }
        set->hwPowerLevel = pwrLvlEvt.txPower;
    }

    //enable the slot
    if (set->hwSetNum)
        ret = hciVendorLeMultiAdvSetAdvEnableSync(true, set->hwSetNum);
    else
        ret = hciLeSetAdvEnableSync(true);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x on channel %u because VendorSetAdvEnable command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), set->hwSetNum, ret);
        return false;
    }

    set->hwEnabled = true;
    return true;
}

/*
 * FUNCTION: hciAdvSetHandleAndBlameNewConnMethodAndroidVendorCmdsTimeCbk
 * USE:      Timer timeout for adv-set blaming for AndroidVendor connections
 * PARAMS:   timer - the timer handle
 *           aclConnHandle - the acl connection handle
 * RETURN:   none
 * NOTES:    if the connection still has not been blamed, we blame it on adv set that was on zero (it was pre-populated in hciAdvSetHandleAndBlameNewConnMethodAndroidVendorCmds)
 */
static void hciAdvSetHandleAndBlameNewConnMethodAndroidVendorCmdsTimeCbk(uniq_t timer,  uint64_t aclConnHandle)
{
    struct hciAclConn* conn;

    //if we got here and conn is still in "wait" state, bad things

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindByHandle((hci_conn_t)aclConnHandle);
    if (conn && conn->state == CONN_STATE_ADV_SET_BLAMING) {
        hciConnDisconnect(conn->id);
        hciConnAclStructDel(conn);
    }
    pthread_mutex_unlock(&mConnsLock);
}

/*
 * FUNCTION: hciAdvSetHandleAndBlameNewConnMethodAndroidVendorCmds
 * USE:      Blame a new connection on an adv set and update accounting info
 * PARAMS:   conn - the ACL connection
 * RETURN:   false always - for this we must always wait for a later "blame" event
 * NOTES:    called with mAdvSetsLock held
 *           This is one of the few "adv set conn blame handlers". This one is used
 *           when the android-vendor methods are available and BT 5.0 is not.
 *           conn->le.advSet will be set to the adv set that is currently in slot 0
 *           since that is the one we blame if no "blame event" shows up
 */
static bool hciAdvSetHandleAndBlameNewConnMethodAndroidVendorCmds(struct hciAclConn *conn)
{
    conn->le.advSet = 0;

    /*
     * we ALWAYS MUST wait here. Either the event will come telling us which adv set
     * caused the connection or the timer will fire and we'll assume bad things
     */
    timerSet(ADV_SET_BLAME_TIMEOUT_ANDROID_VENDOR, hciAdvSetHandleAndBlameNewConnMethodAndroidVendorCmdsTimeCbk, conn->handle);
    return false;
}

/*
 * FUNCTION: hciAdvSetEnableDisableMethodBT4
 * USE:      Enable or disable an adv set on normal BT4 devices
 * PARAMS:   set - the set to operate on
 *           enable - on or off?
 * RETURN:   success
 * NOTES:    called with mAdvSetsLock held
 *           This is one of the few "adv set on/off handlers". This one is used
 *           when neither the BT 5.0 nor the android-vendor methods are available.
 */
static bool hciAdvSetEnableDisableMethodBT4(struct hciAdvSet *set, bool enable)
{
    struct hciCmplLeReadAdvChannelTxPower pwrLvlEvt;
    struct hciAdvSet *t;
    int ret;

    if (!enable) { // we only have one set - simply disable it

        if (hciLeSetAdvEnableSync(false)) {
            logw("Failed to disable BT4 adv\n");
            return false;
        }
        set->hwEnabled = false;
        return true;
    }

    //we want to enable: first see if another set is already on
    for (t = mAdvSets; t; t = t->next) {
        if (t->hwEnabled) {
            logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x because set 0x"HCI_ADV_SET_FMT"x is enabled.\n", HCI_ADV_SET_CONV(set->handle), HCI_ADV_SET_CONV(t->handle));
            return false;
        }
    }

    //we want to enable and no other set is enabled - simply configure the chip and go
    ret = hciLeSetAdvDataSync(set->advDataLen, set->advData);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x because SetAdvData command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), ret);
        return false;
    }
    ret = hciLeSetScanResponseDataSync(set->scanRspDataLen, set->scanRspData);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x because SetScanRspData command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), ret);
        return false;
    }
    ret = hciLeSetAdvParamsSync(set->intervalMin, set->intervalMax, set->advType, set->ownAddressType, set->directAddr.type == BT_ADDR_TYPE_LE_RANDOM ? 1 : 0, set->directAddr.addr, set->channelMap, set->filterPolicy);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x because SetAdvParams command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), ret);
        return false;
    }
    if (set->ownAddressType == HCI_ADV_OWN_ADDR_TYPE_RANDOM || set->ownAddressType == HCI_ADV_OWN_ADDR_TYPE_AUTO_RESOLV_ELSE_RANDOM) {
        ret = hciLeSetRandomAddressSync(set->ownRandomAddr.addr);
        if (ret) {
            logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x because SetRandomAddr command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), ret);
            return false;
        }
    }
    ret = hciLeReadAdvChannelTxPowerSync(&pwrLvlEvt);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x because GetTxPwrLvl command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), ret);
        return false;
    }
    set->hwPowerLevel = pwrLvlEvt.txPower;
    ret = hciLeSetAdvEnableSync(true);
    if (ret) {
        logw("Cannot enable adv 0x"HCI_ADV_SET_FMT"x because SetAdvEnable command failed: %02X\n", HCI_ADV_SET_CONV(set->handle), ret);
        return false;
    }

    set->hwEnabled = true;
    return true;
}

/*
 * FUNCTION: hciAdvSetHandleAndBlameNewConnMethodBT4
 * USE:      Blame a new connection on an adv set and update accounting info
 * PARAMS:   conn - the ACL connection
 * RETURN:   true always - no point in waiting. We either know or do not
 * NOTES:    called with mAdvSetsLock held
 *           This is one of the few "adv set conn blame handlers". This one is used
 *           when neither the BT 5.0 nor the android-vendor methods are available.
 *           conn->le.advSet will be set to the adv set that caused this connection,
 *           or to 0 if we do not know
 */
static bool hciAdvSetHandleAndBlameNewConnMethodBT4(struct hciAclConn *conn)
{
    struct hciAdvSet *t;

    /* easy enough here - just blame the set that is on */
    for (t = mAdvSets; t; t = t->next) {
        if (t->hwEnabled) {
            t->hwEnabled = false;  //adv stops when a connection is formed
            conn->le.advSet = t->handle;
            return true;
        }
    }

    //we do not know but waiting will not resolve it
    conn->le.advSet = 0;
    return true;
}

/*
 * FUNCTION: hciBtStackUp
 * USE:      Brings up the chip in a sane configuration, reads versions, etc
 * PARAMS:   NONE
 * RETURN:   false on error
 * NOTES:
 */
static bool hciBtStackUp(void)
{
    int ret = 0;

    /* sanity and start */
    {
        if (mStackState != STACK_STATE_READY_FOR_UP) {
            loge("Stack cannot be brought up if not ready for bringup\n");
            return false;
        }
        mStackState = STACK_STATE_COMING_UP;
    }

    /* read local BT version */
    {
        struct hciCmplReadLocalVersion evt;
        uint8_t hciVersion, lmpVersion;

        logi("BT UP: reading version\n");
        ret = hciReadLocalVersionSync(&evt);
        if (ret)
            goto out;

        hciVersion = utilGetLE8(&evt.hciVersion);
        lmpVersion = utilGetLE8(&evt.lmpVersion);
        logi("BT UP: bt versions reported: %u, %d\n", hciVersion, lmpVersion);

        if (hciVersion > HCI_VER_MAX_SUPPORTED)
            hciVersion = HCI_VER_MAX_SUPPORTED;

        if (lmpVersion > HCI_VER_MAX_SUPPORTED)
            lmpVersion = HCI_VER_MAX_SUPPORTED;

        mBtVer = hciVersion < lmpVersion ? hciVersion : lmpVersion;

        if (mBtVer == HCI_VERSION_2_0) { /* do 2.0 chips really exist? */
            logi("BT 2.0 chip???\n");
            mBtVer = HCI_VERSION_1_2;
        }

        logi("BT UP: effective BT version: %u (BT spec %s)\n", mBtVer, mBtVers[mBtVer]);

        if (mBtVer < HCI_VERSION_4_0) {
            loge("BT 4.0 minimum!\n");
            ret = -3;
            goto out;
        }
        /* past this point, we can assume BT 4.0+ */
    }

    /* read supported features ad make sure LE is in there*/
    {
        struct hciCmplReadLocalSupportedFeatures evt;

        logi("BT UP: reading features\n");
        ret = hciReadLocalSupportedFeaturesSync(&evt);
        if (ret)
            goto out;

        mLocalFtrs[0] = utilGetLE64(&evt.features);
        logi("BT UP: bt features reported: "FMT64"X\n", CNV64(mLocalFtrs[0]));

        if (!(mLocalFtrs[0] & HCI_LMP_FTR_LE_SUPPORTED_CONTROLLER)) {
            loge("BT LE required!\n");
            ret = -3;
            goto out;
        }
    }

    /* read extended features if possible */
    if (mLocalFtrs[0] & HCI_LMP_FTR_EXTENDED_FEATURES) {
        uint8_t page, numPages = 1;

        for (page = 0; page < numPages && page < MAX_FTR_PAGES; page++) {
            struct hciCmplReadLocalExtendedFeatures evt;
            uint64_t ftrs;
            uint8_t claimedPage;

            ret = hciReadLocalExtendedFeaturesSync(page, &evt);
            if (ret)
                goto out;
            ftrs = utilGetLE64(&evt.features);
            claimedPage = utilGetLE8(&evt.page);
            numPages = utilGetLE8(&evt.maxPage) + 1;

            if (claimedPage < MAX_FTR_PAGES)
                mLocalFtrs[claimedPage] = ftrs;
            else
                logw("Ignoring report for ftr page %u\n", claimedPage);

            logi("BT UP: bt extended features[%d/%d, requested %u] reported: "FMT64"X\n", claimedPage, numPages, page, CNV64(ftrs));
        }
    }

    /* read MAC address and show it */
    {
        struct hciCmplReadBdAddr evt;

        logi("Reading local MAC\n");
        ret = hciReadBdAddrSync(&evt);
        if (ret)
            goto out;

        memcpy(mLocalAddr, evt.mac, sizeof(mLocalAddr));
        logi("Local MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", evt.mac[5], evt.mac[4], evt.mac[3], evt.mac[2], evt.mac[1], evt.mac[0]);
    }

    /* read EDR buffer sizes */
    {
        struct hciCmplReadBufferSize evt;
        uint16_t i;

        logi("BT UP: reading EDR buffer size\n");
        ret = hciReadBufferSizeSync(&evt);
        if (ret)
            goto out;

        mScoBufSz = utilGetLE8(&evt.scoBufferLen);
        mAclBufSzEdr = utilGetLE16(&evt.aclBufferLen);
        mAclBufNumEdr = utilGetLE16(&evt.numAclBuffers);
        mScoBufNum = utilGetLE16(&evt.numScoBuffers);

        logi("BT UP: EDR buffers: %ux%ub ACL + %ux%ub SCO\n", mAclBufNumEdr, mAclBufSzEdr, mScoBufNum, mScoBufSz);

        for (i = 0; i < mAclBufNumEdr; i++)
            sem_post(&mAclPacketsEdr);
    }

    /* read LE buffer sizes & features, if LE exists */
    {
        struct hciCmplLeReadLocalSupportedFeatures evtFtrs;
        struct hciCmplLeReadBufferSize evt;
        uint16_t i;

        logi("BT UP: reading LE buffer size\n");
        ret = hciLeReadBufferSizeSync(&evt);
        if (ret)
            goto out;

        mAclBufSzLe = utilGetLE16(&evt.leBufferSize);
        mAclBufNumLe = utilGetLE8(&evt.leNumBuffers);

        logi("BT UP: LE buffers: %ux%ub\n", mAclBufNumLe, mAclBufSzLe);

        if (!mAclBufNumLe)
            logi("BT UP: joint EDR/LE ACL buffers detected\n");
        else
            mBtJointBuffers = false;

        for (i = 0; i < mAclBufNumLe; i++)
            sem_post(&mAclPacketsLe);

        logi("Reading local LE features\n");
        ret = hciLeReadLocalSupportedFeaturesSync(&evtFtrs);
        if (ret)
            goto out;

        mLocalLeFtrs = utilGetLE64(&evtFtrs.leFeatures);
        logi("BT UP: le features reported: "FMT64"X\n", CNV64(mLocalLeFtrs));
    }

    /* enable LE */
    logi("Enabling LE\n");
    ret = hciWriteLeHostSupportedSync(true, false);
    if (ret)
        goto out;
    logi("LE should be on\n");

    /* set event masks */
    {
        uint64_t evts = 0, evts2 = 0, evtsLe = 0;

        switch (mBtVer) {
        case HCI_VERSION_4_0:
            evts = HCI_EVENT_ALL_BT_4_0;
            evts2 = HCI_EVENT_P2_ALL_BT_4_0;
            evtsLe = HCI_LE_EVENT_ALL_BT_4_0;
            break;
        case HCI_VERSION_4_1:
            evts = HCI_EVENT_ALL_BT_4_1;
            evts2 = HCI_EVENT_P2_ALL_BT_4_1;
            evtsLe = HCI_LE_EVENT_ALL_BT_4_1;
            break;
        case HCI_VERSION_4_2:
            evts = HCI_EVENT_ALL_BT_4_2;
            evts2 = HCI_EVENT_P2_ALL_BT_4_2;
            evtsLe = HCI_LE_EVENT_ALL_BT_4_2;
            break;
        case HCI_VERSION_5_0:
            evts = HCI_EVENT_ALL_BT_5_0;
            evts2 = HCI_EVENT_P2_ALL_BT_5_0;
            evtsLe = HCI_LE_EVENT_ALL_BT_5_0;
            break;
        }
        evts &=~ HCI_EVENT_REMOTE_HOST_SUPPORTED_FEATURES; /* we do not want this one - it is spammy and useless for now */
        evts &=~ HCI_EVENT_MAX_SLOTS_CHANGE; /* same here, really */
        evtsLe &=~ HCI_LE_EVENT_SCAN_REQUEST_RECVD; /* same here */
        evtsLe &=~ HCI_LE_EVENT_ENHANCED_CONN_COMPLETE; /* https://crbug.com/879325 */
        logi("Setting event mask to 0x"FMT64"X\n", CNV64(evts));
        ret = hciSetEventMaskSync(evts);
        if (ret)
            goto out;

        logi("Setting event mask page 2 to 0x"FMT64"X\n", CNV64(evts2));
        ret = hciSetEventMaskPage2Sync(evts2);
        if (ret)
            goto out;

        logi("Setting LE event mask to 0x"FMT64"X\n", CNV64(evtsLe));
        ret = hciLeSetEventMaskSync(evtsLe);
        if (ret)
            goto out;
    }

    /* set up event handler(s) for reset */
    hciSetupResetEventHandler(false);

    /* set up event handler(s) for discovery results */
    {
        struct hciEvtWaitDescr ewd = {
            .cbk = hciInquiryEvtCbk,
            .evtType = HCI_EVT_LE_Meta,
            .extra = HCI_EVTLE_Advertising_Report,
            .persistent = true,
        };

        if (!hciEvtWaitEnqueue(&ewd, 0)) {
            ret = -2;
            loge("Failed to enqueue scan handler\n");
            goto out;
        }
    }

    /* set event handlers for connection states */
    {
        static const uint8_t connEvtTypes[] = {HCI_EVT_Disconnection_Complete, HCI_EVT_Encryption_Change, HCI_EVT_Authentication_Complete,
                                               HCI_EVT_Encryption_Key_Refresh_Complete, HCI_EVT_LE_Meta, HCI_EVT_LE_Meta, HCI_EVT_LE_Meta,
                                               HCI_EVT_Vendor, HCI_EVT_LE_Meta, 0};
        static const uint16_t connEvtExtras[] = {0, 0, 0, 0, HCI_EVTLE_Connection_Complete, HCI_EVTLE_Connection_Update_Complete,
                                                 HCI_EVTLE_LTK_Request, HCI_EVTVENDOR_Android_Subevent_Advt_State_Change,
                                                 HCI_EVTLE_Adv_Set_Terminated};

        if (!hciSetManyEventPersistentHandlers(connEvtTypes, connEvtExtras, hciConnEvtCbk, NULL)) {
            ret = -2;
            loge("Failed to enqueue connection state handlers\n");
            goto out;
        }
    }

    /* set handlers for some LE things (like refusing remote connection parameter changes) */
    if (mBtVer >= HCI_VERSION_4_1) {
        struct hciEvtWaitDescr ewd = {
            .cbk = hciLeParamChangeRequestEventCbk,
            .evtType = HCI_EVT_LE_Meta,
            .extra = HCI_EVTLE_Remote_Connection_Parameter_Request,
            .persistent = true,
        };

        if (!hciEvtWaitEnqueue(&ewd, 0)) {
            ret = -2;
            loge("Failed to enqueue LE connection param change request handler\n");
            goto out;
        }
    }

    /* figure out the multi-adv situation */
    mMaxAdvSets = 1;
    mCanSetAdvTxPower = false;
    mHciAdvSetEnable = hciAdvSetEnableDisableMethodBT4;
    mHciAdvSetHandleAndBlameNewConn = hciAdvSetHandleAndBlameNewConnMethodBT4;
    if (mBtVer >= HCI_VERSION_5_0) {
        struct hciCmplLeReadNumSupportedAdvSets evt;

        logi("Will use BT5 multi-adv support\n");
        ret = hciLeReadNumberOfSupportedAdvertisingSetsSync(&evt);
        if (ret)
            logw(" Read number supported adv sets command errored out (0x%02x) - will use normal advertising\n", ret);
        else {
            mMaxAdvSets = evt.maxAdvsets;
            mCanSetAdvTxPower = true;
            logi(" Controller supports up to %u adv sets\n", mMaxAdvSets);
        }
    }
    else if (mBtVer >= HCI_VERSION_4_0) {
        struct hciCmplVendorLeGetVendorCapabilities evt;

        logi("Will try BT4 android-vendor multi-adv support\n");

        ret = hciVendorLeGetVendorCapabilitiesSync(&evt);
        if (ret == HCI_ERR_Unknown_HCI_Command)
            logi(" android-vendor extensions not found - will use normal advertising\n");
        else if (ret)
            logw(" Vendor test command errored out (0x%02x) - will use normal advertising\n", ret);
        else if (evt.maxAdvtInstances <= 1)
            logw(" Vendor read number supported adv sets command returned a nonsensical value: %u\n", evt.maxAdvtInstances);
        else {
            mMaxAdvSets = evt.maxAdvtInstances - 1; // we cannot count slot 0
            mCanSetAdvTxPower = true;
            mHciAdvSetEnable = hciAdvSetEnableDisableMethodAndroidVendorCmds;
            mHciAdvSetHandleAndBlameNewConn = hciAdvSetHandleAndBlameNewConnMethodAndroidVendorCmds;
            logi(" Controller supports up to %u adv sets\n", mMaxAdvSets);
        }
    }
    else {
        mMaxAdvSets = 0;
        mCanSetAdvTxPower = false;
        logi("BT4.0 required for advetising. Advertising will not be supported\n");
    }

out:
    if (ret) {
        loge("Status was 0x%02X\n", ret);
        mStackState = STACK_STATE_DOWN;
        return false;
    }
    mStackState = STACK_STATE_UP;
    return true;
}

/*
 * FUNCTION: hciAdvSetFindByHandle
 * USE:      Find an adv set by handle
 * PARAMS:   handle - the handle
 * RETURN:   the set structure or NULL
 * NOTES:    call with mAdvSetsLock held
 */
static struct hciAdvSet* hciAdvSetFindByHandle(hci_adv_set_t handle)
{
    struct hciAdvSet* t;

    for (t = mAdvSets; t; t = t->next) {
        if (t->handle == handle)
            return t;
    }

    return NULL;
}

/*
 * FUNCTION: hciAdvIsPowerLevelSettingSupported
 * USE:      Can adv tx power be set with our chip?
 * PARAMS:   none
 * RETURN:   the answer
 * NOTES:
 */
bool hciAdvIsPowerLevelSettingSupported(void)
{
    return mCanSetAdvTxPower;
}

/*
 * FUNCTION: hciAdvGetMaxAdvSetsSupported
 * USE:      How many adv sets can we support (max) on hardware
 * PARAMS:   none
 * RETURN:   the answer
 * NOTES:
 */
uint32_t hciAdvGetMaxAdvSetsSupported(void)
{
    return mMaxAdvSets;
}

/*
 * FUNCTION: hciAdvSetAllocate
 * USE:      Allocate an advertising set structure
 * PARAMS:   none
 * RETURN:   the handle to this set
 * NOTES:    this does not in any way touch hardware
 */
hci_adv_set_t hciAdvSetAllocate(void)
{
    struct hciAdvSet *set = (struct hciAdvSet*)calloc(1, sizeof(struct hciAdvSet));
    hci_adv_set_t handle;

    if (!set)
        return 0;

    set->handle = handle = uniqGetNext();
    set->ownRandomAddr.type = BT_ADDR_TYPE_EDR; //definitely not valid for adv
    set->directAddr.type = BT_ADDR_TYPE_EDR;    //definitely not valid for adv
    pthread_mutex_lock(&mAdvSetsLock);
    set->next = mAdvSets;
    if (mAdvSets)
        mAdvSets->prev = set;
    mAdvSets = set;
    pthread_mutex_unlock(&mAdvSetsLock);

    return handle;
}

/*
 * FUNCTION: hciAdvSetFree
 * USE:      Free an advertising set structure. Set must not be enabled!
 * PARAMS:   handle - the handle to this set
 * RETURN:   success
 * NOTES:    this does not in any way touch hardware
 */
bool hciAdvSetFree(hci_adv_set_t handle)
{
    struct hciAdvSet *set;
    bool ret = false;

    pthread_mutex_lock(&mAdvSetsLock);
    set = hciAdvSetFindByHandle(handle);
    if (!set)
        logw("Set handle 0x"HCI_ADV_SET_FMT"x not found\n", HCI_ADV_SET_CONV(handle));
    else if (set->hwEnabled)
        logw("Set 0x"HCI_ADV_SET_FMT"x is enabled - cannot delete it\n", HCI_ADV_SET_CONV(handle));
    else {
        if (set->next)
            set->next->prev = set->prev;
        if (set->prev)
            set->prev->next = set->next;
        else
            mAdvSets = set->next;
        free(set);
        ret = true;
    }
    pthread_mutex_unlock(&mAdvSetsLock);

    return ret;
}

/*
 * FUNCTION: hciAdvSetConfigureData
 * USE:      Configure an advertising set's data. Set must not be enabled!
 * PARAMS:   handle - the handle to this set
 *           scanRsp - which data to config? SCAN_RSP or ADV
 *           data - the data to use
 *           len - length of said data
 * RETURN:   success
 * NOTES:    this does not in any way touch hardware
 */
bool hciAdvSetConfigureData(hci_adv_set_t handle, bool scanRsp, const uint8_t *data, uint32_t len)
{
    struct hciAdvSet *set;
    bool ret = false;

    pthread_mutex_lock(&mAdvSetsLock);
    set = hciAdvSetFindByHandle(handle);
    if (!set)
        logw("Set handle 0x"HCI_ADV_SET_FMT"x not found\n", HCI_ADV_SET_CONV(handle));
    else if (set->hwEnabled)
        logw("Set 0x"HCI_ADV_SET_FMT"x is enabled - cannot edit it\n", HCI_ADV_SET_CONV(handle));
    else {

        uint32_t *lenP;
        uint8_t *dataP;
        uint32_t lenLimit;

        if (scanRsp) {
            lenP = &set->scanRspDataLen;
            dataP = set->scanRspData;
            lenLimit = HCI_SCAN_RSP_DATA_MAX_LEN;
        }
        else {
            lenP = &set->advDataLen;
            dataP = set->advData;
            lenLimit = HCI_ADV_DATA_MAX_LEN;
        }

        if (len > lenLimit)
            logw("%s data is too long (%u > %u)\n", scanRsp ? "SCAN_RSP" : "ADV", len, lenLimit);
        else {

            memcpy(dataP, data, len);
            *lenP = len;
            ret = true;
        }
    }
    pthread_mutex_unlock(&mAdvSetsLock);

    return ret;
}

/*
 * FUNCTION: hciAdvSetOwnRandomAddr
 * USE:      Configure an advertising set's random adress. Set must not be enabled!
 * PARAMS:   handle - the handle to this set
 *           ownRandomAddr - the random address to use when random address requested for advertising
 * RETURN:   success
 * NOTES:    this does not in any way touch hardware
 */
bool hciAdvSetOwnRandomAddr(hci_adv_set_t handle, const struct bt_addr *ownRandomAddr)
{
    struct hciAdvSet *set;
    bool ret = false;

    pthread_mutex_lock(&mAdvSetsLock);
    set = hciAdvSetFindByHandle(handle);
    if (!set)
        logw("Set handle 0x"HCI_ADV_SET_FMT"x not found\n", HCI_ADV_SET_CONV(handle));
    else if (set->hwEnabled)
        logw("Set 0x"HCI_ADV_SET_FMT"x is enabled - cannot edit it\n", HCI_ADV_SET_CONV(handle));
    else if (ownRandomAddr->type != BT_ADDR_TYPE_LE_RANDOM)
        logw("Set 0x"HCI_ADV_SET_FMT"x random address cannot be set - provided addr is not random\n", HCI_ADV_SET_CONV(handle));
    else {

        set->ownRandomAddr = *ownRandomAddr;
        ret = true;
    }
    pthread_mutex_unlock(&mAdvSetsLock);

    return ret;
}

/*
 * FUNCTION: hciAdvSetSetAdvParams
 * USE:      Configure an advertising set's parameters. Set must not be enabled!
 * PARAMS:   handle - the handle to this set
 *           advIntervalMin - minimum adv interval (in units of 0.625ms)
 *           advIntervalMax - maximum adv interval (in units of 0.625ms)
 *           advType - adv type: HCI_ADV_TYPE_ADV_*
 *           ownAddressType - own addr type: HCI_ADV_OWN_ADDR_TYPE_*
 *           directAddr - if direct adv, the address of target, else ignored
 *           advChannelMap - channels to use: bitmask of HCI_ADV_CHAN_MAP_USE_*
 *           advFilterPolicy - filter policy: HCI_ADV_FILTER_POL_*
 *           advPower - TX power in dBm, ignored if not suported, see hciAdvIsPowerLevelSettingSupported()
 * RETURN:   success
 * NOTES:    this does not in any way touch hardware
 */
bool hciAdvSetSetAdvParams(hci_adv_set_t handle, uint16_t advIntervalMin, uint16_t advIntervalMax, uint8_t advType, uint8_t ownAddressType, struct bt_addr *directAddr, uint8_t advChannelMap, uint8_t advFilterPolicy, int8_t advPower)
{
    struct hciAdvSet *set;
    bool ret = false;

    pthread_mutex_lock(&mAdvSetsLock);
    set = hciAdvSetFindByHandle(handle);
    if (!set)
        logw("Set handle 0x"HCI_ADV_SET_FMT"x not found\n", HCI_ADV_SET_CONV(handle));
    else if (set->hwEnabled)
        logw("Set 0x"HCI_ADV_SET_FMT"x is enabled - cannot edit it\n", HCI_ADV_SET_CONV(handle));
    else {

        set->intervalMin = advIntervalMin;
        set->intervalMax = advIntervalMax;
        set->advType = advType;
        set->ownAddressType = ownAddressType;
        if (directAddr)
            set->directAddr = *directAddr;
        else
            set->directAddr.type = BT_ADDR_TYPE_EDR; //definitely not valid for adv
        set->channelMap = advChannelMap;
        set->filterPolicy = advFilterPolicy;
        set->powerLevel = advPower;

        ret = true;
    }
    pthread_mutex_unlock(&mAdvSetsLock);

    return ret;
}

/*
 * FUNCTION: hciAdvSetGetCurTxPowerLevel
 * USE:      Get the current tx power level of an adv set. Set must be enabled!
 * PARAMS:   handle - the handle to this set
 *           advTxPowerLevelP - where to store the result
 * RETURN:   success
 * NOTES:    this does not in any way touch hardware
 */
bool hciAdvSetGetCurTxPowerLevel(hci_adv_set_t handle, int8_t *advTxPowerLevelP)
{
    struct hciAdvSet *set;
    bool ret = false;

    pthread_mutex_lock(&mAdvSetsLock);
    set = hciAdvSetFindByHandle(handle);
    if (!set)
        logw("Set handle 0x"HCI_ADV_SET_FMT"x not found\n", HCI_ADV_SET_CONV(handle));
    else if (!set->hwEnabled)
        logw("Set 0x"HCI_ADV_SET_FMT"x is not enabled - cannot get its power\n", HCI_ADV_SET_CONV(handle));
    else {

        if (advTxPowerLevelP)
            *advTxPowerLevelP = set->hwPowerLevel;

        ret = true;
    }
    pthread_mutex_unlock(&mAdvSetsLock);

    return ret;
}

/*
 * FUNCTION: hciAdvSetGetCurAdvAddrLocked
 * USE:      Get the current adv addr of an adv set.
 * PARAMS:   set - the adv set structure
 *           ownAddr - where to store the result
 * RETURN:   success
 * NOTES:    must be called with mAdvSetsLock held, assumes set is currently active
 */
static void hciAdvSetGetCurAdvAddrLocked(struct hciAdvSet *set, struct bt_addr *ownAddr)
{
    if (set->ownAddressType == HCI_ADV_OWN_ADDR_TYPE_RANDOM)
        *ownAddr = set->ownRandomAddr;
    else {
        memcpy(ownAddr->addr, mLocalAddr, sizeof(ownAddr->addr));
        ownAddr->type = BT_ADDR_TYPE_LE_PUBLIC;
    }
}

/*
 * FUNCTION: hciAdvSetGetCurAdvAddr
 * USE:      Get the current adv addr of an adv set. Set must be enabled!
 * PARAMS:   handle - the handle to this set
 *           ownAddr - where to store the result
 * RETURN:   success
 * NOTES:    this does not in any way touch hardware
 */
bool hciAdvSetGetCurAdvAddr(hci_adv_set_t handle, struct bt_addr *ownAddr)
{
    struct hciAdvSet *set;
    bool ret = false;

    pthread_mutex_lock(&mAdvSetsLock);
    set = hciAdvSetFindByHandle(handle);
    if (!set)
        logw("Set handle 0x"HCI_ADV_SET_FMT"x not found\n", HCI_ADV_SET_CONV(handle));
    else if (!set->hwEnabled)
        logw("Set 0x"HCI_ADV_SET_FMT"x is not enabled - cannot get its address\n", HCI_ADV_SET_CONV(handle));
    else {
        hciAdvSetGetCurAdvAddrLocked(set, ownAddr);
        ret = true;
    }
    pthread_mutex_unlock(&mAdvSetsLock);

    return ret;
}


/*
 * FUNCTION: hciAdvSetEnable
 * USE:      Try to enable a given adv set
 * PARAMS:   handle - the handle to this set
 * RETURN:   success
 * NOTES:    this may fail sometimes and succeed other times based on hw state
 */
bool hciAdvSetEnable(hci_adv_set_t handle)
{
    struct hciAdvSet *set;
    bool ret = false;

    pthread_mutex_lock(&mAdvSetsLock);
    set = hciAdvSetFindByHandle(handle);
    if (!set)
        logw("Set handle 0x"HCI_ADV_SET_FMT"x not found\n", HCI_ADV_SET_CONV(handle));
    else if (set->hwEnabled)
        logw("Set 0x"HCI_ADV_SET_FMT"x is enabled - cannot enable it again\n", HCI_ADV_SET_CONV(handle));
    else if (!mHciAdvSetEnable)
        logw("No method for enable/disable defined for this chip - cannot enable adv set\n");
    else {

        ret = true;

        /* Sanity checks. All constantrs are from spec */
        if (!set->advDataLen) {
            logw("Cannot enable adv set 0x"HCI_ADV_SET_FMT"x since it has no adv data.\n", HCI_ADV_SET_CONV(handle));
            ret = false;
        }
        if (set->advType != HCI_ADV_TYPE_ADV_DIRECT_IND && (set->intervalMin > set->intervalMax || set->intervalMin < 0x20 || set->intervalMax > 0x4000)) {
            logw("Cannot enable adv set 0x"HCI_ADV_SET_FMT"x since it has invalid interval params.\n", HCI_ADV_SET_CONV(handle));
            ret = false;
        }
        if (set->advType != HCI_ADV_TYPE_ADV_IND && set->advType != HCI_ADV_TYPE_ADV_DIRECT_IND && set->advType != HCI_ADV_TYPE_ADV_SCAN_IND && set->advType != HCI_ADV_TYPE_ADV_NONCONN_IND && set->advType != HCI_ADV_TYPE_ADV_DIRECT_IND_LOW_DUTY) {
            logw("Cannot enable adv set 0x"HCI_ADV_SET_FMT"x since it has invalid adv type.\n", HCI_ADV_SET_CONV(handle));
            ret = false;
        }
        if (set->ownAddressType != HCI_ADV_OWN_ADDR_TYPE_PUBLIC && set->ownAddressType != HCI_ADV_OWN_ADDR_TYPE_RANDOM && set->ownAddressType != HCI_ADV_OWN_ADDR_TYPE_AUTO_RESOLV_ELSE_PUBLIC && set->ownAddressType != HCI_ADV_OWN_ADDR_TYPE_AUTO_RESOLV_ELSE_RANDOM) {
            logw("Cannot enable adv set 0x"HCI_ADV_SET_FMT"x since it has invalid own addr type.\n", HCI_ADV_SET_CONV(handle));
            ret = false;
        }
        if ((set->advType == HCI_ADV_TYPE_ADV_DIRECT_IND || set->advType == HCI_ADV_TYPE_ADV_DIRECT_IND_LOW_DUTY) && set->directAddr.type != BT_ADDR_TYPE_LE_PUBLIC && set->directAddr.type != BT_ADDR_TYPE_LE_RANDOM) {
            logw("Cannot enable adv set 0x"HCI_ADV_SET_FMT"x since it has invalid peer addr type.\n", HCI_ADV_SET_CONV(handle));
            ret = false;
        }
        if (!(set->channelMap & 7)) {
            logw("Cannot enable adv set 0x"HCI_ADV_SET_FMT"x since it has invalid channel map.\n", HCI_ADV_SET_CONV(handle));
            ret = false;
        }
        if (set->filterPolicy != HCI_ADV_FILTER_POL_SCAN_ALL_CONNECT_ALL && set->filterPolicy != HCI_ADV_FILTER_POL_SCAN_LIST_CONNECT_ALL && set->filterPolicy != HCI_ADV_FILTER_POL_SCAN_ALL_CONNECT_LIST && set->filterPolicy != HCI_ADV_FILTER_POL_SCAN_LIST_CONNECT_LIST) {
            logw("Cannot enable adv set 0x"HCI_ADV_SET_FMT"x since it has invalid filter policy.\n", HCI_ADV_SET_CONV(handle));
            ret = false;
        }
        if ((set->ownAddressType == HCI_ADV_OWN_ADDR_TYPE_RANDOM || set->ownAddressType == HCI_ADV_OWN_ADDR_TYPE_AUTO_RESOLV_ELSE_RANDOM) && set->ownRandomAddr.type != BT_ADDR_TYPE_LE_RANDOM) {
            logw("Cannot enable adv set 0x"HCI_ADV_SET_FMT"x since it has no valid random address and might need it.\n", HCI_ADV_SET_CONV(handle));
            ret = false;
        }

        //if all checks pass - do the actual ON procedure
        ret = ret && mHciAdvSetEnable(set, true);
    }
    pthread_mutex_unlock(&mAdvSetsLock);

    return ret;
}

/*
 * FUNCTION: hciAdvSetDisable
 * USE:      Try to disable a given adv set
 * PARAMS:   handle - the handle to this set
 * RETURN:   success
 * NOTES:
 */
bool hciAdvSetDisable(hci_adv_set_t handle)
{
    struct hciAdvSet *set;
    bool ret = false;

    pthread_mutex_lock(&mAdvSetsLock);
    set = hciAdvSetFindByHandle(handle);
    if (!set)
        logw("Set handle 0x"HCI_ADV_SET_FMT"x not found\n", HCI_ADV_SET_CONV(handle));
    else if (!set->hwEnabled)
        logw("Set 0x"HCI_ADV_SET_FMT"x is disabled - cannot disable it again\n", HCI_ADV_SET_CONV(handle));
    else if (!mHciAdvSetEnable)
        logw("No method for enable/disable defined for this chip - cannot enable adv set\n");
    else
        ret = mHciAdvSetEnable(set, false);

    pthread_mutex_unlock(&mAdvSetsLock);

    return ret;
}

/*
 * FUNCTION: hciDiscoverLeStart
 * USE:      Starts LE discovery
 * PARAMS:   cbk - device discovered callback
 *           cbkData - data for said callback
 *           active - do active scan?
 * RETURN:   discovery handle or 0 for error
 * NOTES:    Callbacks might be called even if func returns false, but
 *           will stop once said return value is actually returned.
 *           Discovery goes on until stopped.
 */
uniq_t hciDiscoverLeStart(hciDeviceDiscoveredLeCbk cbk, void *cbkData, bool active, bool useRandomAddr)
{
    uniq_t ret = 0;
    int sta;

    if (!cbk) {
        loge("Refusing discovery with no callback\n");
        return 0;
    }

    pthread_mutex_lock(&mDiscoveryStateLock);
    if (mDiscoverLeHandle)
        logw("Refusing to do LE discovery while another in progress\n");
    else {
        ret = mDiscoverLeHandle = uniqGetNext();

        mDiscoverLeCbk = cbk;
        mDiscoverLeData = cbkData;
    }
    pthread_mutex_unlock(&mDiscoveryStateLock);

    if (!ret)
        return 0;

    sta = hciLeSetScanParamsSync(active, HCI_LE_SCAN_INTERVAL, HCI_LE_SCAN_WINDOW, useRandomAddr, false);
    if (sta) {
        loge("Failed to set LE scan params: %d\n", sta);
        goto err;
    }

    sta = hciLeSetScanEnableSync(true, false);
    if (sta) {
        loge("Failed to set LE scan on: %d\n", sta);
        goto err;
    }

    return ret;

err:
    pthread_mutex_lock(&mDiscoveryStateLock);
    mDiscoverLeHandle = 0;
    pthread_mutex_unlock(&mDiscoveryStateLock);

    return 0;
}

/*
 * FUNCTION: hciDiscoverLeStop
 * USE:      Stops LE discovery
 * PARAMS:   handle - the handle from hciDiscoverLeStart()
 * RETURN:   false on error
 * NOTES:    Callbacks will stop once this returns
 */
bool hciDiscoverLeStop(uniq_t handle)
{
    int sta;

    if (!handle) {
        loge("Cannot pass NULL handle here\n");
        return false;
    }

    pthread_mutex_lock(&mDiscoveryStateLock);
    if (mDiscoverLeHandle != handle)
        handle = 0;
    else
        mDiscoverLeHandle = 0;
    pthread_mutex_unlock(&mDiscoveryStateLock);

    if (handle){
        sta = hciLeSetScanEnableSync(false, false);
        if (sta)
            loge("Failed to set LE scan off: %d\n", sta);
    }

    hciWorkFlush();

    return !!handle;
}


/*
 * FUNCTION: hciInfoSharedBuffers
 * USE:      Provide info on whether EDR & LE ACL buffers are shared in our controller
 * PARAMS:   NONE
 * RETURN:   the answer
 * NOTES:
 */
bool hciInfoSharedBuffers(void)
{
   return mBtJointBuffers;
}

/*
 * FUNCTION: hciInfoScoBufSize
 * USE:      Provide info on SCO buffer size in our controller and SCO support
 * PARAMS:   bufSz - where to store buffer sizes (or NULL if uninterested)
 *           bufNum - where to store number of buffers (or NULL if uninterested)
 * RETURN:   true if SCO supported
 * NOTES:
 */
bool hciInfoScoBufSize(uint16_t *bufSz, uint16_t *bufNum)
{
    return false;
}

/*
 * FUNCTION: hciInfoSharedBuffers
 * USE:      Provide info on LE ACL buffer size in our controller and LE support
 * PARAMS:   bufSz - where to store buffer sizes (or NULL if uninterested)
 *           bufNum - where to store number of buffers (or NULL if uninterested)
 * RETURN:   true if LE supported
 * NOTES:
 */
bool hciInfoAclBufSizeLe(uint16_t *bufSz, uint16_t *bufNum)
{
    if (bufSz)
        *bufSz = mAclBufSzLe;
    if (bufNum)
        *bufNum = mAclBufNumLe;

    return true;
}

/*
 * FUNCTION: hciCmdStatusCbk
 * USE:      Gives us the status of a command we started
 * PARAMS:   cbkData - non-null for LE
 *           status - status from the chip
 * RETURN:   NONE
 * NOTES:    This is the universal sink for status events we do not care much about
 */
static void hciCmdStatusCbk(void *cbkData, uint8_t status)
{
    logd("status: %d\n", status);
}

/*
 * FUNCTION: hciConnEncryptLe
 * USE:      Start an encryption attempt for an LE connection
 * PARAMS:   conn - the connection
 *           demandMitmSafe - do we want mitm-safety?
 * RETURN:   true if attempt will be made
 * NOTES:    call with mConnsLock held
 */
static bool hciConnEncryptLe(struct hciAclConn *conn, bool demandMitmSafe)
{
    if (!(mLocalLeFtrs & HCI_LE_FTR_ENCRYPTION)) {
        loge("Encryption not supported\n");
        return false;
    }

    if (!(conn->le.ftrs & HCI_LE_FTR_ENCRYPTION)) {
        loge("Encryption not supported remotely\n");
        return false;
    }

    //TODO: LE Security Manager integration

    return false;
}

/*
 * FUNCTION: hciConnectLe
 * USE:      Start an LE connection to a given address
 * PARAMS:   mac - the mac
 *           randomAddr - peer address is random?
 *           scanInt - connect scan interval
 *           scanWindow - connect scan window
 *           intMin - minimum wanted interval
 *           intMax - maximum wanted interval
 *           latency - wanted latency
 *           timeout - wanted timeout
 *           useOwnRandomAddr - send peer our random addr?
 * RETURN:   true if attempt will be made
 * NOTES:    call with mConnsLock held. Caller assumed to know limitations (one at a time, radom addr shared with adv, etc)
 */
static bool hciConnectLe(const uint8_t *mac, bool randomAddr, uint16_t scanInt, uint16_t scanWindow, uint16_t intMin, uint16_t intMax, uint16_t latency, uint16_t timeout, bool useOwnRandomAddr)
{
    struct hciLeCreateConnection cmd;

    utilSetLE16(&cmd.scanInterval, scanInt);
    utilSetLE16(&cmd.scanWindow, scanWindow);
    utilSetLE8(&cmd.connectToAnyWhitelistedDevice, 0);
    utilSetLE8(&cmd.peerRandomAddr, randomAddr ? 1 : 0);
    memcpy(cmd.peerMac, mac, sizeof(cmd.peerMac));
    utilSetLE8(&cmd.useOwnRandomAddr, useOwnRandomAddr ? 1 : 0);
    utilSetLE16(&cmd.connIntervalMin, intMin);
    utilSetLE16(&cmd.connIntervalMax, intMax);
    utilSetLE16(&cmd.connLatency, latency);
    utilSetLE16(&cmd.supervisionTimeout, timeout);
    utilSetLE16(&cmd.minConnLen, 0); /* not a useful hint, i know */
    utilSetLE16(&cmd.maxConnLen, intMin * 2);

    if (!hciCmdSubmitSimpleWithStatusWithDoneCbk(HCI_OGF_LE, HCI_CMD_LE_Create_Connection, &cmd, sizeof(cmd), hciCmdStatusCbk, NULL)) {
        logi("Failed to request connect to "MACFMT"\n", MACCONV(mac));
        return false;
    }
    return true;
}

/*
 * FUNCTION: hciMakeProgressOnLeConnectionReqs
 * USE:      Try to make progress on our queue of LE connection requests
 * PARAMS:   NONE
 * RETURN:   NONE
 * NOTES:    call with mConnsLock held, do not do it on the event handler thread (will deadlock in case of random addr use)
 */
static void hciMakeProgressOnLeConnectionReqs(void)
{
    struct hciLeConnReq *req;
    struct hciAclConn *conn;
    bool done = false;

    while (!done) {
        //can we do anything?
        if (!mLeConnReqsHead)
            return;
        if (mLeConnInProgress)
            return;

        //grab a request
        req = mLeConnReqsHead;
        mLeConnReqsHead = mLeConnReqsHead->next;
        if (!mLeConnReqsHead)
            mLeConnReqsTail = NULL;

        //verify the connection exists still and is in valid state
        conn = hciConnFindByHandle(req->aclConn);
        if (!conn)
            logi("Connection request found for a nonexistent connection. Ignoring\n");
        else if (conn->state != CONN_STATE_WAIT)
            logi("Connection request found for a connection not in wait state. Ignoring\n");
        else {
            conn->state = CONN_STATE_TRYING;
            if (req->useRandomAddr && hciLeSetRandomAddressSync(req->selfRandomAddr))
                logi("Failed to set random address for connection. Dropping request and connection\n");
            else if (!hciConnectLe(conn->peerAddr.addr, conn->peerAddr.type == BT_ADDR_TYPE_LE_RANDOM, req->scanInt, req->scanWindow, req->intMin, req->intMax, req->latency, req->timeout, req->useRandomAddr))
                logi("Failed to start connection request. Dropping request and connection\n");
            else
                done = true;

            if (!done)
                hciConnAclStructDel(conn);
        }
        free(req);
    }
}

/*
 * FUNCTION: hciEnqueueConnectLe
 * USE:      Enqueue a request to make an LE connection
 * PARAMS:   aclConn - the acl conn struct allocated for this connection
 *           randomAddr - peer address is random?
 *           scanInt - connect scan interval
 *           scanWindow - connect scan window
 *           intMin - minimum wanted interval
 *           intMax - maximum wanted interval
 *           latency - wanted latency
 *           timeout - wanted timeout
 *           useOwnRandomAddr - send peer our random addr?
 * RETURN:   true if attempt will be made
 * NOTES:    call with mConnsLock held
 */
static bool hciEnqueueConnectLe(hci_conn_t aclConn, uint16_t scanInt, uint16_t scanWindow, uint16_t intMin, uint16_t intMax, uint16_t latency, uint16_t timeout, const uint8_t *sendRandomAddr)
{
    struct hciLeConnReq *req = calloc(1, sizeof(struct hciLeConnReq));

    if (!req)
        return false;

    req->aclConn = aclConn;
    req->scanInt = scanInt;
    req->scanWindow = scanWindow;
    req->intMin = intMin;
    req->intMax = intMax;
    req->latency = latency;
    req->timeout = timeout;
    req->useRandomAddr = !!sendRandomAddr;
    if (sendRandomAddr)
        memcpy(req->selfRandomAddr, sendRandomAddr, sizeof(req->selfRandomAddr));

    if (mLeConnReqsTail)
        mLeConnReqsTail->next = req;
    else
        mLeConnReqsHead = req;
    mLeConnReqsTail = req;

    hciMakeProgressOnLeConnectionReqs();

    return true;
}

/*
 * FUNCTION: hciConnAclStructDel
 * USE:      Delete a connection structure
 * PARAMS:   conn - the structure
 * RETURN:   NONE
 * NOTES:    call with mConnsLock held
 */
static void hciConnAclStructDel(struct hciAclConn* conn)
{
    if (conn->outstandingPackets) {
        if (BT_ADDR_IS_EDR(conn->peerAddr)) {
            while (conn->outstandingPackets--)
                sem_post(&mAclPacketsEdr);
            l2cAclCreditAvail(false);
        } else {
            while (conn->outstandingPackets--)
                sem_post(&mAclPacketsLe);
            l2cAclCreditAvail(true);
        }
    }

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

    if (conn->rxBacklog)
        sgFree(conn->rxBacklog);

    logd("deleting conn struct for "ADDRFMT" h="HANDLEFMT"\n", ADDRCONV(conn->peerAddr), HANDLECNV(conn->handle));
    free(conn);
}

/*
 * FUNCTION: hciConnAclStructNew
 * USE:      Create a connection structure
 * PARAMS:   id - the ACL connection ID
 *           addr - the peer address
 *           state - the state to create the connection in
 *           isMaster - set us as master?
 * RETURN:   the new conn struct or NULL
 * NOTES:    call with mConnsLock held
 */
static struct hciAclConn* hciConnAclStructNew(uint16_t id, const struct bt_addr *addr, uint8_t state, bool isMaster)
{
    struct hciAclConn *conn = (struct hciAclConn*)calloc(1, sizeof(struct hciAclConn));
    if (!conn)
        return NULL;

    memcpy(&conn->peerAddr, addr, sizeof(conn->peerAddr));
    conn->state = state;
    conn->isMaster = isMaster;
    conn->id = id;
    conn->handle = uniqGetNext();

    conn->next = mConns;
    mConns = conn;

    return conn;
}

/*
 * FUNCTION: hciConnect
 * USE:      Start a connection to a given address
 * PARAMS:   addr - the address to connect to
 *           selfRandomAddr - if null will use public addr, else this is the random address to use as own for connection
 *           scanIntervalP - if not null, scan interval to use. if null - stack picks
 *           scanWindowP - if not null, scan window to use. if null - stack picks
 *           connIntervalMinP - if not null, min conn interval to use. if null - stack picks
 *           connIntervalMaxP - if not null, max conn interval to use. if null - stack picks
 *           latencyP - if not null, latency to use. if null - stack picks
 *           timeoutP - if not null, timeout to use. if null - stack picks
 * RETURN:   connectin handle if an attempt will be made to connect. 0 else
 */
hci_conn_t hciConnect(const struct bt_addr* addr, const uint8_t *selfRandomAddr, uint16_t *scanIntervalP, uint16_t *scanWindowP, uint16_t *connIntervalMinP, uint16_t *connIntervalMaxP, uint16_t *latencyP, uint16_t *timeoutP)
{
    uint32_t scanInterval, scanWindow, connIntervalMin, connIntervalMax, latency, timeout;
    hci_conn_t ret = 0;

    logd("Requesting a connection to "ADDRFMT"\n", ADDRCONV(*addr));

    //EDR is not supported
    if (BT_ADDR_IS_EDR(*addr)) {
        loge("EDR unsupported\n");
        return false;
    }

    //read params
    if (scanIntervalP && scanWindowP) {
        scanInterval = *scanIntervalP;
        scanWindow = *scanWindowP;
    }
    else if (scanIntervalP) {
        scanInterval = *scanIntervalP;
        scanWindow = (scanInterval + 1) / 2;
        if (scanWindow < 0x0004)  //min as per spec
            scanWindow = 0x0004;
    }
    else if (scanWindowP) {
        scanWindow = *scanWindowP;
        scanInterval = scanWindow * 2;
        if (scanInterval > 0x4000)  //max as per spec
            scanInterval = 0x4000;
    }
    else {
        scanWindow = HCI_LE_CONN_SCAN_WINDOW;
        scanInterval = HCI_LE_CONN_SCAN_INTERVAL;
    }

    if (connIntervalMinP && connIntervalMaxP) {
        connIntervalMin = *connIntervalMinP;
        connIntervalMax = *connIntervalMaxP;
    }
    else if (connIntervalMinP) {
        connIntervalMin = *connIntervalMinP;
        connIntervalMax = (connIntervalMin + 3) / 2;
        if (connIntervalMax > 0x0c80)  //max as per spec
            connIntervalMax = 0x0c80;
    }
    else if (connIntervalMaxP) {
        connIntervalMax = *connIntervalMaxP;
        connIntervalMin = (connIntervalMax * 2) / 3;
        if (connIntervalMin < 0x0006)  //min as per spec
            connIntervalMax = 0x0006;
    }
    else {
        connIntervalMin = HCI_LE_CONN_INT_MIN;
        connIntervalMax = HCI_LE_CONN_INT_MAX;
    }

    latency = latencyP ? *latencyP : HCI_LE_CONN_LATENCY;
    timeout = timeoutP ? *timeoutP : HCI_LE_CONN_TIMEOUT;

    //sanity check params before we get too far
    if (scanInterval < scanWindow || scanWindow < 0x0004 || scanInterval > 0x4000) { //as per spec
        logw("Scan settings for connection creation are invalid\n");
        return 0;
    }
    if (connIntervalMin > connIntervalMax || connIntervalMin < 0x0006 || connIntervalMax > 0x0c80) { //as per spec
        logw("Connection interval settings for connection creation are invalid\n");
        return 0;
    }
    if (latency > 0x01f3) { //as per spec
        logw("Latency setting for connection creation are invalid\n");
        return 0;
    }
    if (timeout < 0x000a || timeout > 0x0c80 || timeout * 8 <= (1 + latency) * connIntervalMax * 2) { //as per spec
        logw("Timeout setting for connection creation are invalid\n");
        return 0;
    }

    pthread_mutex_lock(&mConnsLock);
    if (hciConnFindByAddr(addr))
        logw("refusing to connect to address I already have a connection to\n");
    else {
        struct hciAclConn* conn = hciConnAclStructNew(ACL_CONN_ID_INVALID, addr, CONN_STATE_WAIT, true);
        if (!conn)
            loge("Failed to allocate conn struct\n");
        else if (hciEnqueueConnectLe(conn->handle, scanInterval, scanWindow, connIntervalMin, connIntervalMax, latency, timeout, selfRandomAddr))
            ret = conn->handle;
        else
            hciConnAclStructDel(conn);
    }
    pthread_mutex_unlock(&mConnsLock);

    return ret;
}

/*
 * FUNCTION: hciDisconnect
 * USE:      Kill a connection [attempt]
 * PARAMS:   aclConn - the connection handle
 * RETURN:   true if attempt will be made
 * NOTES:
 */
bool hciDisconnect(hci_conn_t aclConn)
{
    struct hciAclConn* conn;

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindByHandle(aclConn);
    if (!conn)
        logw("Failed to find connection to disconnect\n");
    else {
        bool isLE = BT_ADDR_IS_LE(conn->peerAddr);

        switch (conn->state) {
        case CONN_STATE_WAIT:
            hciConnAclStructDel(conn);   //conn req will go away when we get to it
            break;
        case CONN_STATE_TRYING:
            if (isLE) {
                if (!hciConnLeCancel())
                    loge("Failed to request LE conection cancellation for "ADDRFMT"\n", ADDRCONV(conn->peerAddr));
            } else
                logd("cannot cancel in-progress EDR connection\n");
            conn->state = CONN_STATE_DELETING;
            break;
        case CONN_STATE_ADV_SET_BLAMING:
        case CONN_STATE_CFG:
        case CONN_STATE_RUNNING:
            hciConnDisconnect(conn->id);
            hciConnAclStructDel(conn);
            break;
        case CONN_STATE_DELETING:
            logd("cannot cancel already-in-cancellation connection\n");
            break;
        default:
            loge("Invalid connection state %d\n", conn->state);
            break;
        }
    }
    pthread_mutex_unlock(&mConnsLock);

    return !!conn;
}

/*
 * FUNCTION: hciUpdateLeParams
 * USE:      Try to update LE params
 * PARAMS:   aclConn - the connection
 *           minInt - the minimum wanted interval
 *           maxInt - the maximum wanted interval
 *           lat - wanted latency
 *           to - wanted timeout
 * RETURN:   true if attempt will be made
 * NOTES:
 */
bool hciUpdateLeParams(hci_conn_t aclConn, uint16_t minInt, uint16_t maxInt, uint16_t lat, uint16_t to)
{
    struct hciAclConn* conn;
    bool ret = false;

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindByHandle(aclConn);
    if (!conn)
        logw("Conection for update not found\n");
    else if (conn->state != CONN_STATE_RUNNING)
        logw("Cannot update params for not-yet-established connection\n");
    else
        ret = hciConnUpdate(conn->id, minInt, maxInt, lat, to);
    pthread_mutex_unlock(&mConnsLock);

    return ret;
}

/*
 * FUNCTION: hciDemandEncr
 * USE:      Try to encrypt a connection
 * PARAMS:   aclConn - the connection
 * RETURN:   true if attempt will be made
 * NOTES:
 */
bool hciDemandEncr(hci_conn_t aclConn, bool demandMitmSafe)
{
    struct hciAclConn* conn;
    bool ret = false;

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindByHandle(aclConn);
    if (!conn)
        logw("Conection for encrypt not found\n");
    else if (conn->state != CONN_STATE_RUNNING)
        logw("Cannot update encryption for not-yet-established connection\n");
    else if (conn->encrypted && (conn->mitmSafe || !demandMitmSafe))
        logw("Connection already encrypted up to requested level\n");
    else if (BT_ADDR_IS_LE(conn->peerAddr))
        ret = hciConnEncryptLe(conn, demandMitmSafe);
    pthread_mutex_unlock(&mConnsLock);

    return conn && ret;
}

/*
 * FUNCTION: hciLeConnGetInfo
 * USE:      Query info for an LE connection
 * PARAMS:   aclConn - the connection
 *           masterP - where to stor if we're master (or NULL)
 *           peerFtrsP - where to store peer features (or NULL)
 *           intP - where to store connection interval (or NULL)
 *           latP - where to sotre connectio nlatency (or NULL)
 *           toP - where to store connection timeout (or NULL)
 *           mcaP - where to store MCA (meaningless if we're master) (or NULL)
 * RETURN:   true if connection was found and results have been returned
 * NOTES:
 */
bool hciLeConnGetInfo(hci_conn_t aclConn, bool *masterP, uint64_t *peerFtrsP, uint16_t *intP, uint16_t *latP, uint16_t *toP, uint8_t *mcaP)
{
    struct hciAclConn* conn;
    bool ret = false;

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindByHandle(aclConn);
    if (!conn)
        logw("Conection for encrypt not found\n");
    else if (!BT_ADDR_IS_LE(conn->peerAddr))
        logw("Not an LE connection\n");
    else {
        if (masterP)
            *masterP = conn->isMaster;
        if (peerFtrsP)
            *peerFtrsP = conn->le.ftrs;
        if (intP)
            *intP = conn->le.interval;
        if (latP)
            *latP = conn->le.latency;
        if (toP)
            *toP = conn->le.timeout;
        if (mcaP)
            *mcaP = conn->le.mca;
        ret = true;
    }
    pthread_mutex_unlock(&mConnsLock);

    return ret;
}

/*
 * FUNCTION: hciLeEncryptConn
 * USE:      Encrypt a connection using the given key
 * PARAMS:   aclConn - the connection
 *           rand - random value
 *           ediv - encrypted diversifier value
 *           key - the key used for encryption
 * RETURN:   true if attempt will be made
 * NOTES:
 */
bool hciLeEncryptConn(hci_conn_t aclConn, uint64_t rand, uint16_t ediv, const uint8_t *key)
{
    struct hciAclConn* conn;
    uint16_t cid;

    pthread_mutex_lock(&mConnsLock);

    conn = hciConnFindByHandle(aclConn);
    if (!conn)
        logw("Cannot find Connection to encrypt\n");
    else if (conn->state != CONN_STATE_RUNNING)
        logw("Cannot encrypt a not-yet-established connection\n");
    else if (conn->encrypted)
        logw("Connection already encrypted up to requested level\n");
    else if (!BT_ADDR_IS_LE(conn->peerAddr))
        logw("Not an LE connection\n");
    else if (key) {
        cid = conn->id;
        pthread_mutex_unlock(&mConnsLock);
        return !hciLeStartEncryptionSync(cid, rand, ediv, key);
    }

    pthread_mutex_unlock(&mConnsLock);
    return false;
}

/*
 * FUNCTION: hciTryToTx
 * USE:      Try to send some data
 * PARAMS:   aclConn - the connection
 *           data - the data
 *           first - mark as first fragment?
 * RETURN:   true if attempt will be made
 * NOTES:    all data larger then controller's buffer WILL be dropped. WILL NOT BLOCK!
 */
uint8_t hciTryToTx(hci_conn_t aclConn, sg data, uint8_t boundary)
{
    struct hciAclConn* conn;
    uint8_t ret = HCI_TX_SEND_ERROR;

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindByHandle(aclConn);
    if (!conn) {
        ret = HCI_TX_SEND_NO_CONN;
        logw("Cannot send on a nonexistent connection\n");
    } else if (conn->state != CONN_STATE_RUNNING) {
        ret = HCI_TX_SEND_NO_CONN;
        logw("Cannot send on a not-yet-established connection\n");
    } else {
        bool isLE = BT_ADDR_IS_LE(conn->peerAddr);
        bool useLeBuffers = isLE && !mBtJointBuffers;
        sem_t *relevantSem = useLeBuffers ? &mAclPacketsLe : &mAclPacketsEdr;
        int rv;

        rv = r_sem_trywait(relevantSem);
        if (rv && errno == EAGAIN)
            ret = HCI_TX_SEND_NO_CREDITS;
        else if (!rv) {
            struct hciAclHdr hdr;
            uint16_t pb = 0xFFFF; /* this will catch all other cases */
            uint16_t start_pb = mBtVer >= HCI_VERSION_2_1 ? ACL_HDR_PB_FIRST_NONAUTO : ACL_HDR_PB_FIRST_AUTO;
            uint16_t complete_pb = /*mBtVer >= HCI_VERSION_3_0 ? ACL_HDR_PB_COMPLETE : */start_pb; /* XXX: this causes problems with TI BT chips - they send "complete" as a "continue" confusing the other side */

            switch(boundary) {
            case HCI_BOUNDARY_COMPLETE:
                pb = isLE ? start_pb : complete_pb;
                break;
            case HCI_BOUNDARY_START:
                pb = start_pb;
                break;
            case HCI_BOUNDARY_CONT:
                pb = ACL_HDR_PB_CONINUED;
                break;
            }

            utilSetLE16(&hdr.len, sgLength(data));
            utilSetLE16(&hdr.hdr, conn->id | pb);

            if (sgConcatFrontCopy(data, &hdr, sizeof(hdr))) {
                if (vendorTx(HCI_PKT_TYP_ACL, data, false)) {
                    conn->outstandingPackets++;
                    ret = HCI_TX_SEND_OK;
                } else {
                    /* undo our concat of header in case caller wants to use this sg again */
                    sgTruncFront(data, sizeof(hdr));
                }
            }
        }
    }
    pthread_mutex_unlock(&mConnsLock);

    return ret;
}

/*
 * FUNCTION: hciHandleConnAclDown
 * USE:      Called when a connection has gone down
 * PARAMS:   cid - the connection ID
 *           reason - the reason
 * RETURN:   NONE
 * NOTES:
 */
static void hciHandleConnAclDown(uint16_t cid, uint8_t reason)
{
    struct hciAclConn* conn;

    pthread_mutex_lock(&mConnsLock);
    conn = hciConnFindById(cid);
    if (!conn)
        logd("Conn down not found %d\n", cid);
    else {
        switch(conn->state) {
        case CONN_STATE_WAIT:
        case CONN_STATE_TRYING:
            logw("Unexpected connection down in wait or trying state!\n");
            /* fallthrough */
        case CONN_STATE_ADV_SET_BLAMING:
        case CONN_STATE_CFG:
        case CONN_STATE_RUNNING:
            if (!hciScheduleConnDownNotif(conn->handle, reason))
                loge("Failed to schedule conn down notif\n");
            break;
        case CONN_STATE_DELETING:
            /* nothing here really */
            break;
        }
        hciConnAclStructDel(conn);
    }
    pthread_mutex_unlock(&mConnsLock);
}

/*
 * FUNCTION: hciConnCfgCbk
 * USE:      event handler for hciConnCfg()
 * PARAMS:   evt - the resuting event
 *           evtSz - event size
 *           cbkData - the data from hciConnCfg (step and aux encoded into a pointer)
 *           evtWaitStateID - unused
 *           forCmdID - unused
 * RETURN:   true if this is our event (always yes)
 * NOTES:    call with mConnsLock held
 */
static bool hciConnCfgCbk(const struct hciEvtHdr *evt, uint32_t evtSz, void *cbkData, uniq_t evtWaitStateID, uniq_t forCmdID)
{
    struct hciEvtLeMeta *leMetaEvt = (struct hciEvtLeMeta*)(evt + 1);
    struct hciEvtLeReadRemoteFeaturesComplete *rrf = (struct hciEvtLeReadRemoteFeaturesComplete*)(leMetaEvt + 1);
    uint16_t step = ((uint32_t)(uintptr_t)cbkData) >> 16;
    uint16_t aux = (uint16_t)(uintptr_t)cbkData;
    struct hciAclConn *c = NULL;
    uint8_t sta = 0xff;
    uint16_t cid;

    pthread_mutex_lock(&mConnsLock);

    switch (step) {
    case CONN_CFG_STEP_LE + 0: /* first LE config step = get remote features & get self addr */
        cid = utilGetLE16(&rrf->conn);
        sta = utilGetLE8(&rrf->status);
        c = hciConnFindById(cid);
        if (!c)
            break;
        if (sta)
            break;
        c->le.ftrs = utilGetLE64(&rrf->leFeatures);
        step++;
        break;
    default:
        loge("unknown connection config step step 0x%04X.05%04X\n", step, aux);
        break;
    }

    if (!c)
        loge("connection config failed: unable to find connection\n");
    else if (!sta)
        hciConnCfg(c, step, aux);
    else if (sta) {
        loge("connection config failed: sta 0x%02X. Closing.\n", sta);
        hciConnDisconnect(c->id);
    }

    pthread_mutex_unlock(&mConnsLock);

    return true;
}

/*
 * FUNCTION: hciConnCfg
 * USE:      Configure a new connection to our liking and tell upper layer when done
 * PARAMS:   c - the connection struct
 *           step - the step to perform
 *           aux - substep
 * RETURN:   NONE
 * NOTES:    call with mConnsLock held
 */
static void hciConnCfg(struct hciAclConn *c, uint32_t step, uint32_t aux)
{
    struct hciEvtWaitDescr ewd[2] = {{.cbk = hciConnCfgCbk, .persistent = false}, {.cbk = hciConnCfgCbk, .persistent = false}};
    void *userData = (void*)(uintptr_t)((step << 16) | aux);
    struct hciLeReadRemoteUsedFeatures rrf;
    bool success = true;

    if (c->state != CONN_STATE_CFG) {
        logw("Tried to config a connection not in config state\n");
        return;
    }

    switch (step) {
    case CONN_CFG_STEP_LE + 0: /* first LE config step = get remote features */
        if (!c->isMaster)
            break; /* as a slave there is no config to do */
        utilSetLE16(&rrf.conn, c->id);
        ewd[0].evtType = HCI_EVT_LE_Meta;
        ewd[0].extra = HCI_EVTLE_Read_Remote_Used_Features_Complete;
        ewd[0].cbkData = userData;
        if (!hciCmdSubmit(HCI_OGF_LE, HCI_CMD_LE_Read_Remote_Used_Features, &rrf, sizeof(rrf), ewd + 0, NULL)) {
            success = false;
            loge("Failed to send read remote used features command\n");
            break;
        }
        return;

    case CONN_CFG_STEP_LE + 1: /* second LE config step = done! */
        break;
    }

    /* if we got here, the configuration step ended and it is time to proceed */
    if (success) {
        c->state = CONN_STATE_RUNNING;
        if (hciScheduleConnUpNotif(c->handle, &c->peerAddr, &c->selfAddr, c->isMaster, c->encrypted, c->mitmSafe)) {
            /* if there are any backlogged RX messages, queue them up too */
            while (c->rxBacklog) {
                struct hciBacklogItemHdr itemHdr;
                sg packet;

                if (!sgSerializeCutFront(c->rxBacklog, &itemHdr, sizeof(itemHdr))) {
                    loge("backlog header dequque fail!\n");
                    goto fail;
                }
                packet = sgSplit(c->rxBacklog, itemHdr.len);
                if (!packet) {
                    loge("backlog packet dequeue fail\n");
                    goto fail;
                }
                sgSwap(packet, c->rxBacklog);
                if (!sgLength(c->rxBacklog)) {
                    sgFree(c->rxBacklog);
                    c->rxBacklog = NULL;
                }

                if (!hciRxAclForRunningConn(c, itemHdr.aclHdr, packet)) {
                    loge("backlog packet rx enqueue fail\n");
                    sgFree(packet);
                    goto fail;
                }
            }
            return;

        } else
            loge("Failed to enqueue upcall for conn up\n");
    }

fail:
    hciConnDisconnect(c->id);
}

/*
 * FUNCTION: hciConnAclUp
 * USE:      Setup a local ACL conn struct for this conn
 * PARAMS:   established - is it established?
 *           id - the id
 *           mac - the mac
 *           addrType - the address type for bt_addr struct
 *           encrypted - true if encrypted
 *           isMaster - am i master?
 * RETURN:   connection struct or NULL if error
 * NOTES:    call with mConnsLock held
 */
static struct hciAclConn* hciConnAclUp(bool established, uint16_t id, const uint8_t *mac, uint8_t addrType, bool encrypted, bool isMaster)
{
    bool isLE = addrType != BT_ADDR_TYPE_EDR;
    struct hciAclConn *c;
    struct bt_addr addr;

    mLeConnInProgress = false;

    memcpy(addr.addr, mac, sizeof(addr.addr));
    addr.type = addrType;

    c = hciConnFindByAddr(&addr);
    if (!established) {
        if (!c)
            logw("cannection we didn't know about failed. Do we care?\n");
        else
            hciConnAclStructDel(c);
        return NULL;
    }

    if (hciConnFindById(id)) {
        loge("Refusing to create conn struct for existing connection %d\n", id);
        return NULL;
    }

    if (!c) {
        c = hciConnAclStructNew(id, &addr, CONN_STATE_CFG, isMaster);
        if (!c) {
            loge("Failed to alloc conn struct for new ACL link\n");
            hciConnDisconnect(id);
            return NULL;
        }
        c->isMaster = isLE ? isMaster : false;
    } else if (c->state == CONN_STATE_TRYING) {
        c->state = CONN_STATE_CFG;
        c->id = id;
        /* TODO: to be removed once a proper way of setting the local address is provided. since
         * the default self address is 00:00:00:00:00:00 if no public/random address was set. */
        hciGetLocalAddress(c->selfAddr.addr);
        c->selfAddr.type = BT_ADDR_TYPE_LE_PUBLIC;

        if (isLE)
            c->isMaster = isMaster;
        hciScheduleMakeProgressOnLeConnectionReqs(); //we are in evt rx thread so no direct calls
    } else {
        loge("Connection in state %d at up time\n", c->state);
    }
    c->encrypted = encrypted;

    return c;
}

/*
 * FUNCTION: hciHandleConnAclLeUp
 * USE:      Setup a local ACL.LE conn struct for this conn
 * PARAMS:   status - the connection status
 *           id - the conection id
 *           isMaster - true if we're the master
 *           mac - the mac
 *           addrRandom - true if adddress is random
 *           interval - LE connection interval
 *           latency - LE conenction latency
 *           timeout - LE connection timeout
 *           mca - LE connection master clock accuracy
 * RETURN:   true on success
 * NOTES:
 */
static bool hciHandleConnAclLeUp(uint8_t status, uint16_t id, bool isMaster, const uint8_t *mac, bool addrRandom, uint16_t interval, uint16_t latency, uint16_t timeout, uint8_t mca)
{
    struct hciAclConn *c;
    bool advSetDetermined;

    pthread_mutex_lock(&mConnsLock);
    c = hciConnAclUp(!status, id, mac, addrRandom ? BT_ADDR_TYPE_LE_RANDOM : BT_ADDR_TYPE_LE_PUBLIC, false, isMaster);
    if (c) {
        c->le.interval = interval;
        c->le.latency = latency;
        c->le.timeout = timeout;
        c->le.mca = mca;

        if (!isMaster) {
            pthread_mutex_lock(&mAdvSetsLock);
            advSetDetermined = mHciAdvSetHandleAndBlameNewConn(c);
            pthread_mutex_unlock(&mAdvSetsLock);
        }

        if (!isMaster && !advSetDetermined)
            c->state = CONN_STATE_ADV_SET_BLAMING;
        else {
            c->state = CONN_STATE_CFG;
            hciConnCfg(c, CONN_CFG_STEP_LE, 0);
        }
    }
    pthread_mutex_unlock(&mConnsLock);
    return !!c;
}

/*
 * FUNCTION: hciHandleConnAclEncr
 * USE:      Notify all interested in encryption change
 * PARAMS:   cid - the connection id
 *           encrOn - is encryption on?
 * RETURN:   true on success
 * NOTES:
 */
static bool hciHandleConnAclEncr(uint16_t cid, bool encrOn)
{
    struct hciAclConn *c;
    bool ret = false;

    logd("cid %d now %sencrypted\n", cid, encrOn ? "" : "not ");

    pthread_mutex_lock(&mConnsLock);
    c = hciConnFindById(cid);
    if (c) {
        logd("cid %d was %sencrypted\n", cid, c->encrypted ? "" : "not ");
        c->encrypted = encrOn;
        ret = hciScheduleConnEncrChange(c->handle, c->encrypted, c->mitmSafe
);
    }
    pthread_mutex_unlock(&mConnsLock);
    return ret;
}

/*
 * FUNCTION: hciHandleConnAclAuth
 * USE:      Notify all interested in authentication change
 * PARAMS:   cid - the connection id
 *           authOn - is auth on
 * RETURN:   true on success
 * NOTES:
 */
static bool hciHandleConnAclAuth(uint16_t cid, bool authOn)
{
    struct hciAclConn *c;
    bool ret = false;

    logd("cid %d now %sauthed\n", cid, authOn ? "" : "not ");

    pthread_mutex_lock(&mConnsLock);
    c = hciConnFindById(cid);
    if (c) {
        logd("cid %d was %sauthed\n", cid, c->mitmSafe ? "" : "not ");
        c->mitmSafe = authOn;
        ret = hciScheduleConnEncrChange(c->handle, c->encrypted, c->mitmSafe);
    }
    pthread_mutex_unlock(&mConnsLock);
    return ret;
}

/* FUNCTION: hciHandleConnAclEncrKeyRefresh
 * USE:      Notify all interested in encryption key refresh
 * PARAMS:   cid - the connection id
 *           encrOn - is encryption on
 * RETURN:   true on success
 * NOTES:
 */
static bool hciHandleConnAclEncrKeyRefresh(uint16_t cid, bool encrOn)
{
    struct hciAclConn *c;
    bool ret = false;

    logd("cid %d now %sencrypted with a new key\n", cid, encrOn ? "" : "not ");

    pthread_mutex_lock(&mConnsLock);
    c = hciConnFindById(cid);
    if (c) {
        logd("cid %d was %sencrypted\n", cid, c->encrypted ? "" : "not ");
        ret = hciScheduleConnEncrKeyRefresh(c->handle, c->encrypted, c->mitmSafe);
    }
    pthread_mutex_unlock(&mConnsLock);
    return ret;
}

/*
 * FUNCTION: hciHandleConnAclLeUpdate
 * USE:      Notify all interested in conn param update
 * PARAMS:   status - did update succeed?
 *           cid - the connection id
 *           interval - the new interval (valid only in case of success)
 *           latency - the new latency (valid only in case of success)
 *           timeout - the new timeout (valid only in case of success)
 * RETURN:   true on success
 * NOTES:
 */
static bool hciHandleConnAclLeUpdate(uint8_t status, uint16_t cid, uint16_t interval, uint16_t latency, uint16_t timeout)
{
    struct hciAclConn *c;
    bool ret = false;

    logd("cid %d update success: %d\n", cid, status);

    pthread_mutex_lock(&mConnsLock);
    c = hciConnFindById(cid);
    if (c) {
        if (!status) {
            logd("update: {%d,%d,%d} -> {%d,%d,%d}\n", c->le.interval, c->le.latency, c->le.timeout, interval, latency, timeout);
            c->le.interval = interval;
            c->le.latency = latency;
            c->le.timeout = timeout;
        }
        ret = hciScheduleConnParamChange(c->handle, !status, c->le.interval, c->le.latency, c->le.timeout);
    }
    pthread_mutex_unlock(&mConnsLock);
    return ret;
}

/*
 * FUNCTION: hciHandleConnLeLtkReq
 * USE:      Handle key request for an LE connection
 * PARAMS:   cid - the connection id
 *           randomNum - provied by other side
 *           diversifier - provied by other side
 * RETURN:   true on success
 * NOTES:
 */
static bool hciHandleConnLeLtkReq(uint16_t cid, uint64_t randomNum, uint16_t diversifier)
{
    struct hciAclConn *c;
    bool ret = false;

    pthread_mutex_lock(&mConnsLock);
    c = hciConnFindById(cid);
    if (c)
        ret = hciScheduleLeLtkRequest(c->handle, randomNum, diversifier);
    pthread_mutex_unlock(&mConnsLock);
    return ret;
}


/*
 * FUNCTION: hciConnLeCancelDoneCbk
 * USE:      Event callback for command complete event used by hciConnLeCancel()
 * PARAMS:   cbkData - unused
 *           status - from command
 * RETURN:   NONE
 * NOTES:
 */
static void hciConnLeCancelDoneCbk(void *cbkData, uint8_t status)
{
    if (status == HCI_STAT_GOING_DOWN)
        return;

    if (status)
        logw("Failed to stop LE connection, status = 0x%02x\n", status);

    pthread_mutex_lock(&mConnsLock);
    if (mLeConnInProgress) {  //spec acknowledges this race between connection succeeded and being cancelled - handle it here
        struct hciAclConn *c;

        c = mConns;
        while (c && c->state != CONN_STATE_DELETING)
            c = c->next;

        if (c) //found the connection we were trying to make
            hciConnAclStructDel(c);
        else
            logw("Cannot find connection that we just cancelled\n");
    }

    mLeConnInProgress = false;
    hciMakeProgressOnLeConnectionReqs();
    pthread_mutex_unlock(&mConnsLock);
}


/*
 * FUNCTION: hciConnLeCancel
 * USE:      Cancel an ongoing LE connection attempt
 * PARAMS:   addr - whom the connection was to
 * RETURN:   true on success
 * NOTES:
 */
static bool hciConnLeCancel(void)
{
    return hciCmdSubmitSimpleWithCompleteWithDoneCbk(HCI_OGF_LE, HCI_CMD_LE_Create_Connection_Cancel, NULL, 0, hciConnLeCancelDoneCbk, NULL);
}

/*
 * FUNCTION: hciConnUpdate
 * USE:      Start a connection update for an LE connection
 * PARAMS:   cid - the cid
 *           intMin - minimum wanted interval
 *           intMax - maximum wanted itnerval
 *           latency - wanted latency
 *           timeout - wanted timeout
 * RETURN:   false on failure. else wait.
 * NOTES:
 */
static bool hciConnUpdate(uint16_t cid, uint16_t intMin, uint16_t intMax, uint16_t latency, uint16_t timeout)
{
    struct hciLeConnectionUpdate cmd;

    utilSetLE16(&cmd.conn, cid);
    utilSetLE16(&cmd.connIntervalMin, intMin);
    utilSetLE16(&cmd.connIntervalMax, intMax);
    utilSetLE16(&cmd.connLatency, latency);
    utilSetLE16(&cmd.supervisionTimeout, timeout);
    utilSetLE16(&cmd.minConnLen, 0); /* not a useful hint, i know */
    utilSetLE16(&cmd.maxConnLen, intMin * 2);

    return hciCmdSubmitSimpleWithStatusWithDoneCbk(HCI_OGF_LE, HCI_CMD_LE_Connection_Update, &cmd, sizeof(cmd), hciCmdStatusCbk, NULL);
}

/*
 * FUNCTION: hciConnDisconnect
 * USE:      Start a disconnection process
 * PARAMS:   cid - the cid
 * RETURN:   false on failure. else wait.
 * NOTES:
 */
static bool hciConnDisconnect(uint16_t cid)
{
    struct hciDisconnect cmd;

    utilSetLE16(&cmd.conn, cid);
    utilSetLE16(&cmd.reason, 0x13); //TODO: better dealings with this value...

    return hciCmdSubmitSimpleWithStatusWithDoneCbk(HCI_OGF_Link_Control, HCI_CMD_Disconnect, &cmd, sizeof(cmd), hciCmdStatusCbk, NULL);
}

