You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2015/10/30 23:21:05 UTC

[1/3] incubator-mynewt-larva git commit: Prefix ll with ble_. This includes filenames

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master a666bf8c9 -> 36623dd5f


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ll_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ll_adv.c b/net/nimble/controller/src/ll_adv.c
deleted file mode 100644
index 497699a..0000000
--- a/net/nimble/controller/src/ll_adv.c
+++ /dev/null
@@ -1,916 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
-#include "os/os.h"
-#include "bsp/bsp.h"
-#include "nimble/ble.h"
-#include "nimble/hci_common.h"
-#include "controller/phy.h"
-#include "controller/ll.h"
-#include "controller/ll_adv.h"
-#include "controller/ll_sched.h"
-#include "controller/ll_scan.h"
-#include "hal/hal_cputime.h"
-#include "hal/hal_gpio.h"
-
-/* 
- * Advertising configuration parameters. These are parameters that I have
- * fixed for now but could be considered "configuration" parameters for either
- * the device or the stack.
- */
-#define BLE_LL_CFG_ADV_PDU_ITVL_HD_USECS    (5000)  /* usecs */
-#define BLE_LL_CFG_ADV_PDU_ITVL_LD_USECS    (10000) /* usecs */
-#define BLE_LL_CFG_ADV_TXPWR                (0)     /* dBm */
-
-/* XXX: TODO
- * 1) Need to look at advertising and scan request PDUs. Do I allocate these
- * once? Do I use a different pool for smaller ones? Do I statically declare
- * them?
- * 2) The random address and initiator address (if doing directed adv) is not
- * set yet. Determine how that is to be done.
- * 3) How do features get supported? What happens if device does not support
- * advertising? (for example)
- * 4) Correct calculation of schedule start and end times for the various
- * scheduled advertising activities.
- * 5) How to determine the advertising interval we will actually use. As of
- * now, we set it to max.
- * 6) Currently, when we set scheduling events, we dont take into account
- * processor overhead/delays. We will want to do that.
- * 7) Need to implement the whole HCI command done stuff.
- * 8) For set adv enable command: if we get a connection, or we time out,
- *    we need to send a CONNECTION COMPLETE event. Do this.
- * 9) How does the advertising channel tx power get set? I dont implement
- * that currently.
- * 10) Add whitelist! Do this to the code.
- */
-
-/* 
- * Advertising state machine 
- * 
- * The advertising state machine data structure.
- * 
- *  adv_pdu_len
- *      The length of the advertising PDU that will be sent. This does not
- *      include the preamble, access address and CRC.
- */
-struct ll_adv_sm
-{
-    uint8_t enabled;
-    uint8_t adv_type;
-    uint8_t adv_len;
-    uint8_t adv_chanmask;
-    uint8_t adv_filter_policy;
-    uint8_t own_addr_type;
-    uint8_t peer_addr_type;
-    uint8_t adv_chan;
-    uint8_t scan_rsp_len;
-    uint8_t adv_pdu_len;
-    uint16_t adv_itvl_min;
-    uint16_t adv_itvl_max;
-    uint32_t adv_itvl_usecs;
-    uint32_t adv_event_start_time;
-    uint32_t adv_pdu_start_time;
-    uint8_t initiator_addr[BLE_DEV_ADDR_LEN];
-    uint8_t adv_data[BLE_ADV_DATA_MAX_LEN];
-    uint8_t scan_rsp_data[BLE_SCAN_RSP_DATA_MAX_LEN];
-    struct os_mbuf *adv_pdu;
-    struct os_mbuf *scan_rsp_pdu;
-    struct os_event adv_txdone_ev;
-};
-
-/* The advertising state machine global object */
-struct ll_adv_sm g_ll_adv_sm;
-
-struct ll_adv_stats
-{
-    uint32_t late_tx_done;
-    uint32_t cant_set_sched;
-    uint32_t scan_rsp_txg;
-    uint32_t adv_txg;
-};
-
-struct ll_adv_stats g_ll_adv_stats;
-
-/* XXX: We can calculate scan response time as well. */
-/* 
- * Worst case time needed for scheduled advertising item. This is the longest
- * possible time to receive a scan request and send a scan response (with the
- * appropriate IFS time between them). This number is calculated using the
- * following formula: IFS + SCAN_REQ + IFS + SCAN_RSP = 150 + 176 + 150 + 376.
- * 
- * NOTE: The advertising PDU transmit time is NOT included here since we know
- * how long that will take.
- */
-#define BLE_LL_ADV_SCHED_MAX_USECS  (852)
-
-/* For debug purposes */
-extern void bletest_inc_adv_pkt_num(void);
-
-/**
- * Calculate the first channel that we should advertise upon when we start 
- * an advertising event. 
- * 
- * @param advsm 
- * 
- * @return uint8_t The number of the first channel usable for advertising.
- */
-static uint8_t
-ll_adv_first_chan(struct ll_adv_sm *advsm)
-{
-    uint8_t adv_chan;
-
-    /* Set first advertising channel */
-    if (advsm->adv_chanmask & 0x01) {
-        adv_chan = BLE_PHY_ADV_CHAN_START;
-    } else if (advsm->adv_chanmask & 0x02) {
-        adv_chan = BLE_PHY_ADV_CHAN_START + 1;
-    } else {
-        adv_chan = BLE_PHY_ADV_CHAN_START + 2;
-    }
-
-    return adv_chan;
-}
-
-/**
- * ll adv pdu make 
- *  
- * Create the advertising PDU 
- * 
- * 
- * @param advsm Pointer to advertisement state machine
- */
-static void
-ll_adv_pdu_make(struct ll_adv_sm *advsm)
-{
-    uint8_t     adv_data_len;
-    uint8_t     *dptr;
-    uint8_t     pdulen;
-    uint8_t     pdu_type;
-    uint8_t     *addr;
-    struct os_mbuf *m;
-
-    /* assume this is not a direct ind */
-    adv_data_len = advsm->adv_len;
-    pdulen = BLE_DEV_ADDR_LEN + adv_data_len;
-
-    /* Must be an advertising type! */
-    switch (advsm->adv_type) {
-    case BLE_HCI_ADV_TYPE_ADV_IND:
-        pdu_type = BLE_ADV_PDU_TYPE_ADV_IND;
-        break;
-
-    case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND:
-        pdu_type = BLE_ADV_PDU_TYPE_ADV_NONCONN_IND;
-        break;
-
-    case BLE_HCI_ADV_TYPE_ADV_SCAN_IND:
-        pdu_type = BLE_ADV_PDU_TYPE_ADV_SCAN_IND;
-        break;
-
-    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD:
-    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD:
-        pdu_type = BLE_ADV_PDU_TYPE_ADV_DIRECT_IND;
-        adv_data_len = 0;
-        pdulen = BLE_ADV_DIRECT_IND_LEN;
-        break;
-
-        /* Set these to avoid compiler warnings */
-    default:
-        pdulen = 0;
-        pdu_type = 0;
-        adv_data_len = 0xFF;
-        break;
-    }
-
-    /* An invalid advertising data length indicates a memory overwrite */
-    assert(adv_data_len <= BLE_ADV_DATA_MAX_LEN);
-
-    /* Set the PDU length in the state machine */
-    advsm->adv_pdu_len = pdulen + BLE_LL_PDU_HDR_LEN;
-
-    /* Get the advertising PDU */
-    m = advsm->adv_pdu;
-    assert(m != NULL);
-    m->om_len = advsm->adv_pdu_len;
-    OS_MBUF_PKTHDR(m)->omp_len = m->om_len;
-
-    /* Construct scan response */
-    if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_PUBLIC) {
-        addr = g_dev_addr;
-    } else if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
-        pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND;
-        addr = g_random_addr;
-    } else {
-        /* XXX: unsupported for now  */
-        addr = NULL;
-        assert(0);
-    }
-
-    /* Construct advertisement */
-    dptr = m->om_data;
-    dptr[0] = pdu_type;
-    dptr[1] = (uint8_t)pdulen;
-    memcpy(dptr + BLE_LL_PDU_HDR_LEN, addr, BLE_DEV_ADDR_LEN);
-    dptr += BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN;
-
-    /* For ADV_DIRECT_IND, we need to put initiators address in there */
-    if (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND) {
-        memcpy(dptr, advsm->initiator_addr, BLE_DEV_ADDR_LEN);
-    }
-
-    /* Copy in advertising data, if any */
-    if (adv_data_len != 0) {
-        memcpy(dptr, advsm->adv_data, adv_data_len);
-    }
-}
-
-/**
- * ll adv scan rsp pdu make
- *  
- * Create a scan response PDU 
- * 
- * @param advsm 
- */
-static void
-ll_adv_scan_rsp_pdu_make(struct ll_adv_sm *advsm)
-{
-    uint8_t     scan_rsp_len;
-    uint8_t     *dptr;
-    uint8_t     *addr;
-    uint8_t     pdulen;
-    uint8_t     hdr;
-    struct os_mbuf *m;
-
-    /* Make sure that the length is valid */
-    scan_rsp_len = advsm->scan_rsp_len;
-    assert(scan_rsp_len <= BLE_SCAN_RSP_DATA_MAX_LEN);
-
-    /* Set PDU payload length */
-    pdulen = BLE_DEV_ADDR_LEN + scan_rsp_len;
-
-    /* Get the advertising PDU */
-    m = advsm->scan_rsp_pdu;
-    assert(m != NULL);
-    m->om_len = BLE_LL_PDU_HDR_LEN + pdulen;
-    OS_MBUF_PKTHDR(m)->omp_len = m->om_len;
-
-    /* Construct scan response */
-    if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_PUBLIC) {
-        hdr = BLE_ADV_PDU_TYPE_SCAN_RSP;
-        addr = g_dev_addr;
-    } else if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
-        hdr = BLE_ADV_PDU_TYPE_SCAN_RSP | BLE_ADV_PDU_HDR_TXADD_RAND;
-        addr = g_random_addr;
-    } else {
-        /* XXX: unsupported for now  */
-        hdr = 0;
-        addr = NULL;
-        assert(0);
-    }
-
-    /* Write into the pdu buffer */
-    dptr = m->om_data;
-    dptr[0] = hdr;
-    dptr[1] = pdulen;
-    memcpy(dptr + BLE_LL_PDU_HDR_LEN, addr, BLE_DEV_ADDR_LEN);
-
-    /* Copy in scan response data, if any */
-    if (scan_rsp_len != 0) {
-        dptr += BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN;  
-        memcpy(dptr, advsm->scan_rsp_data, scan_rsp_len);
-    }
-}
-
-/**
- * ble ll adv rx cb 
- *  
- * Scheduler callback used after advertising PDU sent. 
- * 
- * @param arg 
- */
-static int
-ll_adv_rx_cb(struct ll_sched_item *sch)
-{
-    /* Disable the PHY as we might be receiving */
-    ble_phy_disable();
-    os_eventq_put(&g_ll_data.ll_evq, &g_ll_adv_sm.adv_txdone_ev);
-    return BLE_LL_SCHED_STATE_DONE;
-}
-
-
-/**
- * ble ll adv tx done cb 
- *  
- * Scheduler callback when an advertising PDU has been sent. 
- * 
- * @param arg 
- */
-static int
-ll_adv_tx_done_cb(struct ll_sched_item *sch)
-{
-    os_eventq_put(&g_ll_data.ll_evq, &g_ll_adv_sm.adv_txdone_ev);
-    return BLE_LL_SCHED_STATE_DONE;
-}
-
-/**
- * ll adv tx start cb
- *  
- * This is the scheduler callback (called from interrupt context) which 
- * transmits an advertisement. 
- *  
- * Context: Interrupt (scheduler) 
- *  
- * @param sch 
- * 
- * @return int 
- */
-static int
-ll_adv_tx_start_cb(struct ll_sched_item *sch)
-{
-    int rc;
-    uint8_t end_trans;
-    struct ll_adv_sm *advsm;
-
-    /* Get the state machine for the event */
-    advsm = (struct ll_adv_sm *)sch->cb_arg;
-
-    /* Toggle the LED */
-    gpio_toggle(LED_BLINK_PIN);
-
-    /* Set channel */
-    rc = ble_phy_setchan(advsm->adv_chan);
-    assert(rc == 0);
-
-    /* Set phy mode based on type of advertisement */
-    if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
-        end_trans = BLE_PHY_TRANSITION_NONE;
-    } else {
-        end_trans = BLE_PHY_TRANSITION_TX_RX;
-    }
-
-    /* Transmit advertisement */
-    rc = ble_phy_tx(advsm->adv_pdu, BLE_PHY_TRANSITION_NONE, end_trans);
-    if (rc) {
-        /* Transmit failed. */
-        rc = ll_adv_tx_done_cb(sch);
-    } else {
-        /* Set link layer state to advertising */
-        ble_ll_state_set(BLE_LL_STATE_ADV);
-
-        /* Count # of adv. sent */
-        ++g_ll_adv_stats.adv_txg;
-
-        /* Set schedule item next wakeup time */
-        if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
-            sch->next_wakeup = sch->end_time;
-            sch->sched_cb = ll_adv_tx_done_cb;
-        } else {
-            /* XXX: set next wakeup time. We have to look for either a
-             * connect request or scan request or both, depending on
-             * advertising type. For now, we will just wait until the
-             * end of the scheduled event, which was set to the worst case
-             * time to send a scan response PDU. Note that I use the time
-             * now to insure the callback occurs after we are dont transmitting
-             * the scan response, as we may have been late starting the tx.
-             */
-            sch->next_wakeup = cputime_get32() +
-                (sch->end_time - sch->start_time);
-            sch->sched_cb = ll_adv_rx_cb;
-        }
-
-        rc = BLE_LL_SCHED_STATE_RUNNING;
-    }
-
-    return rc;
-}
-
-static struct ll_sched_item *
-ll_adv_sched_set(struct ll_adv_sm *advsm)
-{
-    int rc;
-    uint32_t max_usecs;
-    struct ll_sched_item *sch;
-
-    sch = ll_sched_get_item();
-    if (sch) {
-        /* Set sched type */
-        sch->sched_type = BLE_LL_SCHED_TYPE_ADV;
-
-        /* XXX: HW output compare to trigger tx start? Look into this */
-        /* Set the start time of the event */
-        sch->start_time = advsm->adv_pdu_start_time - 
-            cputime_usecs_to_ticks(XCVR_TX_SCHED_DELAY_USECS);
-
-        /* Set the callback and argument */
-        sch->cb_arg = advsm;
-        sch->sched_cb = ll_adv_tx_start_cb;
-
-        /* Set end time to maximum time this schedule item may take */
-        max_usecs = ll_pdu_tx_time_get(advsm->adv_pdu_len);
-        if (advsm->adv_type != BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
-            max_usecs += BLE_LL_ADV_SCHED_MAX_USECS;
-        }
-        sch->end_time = advsm->adv_pdu_start_time +
-            cputime_usecs_to_ticks(max_usecs);
-
-        /* XXX: for now, we cant get an overlap so assert on error. */
-        /* Add the item to the scheduler */
-        rc = ll_sched_add(sch);
-        assert(rc == 0);
-    } else {
-        ++g_ll_adv_stats.cant_set_sched;
-    }
-
-    return sch;
-}
-
-/**
- * ll adv set adv params 
- *  
- * Called by the HCI command parser when a set advertising parameters command 
- * has been received. 
- *  
- * Context: Link Layer task (HCI command parser) 
- * 
- * @param cmd 
- * 
- * @return int 
- */
-int
-ll_adv_set_adv_params(uint8_t *cmd)
-{
-    uint8_t adv_type;
-    uint8_t adv_filter_policy;
-    uint8_t adv_chanmask;
-    uint8_t own_addr_type;
-    uint8_t peer_addr_type;
-    uint16_t adv_itvl_min;
-    uint16_t adv_itvl_max;
-    uint16_t min_itvl;
-    struct ll_adv_sm *advsm;
-
-    /* If already enabled, we return an error */
-    advsm = &g_ll_adv_sm;
-    if (advsm->enabled) {
-        return BLE_ERR_CMD_DISALLOWED;
-    }
-
-    /* Make sure intervals are OK (along with advertising type */
-    adv_itvl_min = le16toh(cmd);
-    adv_itvl_max = le16toh(cmd + 2);
-    adv_type = cmd[4];
-
-    /* Min has to be less than max and cannot equal max */
-    if ((adv_itvl_min > adv_itvl_max) || (adv_itvl_min == adv_itvl_max)) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    switch (adv_type) {
-    case BLE_HCI_ADV_TYPE_ADV_IND:
-    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD:
-    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD:
-        min_itvl = BLE_LL_ADV_ITVL_MIN;
-        break;
-    case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND:
-    case BLE_HCI_ADV_TYPE_ADV_SCAN_IND:
-        min_itvl = BLE_LL_ADV_ITVL_NONCONN_MIN;
-        break;
-    default:
-        min_itvl = 0xFFFF;
-        break;
-    }
-
-    /* XXX: isnt there a maximum that we need to check? */
-    /* Make sure interval minimum is valid for the advertising type */
-    if ((adv_itvl_min < min_itvl) || (adv_itvl_min > BLE_HCI_ADV_ITVL_MAX)) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    /* Check own and peer address type */
-    own_addr_type =  cmd[5];
-    peer_addr_type = cmd[6];
-
-    if ((own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) ||
-        (peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX)) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    /* There are only three adv channels, so check for any outside the range */
-    adv_chanmask = cmd[13];
-    if (((adv_chanmask & 0xF8) != 0) || (adv_chanmask == 0)) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    /* Check for valid filter policy */
-    adv_filter_policy = cmd[14];
-    if (adv_filter_policy > BLE_HCI_ADV_FILT_MAX) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    /* XXX: determine if there is anything that needs to be done for
-       own address type or peer address type */
-    advsm->own_addr_type = own_addr_type;
-    advsm->peer_addr_type = peer_addr_type;
-
-    advsm->adv_filter_policy = adv_filter_policy;
-    advsm->adv_chanmask = adv_chanmask;
-    advsm->adv_itvl_min = adv_itvl_min;
-    advsm->adv_itvl_max = adv_itvl_max;
-    advsm->adv_type = adv_type;
-
-    return 0;
-}
-
-/* Stop the advertising state machine */
-static void
-ll_adv_sm_stop(struct ll_adv_sm *advsm)
-{
-    /* XXX: Stop any timers we may have started */
-
-    /* Remove any scheduled advertising items */
-    ll_sched_rmv(BLE_LL_SCHED_TYPE_ADV);
-
-    /* Disable advertising */
-    advsm->enabled = 0;
-}
-
-/**
- * ll adv sm start 
- *  
- * Start the advertising state machine. 
- *  
- * Context: Link-layer task. 
- * 
- * @param advsm Pointer to advertising state machine
- * 
- * @return int 
- */
-static int
-ll_adv_sm_start(struct ll_adv_sm *advsm)
-{
-    uint8_t adv_chan;
-    struct ll_sched_item *sch;
-
-    /* 
-     * XXX: not sure if I should do this or just report whatever random
-     * address the host sent. For now, I will reject the command with a
-     * command disallowed error. All the parameter errors refer to the command
-     * parameter (which in this case is just enable or disable).
-     */ 
-    if (advsm->own_addr_type != BLE_HCI_ADV_OWN_ADDR_PUBLIC) {
-        if (!ble_ll_is_valid_random_addr(g_random_addr)) {
-            return BLE_ERR_CMD_DISALLOWED;
-        }
-
-        /* XXX: support these other types */
-        if (advsm->own_addr_type != BLE_HCI_ADV_OWN_ADDR_RANDOM) {
-            assert(0);
-        }
-    }
-
-    /* Set flag telling us that advertising is enabled */
-    advsm->enabled = 1;
-
-    /* Determine the advertising interval we will use */
-    advsm->adv_itvl_usecs = (uint32_t)advsm->adv_itvl_max * BLE_LL_ADV_ITVL;
-
-    /* Create the advertising PDU */
-    ll_adv_pdu_make(advsm);
-
-    /* Create scan response PDU (if needed) */
-    if (advsm->adv_type != BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
-        ll_adv_scan_rsp_pdu_make(advsm);
-    }
-
-    /* Set first advertising channel */
-    adv_chan = ll_adv_first_chan(advsm);
-    advsm->adv_chan = adv_chan;
-
-    /* 
-     * Set start time for the advertising event. This time is the same
-     * as the time we will send the first PDU. Since there does not seem
-     * to be any requirements as to when we start, we just set the time to
-     * now.
-     */ 
-    advsm->adv_event_start_time = cputime_get32();
-    advsm->adv_pdu_start_time = advsm->adv_event_start_time;
-
-    /* Set packet in schedule */
-    sch = ll_adv_sched_set(advsm);
-    if (!sch) {
-        /* XXX: set a wakeup timer to deal with this. For now, assert */
-        assert(0);
-    }
-
-    return 0;
-}
-
-/**
- * ll adv read txpwr
- *  
- * Called when the LE HCI command read advertising channel tx power command 
- * has been received. Returns the current advertising transmit power. 
- *  
- * Context: Link Layer task (HCI command parser) 
- * 
- * @return int 
- */
-int
-ll_adv_read_txpwr(uint8_t *rspbuf)
-{
-    rspbuf[0] = BLE_LL_CFG_ADV_TXPWR;
-    return BLE_ERR_SUCCESS;
-}
-
-int
-ll_adv_set_enable(uint8_t *cmd)
-{
-    int rc;
-    uint8_t enable;
-    struct ll_adv_sm *advsm;
-
-    advsm = &g_ll_adv_sm;
-
-    rc = 0;
-    enable = cmd[0];
-    if (enable == 1) {
-        /* If already enabled, do nothing */
-        if (!advsm->enabled) {
-            /* Start the advertising state machine */
-            rc = ll_adv_sm_start(advsm);
-        }
-    } else if (enable == 0) {
-        if (advsm->enabled) {
-            ll_adv_sm_stop(advsm);
-        }
-    } else {
-        rc = BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    return rc;
-}
-
-int
-ll_adv_set_scan_rsp_data(uint8_t *cmd, uint8_t len)
-{
-    uint8_t datalen;
-    os_sr_t sr;
-    struct ll_adv_sm *advsm;
-
-    /* Check for valid scan response data length */
-    datalen = cmd[0];
-    if ((datalen > BLE_SCAN_RSP_DATA_MAX_LEN) || (datalen != len)) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    /* Copy the new data into the advertising structure. */
-    advsm = &g_ll_adv_sm;
-    advsm->scan_rsp_len = datalen;
-    memcpy(advsm->scan_rsp_data, cmd + 1, datalen);
-
-    /* Re-make the scan response PDU since data may have changed */
-    OS_ENTER_CRITICAL(sr);
-    /* 
-     * XXX: there is a chance, even with interrupts disabled, that
-     * we are transmitting the scan response PDU while writing to it.
-     */ 
-    ll_adv_scan_rsp_pdu_make(advsm);
-    OS_EXIT_CRITICAL(sr);
-
-    return 0;
-}
-
-/**
- * ble ll adv set adv data 
- *  
- * Called by the LL HCI command parser when a set advertising 
- * data command has been sent from the host to the controller. 
- * 
- * @param cmd Pointer to command data
- * @param len Length of command data
- * 
- * @return int 0: success; BLE_ERR_INV_HCI_CMD_PARMS otherwise.
- */
-int
-ll_adv_set_adv_data(uint8_t *cmd, uint8_t len)
-{
-    uint8_t datalen;
-    struct ll_adv_sm *advsm;
-    os_sr_t sr;
-
-    /* Check for valid advertising data length */
-    datalen = cmd[0];
-    if ((datalen > BLE_ADV_DATA_MAX_LEN) || (datalen != len)) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    /* Copy the new data into the advertising structure. */
-    advsm = &g_ll_adv_sm;
-    advsm->adv_len = datalen;
-    memcpy(advsm->adv_data, cmd + 1, datalen);
-
-    /* If the state machine is enabled, we need to re-make the adv PDU */
-    if (advsm->enabled) {
-        /* 
-         * XXX: currently, even with interrupts disabled, there is a chance
-         * that we are transmitting the advertising PDU while writing into
-         * it.
-         */
-        OS_ENTER_CRITICAL(sr);
-        ll_adv_pdu_make(advsm);
-        OS_EXIT_CRITICAL(sr);
-    }
-
-    return 0;
-}
-
-/**
- * Called when the LL receives a scan request.  
- *  
- * Context: Called from interrupt context. 
- * 
- * @param rxbuf 
- * 
- * @return -1: scan request not for us. 
- *          0: Scan request is for us and we successfully went from rx to tx.
- *        > 0: PHY error attempting to go from rx to tx.
- */
-int
-ble_ll_adv_rx_scan_req(uint8_t *rxbuf)
-{
-    int rc;
-    uint8_t rxaddr_type;
-    uint8_t *our_addr;
-    uint8_t *adva;
-
-    /* Determine if this is addressed to us */
-    rxaddr_type = rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK;
-    if (rxaddr_type) {
-        our_addr = g_random_addr;
-    } else {
-        our_addr = g_dev_addr;
-    }
-
-    rc = -1;
-    adva = rxbuf + BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN;
-    if (!memcmp(our_addr, adva, BLE_DEV_ADDR_LEN)) {
-        /* Setup to transmit the scan response */
-        rc = ble_phy_tx(g_ll_adv_sm.scan_rsp_pdu, BLE_PHY_TRANSITION_RX_TX, 
-                        BLE_PHY_TRANSITION_NONE);
-        if (!rc) {
-            ++g_ll_adv_stats.scan_rsp_txg;
-        }
-    }
-
-    return rc;
-}
-
-/**
- * ll adv tx done proc
- *  
- * Process advertistement tx done event. 
- *  
- * Context: Link Layer task. 
- * 
- * @param arg Pointer to advertising state machine.
- */
-void
-ll_adv_tx_done_proc(void *arg)
-{
-    uint8_t mask;
-    uint8_t final_adv_chan;
-    int32_t delta_t;
-    uint32_t itvl;
-    struct ll_adv_sm *advsm;
-
-    /* Free the advertising packet */
-    advsm = (struct ll_adv_sm *)arg;
-    ble_ll_state_set(BLE_LL_STATE_STANDBY);
-
-    /* For debug purposes */
-    bletest_inc_adv_pkt_num();
-
-    /* 
-     * Check if we have ended our advertising event. If our last advertising
-     * packet was sent on the last channel, it means we are done with this
-     * event.
-     */
-    if (advsm->adv_chanmask & 0x04) {
-        final_adv_chan = BLE_PHY_ADV_CHAN_START + 2;
-    } else if (advsm->adv_chanmask & 0x02) {
-        final_adv_chan = BLE_PHY_ADV_CHAN_START + 1;
-    } else {
-        final_adv_chan = BLE_PHY_ADV_CHAN_START;
-    }
-
-    if (advsm->adv_chan == final_adv_chan) {
-        /* This event is over. Set adv channel to first one */
-        advsm->adv_chan = ll_adv_first_chan(advsm);
-
-        /* Calculate start time of next advertising event */
-        itvl = advsm->adv_itvl_usecs;
-        itvl += rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
-        advsm->adv_event_start_time += cputime_usecs_to_ticks(itvl);
-        advsm->adv_pdu_start_time = advsm->adv_event_start_time;
-
-        /* Toggle the LED */
-        gpio_toggle(LED_BLINK_PIN);
-    } else {
-        /* 
-         * Move to next advertising channel. If not in the mask, just
-         * increment by 1. We can do this because we already checked if we
-         * just transmitted on the last advertising channel
-         */
-        ++advsm->adv_chan;
-        mask = 1 << (advsm->adv_chan - BLE_PHY_ADV_CHAN_START);
-        if ((mask & advsm->adv_chanmask) == 0) {
-            ++advsm->adv_chan;
-        }
-
-        /* Set next start time to next pdu transmit time */
-        if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
-            itvl = BLE_LL_CFG_ADV_PDU_ITVL_HD_USECS;
-        } else {
-            itvl = BLE_LL_CFG_ADV_PDU_ITVL_LD_USECS;
-        }
-        itvl = cputime_usecs_to_ticks(itvl);
-        advsm->adv_pdu_start_time += itvl;
-    }
-
-    /* 
-     * The scheduled time better be in the future! If it is not, we will
-     * count a statistic and close the current advertising event. We will
-     * then setup the next advertising event.
-     */
-    delta_t = (int32_t)(advsm->adv_pdu_start_time - cputime_get32());
-    if (delta_t < 0) {
-        /* Count times we were late */
-        ++g_ll_adv_stats.late_tx_done;
-
-        /* Set back to first adv channel */
-        advsm->adv_chan = ll_adv_first_chan(advsm);
-
-        /* Calculate start time of next advertising event */
-        while (delta_t < 0) {
-            itvl = advsm->adv_itvl_usecs;
-            itvl += rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
-            itvl = cputime_usecs_to_ticks(itvl);
-            advsm->adv_event_start_time += itvl;
-            advsm->adv_pdu_start_time = advsm->adv_event_start_time;
-            delta_t += (int32_t)itvl;
-        }
-    }
-
-    if (!ll_adv_sched_set(advsm)) {
-        /* XXX: we will need to set a timer here to wake us up */
-        assert(0);
-    }
-}
-
-/**
- * ll adv init 
- *  
- * Initialize the advertising functionality of a BLE device. This should 
- * be called once on initialization
- */
-void
-ll_adv_init(void)
-{
-    struct ll_adv_sm *advsm;
-
-    /* Set default advertising parameters */
-    advsm = &g_ll_adv_sm;
-    memset(advsm, 0, sizeof(struct ll_adv_sm));
-
-    advsm->adv_itvl_min = BLE_HCI_ADV_ITVL_DEF;
-    advsm->adv_itvl_max = BLE_HCI_ADV_ITVL_DEF;
-    advsm->adv_chanmask = BLE_HCI_ADV_CHANMASK_DEF;
-
-    /* Initialize advertising tx done event */
-    advsm->adv_txdone_ev.ev_type = BLE_LL_EVENT_ADV_TXDONE;
-    advsm->adv_txdone_ev.ev_arg = advsm;
-
-    /* Get an advertising mbuf (packet header) and attach to state machine */
-    advsm->adv_pdu = os_mbuf_get_pkthdr(&g_mbuf_pool);
-    assert(advsm->adv_pdu != NULL);
-
-    /* Get a scan response mbuf (packet header) and attach to state machine */
-    advsm->scan_rsp_pdu = os_mbuf_get_pkthdr(&g_mbuf_pool);
-    assert(advsm->scan_rsp_pdu != NULL);
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ll_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ll_hci.c b/net/nimble/controller/src/ll_hci.c
deleted file mode 100644
index 8807a5b..0000000
--- a/net/nimble/controller/src/ll_hci.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <stdint.h>
-#include <assert.h>
-#include <string.h>
-#include "os/os.h"
-#include "nimble/ble.h"
-#include "nimble/hci_common.h"
-#include "nimble/hci_transport.h"
-#include "controller/ll_adv.h"
-#include "controller/ll_scan.h"
-#include "controller/ll.h"
-#include "controller/ll_hci.h"
-
-/* LE event mask */
-uint8_t g_ble_ll_hci_le_event_mask[BLE_HCI_SET_LE_EVENT_MASK_LEN];
-uint8_t g_ble_ll_hci_event_mask[BLE_HCI_SET_EVENT_MASK_LEN];
-
-/**
- * ll hci get num cmd pkts 
- *  
- * Returns the number of command packets that the host is allowed to send 
- * to the controller. 
- *  
- * @return uint8_t 
- */
-static uint8_t
-ble_ll_hci_get_num_cmd_pkts(void)
-{
-    return BLE_LL_CFG_NUM_HCI_CMD_PKTS;
-}
-
-/**
- * Send an event to the host. 
- * 
- * @param evbuf Pointer to event buffer to send
- * 
- * @return int 0: success; -1 otherwise.
- */
-int
-ble_ll_hci_event_send(uint8_t *evbuf)
-{
-    int rc;
-
-    /* Count number of events sent */
-    ++g_ll_stats.hci_events_sent;
-
-    /* Send the event to the host */
-    rc = ble_hci_transport_ctlr_event_send(evbuf);
-
-    return rc;
-}
-
-/**
- * ll hci set le event mask
- *  
- * Called when the LL controller receives a set LE event mask command.
- *  
- * Context: Link Layer task (HCI command parser) 
- * 
- * @param cmdbuf Pointer to command buf.
- * 
- * @return int BLE_ERR_SUCCESS. Does not return any errors.
- */
-static int
-ble_ll_hci_set_le_event_mask(uint8_t *cmdbuf)
-{
-    /* Copy the data into the event mask */
-    memcpy(g_ble_ll_hci_le_event_mask, cmdbuf, BLE_HCI_SET_LE_EVENT_MASK_LEN);
-    return BLE_ERR_SUCCESS;
-}
-
-/**
- * ll hci le read bufsize
- *  
- * This is the function that processes the LE read buffer size command.
- *  
- * Context: Link Layer task (HCI command parser) 
- * 
- * @param cmdbuf 
- * 
- * @return int 
- */
-static int
-ble_ll_hci_le_read_bufsize(uint8_t *rspbuf)
-{    
-    /* Place the data packet length and number of packets in the buffer */
-    htole16(rspbuf, BLE_LL_CFG_ACL_DATA_PKT_LEN);
-    rspbuf[2] = BLE_LL_CFG_NUM_ACL_DATA_PKTS;
-    return BLE_ERR_SUCCESS;
-}
-
-/**
- * Checks to see if a LE event has been disabled by the host. 
- * 
- * @param bitpos This is the bit position of the LE event. Note that this can 
- * be a value from 0 to 63, inclusive. 
- * 
- * @return uint8_t 0: event is not enabled; otherwise event is enabled.
- */
-uint8_t
-ble_ll_hci_is_le_event_enabled(int bitpos)
-{
-    uint8_t enabled;
-    uint8_t bytenum;
-    uint8_t bitmask;
-
-    bytenum = bitpos / 8;
-    bitmask = 1 << (bitpos & 0x7);
-    enabled = g_ble_ll_hci_le_event_mask[bytenum] & bitmask;
-
-    return enabled;
-}
-
-/**
- * Process a LE command sent from the host to the controller. The HCI command 
- * has a 3 byte command header followed by data. The header is: 
- *  -> opcode (2 bytes)
- *  -> Length of parameters (1 byte; does include command header bytes).
- * 
- * @param cmdbuf Pointer to command buffer. Points to start of command header.
- * @param len 
- * @param ocf 
- * 
- * @return int 
- */
-static int
-ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
-{
-    int rc;
-    uint8_t len;
-    uint8_t *rspbuf;
-
-    /* Assume error; if all pass rc gets set to 0 */
-    rc = BLE_ERR_INV_HCI_CMD_PARMS;
-
-    /* Get length from command */
-    len = cmdbuf[sizeof(uint16_t)];
-
-    /* 
-     * The command response pointer points into the same buffer as the
-     * command data itself. That is fine, as each command reads all the data
-     * before crafting a response.
-     */ 
-    rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
-
-    /* Move past HCI command header */
-    cmdbuf += BLE_HCI_CMD_HDR_LEN;
-
-    switch (ocf) {
-    case BLE_HCI_OCF_LE_SET_EVENT_MASK:
-        if (len == BLE_HCI_SET_LE_EVENT_MASK_LEN) {
-            rc = ble_ll_hci_set_le_event_mask(cmdbuf);
-        }
-        break;
-    case BLE_HCI_OCF_LE_RD_BUF_SIZE:
-        if (len == BLE_HCI_RD_BUF_SIZE_LEN) {
-            rc = ble_ll_hci_le_read_bufsize(rspbuf);
-            *rsplen = 3;
-        }
-        break;
-
-    case BLE_HCI_OCF_LE_SET_RAND_ADDR:
-        if (len == BLE_DEV_ADDR_LEN) {
-            rc = ble_ll_set_random_addr(cmdbuf);
-        }
-        break;
-    case BLE_HCI_OCF_LE_SET_ADV_PARAMS:
-        /* Length should be one byte */
-        if (len == BLE_HCI_SET_ADV_PARAM_LEN) {
-            rc = ll_adv_set_adv_params(cmdbuf);
-        }
-        break;
-    case BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR:
-        if (len == BLE_HCI_RD_BUF_SIZE_LEN) {
-            rc = ll_adv_read_txpwr(rspbuf);
-            *rsplen = 1;
-        }
-        break;
-    case BLE_HCI_OCF_LE_SET_ADV_DATA:
-        if (len > 0) {
-            --len;
-            rc = ll_adv_set_adv_data(cmdbuf, len);
-        }
-        break;
-    case BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA:
-        if (len > 0) {
-            --len;
-            rc = ll_adv_set_scan_rsp_data(cmdbuf, len);
-        }
-        break;
-    case BLE_HCI_OCF_LE_SET_ADV_ENABLE:
-        /* Length should be one byte */
-        if (len == BLE_HCI_SET_ADV_ENABLE_LEN) {
-            rc = ll_adv_set_enable(cmdbuf);
-        }
-        break;
-    case BLE_HCI_OCF_LE_SET_SCAN_ENABLE:
-        if (len == BLE_HCI_SET_SCAN_ENABLE_LEN) {
-            rc = ble_ll_scan_set_enable(cmdbuf);
-        }
-        break;
-    case BLE_HCI_OCF_LE_SET_SCAN_PARAMS:
-        /* Length should be one byte */
-        if (len == BLE_HCI_SET_SCAN_PARAM_LEN) {
-            rc = ble_ll_scan_set_scan_params(cmdbuf);
-        }
-        break;
-    default:
-        /* XXX: deal with unsupported command */
-        break;
-    }
-
-    return rc;
-}
-
-void
-ble_ll_hci_cmd_proc(struct os_event *ev)
-{
-    int rc;
-    uint8_t ogf;
-    uint8_t rsplen;
-    uint8_t *cmdbuf;
-    uint16_t opcode;
-    uint16_t ocf;
-    os_error_t err;
-
-    /* The command buffer is the event argument */
-    cmdbuf = (uint8_t *)ev->ev_arg;
-    assert(cmdbuf != NULL);
-
-    /* Free the event */
-    err = os_memblock_put(&g_hci_os_event_pool, ev);
-    assert(err == OS_OK);
-
-    /* Get the opcode from the command buffer */
-    opcode = le16toh(cmdbuf);
-    ocf = BLE_HCI_OCF(opcode);
-    ogf = BLE_HCI_OGF(opcode);
-
-    /* Assume response length is zero */
-    rsplen = 0;
-
-    switch (ogf) {
-    case BLE_HCI_OGF_LE:
-        rc = ble_ll_hci_le_cmd_proc(cmdbuf, ocf, &rsplen);
-        break;
-    case BLE_HCI_OGF_CTLR_BASEBAND:
-        /* XXX: Implement  */
-        rc = BLE_ERR_UNKNOWN_HCI_CMD;
-        break;
-    default:
-        /* XXX: Need to support other OGF. For now, return unsupported */
-        rc = BLE_ERR_UNKNOWN_HCI_CMD;
-        break;
-    }
-
-    /* Make sure valid error code */
-    assert(rc >= 0);
-    if (rc) {
-        ++g_ll_stats.hci_cmd_errs;
-    } else {
-        ++g_ll_stats.hci_cmds;
-    }
-
-    /* If no response is generated, we free the buffers */
-    if (rc <= BLE_ERR_MAX) {
-        /* Create a command complete event with status from command */
-        cmdbuf[0] = BLE_HCI_EVCODE_COMMAND_COMPLETE;
-        cmdbuf[1] = 4 + rsplen;    /* Length of the data */
-        cmdbuf[2] = ble_ll_hci_get_num_cmd_pkts();
-        htole16(cmdbuf + 3, opcode);
-        cmdbuf[5] = (uint8_t)rc;
-
-        /* Send the event. This event cannot be masked */
-        ble_ll_hci_event_send(cmdbuf);
-    } else {
-        /* XXX: placeholder for sending command status or other events */
-        assert(0);
-    }
-}
-
-/* XXX: For now, put this here */
-int
-ble_hci_transport_host_cmd_send(uint8_t *cmd)
-{
-    os_error_t err;
-    struct os_event *ev;
-
-    /* Get an event structure off the queue */
-    ev = (struct os_event *)os_memblock_get(&g_hci_os_event_pool);
-    if (!ev) {
-        err = os_memblock_put(&g_hci_cmd_pool, cmd);
-        assert(err == OS_OK);
-        return -1;
-    }
-
-    /* Fill out the event and post to Link Layer */
-    ev->ev_queued = 0;
-    ev->ev_type = BLE_LL_EVENT_HCI_CMD;
-    ev->ev_arg = cmd;
-    os_eventq_put(&g_ll_data.ll_evq, ev);
-
-    return 0;
-}
-
-/**
- * Initalize the LL HCI.
- */
-void
-ble_ll_hci_init(void)
-{
-    /* Set defaults for LE events: Vol 2 Part E 7.8.1 */
-    g_ble_ll_hci_le_event_mask[0] = 0x1f;
-
-    /* Set defaults for controller/baseband events: Vol 2 Part E 7.3.1 */
-    g_ble_ll_hci_event_mask[0] = 0xff;
-    g_ble_ll_hci_event_mask[1] = 0xff;
-    g_ble_ll_hci_event_mask[2] = 0xff;
-    g_ble_ll_hci_event_mask[3] = 0xff;
-    g_ble_ll_hci_event_mask[4] = 0xff;
-    g_ble_ll_hci_event_mask[5] = 0x1f;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ll_sched.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ll_sched.c b/net/nimble/controller/src/ll_sched.c
deleted file mode 100644
index 594fe57..0000000
--- a/net/nimble/controller/src/ll_sched.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <stdint.h>
-#include <assert.h>
-#include <string.h>
-#include "os/os.h"
-#include "controller/phy.h"
-#include "controller/ll.h"
-#include "controller/ll_sched.h"
-#include "hal/hal_cputime.h"
-
-/* XXX: this is temporary. Not sure what I want to do here */
-struct cpu_timer g_ll_sched_timer;
-
-/* XXX: TODO:
- *  1) Add a "priority" scheme possibly. This would allow items to be
- *  added if they overlapped.
- *  2) Add some accounting to the schedule code to see how late we are
- *  (min/max?)
- */
-#define BLE_LL_CFG_SCHED_ITEMS      (8)
-#define BLE_LL_SCHED_POOL_SIZE      \
-    OS_MEMPOOL_SIZE(BLE_LL_CFG_SCHED_ITEMS, sizeof(struct ll_sched_item))
-
-struct os_mempool g_ll_sched_pool;
-os_membuf_t g_ll_sched_mem[BLE_LL_SCHED_POOL_SIZE];
-
-/* Queue for timers */
-TAILQ_HEAD(ll_sched_qhead, ll_sched_item) g_ll_sched_q;
-
-/**
- * ll sched execute
- *  
- * Executes a schedule item by calling the schedule callback function.
- * 
- * @param sch Pointer to schedule item
- * 
- * @return int 0: schedule item is not over; otherwise schedule item is done.
- */
-int
-ll_sched_execute(struct ll_sched_item *sch)
-{
-    int rc;
-
-    assert(sch->sched_cb);
-    rc = sch->sched_cb(sch);
-    return rc;
-}
-
-/* Get a schedule item from the event pool */
-struct ll_sched_item *
-ll_sched_get_item(void)
-{
-    struct ll_sched_item *sch;
-
-    sch = os_memblock_get(&g_ll_sched_pool);
-    if (sch) {
-        memset(sch, 0, sizeof(struct ll_sched_item));
-    }
-    return sch;
-}
-
-/* Free the schedule item */
-void
-ll_sched_free_item(struct ll_sched_item *sch)
-{
-    os_error_t err;
-    err = os_memblock_put(&g_ll_sched_pool, sch);
-    assert(err == OS_OK);
-}
-
-/* Schedule a LL event */
-int
-ll_sched_add(struct ll_sched_item *sch)
-{
-    int rc;
-    os_sr_t sr;
-    struct ll_sched_item *entry;
-
-    /* Determine if we are able to add this to the schedule */
-    OS_ENTER_CRITICAL(sr);
-
-    rc = 0;
-    if (TAILQ_EMPTY(&g_ll_sched_q)) {
-        TAILQ_INSERT_HEAD(&g_ll_sched_q, sch, link);
-    } else {
-        cputime_timer_stop(&g_ll_sched_timer);
-        TAILQ_FOREACH(entry, &g_ll_sched_q, link) {
-            if ((int32_t)(sch->start_time - entry->start_time) < 0) {
-                /* Make sure this event does not overlap current event */
-                if ((int32_t)(sch->end_time - entry->start_time) < 0) {
-                    TAILQ_INSERT_BEFORE(entry, sch, link);   
-                } else {
-                    rc = BLE_LL_SCHED_ERR_OVERLAP;
-                }
-                break;
-            } else {
-                /* Check for overlap */
-                if ((int32_t)(sch->start_time - entry->end_time) < 0) {
-                    rc = BLE_LL_SCHED_ERR_OVERLAP;
-                    break;
-                }
-            }
-        }
-        if (!entry) {
-            TAILQ_INSERT_TAIL(&g_ll_sched_q, sch, link);
-        }
-    }
-
-    OS_EXIT_CRITICAL(sr);
-
-    cputime_timer_start(&g_ll_sched_timer, sch->start_time);
-
-    return rc;
-}
-
-/* Remove an event (or events) from the scheduler */
-int
-ll_sched_rmv(uint8_t sched_type)
-{
-    os_sr_t sr;
-    struct ll_sched_item *entry;
-    struct ll_sched_item *next;
-
-    OS_ENTER_CRITICAL(sr);
-
-    entry = TAILQ_FIRST(&g_ll_sched_q);
-    if (entry) {
-        cputime_timer_stop(&g_ll_sched_timer);
-        while (entry) {
-            next = TAILQ_NEXT(entry, link);
-            if (entry->sched_type == sched_type) {
-                TAILQ_REMOVE(&g_ll_sched_q, entry, link);
-                os_memblock_put(&g_ll_sched_pool, entry);
-            } 
-            entry = next;
-        }
-
-        /* Start the timer if there is an item */
-        entry = TAILQ_FIRST(&g_ll_sched_q);
-        if (entry) {
-            cputime_timer_start(&g_ll_sched_timer, entry->start_time);
-        }
-    }
-
-    OS_EXIT_CRITICAL(sr);
-
-    return 0;
-}
-
-/**
- * ll sched run 
- *  
- * Run the BLE scheduler. Iterate through all items on the schedule queue.
- *  
- * Context: interrupt (scheduler) 
- * 
- * @return int 
- */
-void
-ll_sched_run(void *arg)
-{
-    int rc;
-    struct ll_sched_item *sch;
-
-    /* Look through schedule queue */
-    while ((sch = TAILQ_FIRST(&g_ll_sched_q)) != NULL) {
-        /* Make sure we have passed the start time of the first event */
-        if ((int32_t)(cputime_get32() - sch->start_time) >= 0) {
-            /* Execute the schedule item */
-            rc = ll_sched_execute(sch);
-            if (rc) {
-                TAILQ_REMOVE(&g_ll_sched_q, sch, link);
-                os_memblock_put(&g_ll_sched_pool, sch);
-            } else {
-                /* Event is not over; schedule next wakeup time */
-                cputime_timer_start(&g_ll_sched_timer, sch->next_wakeup);
-                break;
-            }
-        } else {
-            cputime_timer_start(&g_ll_sched_timer, sch->start_time);
-            break;
-        }
-    }
-}
-
-/**
- * ble ll sched init 
- *  
- * Initialize the scheduler. Should only be called once and should be called 
- * before any of the scheduler API are called. 
- * 
- * @return int 
- */
-int
-ll_sched_init(void)
-{
-    os_error_t err;
-
-    err = os_mempool_init(&g_ll_sched_pool, BLE_LL_CFG_SCHED_ITEMS, 
-                          sizeof(struct ll_sched_item), 
-                          g_ll_sched_mem, "ll_sched");
-    assert(err == OS_OK);
-
-    /* Start cputimer for the scheduler */
-    cputime_timer_init(&g_ll_sched_timer, ll_sched_run, NULL);
-
-    return err;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/phy.c b/net/nimble/controller/src/phy.c
index 83050a3..f987ba6 100644
--- a/net/nimble/controller/src/phy.c
+++ b/net/nimble/controller/src/phy.c
@@ -19,7 +19,7 @@
 #include "bsp/cmsis_nvic.h"
 #include "nimble/ble.h"
 #include "controller/phy.h"
-#include "controller/ll.h"
+#include "controller/ble_ll.h"
 #include "hal/hal_cputime.h"
 #include "mcu/nrf52.h"
 #include "mcu/nrf52_bitfields.h"
@@ -206,7 +206,7 @@ ble_phy_isr(void)
         }
 
         /* Call Link Layer receive start function */
-        rc = ll_rx_start(g_ble_phy_data.rxpdu);
+        rc = ble_ll_rx_start(g_ble_phy_data.rxpdu);
         if (rc >= 0) {
             if (rc > 0) {
                 /* We need to go from disabled to TXEN */
@@ -254,7 +254,7 @@ ble_phy_isr(void)
         /* Call Link Layer receive payload function */
         rxpdu = g_ble_phy_data.rxpdu;
         g_ble_phy_data.rxpdu = NULL;
-        rc = ll_rx_end(rxpdu, ble_hdr->crcok);
+        rc = ble_ll_rx_end(rxpdu, ble_hdr->crcok);
         if (rc < 0) {
             /* Disable the PHY. */
             ble_phy_disable();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/project/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c
index a26f974..eb6a758 100755
--- a/project/bletest/src/main.c
+++ b/project/bletest/src/main.c
@@ -24,7 +24,7 @@
 /* BLE */
 #include "nimble/ble.h"
 #include "host/host_hci.h"
-#include "controller/ll.h"
+#include "controller/ble_ll.h"
 
 /* Init all tasks */
 volatile int tasks_initialized;
@@ -202,7 +202,7 @@ host_task_handler(void *arg)
     host_hci_init();
 
     /* Initialize the BLE LL */
-    ll_init();
+    ble_ll_init();
 
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
     /* Initialize the advertiser */



[3/3] incubator-mynewt-larva git commit: Prefix ll with ble_. This includes filenames

Posted by we...@apache.org.
Prefix ll with ble_. This includes filenames


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/36623dd5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/36623dd5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/36623dd5

Branch: refs/heads/master
Commit: 36623dd5f5cdb07f60f72e3b7d995cc854b87b4e
Parents: a666bf8
Author: Willam San Filippo <wi...@micosa.io>
Authored: Fri Oct 30 15:20:57 2015 -0700
Committer: Willam San Filippo <wi...@micosa.io>
Committed: Fri Oct 30 15:20:57 2015 -0700

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll.h      | 437 +++++++++
 .../controller/include/controller/ble_ll_adv.h  | 153 ++++
 .../include/controller/ble_ll_sched.h           |  63 ++
 net/nimble/controller/include/controller/ll.h   | 437 ---------
 .../controller/include/controller/ll_adv.h      | 153 ----
 .../controller/include/controller/ll_sched.h    |  63 --
 net/nimble/controller/src/ble_ll.c              | 655 +++++++++++++
 net/nimble/controller/src/ble_ll_adv.c          | 912 ++++++++++++++++++
 net/nimble/controller/src/ble_ll_hci.c          | 336 +++++++
 net/nimble/controller/src/ble_ll_scan.c         |  22 +-
 net/nimble/controller/src/ble_ll_sched.c        | 237 +++++
 net/nimble/controller/src/ll.c                  | 661 -------------
 net/nimble/controller/src/ll_adv.c              | 916 -------------------
 net/nimble/controller/src/ll_hci.c              | 336 -------
 net/nimble/controller/src/ll_sched.c            | 222 -----
 net/nimble/controller/src/phy.c                 |   6 +-
 project/bletest/src/main.c                      |   4 +-
 17 files changed, 2809 insertions(+), 2804 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/include/controller/ble_ll.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h
new file mode 100644
index 0000000..6d8504c
--- /dev/null
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -0,0 +1,437 @@
+/**
+ * Copyright (c) 2015 Stack Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_LL_
+#define H_BLE_LL_
+
+/* XXX: Not sure this should go here, but whatever */
+/* 
+ * ble ll global parameters
+ * 
+ * NOTES:
+ *  1) Controller should not change value of supported max tx and rx time and
+ *  octets.
+ */
+struct ble_ll_global_params
+{
+    int conn_init_max_tx_octets;
+    int conn_init_max_tx_time;
+    int supp_max_tx_octets;
+    int supp_max_tx_time;
+    int supp_max_rx_octets;
+    int supp_max_rx_time;
+};
+
+struct ble_ll_obj
+{
+    uint8_t ll_state;
+    struct os_eventq ll_evq;
+    struct ble_ll_global_params ll_params;
+    struct os_event ll_rx_pkt_ev;
+    STAILQ_HEAD(ll_rxpkt_qh, os_mbuf_pkthdr) ll_rx_pkt_q;
+};
+
+struct ble_ll_stats
+{
+    uint32_t rx_crc_ok;
+    uint32_t rx_crc_fail;
+    uint32_t rx_bytes;
+    uint32_t rx_adv_ind;
+    uint32_t rx_adv_direct_ind;
+    uint32_t rx_adv_nonconn_ind;
+    uint32_t rx_scan_reqs;
+    uint32_t rx_scan_rsps;
+    uint32_t rx_connect_reqs;
+    uint32_t rx_scan_ind;
+    uint32_t rx_unk_pdu;
+    uint32_t rx_malformed_pkts;
+    uint32_t hci_cmds;
+    uint32_t hci_cmd_errs;
+    uint32_t hci_events_sent;
+};
+
+extern struct ble_ll_stats g_ble_ll_stats;
+extern struct ble_ll_obj g_ble_ll_data;
+
+/* States */
+#define BLE_LL_STATE_STANDBY        (0)
+#define BLE_LL_STATE_ADV            (1)
+#define BLE_LL_STATE_SCANNING       (2)
+#define BLE_LL_STATE_INITITATING    (3)
+#define BLE_LL_STATE_CONNECT        (4)
+
+/* BLE LL Task Events */
+#define BLE_LL_EVENT_HCI_CMD        (OS_EVENT_T_PERUSER)
+#define BLE_LL_EVENT_ADV_TXDONE     (OS_EVENT_T_PERUSER + 1)
+#define BLE_LL_EVENT_RX_PKT_IN      (OS_EVENT_T_PERUSER + 2)
+#define BLE_LL_EVENT_SCAN_WIN_END   (OS_EVENT_T_PERUSER + 3)
+
+/* LL Features */
+#define BLE_LL_FEAT_LE_ENCRYPTION   (0x01)
+#define BLE_LL_FEAT_CONN_PARM_REQ   (0x02)
+#define BLE_LL_FEAT_EXTENDED_REJ    (0x04)
+#define BLE_LL_FEAT_SLAVE_INIT      (0x08)
+#define BLE_LL_FEAT_LE_PING         (0x10)
+#define BLE_LL_FEAT_DATA_LEN_EXT    (0x20)
+#define BLE_LL_FEAT_LL_PRIVACY      (0x40)
+#define BLE_LL_FEAT_EXT_SCAN_FILT   (0x80)
+
+/* LL timing */
+#define BLE_LL_IFS              (150)       /* usecs */
+#define BLE_CLOCK_DRIFT_ACTIVE  (50)        /* +/- ppm */
+#define BLE_CLOCK_DRIFT_SLEEP   (500)       /* +/- ppm */
+
+/* 
+ * BLE LL device address. Note that element 0 of the array is the LSB and
+ * is sent over the air first. Byte 5 is the MSB and is the last one sent over
+ * the air.
+ */
+#define BLE_DEV_ADDR_LEN    (6)     /* bytes */
+
+struct ble_dev_addr
+{
+    uint8_t u8[BLE_DEV_ADDR_LEN];
+};
+
+#define BLE_IS_DEV_ADDR_STATIC(addr)        ((addr->u8[5] & 0xc0) == 0xc0)
+#define BLE_IS_DEV_ADDR_RESOLVABLE(addr)    ((addr->u8[5] & 0xc0) == 0x40)
+#define BLE_IS_DEV_ADDR_UNRESOLVABLE(addr)  ((addr->u8[5] & 0xc0) == 0x00)
+
+/* 
+ * LL packet format
+ * 
+ *  -> Preamble         (1 byte)
+ *  -> Access Address   (4 bytes)
+ *  -> PDU              (2 to 257 octets)
+ *  -> CRC              (3 bytes)
+ */
+#define BLE_LL_PREAMBLE_LEN     (1)
+#define BLE_LL_ACC_ADDR_LEN     (4)
+#define BLE_LL_CRC_LEN          (3)
+#define BLE_LL_OVERHEAD_LEN     \
+    (BLE_LL_CRC_LEN + BLE_LL_ACC_ADDR_LEN + BLE_LL_PREAMBLE_LEN)
+#define BLE_LL_PDU_HDR_LEN      (2)
+#define BLE_LL_MIN_PDU_LEN      (BLE_LL_PDU_HDR_LEN)
+#define BLE_LL_MAX_PDU_LEN      (257)
+#define BLE_LL_CRCINIT_ADV      (0x555555)
+
+/* Access address for advertising channels */
+#define BLE_ACCESS_ADDR_ADV             (0x8E89BED6)
+
+/*
+ * Data Channel format
+ * 
+ *  -> Header (2 bytes.
+ *      -> LSB contains llid, nesn, sn and md
+ *      -> MSB contains length (8 bits)
+ *  -> Payload (0 to 251)
+ *  -> MIC (0 or 4 bytes)
+ */
+#define BLE_LL_DATA_HDR_LLID_MASK       (0x03)
+#define BLE_LL_DATA_HDR_NESN_MASK       (0x04)
+#define BLE_LL_DATA_HDR_SN_MASK         (0x08)
+#define BLE_LL_DATA_HDR_MD_MASK         (0x10)
+#define BLE_LL_DATA_HDR_RSRVD_MASK      (0xE0)
+
+/* LLID definitions */
+#define BLE_LL_LLID_RSRVD               (0)
+#define BLE_LL_LLID_DATA_FRAG           (1)
+#define BLE_LL_LLID_DATA_START          (2)
+#define BLE_LL_LLID_CTRL                (3)
+
+/* 
+ * LL CTRL PDU format
+ *  -> Opcode (1 byte)
+ *  -> Ctrl data (0 - 26 bytes)
+ */
+#define BLE_LL_CTRL_CONN_UPDATE_REQ     (0)
+#define BLE_LL_CTRL_CHANNEL_MAP_REQ     (1)
+#define BLE_LL_CTRL_TERMINATE_IND       (2)
+#define BLE_LL_CTRL_ENC_REQ             (3)
+#define BLE_LL_CTRL_ENC_RSP             (4)
+#define BLE_LL_CTRL_START_ENC_REQ       (5)
+#define BLE_LL_CTRL_START_ENC_RSP       (6)
+#define BLE_LL_CTRL_UNKNOWN_RSP         (7)
+#define BLE_LL_CTRL_FEATURE_REQ         (8)
+#define BLE_LL_CTRL_FEATURE_RSP         (9)
+#define BLE_LL_CTRL_PAUSE_ENC_REQ       (10)
+#define BLE_LL_CTRL_PAUSE_ENC_RSP       (11)
+#define BLE_LL_CTRL_VERSION_IND         (12)
+#define BLE_LL_CTRL_REJECT_IND          (13)
+#define BLE_LL_CTRL_SLAVE_FEATURE_REQ   (14)
+#define BLE_LL_CTRL_CONN_PARM_REQ       (15)
+#define BLE_LL_CTRL_CONN_PARM_RSP       (16)
+#define BLE_LL_CTRL_REJECT_IND_EXT      (17)
+#define BLE_LL_CTRL_PING_REQ            (18)
+#define BLE_LL_CTRL_PING_RSP            (19)
+#define BLE_LL_CTRL_LENGTH_REQ          (20)
+#define BLE_LL_CTRL_LENGTH_RSP          (21)
+
+/* LL control connection update request */
+struct ble_ll_conn_upd_req
+{
+    uint8_t winsize;
+    uint16_t winoffset;
+    uint16_t interval;
+    uint16_t latency;
+    uint16_t timeout;
+    uint16_t instant;
+};
+
+#define BLE_LL_CTRL_CONN_UPD_REQ_LEN        (11)
+
+/* LL control channel map request */
+struct ble_ll_chan_map_req
+{
+    uint8_t chmap[5];
+    uint16_t instant;
+};
+
+#define BLE_LL_CTRL_CHAN_MAP_LEN            (7)
+
+/* 
+ * LL control terminate ind
+ *  -> error code (1 byte)                         
+ */
+#define BLE_LL_CTRL_TERMINATE_IND_LEN      (1)
+
+/* LL control enc req */
+struct ble_ll_enc_req
+{
+    uint8_t rand[8];
+    uint16_t ediv;
+    uint8_t skdm[8];
+    uint32_t ivm;
+};
+
+#define BLE_LL_CTRL_ENC_REQ_LEN             (22)
+
+/* LL control enc rsp */
+struct ble_ll_enc_rsp
+{
+    uint8_t skds[8];
+    uint32_t ivs;
+};
+
+#define BLE_LL_CTRL_ENC_RSP_LEN             (12)
+
+/* LL control start enc req and start enc rsp have no data */ 
+#define BLE_LL_CTRL_START_ENC_LEN           (0)
+
+/* 
+ * LL control unknown response
+ *  -> 1 byte which contains the unknown or un-supported opcode.
+ */
+#define BLE_LL_CTRL_UNK_RSP_LEN             (1)
+
+/*
+ * LL control feature req and LL control feature rsp 
+ *  -> 8 bytes of data containing features supported by device.
+ */
+#define BLE_LL_CTRL_FEATURE_LEN             (8)
+
+/* LL control pause enc req and pause enc rsp have no data */
+#define BLE_LL_CTRL_PAUSE_ENC_LEN           (0)
+
+/* 
+ * LL control version ind 
+ *  -> version (1 byte):
+ *      Contains the version number of the bluetooth controller specification.
+ *  -> comp_id (2 bytes)
+ *      Contains the company identifier of the manufacturer of the controller.
+ *  -> sub_ver_num: Contains a unique value for implementation or revision of
+ *      the bluetooth controller.
+ */
+struct ble_ll_version_ind
+{
+    uint8_t ble_ctrlr_ver;
+    uint16_t company_id;
+    uint16_t sub_ver_num;
+};
+
+#define BLE_LL_CTRL_VERSION_IND_LEN         (5)
+
+/* 
+ * LL control reject ind
+ *  -> error code (1 byte): contains reason why request was rejected.
+ */
+#define BLE_LL_CTRL_REJ_IND_LEN             (1)
+
+/*
+ * LL control slave feature req
+ *  -> 8 bytes of data containing features supported by device.
+ */
+#define BLE_LL_CTRL_SLAVE_FEATURE_REQ_LEN   (8)
+
+/* LL control connection param req and connection param rsp */
+struct ble_ll_conn_params
+{
+    uint16_t interval_min;
+    uint16_t interval_max;
+    uint16_t latency;
+    uint16_t timeout;
+    uint16_t pref_periodicity;
+    uint16_t ref_conn_event_cnt;
+    uint16_t offset0;
+    uint16_t offset1;
+    uint16_t offset2;
+    uint16_t offset3;
+    uint16_t offset4;
+    uint16_t offset5;
+};
+
+#define BLE_LL_CTRL_CONN_PARAMS_LEN     (24)
+
+/* LL control reject ind ext */
+struct ble_ll_reject_ind_ext
+{
+    uint8_t reject_opcode;
+    uint8_t err_code;
+};
+
+#define BLE_LL_CTRL_REJECT_IND_EXT_LEN  (2)
+
+/* LL control ping req and ping rsp (contain no data) */
+#define BLE_LL_CTRL_PING_LEN            (0)
+
+/* 
+ * LL control length req and length rsp
+ *  -> max_rx_bytes (2 bytes): defines connMaxRxOctets. Range 27 to 251
+ *  -> max_rx_time (2 bytes): defines connMaxRxTime. Range 328 to 2120 usecs.
+ *  -> max_tx_bytes (2 bytes): defines connMaxTxOctets. Range 27 to 251
+ *  -> max_tx_time (2 bytes): defines connMaxTxTime. Range 328 to 2120 usecs.
+ */
+struct ble_ll_len_req
+{
+    uint16_t max_rx_bytes;
+    uint16_t max_rx_time;
+    uint16_t max_tx_bytes;
+    uint16_t max_tx_time;
+};
+
+#define BLE_LL_CTRL_LENGTH_REQ_LEN      (8)
+
+/*
+ * CONNECT_REQ
+ *      -> InitA        (6 bytes)
+ *      -> AdvA         (6 bytes)
+ *      -> LLData       (22 bytes)
+ *          -> Access address (4 bytes)
+ *          -> CRC init (3 bytes)
+ *          -> WinSize (1 byte)
+ *          -> WinOffset (2 bytes)
+ *          -> Interval (2 bytes)
+ *          -> Latency (2 bytes)
+ *          -> Timeout (2 bytes)
+ *          -> Channel Map (5 bytes)
+ *          -> Hop Increment (5 bits)
+ *          -> SCA (3 bits)
+ * 
+ *  InitA is the initiators public (TxAdd=0) or random (TxAdd=1) address.
+ *  AdvaA is the advertisers public (RxAdd=0) or random (RxAdd=1) address.
+ *  LLData contains connection request data.
+ *      aa: Link Layer's access address
+ *      crc_init: The CRC initialization value used for CRC calculation.
+ *      winsize: The transmit window size = winsize * 1.25 msecs
+ *      winoffset: The transmit window offset =  winoffset * 1.25 msecs
+ *      interval: The connection interval = interval * 1.25 msecs.
+ *      latency: connection slave latency = latency
+ *      timeout: Connection supervision timeout = timeout * 10 msecs.
+ *      chanmap: contains channel mapping indicating used and unused data
+ *               channels. Only bits that are 1 are usable. LSB is channel 0.
+ *      hop_inc: Hop increment used for frequency hopping. Random value in
+ *               range of 5 to 16.
+ */
+#define BLE_CONNECT_REQ_LEN             (34)
+
+struct ble_conn_req_data
+{
+    uint32_t    aa;
+    uint8_t     crc_init[3];
+    uint8_t     winsize;
+    uint16_t    winoffset;
+    uint16_t    interval;
+    uint16_t    latency;
+    uint16_t    timeout;
+    uint8_t     chanmap[5];
+    uint8_t     hop_inc;
+    uint8_t     master_sca;
+};
+
+#define BLE_CONN_REQ_HOP_MASK           (0x1F)
+#define BLE_CONN_REQ_SCA_MASK           (0xE0)
+
+#define BLE_MASTER_SCA_251_500_PPM      (0)
+#define BLE_MASTER_SCA_151_250_PPM      (1)
+#define BLE_MASTER_SCA_101_150_PPM      (2)
+#define BLE_MASTER_SCA_76_100_PPM       (3)
+#define BLE_MASTER_SCA_51_75_PPM        (4)
+#define BLE_MASTER_SCA_31_50_PPM        (5)
+#define BLE_MASTER_SCA_21_30_PPM        (6)
+#define BLE_MASTER_SCA_0_20_PPM         (7)
+
+/*
+ * Initiator filter policy 
+ * 
+ * Determines how the initiator's Link Layer processes advertisements.
+ * 
+ *  LIST: process connectable advertisements only from devices in white list.
+ *  SINGLE: do not use white list; process connectable advertisements from
+ *      a single specific device specified by the host.
+ */
+enum ble_ll_init_filt_policy
+{
+    BLE_LL_INIT_FILT_LIST = 0,
+    BLE_LL_INIT_FILT_SINGLE,
+};
+
+/*--- External API ---*/
+/* Initialize the Link Layer */
+int ble_ll_init(void);
+
+/* 'Boolean' function returning true if address is a valid random address */
+int ble_ll_is_valid_random_addr(uint8_t *addr);
+
+/* Calculate the amount of time a pdu of 'len' bytes will take to transmit */
+uint16_t ble_ll_pdu_tx_time_get(uint16_t len);
+
+/* Boolean returning true if device is on whitelist */
+int ble_ll_is_on_whitelist(uint8_t *addr, int addr_type);
+
+/* Is this address a resolvable private address? */
+int ble_ll_is_resolvable_priv_addr(uint8_t *addr);
+
+/* Is 'addr' our device address? 'addr_type' is public (0) or random (!=0) */
+int ble_ll_is_our_devaddr(uint8_t *addr, int addr_type);
+
+/*--- PHY interfaces ---*/
+/* Called by the PHY when a packet has started */
+int ble_ll_rx_start(struct os_mbuf *rxpdu);
+
+/* Called by the PHY when a packet reception ends */
+int ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t crcok);
+
+/*--- Controller API ---*/
+/* Set the link layer state */
+void ble_ll_state_set(int ll_state);
+
+/* Send an event to LL task */
+void ble_ll_event_send(struct os_event *ev);
+
+/* Set random address */
+int ble_ll_set_random_addr(uint8_t *addr);
+
+#endif /* H_LL_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/include/controller/ble_ll_adv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_adv.h b/net/nimble/controller/include/controller/ble_ll_adv.h
new file mode 100644
index 0000000..15f8d25
--- /dev/null
+++ b/net/nimble/controller/include/controller/ble_ll_adv.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2015 Stack Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_LL_ADV_
+#define H_BLE_LL_ADV_
+
+/* 
+ * ADV event timing
+ *      T_advEvent = advInterval + advDelay
+ * 
+ *      advInterval: increments of 625 usecs
+ *      advDelay: RAND[0, 10] msecs
+ * 
+ */
+#define BLE_LL_ADV_ITVL                 (625)           /* usecs */
+#define BLE_LL_ADV_ITVL_MIN             (32)            /* units */
+#define BLE_LL_ADV_ITVL_MAX             (16384)         /* units */
+#define BLE_LL_ADV_ITVL_MS_MIN          (20)            /* msecs */
+#define BLE_LL_ADV_ITVL_MS_MAX          (10240)         /* msecs */
+#define BLE_LL_ADV_ITVL_SCAN_MIN        (160)           /* units */
+#define BLE_LL_ADV_ITVL_SCAN_MS_MIN     (100)           /* msecs */
+#define BLE_LL_ADV_ITVL_NONCONN_MIN     (160)           /* units */
+#define BLE_LL_ADV_ITVL_NONCONN_MS_MIN  (100)           /* msecs */
+#define BLE_LL_ADV_DELAY_MS_MIN         (0)             /* msecs */
+#define BLE_LL_ADV_DELAY_MS_MAX         (10)            /* msecs */
+#define BLE_LL_ADV_PDU_ITVL_LD_MS_MAX   (10)            /* msecs */
+#define BLE_LL_ADV_PDU_ITVL_HD_MS_MAX   (3750)          /* usecs */
+#define BLE_LL_ADV_STATE_HD_MAX         (1280)          /* msecs */
+
+/* 
+ * Advertising PDU format:
+ * -> 2 byte header
+ *      -> LSB contains pdu type, txadd and rxadd bits.
+ *      -> MSB contains length (6 bits).
+ * -> Payload
+ */
+#define BLE_ADV_PDU_HDR_TYPE_MASK           (0x0F)
+#define BLE_ADV_PDU_HDR_TXADD_MASK          (0x40)
+#define BLE_ADV_PDU_HDR_RXADD_MASK          (0x80)
+#define BLE_ADV_PDU_HDR_LEN_MASK            (0x3F)
+
+/* Advertising channel PDU types */
+#define BLE_ADV_PDU_TYPE_ADV_IND            (0)
+#define BLE_ADV_PDU_TYPE_ADV_DIRECT_IND     (1)
+#define BLE_ADV_PDU_TYPE_ADV_NONCONN_IND    (2)
+#define BLE_ADV_PDU_TYPE_SCAN_REQ           (3)
+#define BLE_ADV_PDU_TYPE_SCAN_RSP           (4)
+#define BLE_ADV_PDU_TYPE_CONNECT_REQ        (5)
+#define BLE_ADV_PDU_TYPE_ADV_SCAN_IND       (6)
+
+/* 
+ * TxAdd and RxAdd bit definitions. A 0 is a public address; a 1 is a
+ * random address.
+ */
+#define BLE_ADV_PDU_HDR_TXADD_RAND          (0x40)
+#define BLE_ADV_PDU_HDR_RXADD_RAND          (0x80)
+
+/* Maximum advertisement data length */
+#define BLE_ADV_DATA_MAX_LEN            (31)
+
+/* 
+ * ADV_IND
+ *      -> AdvA     (6 bytes)
+ *      -> AdvData  (0 - 31 bytes)
+ * 
+ *  The advertising address (AdvA) is a public address (TxAdd=0) or random 
+ *  address (TxAdd = 1)
+ */
+#define BLE_ADV_IND_MIN_LEN             (6)
+#define BLE_ADV_IND_MAX_LEN             (37)
+
+/* 
+ * ADV_DIRECT_IND
+ *      -> AdvA     (6 bytes)
+ *      -> InitA    (6 bytes)
+ * 
+ *  AdvA is the advertisers public address (TxAdd=0) or random address
+ *  (TxAdd = 1).
+ * 
+ *  InitA is the initiators public or random address. This is the address
+ *  to which this packet is addressed.
+ * 
+ */
+#define BLE_ADV_DIRECT_IND_LEN          (12)
+
+/*
+ * ADV_NONCONN_IND 
+ *      -> AdvA     (6 bytes)
+ *      -> AdvData  (0 - 31 bytes)
+ * 
+ *  The advertising address (AdvA) is a public address (TxAdd=0) or random 
+ *  address (TxAdd = 1)
+ * 
+ */
+#define BLE_ADV_NONCONN_IND_MIN_LEN     (6)
+#define BLE_ADV_NONCONN_IND_MAX_LEN     (37)
+
+/*
+ * ADV_SCAN_IND
+ *      -> AdvA     (6 bytes)
+ *      -> AdvData  (0 - 31 bytes)
+ * 
+ *  The advertising address (AdvA) is a public address (TxAdd=0) or random 
+ *  address (TxAdd = 1)
+ * 
+ */
+#define BLE_ADV_SCAN_IND_MIN_LEN        (6)
+#define BLE_ADV_SCAN_IND_MAX_LEN        (37)
+
+/*---- HCI ----*/
+/* Start an advertiser */
+int ble_ll_adv_start_req(uint8_t adv_chanmask, uint8_t adv_type, 
+                         uint8_t *init_addr, uint16_t adv_itvl, void *handle);
+
+/* Start or stop advertising */
+int ble_ll_adv_set_enable(uint8_t *cmd);
+
+/* Set advertising data */
+int ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t len);
+
+/* Set scan response data */
+int ble_ll_adv_set_scan_rsp_data(uint8_t *cmd, uint8_t len);
+
+/* Set advertising parameters */
+int ble_ll_adv_set_adv_params(uint8_t *cmd);
+
+/* Read advertising channel power */
+int ble_ll_adv_read_txpwr(uint8_t *rspbuf);
+
+/*---- API used by BLE LL ----*/
+/* Called when advertising tx done event posted to LL task */
+void ble_ll_adv_tx_done_proc(void *arg);
+
+/* Called to initialize advertising functionality. */
+void ble_ll_adv_init(void);
+
+/* Called when a scan request has been received. */
+int ble_ll_adv_rx_scan_req(uint8_t *rxbuf);
+
+#endif /* H_LL_ADV_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/include/controller/ble_ll_sched.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_sched.h b/net/nimble/controller/include/controller/ble_ll_sched.h
new file mode 100644
index 0000000..ba2bd20
--- /dev/null
+++ b/net/nimble/controller/include/controller/ble_ll_sched.h
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2015 Stack Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_LL_SCHED_
+#define H_BLE_LL_SCHED_
+
+/* BLE scheduler errors */
+#define BLE_LL_SCHED_ERR_OVERLAP    (1)
+
+/* Types of scheduler events */
+#define BLE_LL_SCHED_TYPE_ADV       (0)
+#define BLE_LL_SCHED_TYPE_SCAN      (1)
+#define BLE_LL_SCHED_TYPE_TX        (2)
+#define BLE_LL_SCHED_TYPE_RX        (3)
+
+/* Return values for schedule callback. */
+#define BLE_LL_SCHED_STATE_RUNNING  (0)
+#define BLE_LL_SCHED_STATE_DONE     (1)
+
+/* Callback function */
+struct ble_ll_sched_item;
+typedef int (*sched_cb_func)(struct ble_ll_sched_item *sch);
+
+struct ble_ll_sched_item
+{
+    int             sched_type;
+    uint32_t        start_time;
+    uint32_t        end_time;
+    uint32_t        next_wakeup;
+    void            *cb_arg;
+    sched_cb_func   sched_cb;
+    TAILQ_ENTRY(ble_ll_sched_item) link;
+};
+
+/* Add an item to the schedule */
+int ble_ll_sched_add(struct ble_ll_sched_item *sch);
+
+/* Remove item(s) from schedule */
+int ble_ll_sched_rmv(uint8_t sched_type);
+
+/* Initialize the scheduler */
+int ble_ll_sched_init(void);
+
+/* Get a schedule item */
+struct ble_ll_sched_item *ble_ll_sched_get_item(void);
+
+/* Free a schedule item */
+void ble_ll_sched_free_item(struct ble_ll_sched_item *sch);
+
+#endif /* H_LL_SCHED_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/include/controller/ll.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ll.h b/net/nimble/controller/include/controller/ll.h
deleted file mode 100644
index 7fbf8db..0000000
--- a/net/nimble/controller/include/controller/ll.h
+++ /dev/null
@@ -1,437 +0,0 @@
-/**
- * Copyright (c) 2015 Stack Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef H_LL_
-#define H_LL_
-
-/* XXX: Not sure this should go here, but whatever */
-/* 
- * ble ll global parameters
- * 
- * NOTES:
- *  1) Controller should not change value of supported max tx and rx time and
- *  octets.
- */
-struct ll_global_params
-{
-    int conn_init_max_tx_octets;
-    int conn_init_max_tx_time;
-    int supp_max_tx_octets;
-    int supp_max_tx_time;
-    int supp_max_rx_octets;
-    int supp_max_rx_time;
-};
-
-struct ll_obj
-{
-    uint8_t ll_state;
-    struct os_eventq ll_evq;
-    struct ll_global_params ll_params;
-    struct os_event ll_rx_pkt_ev;
-    STAILQ_HEAD(ll_rxpkt_qh, os_mbuf_pkthdr) ll_rx_pkt_q;
-};
-
-struct ll_stats
-{
-    uint32_t rx_crc_ok;
-    uint32_t rx_crc_fail;
-    uint32_t rx_bytes;
-    uint32_t rx_adv_ind;
-    uint32_t rx_adv_direct_ind;
-    uint32_t rx_adv_nonconn_ind;
-    uint32_t rx_scan_reqs;
-    uint32_t rx_scan_rsps;
-    uint32_t rx_connect_reqs;
-    uint32_t rx_scan_ind;
-    uint32_t rx_unk_pdu;
-    uint32_t rx_malformed_pkts;
-    uint32_t hci_cmds;
-    uint32_t hci_cmd_errs;
-    uint32_t hci_events_sent;
-};
-
-extern struct ll_stats g_ll_stats;
-extern struct ll_obj g_ll_data;
-
-/* States */
-#define BLE_LL_STATE_STANDBY        (0)
-#define BLE_LL_STATE_ADV            (1)
-#define BLE_LL_STATE_SCANNING       (2)
-#define BLE_LL_STATE_INITITATING    (3)
-#define BLE_LL_STATE_CONNECT        (4)
-
-/* BLE LL Task Events */
-#define BLE_LL_EVENT_HCI_CMD        (OS_EVENT_T_PERUSER)
-#define BLE_LL_EVENT_ADV_TXDONE     (OS_EVENT_T_PERUSER + 1)
-#define BLE_LL_EVENT_RX_PKT_IN      (OS_EVENT_T_PERUSER + 2)
-#define BLE_LL_EVENT_SCAN_WIN_END   (OS_EVENT_T_PERUSER + 3)
-
-/* LL Features */
-#define BLE_LL_FEAT_LE_ENCRYPTION   (0x01)
-#define BLE_LL_FEAT_CONN_PARM_REQ   (0x02)
-#define BLE_LL_FEAT_EXTENDED_REJ    (0x04)
-#define BLE_LL_FEAT_SLAVE_INIT      (0x08)
-#define BLE_LL_FEAT_LE_PING         (0x10)
-#define BLE_LL_FEAT_DATA_LEN_EXT    (0x20)
-#define BLE_LL_FEAT_LL_PRIVACY      (0x40)
-#define BLE_LL_FEAT_EXT_SCAN_FILT   (0x80)
-
-/* LL timing */
-#define BLE_LL_IFS              (150)       /* usecs */
-#define BLE_CLOCK_DRIFT_ACTIVE  (50)        /* +/- ppm */
-#define BLE_CLOCK_DRIFT_SLEEP   (500)       /* +/- ppm */
-
-/* 
- * BLE LL device address. Note that element 0 of the array is the LSB and
- * is sent over the air first. Byte 5 is the MSB and is the last one sent over
- * the air.
- */
-#define BLE_DEV_ADDR_LEN    (6)     /* bytes */
-
-struct ble_dev_addr
-{
-    uint8_t u8[BLE_DEV_ADDR_LEN];
-};
-
-#define BLE_IS_DEV_ADDR_STATIC(addr)        ((addr->u8[5] & 0xc0) == 0xc0)
-#define BLE_IS_DEV_ADDR_RESOLVABLE(addr)    ((addr->u8[5] & 0xc0) == 0x40)
-#define BLE_IS_DEV_ADDR_UNRESOLVABLE(addr)  ((addr->u8[5] & 0xc0) == 0x00)
-
-/* 
- * LL packet format
- * 
- *  -> Preamble         (1 byte)
- *  -> Access Address   (4 bytes)
- *  -> PDU              (2 to 257 octets)
- *  -> CRC              (3 bytes)
- */
-#define BLE_LL_PREAMBLE_LEN     (1)
-#define BLE_LL_ACC_ADDR_LEN     (4)
-#define BLE_LL_CRC_LEN          (3)
-#define BLE_LL_OVERHEAD_LEN     \
-    (BLE_LL_CRC_LEN + BLE_LL_ACC_ADDR_LEN + BLE_LL_PREAMBLE_LEN)
-#define BLE_LL_PDU_HDR_LEN      (2)
-#define BLE_LL_MIN_PDU_LEN      (BLE_LL_PDU_HDR_LEN)
-#define BLE_LL_MAX_PDU_LEN      (257)
-#define BLE_LL_CRCINIT_ADV      (0x555555)
-
-/* Access address for advertising channels */
-#define BLE_ACCESS_ADDR_ADV             (0x8E89BED6)
-
-/*
- * Data Channel format
- * 
- *  -> Header (2 bytes.
- *      -> LSB contains llid, nesn, sn and md
- *      -> MSB contains length (8 bits)
- *  -> Payload (0 to 251)
- *  -> MIC (0 or 4 bytes)
- */
-#define BLE_LL_DATA_HDR_LLID_MASK       (0x03)
-#define BLE_LL_DATA_HDR_NESN_MASK       (0x04)
-#define BLE_LL_DATA_HDR_SN_MASK         (0x08)
-#define BLE_LL_DATA_HDR_MD_MASK         (0x10)
-#define BLE_LL_DATA_HDR_RSRVD_MASK      (0xE0)
-
-/* LLID definitions */
-#define BLE_LL_LLID_RSRVD               (0)
-#define BLE_LL_LLID_DATA_FRAG           (1)
-#define BLE_LL_LLID_DATA_START          (2)
-#define BLE_LL_LLID_CTRL                (3)
-
-/* 
- * LL CTRL PDU format
- *  -> Opcode (1 byte)
- *  -> Ctrl data (0 - 26 bytes)
- */
-#define BLE_LL_CTRL_CONN_UPDATE_REQ     (0)
-#define BLE_LL_CTRL_CHANNEL_MAP_REQ     (1)
-#define BLE_LL_CTRL_TERMINATE_IND       (2)
-#define BLE_LL_CTRL_ENC_REQ             (3)
-#define BLE_LL_CTRL_ENC_RSP             (4)
-#define BLE_LL_CTRL_START_ENC_REQ       (5)
-#define BLE_LL_CTRL_START_ENC_RSP       (6)
-#define BLE_LL_CTRL_UNKNOWN_RSP         (7)
-#define BLE_LL_CTRL_FEATURE_REQ         (8)
-#define BLE_LL_CTRL_FEATURE_RSP         (9)
-#define BLE_LL_CTRL_PAUSE_ENC_REQ       (10)
-#define BLE_LL_CTRL_PAUSE_ENC_RSP       (11)
-#define BLE_LL_CTRL_VERSION_IND         (12)
-#define BLE_LL_CTRL_REJECT_IND          (13)
-#define BLE_LL_CTRL_SLAVE_FEATURE_REQ   (14)
-#define BLE_LL_CTRL_CONN_PARM_REQ       (15)
-#define BLE_LL_CTRL_CONN_PARM_RSP       (16)
-#define BLE_LL_CTRL_REJECT_IND_EXT      (17)
-#define BLE_LL_CTRL_PING_REQ            (18)
-#define BLE_LL_CTRL_PING_RSP            (19)
-#define BLE_LL_CTRL_LENGTH_REQ          (20)
-#define BLE_LL_CTRL_LENGTH_RSP          (21)
-
-/* LL control connection update request */
-struct ll_conn_upd_req
-{
-    uint8_t winsize;
-    uint16_t winoffset;
-    uint16_t interval;
-    uint16_t latency;
-    uint16_t timeout;
-    uint16_t instant;
-};
-
-#define BLE_LL_CTRL_CONN_UPD_REQ_LEN        (11)
-
-/* LL control channel map request */
-struct ll_chan_map_req
-{
-    uint8_t chmap[5];
-    uint16_t instant;
-};
-
-#define BLE_LL_CTRL_CHAN_MAP_LEN            (7)
-
-/* 
- * LL control terminate ind
- *  -> error code (1 byte)                         
- */
-#define BLE_LL_CTRL_TERMINATE_IND_LEN      (1)
-
-/* LL control enc req */
-struct ll_enc_req
-{
-    uint8_t rand[8];
-    uint16_t ediv;
-    uint8_t skdm[8];
-    uint32_t ivm;
-};
-
-#define BLE_LL_CTRL_ENC_REQ_LEN             (22)
-
-/* LL control enc rsp */
-struct ll_enc_rsp
-{
-    uint8_t skds[8];
-    uint32_t ivs;
-};
-
-#define BLE_LL_CTRL_ENC_RSP_LEN             (12)
-
-/* LL control start enc req and start enc rsp have no data */ 
-#define BLE_LL_CTRL_START_ENC_LEN           (0)
-
-/* 
- * LL control unknown response
- *  -> 1 byte which contains the unknown or un-supported opcode.
- */
-#define BLE_LL_CTRL_UNK_RSP_LEN             (1)
-
-/*
- * LL control feature req and LL control feature rsp 
- *  -> 8 bytes of data containing features supported by device.
- */
-#define BLE_LL_CTRL_FEATURE_LEN             (8)
-
-/* LL control pause enc req and pause enc rsp have no data */
-#define BLE_LL_CTRL_PAUSE_ENC_LEN           (0)
-
-/* 
- * LL control version ind 
- *  -> version (1 byte):
- *      Contains the version number of the bluetooth controller specification.
- *  -> comp_id (2 bytes)
- *      Contains the company identifier of the manufacturer of the controller.
- *  -> sub_ver_num: Contains a unique value for implementation or revision of
- *      the bluetooth controller.
- */
-struct ll_version_ind
-{
-    uint8_t ble_ctrlr_ver;
-    uint16_t company_id;
-    uint16_t sub_ver_num;
-};
-
-#define BLE_LL_CTRL_VERSION_IND_LEN         (5)
-
-/* 
- * LL control reject ind
- *  -> error code (1 byte): contains reason why request was rejected.
- */
-#define BLE_LL_CTRL_REJ_IND_LEN             (1)
-
-/*
- * LL control slave feature req
- *  -> 8 bytes of data containing features supported by device.
- */
-#define BLE_LL_CTRL_SLAVE_FEATURE_REQ_LEN   (8)
-
-/* LL control connection param req and connection param rsp */
-struct ll_conn_params
-{
-    uint16_t interval_min;
-    uint16_t interval_max;
-    uint16_t latency;
-    uint16_t timeout;
-    uint16_t pref_periodicity;
-    uint16_t ref_conn_event_cnt;
-    uint16_t offset0;
-    uint16_t offset1;
-    uint16_t offset2;
-    uint16_t offset3;
-    uint16_t offset4;
-    uint16_t offset5;
-};
-
-#define BLE_LL_CTRL_CONN_PARAMS_LEN     (24)
-
-/* LL control reject ind ext */
-struct ll_reject_ind_ext
-{
-    uint8_t reject_opcode;
-    uint8_t err_code;
-};
-
-#define BLE_LL_CTRL_REJECT_IND_EXT_LEN  (2)
-
-/* LL control ping req and ping rsp (contain no data) */
-#define BLE_LL_CTRL_PING_LEN            (0)
-
-/* 
- * LL control length req and length rsp
- *  -> max_rx_bytes (2 bytes): defines connMaxRxOctets. Range 27 to 251
- *  -> max_rx_time (2 bytes): defines connMaxRxTime. Range 328 to 2120 usecs.
- *  -> max_tx_bytes (2 bytes): defines connMaxTxOctets. Range 27 to 251
- *  -> max_tx_time (2 bytes): defines connMaxTxTime. Range 328 to 2120 usecs.
- */
-struct ll_len_req
-{
-    uint16_t max_rx_bytes;
-    uint16_t max_rx_time;
-    uint16_t max_tx_bytes;
-    uint16_t max_tx_time;
-};
-
-#define BLE_LL_CTRL_LENGTH_REQ_LEN      (8)
-
-/*
- * CONNECT_REQ
- *      -> InitA        (6 bytes)
- *      -> AdvA         (6 bytes)
- *      -> LLData       (22 bytes)
- *          -> Access address (4 bytes)
- *          -> CRC init (3 bytes)
- *          -> WinSize (1 byte)
- *          -> WinOffset (2 bytes)
- *          -> Interval (2 bytes)
- *          -> Latency (2 bytes)
- *          -> Timeout (2 bytes)
- *          -> Channel Map (5 bytes)
- *          -> Hop Increment (5 bits)
- *          -> SCA (3 bits)
- * 
- *  InitA is the initiators public (TxAdd=0) or random (TxAdd=1) address.
- *  AdvaA is the advertisers public (RxAdd=0) or random (RxAdd=1) address.
- *  LLData contains connection request data.
- *      aa: Link Layer's access address
- *      crc_init: The CRC initialization value used for CRC calculation.
- *      winsize: The transmit window size = winsize * 1.25 msecs
- *      winoffset: The transmit window offset =  winoffset * 1.25 msecs
- *      interval: The connection interval = interval * 1.25 msecs.
- *      latency: connection slave latency = latency
- *      timeout: Connection supervision timeout = timeout * 10 msecs.
- *      chanmap: contains channel mapping indicating used and unused data
- *               channels. Only bits that are 1 are usable. LSB is channel 0.
- *      hop_inc: Hop increment used for frequency hopping. Random value in
- *               range of 5 to 16.
- */
-#define BLE_CONNECT_REQ_LEN             (34)
-
-struct ble_conn_req_data
-{
-    uint32_t    aa;
-    uint8_t     crc_init[3];
-    uint8_t     winsize;
-    uint16_t    winoffset;
-    uint16_t    interval;
-    uint16_t    latency;
-    uint16_t    timeout;
-    uint8_t     chanmap[5];
-    uint8_t     hop_inc;
-    uint8_t     master_sca;
-};
-
-#define BLE_CONN_REQ_HOP_MASK           (0x1F)
-#define BLE_CONN_REQ_SCA_MASK           (0xE0)
-
-#define BLE_MASTER_SCA_251_500_PPM      (0)
-#define BLE_MASTER_SCA_151_250_PPM      (1)
-#define BLE_MASTER_SCA_101_150_PPM      (2)
-#define BLE_MASTER_SCA_76_100_PPM       (3)
-#define BLE_MASTER_SCA_51_75_PPM        (4)
-#define BLE_MASTER_SCA_31_50_PPM        (5)
-#define BLE_MASTER_SCA_21_30_PPM        (6)
-#define BLE_MASTER_SCA_0_20_PPM         (7)
-
-/*
- * Initiator filter policy 
- * 
- * Determines how the initiator's Link Layer processes advertisements.
- * 
- *  LIST: process connectable advertisements only from devices in white list.
- *  SINGLE: do not use white list; process connectable advertisements from
- *      a single specific device specified by the host.
- */
-enum ll_init_filt_policy
-{
-    BLE_LL_INIT_FILT_LIST = 0,
-    BLE_LL_INIT_FILT_SINGLE,
-};
-
-/*--- External API ---*/
-/* Initialize the Link Layer */
-int ll_init(void);
-
-/* 'Boolean' function returning true if address is a valid random address */
-int ble_ll_is_valid_random_addr(uint8_t *addr);
-
-/* Calculate the amount of time a pdu of 'len' bytes will take to transmit */
-uint16_t ll_pdu_tx_time_get(uint16_t len);
-
-/* Boolean returning true if device is on whitelist */
-int ble_ll_is_on_whitelist(uint8_t *addr, int addr_type);
-
-/* Is this address a resolvable private address? */
-int ble_ll_is_resolvable_priv_addr(uint8_t *addr);
-
-/* Is 'addr' our device address? 'addr_type' is public (0) or random (!=0) */
-int ble_ll_is_our_devaddr(uint8_t *addr, int addr_type);
-
-/*--- PHY interfaces ---*/
-/* Called by the PHY when a packet has started */
-int ll_rx_start(struct os_mbuf *rxpdu);
-
-/* Called by the PHY when a packet reception ends */
-int ll_rx_end(struct os_mbuf *rxpdu, uint8_t crcok);
-
-/*--- Controller API ---*/
-/* Set the link layer state */
-void ble_ll_state_set(int ll_state);
-
-/* Send an event to LL task */
-void ble_ll_event_send(struct os_event *ev);
-
-/* Set random address */
-int ble_ll_set_random_addr(uint8_t *addr);
-
-#endif /* H_LL_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/include/controller/ll_adv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ll_adv.h b/net/nimble/controller/include/controller/ll_adv.h
deleted file mode 100644
index 0f0a8b7..0000000
--- a/net/nimble/controller/include/controller/ll_adv.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * Copyright (c) 2015 Stack Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef H_LL_ADV_
-#define H_LL_ADV_
-
-/* 
- * ADV event timing
- *      T_advEvent = advInterval + advDelay
- * 
- *      advInterval: increments of 625 usecs
- *      advDelay: RAND[0, 10] msecs
- * 
- */
-#define BLE_LL_ADV_ITVL                 (625)           /* usecs */
-#define BLE_LL_ADV_ITVL_MIN             (32)            /* units */
-#define BLE_LL_ADV_ITVL_MAX             (16384)         /* units */
-#define BLE_LL_ADV_ITVL_MS_MIN          (20)            /* msecs */
-#define BLE_LL_ADV_ITVL_MS_MAX          (10240)         /* msecs */
-#define BLE_LL_ADV_ITVL_SCAN_MIN        (160)           /* units */
-#define BLE_LL_ADV_ITVL_SCAN_MS_MIN     (100)           /* msecs */
-#define BLE_LL_ADV_ITVL_NONCONN_MIN     (160)           /* units */
-#define BLE_LL_ADV_ITVL_NONCONN_MS_MIN  (100)           /* msecs */
-#define BLE_LL_ADV_DELAY_MS_MIN         (0)             /* msecs */
-#define BLE_LL_ADV_DELAY_MS_MAX         (10)            /* msecs */
-#define BLE_LL_ADV_PDU_ITVL_LD_MS_MAX   (10)            /* msecs */
-#define BLE_LL_ADV_PDU_ITVL_HD_MS_MAX   (3750)          /* usecs */
-#define BLE_LL_ADV_STATE_HD_MAX         (1280)          /* msecs */
-
-/* 
- * Advertising PDU format:
- * -> 2 byte header
- *      -> LSB contains pdu type, txadd and rxadd bits.
- *      -> MSB contains length (6 bits).
- * -> Payload
- */
-#define BLE_ADV_PDU_HDR_TYPE_MASK           (0x0F)
-#define BLE_ADV_PDU_HDR_TXADD_MASK          (0x40)
-#define BLE_ADV_PDU_HDR_RXADD_MASK          (0x80)
-#define BLE_ADV_PDU_HDR_LEN_MASK            (0x3F)
-
-/* Advertising channel PDU types */
-#define BLE_ADV_PDU_TYPE_ADV_IND            (0)
-#define BLE_ADV_PDU_TYPE_ADV_DIRECT_IND     (1)
-#define BLE_ADV_PDU_TYPE_ADV_NONCONN_IND    (2)
-#define BLE_ADV_PDU_TYPE_SCAN_REQ           (3)
-#define BLE_ADV_PDU_TYPE_SCAN_RSP           (4)
-#define BLE_ADV_PDU_TYPE_CONNECT_REQ        (5)
-#define BLE_ADV_PDU_TYPE_ADV_SCAN_IND       (6)
-
-/* 
- * TxAdd and RxAdd bit definitions. A 0 is a public address; a 1 is a
- * random address.
- */
-#define BLE_ADV_PDU_HDR_TXADD_RAND          (0x40)
-#define BLE_ADV_PDU_HDR_RXADD_RAND          (0x80)
-
-/* Maximum advertisement data length */
-#define BLE_ADV_DATA_MAX_LEN            (31)
-
-/* 
- * ADV_IND
- *      -> AdvA     (6 bytes)
- *      -> AdvData  (0 - 31 bytes)
- * 
- *  The advertising address (AdvA) is a public address (TxAdd=0) or random 
- *  address (TxAdd = 1)
- */
-#define BLE_ADV_IND_MIN_LEN             (6)
-#define BLE_ADV_IND_MAX_LEN             (37)
-
-/* 
- * ADV_DIRECT_IND
- *      -> AdvA     (6 bytes)
- *      -> InitA    (6 bytes)
- * 
- *  AdvA is the advertisers public address (TxAdd=0) or random address
- *  (TxAdd = 1).
- * 
- *  InitA is the initiators public or random address. This is the address
- *  to which this packet is addressed.
- * 
- */
-#define BLE_ADV_DIRECT_IND_LEN          (12)
-
-/*
- * ADV_NONCONN_IND 
- *      -> AdvA     (6 bytes)
- *      -> AdvData  (0 - 31 bytes)
- * 
- *  The advertising address (AdvA) is a public address (TxAdd=0) or random 
- *  address (TxAdd = 1)
- * 
- */
-#define BLE_ADV_NONCONN_IND_MIN_LEN     (6)
-#define BLE_ADV_NONCONN_IND_MAX_LEN     (37)
-
-/*
- * ADV_SCAN_IND
- *      -> AdvA     (6 bytes)
- *      -> AdvData  (0 - 31 bytes)
- * 
- *  The advertising address (AdvA) is a public address (TxAdd=0) or random 
- *  address (TxAdd = 1)
- * 
- */
-#define BLE_ADV_SCAN_IND_MIN_LEN        (6)
-#define BLE_ADV_SCAN_IND_MAX_LEN        (37)
-
-/*---- HCI ----*/
-/* Start an advertiser */
-int ll_adv_start_req(uint8_t adv_chanmask, uint8_t adv_type, uint8_t *init_addr,
-                     uint16_t adv_itvl, void *handle);
-
-/* Start or stop advertising */
-int ll_adv_set_enable(uint8_t *cmd);
-
-/* Set advertising data */
-int ll_adv_set_adv_data(uint8_t *cmd, uint8_t len);
-
-/* Set scan response data */
-int ll_adv_set_scan_rsp_data(uint8_t *cmd, uint8_t len);
-
-/* Set advertising parameters */
-int ll_adv_set_adv_params(uint8_t *cmd);
-
-/* Read advertising channel power */
-int ll_adv_read_txpwr(uint8_t *rspbuf);
-
-/*---- API used by BLE LL ----*/
-/* Called when advertising tx done event posted to LL task */
-void ll_adv_tx_done_proc(void *arg);
-
-/* Called to initialize advertising functionality. */
-void ll_adv_init(void);
-
-/* Called when a scan request has been received. */
-int ble_ll_adv_rx_scan_req(uint8_t *rxbuf);
-
-#endif /* H_LL_ADV_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/include/controller/ll_sched.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ll_sched.h b/net/nimble/controller/include/controller/ll_sched.h
deleted file mode 100644
index 22be5f5..0000000
--- a/net/nimble/controller/include/controller/ll_sched.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright (c) 2015 Stack Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef H_LL_SCHED_
-#define H_LL_SCHED_
-
-/* BLE scheduler errors */
-#define BLE_LL_SCHED_ERR_OVERLAP    (1)
-
-/* Types of scheduler events */
-#define BLE_LL_SCHED_TYPE_ADV       (0)
-#define BLE_LL_SCHED_TYPE_SCAN      (1)
-#define BLE_LL_SCHED_TYPE_TX        (2)
-#define BLE_LL_SCHED_TYPE_RX        (3)
-
-/* Return values for schedule callback. */
-#define BLE_LL_SCHED_STATE_RUNNING  (0)
-#define BLE_LL_SCHED_STATE_DONE     (1)
-
-/* Callback function */
-struct ll_sched_item;
-typedef int (*sched_cb_func)(struct ll_sched_item *sch);
-
-struct ll_sched_item
-{
-    int             sched_type;
-    uint32_t        start_time;
-    uint32_t        end_time;
-    uint32_t        next_wakeup;
-    void            *cb_arg;
-    sched_cb_func   sched_cb;
-    TAILQ_ENTRY(ll_sched_item) link;
-};
-
-/* Add an item to the schedule */
-int ll_sched_add(struct ll_sched_item *sch);
-
-/* Remove item(s) from schedule */
-int ll_sched_rmv(uint8_t sched_type);
-
-/* Initialize the scheduler */
-int ll_sched_init(void);
-
-/* Get a schedule item */
-struct ll_sched_item *ll_sched_get_item(void);
-
-/* Free a schedule item */
-void ll_sched_free_item(struct ll_sched_item *sch);
-
-#endif /* H_LL_SCHED_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ble_ll.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
new file mode 100644
index 0000000..2c50a09
--- /dev/null
+++ b/net/nimble/controller/src/ble_ll.c
@@ -0,0 +1,655 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include "os/os.h"
+#include "nimble/ble.h"
+#include "controller/phy.h"
+#include "controller/ble_ll.h"
+#include "controller/ble_ll_adv.h"
+#include "controller/ble_ll_sched.h"
+#include "controller/ll_scan.h"
+#include "controller/ll_hci.h"
+
+/* XXX: use the sanity task! */
+
+/* Connection related define */
+#define BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS  (27)
+#define BLE_LL_CONN_INIT_MAX_REMOTE_TIME    (238)
+
+/* The global BLE LL data object */
+struct ble_ll_obj g_ble_ll_data;
+
+/* Global link layer statistics */
+struct ble_ll_stats g_ble_ll_stats;
+
+/* The BLE LL task data structure */
+#define BLE_LL_TASK_PRI     (OS_TASK_PRI_HIGHEST)
+#define BLE_LL_STACK_SIZE   (128)
+struct os_task g_ble_ll_task;
+os_stack_t g_ble_ll_stack[BLE_LL_STACK_SIZE];
+
+/* XXX: this is just temporary; used to calculate the channel index */
+struct ble_ll_sm_connection
+{
+    /* Data channel index for connection */
+    uint8_t unmapped_chan;
+    uint8_t last_unmapped_chan;
+    uint8_t num_used_channels;
+
+    /* Flow control */
+    uint8_t tx_seq;
+    uint8_t next_exp_seq;
+
+    /* Parameters kept by the link-layer per connection */
+    uint8_t max_tx_octets;
+    uint8_t max_rx_octets;
+    uint8_t max_tx_time;
+    uint8_t max_rx_time;
+    uint8_t remote_max_tx_octets;
+    uint8_t remote_max_rx_octets;
+    uint8_t remote_max_tx_time;
+    uint8_t remote_max_rx_time;
+    uint8_t effective_max_tx_octets;
+    uint8_t effective_max_rx_octets;
+    uint8_t effective_max_tx_time;
+    uint8_t effective_max_rx_time;
+
+    /* The connection request data */
+    struct ble_conn_req_data req_data; 
+};
+
+uint8_t
+ble_ll_next_data_channel(struct ble_ll_sm_connection *cnxn)
+{
+    int     i;
+    int     j;
+    uint8_t curchan;
+    uint8_t remap_index;
+    uint8_t bitpos;
+    uint8_t cntr;
+    uint8_t mask;
+    uint8_t usable_chans;
+
+    /* Get next un mapped channel */
+    curchan = (cnxn->last_unmapped_chan + cnxn->req_data.hop_inc) % 
+              BLE_PHY_NUM_DATA_CHANS;
+
+    /* Set the current unmapped channel */
+    cnxn->unmapped_chan = curchan;
+
+    /* Is this a valid channel? */
+    bitpos = 1 << (curchan & 0x07);
+    if ((cnxn->req_data.chanmap[curchan >> 3] & bitpos) == 0) {
+
+        /* Calculate remap index */
+        remap_index = curchan % cnxn->num_used_channels;
+
+        /* Iterate through channel map to find this channel */
+        cntr = 0;
+        for (i = 0; i < 5; i++) {
+            usable_chans = cnxn->req_data.chanmap[i];
+            if (usable_chans != 0) {
+                mask = 0x01;
+                for (j = 0; j < 8; j++) {
+                    if (usable_chans & mask) {
+                        if (cntr == remap_index) {
+                            return cntr;
+                        }
+                        ++cntr;
+                    }
+                    mask <<= 1;
+                }
+            }
+        }
+    }
+
+    return curchan;
+}
+
+/* Called when a connection gets initialized */
+int
+ble_init_conn_sm(struct ble_ll_sm_connection *cnxn)
+{
+    cnxn->max_tx_time = g_ble_ll_data.ll_params.conn_init_max_tx_time;
+    cnxn->max_rx_time = g_ble_ll_data.ll_params.supp_max_rx_time;
+    cnxn->max_tx_octets = g_ble_ll_data.ll_params.conn_init_max_tx_octets;
+    cnxn->max_rx_octets = g_ble_ll_data.ll_params.supp_max_rx_octets;
+    cnxn->remote_max_rx_octets = BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS;
+    cnxn->remote_max_tx_octets = BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS;
+    cnxn->remote_max_rx_time = BLE_LL_CONN_INIT_MAX_REMOTE_TIME;
+    cnxn->remote_max_tx_time = BLE_LL_CONN_INIT_MAX_REMOTE_TIME;
+
+    return 0;
+}
+
+static void
+ble_ll_count_rx_pkts(uint8_t pdu_type)
+{
+    /* Count received packet types  */
+    switch (pdu_type) {
+    case BLE_ADV_PDU_TYPE_ADV_IND:
+        ++g_ble_ll_stats.rx_adv_ind;
+        break;
+    case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
+        /* XXX: Do I want to count these if they are not for me? */
+        ++g_ble_ll_stats.rx_adv_direct_ind;
+        break;
+    case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND:
+        ++g_ble_ll_stats.rx_adv_nonconn_ind;
+        break;
+    case BLE_ADV_PDU_TYPE_SCAN_REQ:
+        /* XXX: Do I want to count these if they are not for me? */
+        ++g_ble_ll_stats.rx_scan_reqs;
+        break;
+    case BLE_ADV_PDU_TYPE_SCAN_RSP:
+        ++g_ble_ll_stats.rx_scan_rsps;
+        break;
+    case BLE_ADV_PDU_TYPE_CONNECT_REQ:
+        /* XXX: Do I want to count these if they are not for me? */
+        ++g_ble_ll_stats.rx_connect_reqs;
+        break;
+    case BLE_ADV_PDU_TYPE_ADV_SCAN_IND:
+        ++g_ble_ll_stats.rx_scan_ind;
+        break;
+    default:
+        ++g_ble_ll_stats.rx_unk_pdu;
+        break;
+    }
+}
+
+
+int
+ble_ll_is_on_whitelist(uint8_t *addr, int addr_type)
+{
+    /* XXX: implement this */
+    return 1;
+}
+
+int
+ble_ll_is_resolvable_priv_addr(uint8_t *addr)
+{
+    /* XXX: implement this */
+    return 0;
+}
+
+/* Checks to see that the device is a valid random address */
+int
+ble_ll_is_valid_random_addr(uint8_t *addr)
+{
+    int i;
+    int rc;
+    uint16_t sum;
+    uint8_t addr_type;
+
+    /* Make sure all bits are neither one nor zero */
+    sum = 0;
+    for (i = 0; i < (BLE_DEV_ADDR_LEN -1); ++i) {
+        sum += addr[i];
+    }
+    sum += addr[5] & 0x3f;
+
+    if ((sum == 0) || (sum == ((5*255) + 0x3f))) {
+        return 0;
+    }
+
+    /* Get the upper two bits of the address */
+    rc = 1;
+    addr_type = addr[5] & 0xc0;
+    if (addr_type == 0xc0) {
+        /* Static random address. No other checks needed */
+    } else if (addr_type == 0x40) {
+        /* Resolvable */
+        sum = addr[3] + addr[4] + (addr[5] & 0x3f);
+        if ((sum == 0) || (sum == (255 + 255 + 0x3f))) {
+            rc = 0;
+        }
+    } else if (addr_type == 0) {
+        /* non-resolvable. Cant be equal to public */
+        if (!memcmp(g_dev_addr, addr, BLE_DEV_ADDR_LEN)) {
+            rc = 0;
+        }
+    } else {
+        /* Invalid upper two bits */
+        rc = 0;
+    }
+
+    return rc;
+}
+
+/**
+ * Called from the HCI command parser when the set random address command 
+ * is received. 
+ *  
+ * Context: Link Layer task (HCI command parser) 
+ * 
+ * @param addr Pointer to address
+ * 
+ * @return int 0: success
+ */
+int
+ble_ll_set_random_addr(uint8_t *addr)
+{
+    int rc;
+
+    rc = BLE_ERR_INV_HCI_CMD_PARMS;
+    if (ble_ll_is_valid_random_addr(addr)) {
+        memcpy(g_random_addr, addr, BLE_DEV_ADDR_LEN);
+        rc = BLE_ERR_SUCCESS;
+    }
+
+    return rc;
+}
+
+int
+ble_ll_is_our_devaddr(uint8_t *addr, int addr_type)
+{
+    int rc;
+    uint8_t *our_addr;
+
+    rc = 0;
+    if (addr_type) {
+        our_addr = g_dev_addr;
+    } else {
+        our_addr = g_random_addr;
+    }
+
+    rc = 0;
+    if (!memcmp(our_addr, g_random_addr, BLE_DEV_ADDR_LEN)) {
+        rc = 1;
+    }
+
+    return rc;
+}
+
+/**
+ * ll pdu tx time get 
+ *  
+ * Returns the number of usecs it will take to transmit a PDU of length 'len' 
+ * bytes. Each byte takes 8 usecs. 
+ * 
+ * @param len The number of PDU bytes to transmit
+ * 
+ * @return uint16_t The number of usecs it will take to transmit a PDU of 
+ *                  length 'len' bytes. 
+ */
+uint16_t
+ble_ll_pdu_tx_time_get(uint16_t len)
+{
+    len += BLE_LL_OVERHEAD_LEN;
+    len = len << 3;
+    return len;
+}
+
+/**
+ * ll rx pkt in proc
+ *  
+ * Process received packet from PHY 
+ *  
+ * Callers: LL task. 
+ *  
+ */
+void
+ble_ll_rx_pkt_in_proc(void)
+{
+    os_sr_t sr;
+    uint8_t pdu_type;
+    uint8_t *rxbuf;
+    struct os_mbuf_pkthdr *pkthdr;
+    struct ble_mbuf_hdr *ble_hdr;
+    struct os_mbuf *m;
+
+    /* Drain all packets off the queue */
+    while (STAILQ_FIRST(&g_ble_ll_data.ll_rx_pkt_q)) {
+        /* Get mbuf pointer from packet header pointer */
+        pkthdr = STAILQ_FIRST(&g_ble_ll_data.ll_rx_pkt_q);
+        m = (struct os_mbuf *)((uint8_t *)pkthdr - sizeof(struct os_mbuf));
+
+        /* Remove from queue */
+        OS_ENTER_CRITICAL(sr);
+        STAILQ_REMOVE_HEAD(&g_ble_ll_data.ll_rx_pkt_q, omp_next);
+        OS_EXIT_CRITICAL(sr);
+
+        /* XXX: need to check if this is an adv channel or data channel */
+
+        /* Count statistics */
+        rxbuf = m->om_data;
+        pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
+        ble_hdr = BLE_MBUF_HDR_PTR(m); 
+        if (ble_hdr->crcok) {
+            /* The total bytes count the PDU header and PDU payload */
+            g_ble_ll_stats.rx_bytes += pkthdr->omp_len;
+            ++g_ble_ll_stats.rx_crc_ok;
+            ble_ll_count_rx_pkts(pdu_type);
+        } else {
+            ++g_ble_ll_stats.rx_crc_fail;
+        }
+
+        /* 
+         * XXX: The reason I dont bail earlier on bad CRC is that
+         * there may be some connection stuff I need to do with a packet
+         * that has failed the CRC.
+         */ 
+
+        /* Process the PDU */
+        switch (g_ble_ll_data.ll_state) {
+        case BLE_LL_STATE_ADV:
+            /* XXX: implement this */
+            break;
+        case BLE_LL_STATE_SCANNING:
+            if (ble_hdr->crcok) {
+                ble_ll_scan_rx_pdu_proc(pdu_type, rxbuf, ble_hdr->rssi);
+            }
+
+            /* We need to re-enable the PHY if we are in idle state */
+            if (ble_phy_state_get() == BLE_PHY_STATE_IDLE) {
+                /* XXX: If this returns error, we will need to attempt to
+                   re-start scanning! */
+                ble_phy_rx();
+            }
+            break;
+        default:
+            /* XXX: implement */
+            assert(0);
+            break;
+        }
+
+        /* XXX: Free the mbuf for now */
+        os_mbuf_free(&g_mbuf_pool, m);
+    }
+}
+
+/**
+ * Called to put a packet on the Link Layer receive packet queue. 
+ * 
+ * @param rxpdu Pointer to received PDU
+ */
+void
+ble_ll_rx_pdu_in(struct os_mbuf *rxpdu)
+{
+    struct os_mbuf_pkthdr *pkthdr;
+
+    pkthdr = OS_MBUF_PKTHDR(rxpdu);
+    STAILQ_INSERT_TAIL(&g_ble_ll_data.ll_rx_pkt_q, pkthdr, omp_next);
+    os_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_rx_pkt_ev);
+}
+
+/** 
+ * Called upon start of received PDU 
+ * 
+ * @param rxpdu 
+ * 
+ * @return int 
+ *   < 0: A frame we dont want to receive.
+ *   = 0: Continue to receive frame. Dont go from rx to tx
+ *   > 1: Continue to receive frame and go from rx to idle when done
+ */
+int
+ble_ll_rx_start(struct os_mbuf *rxpdu)
+{
+    int rc;
+    uint8_t pdu_type;
+    uint8_t *rxbuf;
+
+    /* XXX: need to check if this is an adv channel or data channel */
+    rxbuf = rxpdu->om_data;
+    pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
+
+    switch (g_ble_ll_data.ll_state) {
+    case BLE_LL_STATE_ADV:
+        /* If we get a scan request we must tell the phy to go from rx to tx */
+        if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
+            rc = 1;
+        } else if (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_REQ) {
+            rc = 0;
+        } else {
+            /* This is a frame we dont want. Just abort it */
+            rc = -1;
+        }
+        break;
+    case BLE_LL_STATE_SCANNING:
+        rc = ble_ll_scan_rx_pdu_start(pdu_type, rxpdu);
+        break;
+    default:
+        /* XXX: should we really assert here? What to do... */
+        rc = -1;
+        assert(0);
+        break;
+    }
+
+    return rc;
+}
+
+/**
+ * Called by the PHY when a receive packet has ended. 
+ *  
+ * NOTE: Called from interrupt context!
+ * 
+ * @param rxbuf 
+ * 
+ * @return int 
+ *       < 0: Disable the phy after reception.
+ *      == 0: Success. Do not disable the PHY.
+ *       > 0: Do not disable PHY as that has already been done.
+ */
+int
+ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t crcok)
+{
+    int rc;
+    int badpkt;
+    uint8_t pdu_type;
+    uint8_t len;
+    uint16_t mblen;
+    uint8_t *rxbuf;
+
+    /* Set the rx buffer pointer to the start of the received data */
+    rxbuf = rxpdu->om_data;
+
+    /* XXX: need to check if this is an adv channel or data channel */
+    pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
+    len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
+
+    /* XXX: Should I do this at LL task context? */
+    /* If the CRC checks, make sure lengths check! */
+    badpkt = 0;
+    if (crcok) {
+        switch (pdu_type) {
+        case BLE_ADV_PDU_TYPE_SCAN_REQ:
+        case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
+            if (len != BLE_SCAN_REQ_LEN) {
+                badpkt = 1;
+            }
+            break;
+        case BLE_ADV_PDU_TYPE_SCAN_RSP:
+        case BLE_ADV_PDU_TYPE_ADV_IND:
+        case BLE_ADV_PDU_TYPE_ADV_SCAN_IND:
+        case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND:
+            if ((len < BLE_DEV_ADDR_LEN) || (len > BLE_ADV_SCAN_IND_MAX_LEN)) {
+                badpkt = 1;
+            }
+            break;
+        case BLE_ADV_PDU_TYPE_CONNECT_REQ:
+            if (len != BLE_CONNECT_REQ_LEN) {
+                badpkt = 1;
+            }
+            break;
+        default:
+            badpkt = 1;
+            break;
+        }
+    }
+
+    /* If this is a malformed packet, just kill it here */
+    if (badpkt) {
+        ++g_ble_ll_stats.rx_malformed_pkts;
+        os_mbuf_free(&g_mbuf_pool, rxpdu);
+        return -1;
+    }
+
+    /* Setup the mbuf */
+    mblen = len + BLE_LL_PDU_HDR_LEN;
+    OS_MBUF_PKTHDR(rxpdu)->omp_len = mblen;
+    rxpdu->om_len = mblen;
+
+    rc = -1;
+    switch (g_ble_ll_data.ll_state) {
+    case BLE_LL_STATE_ADV:
+        /* If we get a scan request*/
+        if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
+            /* Just bail if CRC is not good */
+            if (crcok) {
+                rc = ble_ll_adv_rx_scan_req(rxbuf);
+                if (rc) {
+                    /* XXX: One thing left to reconcile here. We have
+                     * the advertisement schedule element still running.
+                     * How to deal with the end of the advertising event?
+                     * Need to figure that out.
+                     */
+                }
+            }
+        } else {
+            if (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_REQ) {
+                rc = 0;
+                /* XXX: deal with this */
+            }
+        }
+        break;
+    case BLE_LL_STATE_SCANNING:
+        if (crcok) {
+            /* 
+             * NOTE: If this returns a positive number there was an error but
+             * there is no need to disable the PHY on return as that was
+             * done already.
+             */
+            rc = ble_ll_scan_rx_pdu_end(rxbuf);
+        }
+        break;
+    default:
+        assert(0);
+        break;
+    }
+
+    /* Hand packet up to higher layer */
+    ble_ll_rx_pdu_in(rxpdu);
+
+    return rc;
+}
+
+void
+ble_ll_task(void *arg)
+{
+    struct os_event *ev;
+
+    /* Init ble phy */
+    ble_phy_init();
+
+    /* Set output power to 1mW (0 dBm) */
+    ble_phy_txpwr_set(0);
+
+    /* Wait for an event */
+    while (1) {
+        ev = os_eventq_get(&g_ble_ll_data.ll_evq);
+        switch (ev->ev_type) {
+        case OS_EVENT_T_TIMER:
+            break;
+        case BLE_LL_EVENT_HCI_CMD:
+            /* Process HCI command */
+            ble_ll_hci_cmd_proc(ev);
+            break;
+        case BLE_LL_EVENT_ADV_TXDONE:
+            ble_ll_adv_tx_done_proc(ev->ev_arg);
+            break;
+        case BLE_LL_EVENT_SCAN_WIN_END:
+            ble_ll_scan_win_end_proc(ev->ev_arg);
+            break;
+        case BLE_LL_EVENT_RX_PKT_IN:
+            ble_ll_rx_pkt_in_proc();
+            break;
+        default:
+            assert(0);
+            break;
+        }
+
+        /* XXX: we can possibly take any finished schedule items and
+           free them here. Have a queue for them. */
+    }
+}
+
+/**
+ * ble ll state set
+ *  
+ * Called to set the current link layer state. 
+ *  
+ * Context: Interrupt and Link Layer task
+ * 
+ * @param ll_state 
+ */
+void
+ble_ll_state_set(int ll_state)
+{
+    g_ble_ll_data.ll_state = ll_state;
+}
+
+/**
+ * ble ll event send
+ *  
+ * Send an event to the Link Layer task 
+ * 
+ * @param ev Event to add to the Link Layer event queue.
+ */
+void
+ble_ll_event_send(struct os_event *ev)
+{
+    os_eventq_put(&g_ble_ll_data.ll_evq, ev);
+}
+
+/**
+ * Initialize the Link Layer. Should be called only once 
+ * 
+ * @return int 
+ */
+int
+ble_ll_init(void)
+{
+    /* Initialize the receive queue */
+    STAILQ_INIT(&g_ble_ll_data.ll_rx_pkt_q);
+
+    /* Initialize eventq */
+    os_eventq_init(&g_ble_ll_data.ll_evq);
+
+    /* Initialize receive packet (from phy) event */
+    g_ble_ll_data.ll_rx_pkt_ev.ev_type = BLE_LL_EVENT_RX_PKT_IN;
+
+    /* Initialize LL HCI */
+    ble_ll_hci_init();
+
+    /* Init the scheduler */
+    ble_ll_sched_init();
+
+    /* Initialize advertiser */
+    ble_ll_adv_init();
+
+    /* Initialize a scanner */
+    ble_ll_scan_init();
+
+    /* Initialize the LL task */
+    os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL, BLE_LL_TASK_PRI, 
+                 OS_WAIT_FOREVER, g_ble_ll_stack, BLE_LL_STACK_SIZE);
+
+    return 0;
+}
+


Re: [2/3] incubator-mynewt-larva git commit: Prefix ll with ble_. This includes filenames

Posted by Justin Mclean <ju...@classsoftware.com>.
Hi,

> It was the original company name.  it should be runtime / the same
> assignment covers both.

Good to know.

> we should change the header to the spiffy new ones.  I didn't want to
> do it prior to source code migration, but we can go through and update
> them all now...  something for the next week or two.

No urgency just something we should be aware of and has to done at some point. There’s a few tools about that will replace headers so no need for it to be a manual process. [1]

Thanks,
Justin

1. http://www.apache.org/legal/src-headers.html#faq-update-scripts


Re: [2/3] incubator-mynewt-larva git commit: Prefix ll with ble_. This includes filenames

Posted by Sterling Hughes <st...@apache.org>.
It was the original company name.  it should be runtime / the same
assignment covers both.

we should change the header to the spiffy new ones.  I didn't want to
do it prior to source code migration, but we can go through and update
them all now...  something for the next week or two.



On Fri, Oct 30, 2015 at 3:30 PM, Justin Mclean <ju...@classsoftware.com> wrote:
> Hi,
>
> I notice a couple of the headers have:
> - Copyright (c) 2015 Stack Inc.
> - Copyright (c) 2015 Runtime Inc.
>
> When it should be [1]. This is something we’ll need to clean up before graduation (and preferably before). [2]
>
> BTW who is Stack? Do we have permission to use that code/was it part of the original donation?
>
> Thanks,
> Justin
>
> 1. http://www.apache.org/legal/src-headers.html#headers
> 2. http://incubator.apache.org/guides/mentor.html#initial-clean-up

Re: [2/3] incubator-mynewt-larva git commit: Prefix ll with ble_. This includes filenames

Posted by Justin Mclean <ju...@classsoftware.com>.
Hi,

I notice a couple of the headers have:
- Copyright (c) 2015 Stack Inc.
- Copyright (c) 2015 Runtime Inc.

When it should be [1]. This is something we’ll need to clean up before graduation (and preferably before). [2]

BTW who is Stack? Do we have permission to use that code/was it part of the original donation?

Thanks,
Justin

1. http://www.apache.org/legal/src-headers.html#headers
2. http://incubator.apache.org/guides/mentor.html#initial-clean-up

[2/3] incubator-mynewt-larva git commit: Prefix ll with ble_. This includes filenames

Posted by we...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ble_ll_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c
new file mode 100644
index 0000000..b1d1960
--- /dev/null
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -0,0 +1,912 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include "os/os.h"
+#include "bsp/bsp.h"
+#include "nimble/ble.h"
+#include "nimble/hci_common.h"
+#include "controller/phy.h"
+#include "controller/ble_ll.h"
+#include "controller/ble_ll_adv.h"
+#include "controller/ble_ll_sched.h"
+#include "controller/ll_scan.h"
+#include "hal/hal_cputime.h"
+#include "hal/hal_gpio.h"
+
+/* 
+ * Advertising configuration parameters. These are parameters that I have
+ * fixed for now but could be considered "configuration" parameters for either
+ * the device or the stack.
+ */
+#define BLE_LL_CFG_ADV_PDU_ITVL_HD_USECS    (5000)  /* usecs */
+#define BLE_LL_CFG_ADV_PDU_ITVL_LD_USECS    (10000) /* usecs */
+#define BLE_LL_CFG_ADV_TXPWR                (0)     /* dBm */
+
+/* XXX: TODO
+ * 1) Need to look at advertising and scan request PDUs. Do I allocate these
+ * once? Do I use a different pool for smaller ones? Do I statically declare
+ * them?
+ * 2) The random address and initiator address (if doing directed adv) is not
+ * set yet. Determine how that is to be done.
+ * 3) How do features get supported? What happens if device does not support
+ * advertising? (for example)
+ * 4) Correct calculation of schedule start and end times for the various
+ * scheduled advertising activities.
+ * 5) How to determine the advertising interval we will actually use. As of
+ * now, we set it to max.
+ * 6) Currently, when we set scheduling events, we dont take into account
+ * processor overhead/delays. We will want to do that.
+ * 7) Need to implement the whole HCI command done stuff.
+ * 8) For set adv enable command: if we get a connection, or we time out,
+ *    we need to send a CONNECTION COMPLETE event. Do this.
+ * 9) How does the advertising channel tx power get set? I dont implement
+ * that currently.
+ * 10) Add whitelist! Do this to the code.
+ */
+
+/* 
+ * Advertising state machine 
+ * 
+ * The advertising state machine data structure.
+ * 
+ *  adv_pdu_len
+ *      The length of the advertising PDU that will be sent. This does not
+ *      include the preamble, access address and CRC.
+ */
+struct ble_ll_adv_sm
+{
+    uint8_t enabled;
+    uint8_t adv_type;
+    uint8_t adv_len;
+    uint8_t adv_chanmask;
+    uint8_t adv_filter_policy;
+    uint8_t own_addr_type;
+    uint8_t peer_addr_type;
+    uint8_t adv_chan;
+    uint8_t scan_rsp_len;
+    uint8_t adv_pdu_len;
+    uint16_t adv_itvl_min;
+    uint16_t adv_itvl_max;
+    uint32_t adv_itvl_usecs;
+    uint32_t adv_event_start_time;
+    uint32_t adv_pdu_start_time;
+    uint8_t initiator_addr[BLE_DEV_ADDR_LEN];
+    uint8_t adv_data[BLE_ADV_DATA_MAX_LEN];
+    uint8_t scan_rsp_data[BLE_SCAN_RSP_DATA_MAX_LEN];
+    struct os_mbuf *adv_pdu;
+    struct os_mbuf *scan_rsp_pdu;
+    struct os_event adv_txdone_ev;
+};
+
+/* The advertising state machine global object */
+struct ble_ll_adv_sm g_ble_ll_adv_sm;
+
+struct ble_ll_adv_stats
+{
+    uint32_t late_tx_done;
+    uint32_t cant_set_sched;
+    uint32_t scan_rsp_txg;
+    uint32_t adv_txg;
+};
+
+struct ble_ll_adv_stats g_ble_ll_adv_stats;
+
+/* XXX: We can calculate scan response time as well. */
+/* 
+ * Worst case time needed for scheduled advertising item. This is the longest
+ * possible time to receive a scan request and send a scan response (with the
+ * appropriate IFS time between them). This number is calculated using the
+ * following formula: IFS + SCAN_REQ + IFS + SCAN_RSP = 150 + 176 + 150 + 376.
+ * 
+ * NOTE: The advertising PDU transmit time is NOT included here since we know
+ * how long that will take.
+ */
+#define BLE_LL_ADV_SCHED_MAX_USECS  (852)
+
+/* For debug purposes */
+extern void bletest_inc_adv_pkt_num(void);
+
+/**
+ * Calculate the first channel that we should advertise upon when we start 
+ * an advertising event. 
+ * 
+ * @param advsm 
+ * 
+ * @return uint8_t The number of the first channel usable for advertising.
+ */
+static uint8_t
+ble_ll_adv_first_chan(struct ble_ll_adv_sm *advsm)
+{
+    uint8_t adv_chan;
+
+    /* Set first advertising channel */
+    if (advsm->adv_chanmask & 0x01) {
+        adv_chan = BLE_PHY_ADV_CHAN_START;
+    } else if (advsm->adv_chanmask & 0x02) {
+        adv_chan = BLE_PHY_ADV_CHAN_START + 1;
+    } else {
+        adv_chan = BLE_PHY_ADV_CHAN_START + 2;
+    }
+
+    return adv_chan;
+}
+
+/**
+ * Create the advertising PDU 
+ * 
+ * @param advsm Pointer to advertisement state machine
+ */
+static void
+ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm)
+{
+    uint8_t     adv_data_len;
+    uint8_t     *dptr;
+    uint8_t     pdulen;
+    uint8_t     pdu_type;
+    uint8_t     *addr;
+    struct os_mbuf *m;
+
+    /* assume this is not a direct ind */
+    adv_data_len = advsm->adv_len;
+    pdulen = BLE_DEV_ADDR_LEN + adv_data_len;
+
+    /* Must be an advertising type! */
+    switch (advsm->adv_type) {
+    case BLE_HCI_ADV_TYPE_ADV_IND:
+        pdu_type = BLE_ADV_PDU_TYPE_ADV_IND;
+        break;
+
+    case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND:
+        pdu_type = BLE_ADV_PDU_TYPE_ADV_NONCONN_IND;
+        break;
+
+    case BLE_HCI_ADV_TYPE_ADV_SCAN_IND:
+        pdu_type = BLE_ADV_PDU_TYPE_ADV_SCAN_IND;
+        break;
+
+    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD:
+    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD:
+        pdu_type = BLE_ADV_PDU_TYPE_ADV_DIRECT_IND;
+        adv_data_len = 0;
+        pdulen = BLE_ADV_DIRECT_IND_LEN;
+        break;
+
+        /* Set these to avoid compiler warnings */
+    default:
+        pdulen = 0;
+        pdu_type = 0;
+        adv_data_len = 0xFF;
+        break;
+    }
+
+    /* An invalid advertising data length indicates a memory overwrite */
+    assert(adv_data_len <= BLE_ADV_DATA_MAX_LEN);
+
+    /* Set the PDU length in the state machine */
+    advsm->adv_pdu_len = pdulen + BLE_LL_PDU_HDR_LEN;
+
+    /* Get the advertising PDU */
+    m = advsm->adv_pdu;
+    assert(m != NULL);
+    m->om_len = advsm->adv_pdu_len;
+    OS_MBUF_PKTHDR(m)->omp_len = m->om_len;
+
+    /* Construct scan response */
+    if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_PUBLIC) {
+        addr = g_dev_addr;
+    } else if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
+        pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND;
+        addr = g_random_addr;
+    } else {
+        /* XXX: unsupported for now  */
+        addr = NULL;
+        assert(0);
+    }
+
+    /* Construct advertisement */
+    dptr = m->om_data;
+    dptr[0] = pdu_type;
+    dptr[1] = (uint8_t)pdulen;
+    memcpy(dptr + BLE_LL_PDU_HDR_LEN, addr, BLE_DEV_ADDR_LEN);
+    dptr += BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN;
+
+    /* For ADV_DIRECT_IND, we need to put initiators address in there */
+    if (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND) {
+        memcpy(dptr, advsm->initiator_addr, BLE_DEV_ADDR_LEN);
+    }
+
+    /* Copy in advertising data, if any */
+    if (adv_data_len != 0) {
+        memcpy(dptr, advsm->adv_data, adv_data_len);
+    }
+}
+
+/**
+ * Create a scan response PDU 
+ * 
+ * @param advsm 
+ */
+static void
+ble_ll_adv_scan_rsp_pdu_make(struct ble_ll_adv_sm *advsm)
+{
+    uint8_t     scan_rsp_len;
+    uint8_t     *dptr;
+    uint8_t     *addr;
+    uint8_t     pdulen;
+    uint8_t     hdr;
+    struct os_mbuf *m;
+
+    /* Make sure that the length is valid */
+    scan_rsp_len = advsm->scan_rsp_len;
+    assert(scan_rsp_len <= BLE_SCAN_RSP_DATA_MAX_LEN);
+
+    /* Set PDU payload length */
+    pdulen = BLE_DEV_ADDR_LEN + scan_rsp_len;
+
+    /* Get the advertising PDU */
+    m = advsm->scan_rsp_pdu;
+    assert(m != NULL);
+    m->om_len = BLE_LL_PDU_HDR_LEN + pdulen;
+    OS_MBUF_PKTHDR(m)->omp_len = m->om_len;
+
+    /* Construct scan response */
+    if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_PUBLIC) {
+        hdr = BLE_ADV_PDU_TYPE_SCAN_RSP;
+        addr = g_dev_addr;
+    } else if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
+        hdr = BLE_ADV_PDU_TYPE_SCAN_RSP | BLE_ADV_PDU_HDR_TXADD_RAND;
+        addr = g_random_addr;
+    } else {
+        /* XXX: unsupported for now  */
+        hdr = 0;
+        addr = NULL;
+        assert(0);
+    }
+
+    /* Write into the pdu buffer */
+    dptr = m->om_data;
+    dptr[0] = hdr;
+    dptr[1] = pdulen;
+    memcpy(dptr + BLE_LL_PDU_HDR_LEN, addr, BLE_DEV_ADDR_LEN);
+
+    /* Copy in scan response data, if any */
+    if (scan_rsp_len != 0) {
+        dptr += BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN;  
+        memcpy(dptr, advsm->scan_rsp_data, scan_rsp_len);
+    }
+}
+
+/**
+ * Scheduler callback used after advertising PDU sent. 
+ * 
+ * @param arg 
+ */
+static int
+ble_ll_adv_rx_cb(struct ble_ll_sched_item *sch)
+{
+    /* Disable the PHY as we might be receiving */
+    ble_phy_disable();
+    os_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_adv_sm.adv_txdone_ev);
+    return BLE_LL_SCHED_STATE_DONE;
+}
+
+
+/**
+ * Scheduler callback when an advertising PDU has been sent. 
+ * 
+ * @param arg 
+ */
+static int
+ble_ll_adv_tx_done_cb(struct ble_ll_sched_item *sch)
+{
+    os_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_adv_sm.adv_txdone_ev);
+    return BLE_LL_SCHED_STATE_DONE;
+}
+
+/**
+ * This is the scheduler callback (called from interrupt context) which 
+ * transmits an advertisement. 
+ *  
+ * Context: Interrupt (scheduler) 
+ *  
+ * @param sch 
+ * 
+ * @return int 
+ */
+static int
+ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
+{
+    int rc;
+    uint8_t end_trans;
+    struct ble_ll_adv_sm *advsm;
+
+    /* Get the state machine for the event */
+    advsm = (struct ble_ll_adv_sm *)sch->cb_arg;
+
+    /* Toggle the LED */
+    gpio_toggle(LED_BLINK_PIN);
+
+    /* Set channel */
+    rc = ble_phy_setchan(advsm->adv_chan);
+    assert(rc == 0);
+
+    /* Set phy mode based on type of advertisement */
+    if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
+        end_trans = BLE_PHY_TRANSITION_NONE;
+    } else {
+        end_trans = BLE_PHY_TRANSITION_TX_RX;
+    }
+
+    /* Transmit advertisement */
+    rc = ble_phy_tx(advsm->adv_pdu, BLE_PHY_TRANSITION_NONE, end_trans);
+    if (rc) {
+        /* Transmit failed. */
+        rc = ble_ll_adv_tx_done_cb(sch);
+    } else {
+        /* Set link layer state to advertising */
+        ble_ll_state_set(BLE_LL_STATE_ADV);
+
+        /* Count # of adv. sent */
+        ++g_ble_ll_adv_stats.adv_txg;
+
+        /* Set schedule item next wakeup time */
+        if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
+            sch->next_wakeup = sch->end_time;
+            sch->sched_cb = ble_ll_adv_tx_done_cb;
+        } else {
+            /* XXX: set next wakeup time. We have to look for either a
+             * connect request or scan request or both, depending on
+             * advertising type. For now, we will just wait until the
+             * end of the scheduled event, which was set to the worst case
+             * time to send a scan response PDU. Note that I use the time
+             * now to insure the callback occurs after we are dont transmitting
+             * the scan response, as we may have been late starting the tx.
+             */
+            sch->next_wakeup = cputime_get32() +
+                (sch->end_time - sch->start_time);
+            sch->sched_cb = ble_ll_adv_rx_cb;
+        }
+
+        rc = BLE_LL_SCHED_STATE_RUNNING;
+    }
+
+    return rc;
+}
+
+static struct ble_ll_sched_item *
+ble_ll_adv_sched_set(struct ble_ll_adv_sm *advsm)
+{
+    int rc;
+    uint32_t max_usecs;
+    struct ble_ll_sched_item *sch;
+
+    sch = ble_ll_sched_get_item();
+    if (sch) {
+        /* Set sched type */
+        sch->sched_type = BLE_LL_SCHED_TYPE_ADV;
+
+        /* XXX: HW output compare to trigger tx start? Look into this */
+        /* Set the start time of the event */
+        sch->start_time = advsm->adv_pdu_start_time - 
+            cputime_usecs_to_ticks(XCVR_TX_SCHED_DELAY_USECS);
+
+        /* Set the callback and argument */
+        sch->cb_arg = advsm;
+        sch->sched_cb = ble_ll_adv_tx_start_cb;
+
+        /* Set end time to maximum time this schedule item may take */
+        max_usecs = ble_ll_pdu_tx_time_get(advsm->adv_pdu_len);
+        if (advsm->adv_type != BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
+            max_usecs += BLE_LL_ADV_SCHED_MAX_USECS;
+        }
+        sch->end_time = advsm->adv_pdu_start_time +
+            cputime_usecs_to_ticks(max_usecs);
+
+        /* XXX: for now, we cant get an overlap so assert on error. */
+        /* Add the item to the scheduler */
+        rc = ble_ll_sched_add(sch);
+        assert(rc == 0);
+    } else {
+        ++g_ble_ll_adv_stats.cant_set_sched;
+    }
+
+    return sch;
+}
+
+/**
+ * Called by the HCI command parser when a set advertising parameters command 
+ * has been received. 
+ *  
+ * Context: Link Layer task (HCI command parser) 
+ * 
+ * @param cmd 
+ * 
+ * @return int 
+ */
+int
+ble_ll_adv_set_adv_params(uint8_t *cmd)
+{
+    uint8_t adv_type;
+    uint8_t adv_filter_policy;
+    uint8_t adv_chanmask;
+    uint8_t own_addr_type;
+    uint8_t peer_addr_type;
+    uint16_t adv_itvl_min;
+    uint16_t adv_itvl_max;
+    uint16_t min_itvl;
+    struct ble_ll_adv_sm *advsm;
+
+    /* If already enabled, we return an error */
+    advsm = &g_ble_ll_adv_sm;
+    if (advsm->enabled) {
+        return BLE_ERR_CMD_DISALLOWED;
+    }
+
+    /* Make sure intervals are OK (along with advertising type */
+    adv_itvl_min = le16toh(cmd);
+    adv_itvl_max = le16toh(cmd + 2);
+    adv_type = cmd[4];
+
+    /* Min has to be less than max and cannot equal max */
+    if ((adv_itvl_min > adv_itvl_max) || (adv_itvl_min == adv_itvl_max)) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    switch (adv_type) {
+    case BLE_HCI_ADV_TYPE_ADV_IND:
+    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD:
+    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD:
+        min_itvl = BLE_LL_ADV_ITVL_MIN;
+        break;
+    case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND:
+    case BLE_HCI_ADV_TYPE_ADV_SCAN_IND:
+        min_itvl = BLE_LL_ADV_ITVL_NONCONN_MIN;
+        break;
+    default:
+        min_itvl = 0xFFFF;
+        break;
+    }
+
+    /* XXX: isnt there a maximum that we need to check? */
+    /* Make sure interval minimum is valid for the advertising type */
+    if ((adv_itvl_min < min_itvl) || (adv_itvl_min > BLE_HCI_ADV_ITVL_MAX)) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    /* Check own and peer address type */
+    own_addr_type =  cmd[5];
+    peer_addr_type = cmd[6];
+
+    if ((own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) ||
+        (peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX)) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    /* There are only three adv channels, so check for any outside the range */
+    adv_chanmask = cmd[13];
+    if (((adv_chanmask & 0xF8) != 0) || (adv_chanmask == 0)) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    /* Check for valid filter policy */
+    adv_filter_policy = cmd[14];
+    if (adv_filter_policy > BLE_HCI_ADV_FILT_MAX) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    /* XXX: determine if there is anything that needs to be done for
+       own address type or peer address type */
+    advsm->own_addr_type = own_addr_type;
+    advsm->peer_addr_type = peer_addr_type;
+
+    advsm->adv_filter_policy = adv_filter_policy;
+    advsm->adv_chanmask = adv_chanmask;
+    advsm->adv_itvl_min = adv_itvl_min;
+    advsm->adv_itvl_max = adv_itvl_max;
+    advsm->adv_type = adv_type;
+
+    return 0;
+}
+
+/**
+ * Stop advertising state machine 
+ * 
+ * @param advsm 
+ */
+static void
+ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
+{
+    /* XXX: Stop any timers we may have started */
+
+    /* Remove any scheduled advertising items */
+    ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_ADV);
+
+    /* Disable advertising */
+    advsm->enabled = 0;
+}
+
+/**
+ * Start the advertising state machine. 
+ *  
+ * Context: Link-layer task. 
+ * 
+ * @param advsm Pointer to advertising state machine
+ * 
+ * @return int 
+ */
+static int
+ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm)
+{
+    uint8_t adv_chan;
+    struct ble_ll_sched_item *sch;
+
+    /* 
+     * XXX: not sure if I should do this or just report whatever random
+     * address the host sent. For now, I will reject the command with a
+     * command disallowed error. All the parameter errors refer to the command
+     * parameter (which in this case is just enable or disable).
+     */ 
+    if (advsm->own_addr_type != BLE_HCI_ADV_OWN_ADDR_PUBLIC) {
+        if (!ble_ll_is_valid_random_addr(g_random_addr)) {
+            return BLE_ERR_CMD_DISALLOWED;
+        }
+
+        /* XXX: support these other types */
+        if (advsm->own_addr_type != BLE_HCI_ADV_OWN_ADDR_RANDOM) {
+            assert(0);
+        }
+    }
+
+    /* Set flag telling us that advertising is enabled */
+    advsm->enabled = 1;
+
+    /* Determine the advertising interval we will use */
+    advsm->adv_itvl_usecs = (uint32_t)advsm->adv_itvl_max * BLE_LL_ADV_ITVL;
+
+    /* Create the advertising PDU */
+    ble_ll_adv_pdu_make(advsm);
+
+    /* Create scan response PDU (if needed) */
+    if (advsm->adv_type != BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
+        ble_ll_adv_scan_rsp_pdu_make(advsm);
+    }
+
+    /* Set first advertising channel */
+    adv_chan = ble_ll_adv_first_chan(advsm);
+    advsm->adv_chan = adv_chan;
+
+    /* 
+     * Set start time for the advertising event. This time is the same
+     * as the time we will send the first PDU. Since there does not seem
+     * to be any requirements as to when we start, we just set the time to
+     * now.
+     */ 
+    advsm->adv_event_start_time = cputime_get32();
+    advsm->adv_pdu_start_time = advsm->adv_event_start_time;
+
+    /* Set packet in schedule */
+    sch = ble_ll_adv_sched_set(advsm);
+    if (!sch) {
+        /* XXX: set a wakeup timer to deal with this. For now, assert */
+        assert(0);
+    }
+
+    return 0;
+}
+
+/**
+ * Called when the LE HCI command read advertising channel tx power command 
+ * has been received. Returns the current advertising transmit power. 
+ *  
+ * Context: Link Layer task (HCI command parser) 
+ * 
+ * @return int 
+ */
+int
+ble_ll_adv_read_txpwr(uint8_t *rspbuf)
+{
+    rspbuf[0] = BLE_LL_CFG_ADV_TXPWR;
+    return BLE_ERR_SUCCESS;
+}
+
+/**
+ * Turn advertising on/off.
+ * 
+ * @param cmd 
+ * 
+ * @return int 
+ */
+int
+ble_ll_adv_set_enable(uint8_t *cmd)
+{
+    int rc;
+    uint8_t enable;
+    struct ble_ll_adv_sm *advsm;
+
+    advsm = &g_ble_ll_adv_sm;
+
+    rc = 0;
+    enable = cmd[0];
+    if (enable == 1) {
+        /* If already enabled, do nothing */
+        if (!advsm->enabled) {
+            /* Start the advertising state machine */
+            rc = ble_ll_adv_sm_start(advsm);
+        }
+    } else if (enable == 0) {
+        if (advsm->enabled) {
+            ble_ll_adv_sm_stop(advsm);
+        }
+    } else {
+        rc = BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    return rc;
+}
+
+/**
+ * Set the scan response data that the controller will send.
+ * 
+ * @param cmd 
+ * @param len 
+ * 
+ * @return int 
+ */
+int
+ble_ll_adv_set_scan_rsp_data(uint8_t *cmd, uint8_t len)
+{
+    uint8_t datalen;
+    os_sr_t sr;
+    struct ble_ll_adv_sm *advsm;
+
+    /* Check for valid scan response data length */
+    datalen = cmd[0];
+    if ((datalen > BLE_SCAN_RSP_DATA_MAX_LEN) || (datalen != len)) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    /* Copy the new data into the advertising structure. */
+    advsm = &g_ble_ll_adv_sm;
+    advsm->scan_rsp_len = datalen;
+    memcpy(advsm->scan_rsp_data, cmd + 1, datalen);
+
+    /* Re-make the scan response PDU since data may have changed */
+    OS_ENTER_CRITICAL(sr);
+    /* 
+     * XXX: there is a chance, even with interrupts disabled, that
+     * we are transmitting the scan response PDU while writing to it.
+     */ 
+    ble_ll_adv_scan_rsp_pdu_make(advsm);
+    OS_EXIT_CRITICAL(sr);
+
+    return 0;
+}
+
+/**
+ * Called by the LL HCI command parser when a set advertising 
+ * data command has been sent from the host to the controller. 
+ * 
+ * @param cmd Pointer to command data
+ * @param len Length of command data
+ * 
+ * @return int 0: success; BLE_ERR_INV_HCI_CMD_PARMS otherwise.
+ */
+int
+ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t len)
+{
+    uint8_t datalen;
+    struct ble_ll_adv_sm *advsm;
+    os_sr_t sr;
+
+    /* Check for valid advertising data length */
+    datalen = cmd[0];
+    if ((datalen > BLE_ADV_DATA_MAX_LEN) || (datalen != len)) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    /* Copy the new data into the advertising structure. */
+    advsm = &g_ble_ll_adv_sm;
+    advsm->adv_len = datalen;
+    memcpy(advsm->adv_data, cmd + 1, datalen);
+
+    /* If the state machine is enabled, we need to re-make the adv PDU */
+    if (advsm->enabled) {
+        /* 
+         * XXX: currently, even with interrupts disabled, there is a chance
+         * that we are transmitting the advertising PDU while writing into
+         * it.
+         */
+        OS_ENTER_CRITICAL(sr);
+        ble_ll_adv_pdu_make(advsm);
+        OS_EXIT_CRITICAL(sr);
+    }
+
+    return 0;
+}
+
+/**
+ * Called when the LL receives a scan request.  
+ *  
+ * Context: Called from interrupt context. 
+ * 
+ * @param rxbuf 
+ * 
+ * @return -1: scan request not for us. 
+ *          0: Scan request is for us and we successfully went from rx to tx.
+ *        > 0: PHY error attempting to go from rx to tx.
+ */
+int
+ble_ll_adv_rx_scan_req(uint8_t *rxbuf)
+{
+    int rc;
+    uint8_t rxaddr_type;
+    uint8_t *our_addr;
+    uint8_t *adva;
+
+    /* Determine if this is addressed to us */
+    rxaddr_type = rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK;
+    if (rxaddr_type) {
+        our_addr = g_random_addr;
+    } else {
+        our_addr = g_dev_addr;
+    }
+
+    rc = -1;
+    adva = rxbuf + BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN;
+    if (!memcmp(our_addr, adva, BLE_DEV_ADDR_LEN)) {
+        /* Setup to transmit the scan response */
+        rc = ble_phy_tx(g_ble_ll_adv_sm.scan_rsp_pdu, BLE_PHY_TRANSITION_RX_TX, 
+                        BLE_PHY_TRANSITION_NONE);
+        if (!rc) {
+            ++g_ble_ll_adv_stats.scan_rsp_txg;
+        }
+    }
+
+    return rc;
+}
+
+/**
+ * Process advertistement tx done event. 
+ *  
+ * Context: Link Layer task. 
+ * 
+ * @param arg Pointer to advertising state machine.
+ */
+void
+ble_ll_adv_tx_done_proc(void *arg)
+{
+    uint8_t mask;
+    uint8_t final_adv_chan;
+    int32_t delta_t;
+    uint32_t itvl;
+    struct ble_ll_adv_sm *advsm;
+
+    /* Free the advertising packet */
+    advsm = (struct ble_ll_adv_sm *)arg;
+    ble_ll_state_set(BLE_LL_STATE_STANDBY);
+
+    /* For debug purposes */
+    bletest_inc_adv_pkt_num();
+
+    /* 
+     * Check if we have ended our advertising event. If our last advertising
+     * packet was sent on the last channel, it means we are done with this
+     * event.
+     */
+    if (advsm->adv_chanmask & 0x04) {
+        final_adv_chan = BLE_PHY_ADV_CHAN_START + 2;
+    } else if (advsm->adv_chanmask & 0x02) {
+        final_adv_chan = BLE_PHY_ADV_CHAN_START + 1;
+    } else {
+        final_adv_chan = BLE_PHY_ADV_CHAN_START;
+    }
+
+    if (advsm->adv_chan == final_adv_chan) {
+        /* This event is over. Set adv channel to first one */
+        advsm->adv_chan = ble_ll_adv_first_chan(advsm);
+
+        /* Calculate start time of next advertising event */
+        itvl = advsm->adv_itvl_usecs;
+        itvl += rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
+        advsm->adv_event_start_time += cputime_usecs_to_ticks(itvl);
+        advsm->adv_pdu_start_time = advsm->adv_event_start_time;
+
+        /* Toggle the LED */
+        gpio_toggle(LED_BLINK_PIN);
+    } else {
+        /* 
+         * Move to next advertising channel. If not in the mask, just
+         * increment by 1. We can do this because we already checked if we
+         * just transmitted on the last advertising channel
+         */
+        ++advsm->adv_chan;
+        mask = 1 << (advsm->adv_chan - BLE_PHY_ADV_CHAN_START);
+        if ((mask & advsm->adv_chanmask) == 0) {
+            ++advsm->adv_chan;
+        }
+
+        /* Set next start time to next pdu transmit time */
+        if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
+            itvl = BLE_LL_CFG_ADV_PDU_ITVL_HD_USECS;
+        } else {
+            itvl = BLE_LL_CFG_ADV_PDU_ITVL_LD_USECS;
+        }
+        itvl = cputime_usecs_to_ticks(itvl);
+        advsm->adv_pdu_start_time += itvl;
+    }
+
+    /* 
+     * The scheduled time better be in the future! If it is not, we will
+     * count a statistic and close the current advertising event. We will
+     * then setup the next advertising event.
+     */
+    delta_t = (int32_t)(advsm->adv_pdu_start_time - cputime_get32());
+    if (delta_t < 0) {
+        /* Count times we were late */
+        ++g_ble_ll_adv_stats.late_tx_done;
+
+        /* Set back to first adv channel */
+        advsm->adv_chan = ble_ll_adv_first_chan(advsm);
+
+        /* Calculate start time of next advertising event */
+        while (delta_t < 0) {
+            itvl = advsm->adv_itvl_usecs;
+            itvl += rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
+            itvl = cputime_usecs_to_ticks(itvl);
+            advsm->adv_event_start_time += itvl;
+            advsm->adv_pdu_start_time = advsm->adv_event_start_time;
+            delta_t += (int32_t)itvl;
+        }
+    }
+
+    if (!ble_ll_adv_sched_set(advsm)) {
+        /* XXX: we will need to set a timer here to wake us up */
+        assert(0);
+    }
+}
+
+/**
+ * Initialize the advertising functionality of a BLE device. This should 
+ * be called once on initialization
+ */
+void
+ble_ll_adv_init(void)
+{
+    struct ble_ll_adv_sm *advsm;
+
+    /* Set default advertising parameters */
+    advsm = &g_ble_ll_adv_sm;
+    memset(advsm, 0, sizeof(struct ble_ll_adv_sm));
+
+    advsm->adv_itvl_min = BLE_HCI_ADV_ITVL_DEF;
+    advsm->adv_itvl_max = BLE_HCI_ADV_ITVL_DEF;
+    advsm->adv_chanmask = BLE_HCI_ADV_CHANMASK_DEF;
+
+    /* Initialize advertising tx done event */
+    advsm->adv_txdone_ev.ev_type = BLE_LL_EVENT_ADV_TXDONE;
+    advsm->adv_txdone_ev.ev_arg = advsm;
+
+    /* Get an advertising mbuf (packet header) and attach to state machine */
+    advsm->adv_pdu = os_mbuf_get_pkthdr(&g_mbuf_pool);
+    assert(advsm->adv_pdu != NULL);
+
+    /* Get a scan response mbuf (packet header) and attach to state machine */
+    advsm->scan_rsp_pdu = os_mbuf_get_pkthdr(&g_mbuf_pool);
+    assert(advsm->scan_rsp_pdu != NULL);
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ble_ll_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c
new file mode 100644
index 0000000..a299554
--- /dev/null
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -0,0 +1,336 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include "os/os.h"
+#include "nimble/ble.h"
+#include "nimble/hci_common.h"
+#include "nimble/hci_transport.h"
+#include "controller/ble_ll_adv.h"
+#include "controller/ll_scan.h"
+#include "controller/ble_ll.h"
+#include "controller/ll_hci.h"
+
+/* LE event mask */
+uint8_t g_ble_ll_hci_le_event_mask[BLE_HCI_SET_LE_EVENT_MASK_LEN];
+uint8_t g_ble_ll_hci_event_mask[BLE_HCI_SET_EVENT_MASK_LEN];
+
+/**
+ * ll hci get num cmd pkts 
+ *  
+ * Returns the number of command packets that the host is allowed to send 
+ * to the controller. 
+ *  
+ * @return uint8_t 
+ */
+static uint8_t
+ble_ll_hci_get_num_cmd_pkts(void)
+{
+    return BLE_LL_CFG_NUM_HCI_CMD_PKTS;
+}
+
+/**
+ * Send an event to the host. 
+ * 
+ * @param evbuf Pointer to event buffer to send
+ * 
+ * @return int 0: success; -1 otherwise.
+ */
+int
+ble_ll_hci_event_send(uint8_t *evbuf)
+{
+    int rc;
+
+    /* Count number of events sent */
+    ++g_ble_ll_stats.hci_events_sent;
+
+    /* Send the event to the host */
+    rc = ble_hci_transport_ctlr_event_send(evbuf);
+
+    return rc;
+}
+
+/**
+ * ll hci set le event mask
+ *  
+ * Called when the LL controller receives a set LE event mask command.
+ *  
+ * Context: Link Layer task (HCI command parser) 
+ * 
+ * @param cmdbuf Pointer to command buf.
+ * 
+ * @return int BLE_ERR_SUCCESS. Does not return any errors.
+ */
+static int
+ble_ll_hci_set_le_event_mask(uint8_t *cmdbuf)
+{
+    /* Copy the data into the event mask */
+    memcpy(g_ble_ll_hci_le_event_mask, cmdbuf, BLE_HCI_SET_LE_EVENT_MASK_LEN);
+    return BLE_ERR_SUCCESS;
+}
+
+/**
+ * ll hci le read bufsize
+ *  
+ * This is the function that processes the LE read buffer size command.
+ *  
+ * Context: Link Layer task (HCI command parser) 
+ * 
+ * @param cmdbuf 
+ * 
+ * @return int 
+ */
+static int
+ble_ll_hci_le_read_bufsize(uint8_t *rspbuf)
+{    
+    /* Place the data packet length and number of packets in the buffer */
+    htole16(rspbuf, BLE_LL_CFG_ACL_DATA_PKT_LEN);
+    rspbuf[2] = BLE_LL_CFG_NUM_ACL_DATA_PKTS;
+    return BLE_ERR_SUCCESS;
+}
+
+/**
+ * Checks to see if a LE event has been disabled by the host. 
+ * 
+ * @param bitpos This is the bit position of the LE event. Note that this can 
+ * be a value from 0 to 63, inclusive. 
+ * 
+ * @return uint8_t 0: event is not enabled; otherwise event is enabled.
+ */
+uint8_t
+ble_ll_hci_is_le_event_enabled(int bitpos)
+{
+    uint8_t enabled;
+    uint8_t bytenum;
+    uint8_t bitmask;
+
+    bytenum = bitpos / 8;
+    bitmask = 1 << (bitpos & 0x7);
+    enabled = g_ble_ll_hci_le_event_mask[bytenum] & bitmask;
+
+    return enabled;
+}
+
+/**
+ * Process a LE command sent from the host to the controller. The HCI command 
+ * has a 3 byte command header followed by data. The header is: 
+ *  -> opcode (2 bytes)
+ *  -> Length of parameters (1 byte; does include command header bytes).
+ * 
+ * @param cmdbuf Pointer to command buffer. Points to start of command header.
+ * @param len 
+ * @param ocf 
+ * 
+ * @return int 
+ */
+static int
+ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
+{
+    int rc;
+    uint8_t len;
+    uint8_t *rspbuf;
+
+    /* Assume error; if all pass rc gets set to 0 */
+    rc = BLE_ERR_INV_HCI_CMD_PARMS;
+
+    /* Get length from command */
+    len = cmdbuf[sizeof(uint16_t)];
+
+    /* 
+     * The command response pointer points into the same buffer as the
+     * command data itself. That is fine, as each command reads all the data
+     * before crafting a response.
+     */ 
+    rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
+
+    /* Move past HCI command header */
+    cmdbuf += BLE_HCI_CMD_HDR_LEN;
+
+    switch (ocf) {
+    case BLE_HCI_OCF_LE_SET_EVENT_MASK:
+        if (len == BLE_HCI_SET_LE_EVENT_MASK_LEN) {
+            rc = ble_ll_hci_set_le_event_mask(cmdbuf);
+        }
+        break;
+    case BLE_HCI_OCF_LE_RD_BUF_SIZE:
+        if (len == BLE_HCI_RD_BUF_SIZE_LEN) {
+            rc = ble_ll_hci_le_read_bufsize(rspbuf);
+            *rsplen = 3;
+        }
+        break;
+
+    case BLE_HCI_OCF_LE_SET_RAND_ADDR:
+        if (len == BLE_DEV_ADDR_LEN) {
+            rc = ble_ll_set_random_addr(cmdbuf);
+        }
+        break;
+    case BLE_HCI_OCF_LE_SET_ADV_PARAMS:
+        /* Length should be one byte */
+        if (len == BLE_HCI_SET_ADV_PARAM_LEN) {
+            rc = ble_ll_adv_set_adv_params(cmdbuf);
+        }
+        break;
+    case BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR:
+        if (len == BLE_HCI_RD_BUF_SIZE_LEN) {
+            rc = ble_ll_adv_read_txpwr(rspbuf);
+            *rsplen = 1;
+        }
+        break;
+    case BLE_HCI_OCF_LE_SET_ADV_DATA:
+        if (len > 0) {
+            --len;
+            rc = ble_ll_adv_set_adv_data(cmdbuf, len);
+        }
+        break;
+    case BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA:
+        if (len > 0) {
+            --len;
+            rc = ble_ll_adv_set_scan_rsp_data(cmdbuf, len);
+        }
+        break;
+    case BLE_HCI_OCF_LE_SET_ADV_ENABLE:
+        /* Length should be one byte */
+        if (len == BLE_HCI_SET_ADV_ENABLE_LEN) {
+            rc = ble_ll_adv_set_enable(cmdbuf);
+        }
+        break;
+    case BLE_HCI_OCF_LE_SET_SCAN_ENABLE:
+        if (len == BLE_HCI_SET_SCAN_ENABLE_LEN) {
+            rc = ble_ll_scan_set_enable(cmdbuf);
+        }
+        break;
+    case BLE_HCI_OCF_LE_SET_SCAN_PARAMS:
+        /* Length should be one byte */
+        if (len == BLE_HCI_SET_SCAN_PARAM_LEN) {
+            rc = ble_ll_scan_set_scan_params(cmdbuf);
+        }
+        break;
+    default:
+        /* XXX: deal with unsupported command */
+        break;
+    }
+
+    return rc;
+}
+
+void
+ble_ll_hci_cmd_proc(struct os_event *ev)
+{
+    int rc;
+    uint8_t ogf;
+    uint8_t rsplen;
+    uint8_t *cmdbuf;
+    uint16_t opcode;
+    uint16_t ocf;
+    os_error_t err;
+
+    /* The command buffer is the event argument */
+    cmdbuf = (uint8_t *)ev->ev_arg;
+    assert(cmdbuf != NULL);
+
+    /* Free the event */
+    err = os_memblock_put(&g_hci_os_event_pool, ev);
+    assert(err == OS_OK);
+
+    /* Get the opcode from the command buffer */
+    opcode = le16toh(cmdbuf);
+    ocf = BLE_HCI_OCF(opcode);
+    ogf = BLE_HCI_OGF(opcode);
+
+    /* Assume response length is zero */
+    rsplen = 0;
+
+    switch (ogf) {
+    case BLE_HCI_OGF_LE:
+        rc = ble_ll_hci_le_cmd_proc(cmdbuf, ocf, &rsplen);
+        break;
+    case BLE_HCI_OGF_CTLR_BASEBAND:
+        /* XXX: Implement  */
+        rc = BLE_ERR_UNKNOWN_HCI_CMD;
+        break;
+    default:
+        /* XXX: Need to support other OGF. For now, return unsupported */
+        rc = BLE_ERR_UNKNOWN_HCI_CMD;
+        break;
+    }
+
+    /* Make sure valid error code */
+    assert(rc >= 0);
+    if (rc) {
+        ++g_ble_ll_stats.hci_cmd_errs;
+    } else {
+        ++g_ble_ll_stats.hci_cmds;
+    }
+
+    /* If no response is generated, we free the buffers */
+    if (rc <= BLE_ERR_MAX) {
+        /* Create a command complete event with status from command */
+        cmdbuf[0] = BLE_HCI_EVCODE_COMMAND_COMPLETE;
+        cmdbuf[1] = 4 + rsplen;    /* Length of the data */
+        cmdbuf[2] = ble_ll_hci_get_num_cmd_pkts();
+        htole16(cmdbuf + 3, opcode);
+        cmdbuf[5] = (uint8_t)rc;
+
+        /* Send the event. This event cannot be masked */
+        ble_ll_hci_event_send(cmdbuf);
+    } else {
+        /* XXX: placeholder for sending command status or other events */
+        assert(0);
+    }
+}
+
+/* XXX: For now, put this here */
+int
+ble_hci_transport_host_cmd_send(uint8_t *cmd)
+{
+    os_error_t err;
+    struct os_event *ev;
+
+    /* Get an event structure off the queue */
+    ev = (struct os_event *)os_memblock_get(&g_hci_os_event_pool);
+    if (!ev) {
+        err = os_memblock_put(&g_hci_cmd_pool, cmd);
+        assert(err == OS_OK);
+        return -1;
+    }
+
+    /* Fill out the event and post to Link Layer */
+    ev->ev_queued = 0;
+    ev->ev_type = BLE_LL_EVENT_HCI_CMD;
+    ev->ev_arg = cmd;
+    os_eventq_put(&g_ble_ll_data.ll_evq, ev);
+
+    return 0;
+}
+
+/**
+ * Initalize the LL HCI.
+ */
+void
+ble_ll_hci_init(void)
+{
+    /* Set defaults for LE events: Vol 2 Part E 7.8.1 */
+    g_ble_ll_hci_le_event_mask[0] = 0x1f;
+
+    /* Set defaults for controller/baseband events: Vol 2 Part E 7.3.1 */
+    g_ble_ll_hci_event_mask[0] = 0xff;
+    g_ble_ll_hci_event_mask[1] = 0xff;
+    g_ble_ll_hci_event_mask[2] = 0xff;
+    g_ble_ll_hci_event_mask[3] = 0xff;
+    g_ble_ll_hci_event_mask[4] = 0xff;
+    g_ble_ll_hci_event_mask[5] = 0x1f;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ble_ll_scan.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c
index 554ebe4..4d1d79f 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -21,9 +21,9 @@
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
 #include "controller/phy.h"
-#include "controller/ll.h"
-#include "controller/ll_sched.h"
-#include "controller/ll_adv.h"
+#include "controller/ble_ll.h"
+#include "controller/ble_ll_sched.h"
+#include "controller/ble_ll_adv.h"
 #include "controller/ll_scan.h"
 #include "controller/ll_hci.h"
 #include "hal/hal_cputime.h"
@@ -514,7 +514,7 @@ ble_ll_scan_chk_filter_policy(uint8_t pdu_type, uint8_t *rxbuf)
 }
 
 static int
-ble_ll_scan_win_end_cb(struct ll_sched_item *sch)
+ble_ll_scan_win_end_cb(struct ble_ll_sched_item *sch)
 {
     ble_phy_disable();
     ble_ll_event_send(&g_ble_ll_scan_sm.scan_win_end_ev);
@@ -522,7 +522,7 @@ ble_ll_scan_win_end_cb(struct ll_sched_item *sch)
 }
 
 static int
-ble_ll_scan_start_cb(struct ll_sched_item *sch)
+ble_ll_scan_start_cb(struct ble_ll_sched_item *sch)
 {
     int rc;
     struct ble_ll_scan_sm *scansm;
@@ -571,7 +571,7 @@ ble_ll_scan_sm_stop(struct ble_ll_scan_sm *scansm)
     /* XXX: Stop any timers we may have started */
 
     /* Remove any scheduled advertising items */
-    ll_sched_rmv(BLE_LL_SCHED_TYPE_SCAN);
+    ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_SCAN);
 
     /* Disable the PHY */
     ble_phy_disable();
@@ -583,13 +583,13 @@ ble_ll_scan_sm_stop(struct ble_ll_scan_sm *scansm)
     ++g_ble_ll_scan_stats.scan_stops;
 }
 
-static struct ll_sched_item *
+static struct ble_ll_sched_item *
 ble_ll_scan_sched_set(struct ble_ll_scan_sm *scansm)
 {
     int rc;
-    struct ll_sched_item *sch;
+    struct ble_ll_sched_item *sch;
 
-    sch = ll_sched_get_item();
+    sch = ble_ll_sched_get_item();
     if (sch) {
         /* Set sched type */
         sch->sched_type = BLE_LL_SCHED_TYPE_SCAN;
@@ -609,7 +609,7 @@ ble_ll_scan_sched_set(struct ble_ll_scan_sm *scansm)
 
         /* XXX: for now, we cant get an overlap so assert on error. */
         /* Add the item to the scheduler */
-        rc = ll_sched_add(sch);
+        rc = ble_ll_sched_add(sch);
         assert(rc == 0);
     } else {
         ++g_ble_ll_scan_stats.cant_set_sched;
@@ -621,7 +621,7 @@ ble_ll_scan_sched_set(struct ble_ll_scan_sm *scansm)
 static int
 ble_ll_scan_sm_start(struct ble_ll_scan_sm *scansm)
 {
-    struct ll_sched_item *sch;
+    struct ble_ll_sched_item *sch;
 
     /* 
      * XXX: not sure if I should do this or just report whatever random

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ble_ll_sched.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_sched.c b/net/nimble/controller/src/ble_ll_sched.c
new file mode 100644
index 0000000..18c7245
--- /dev/null
+++ b/net/nimble/controller/src/ble_ll_sched.c
@@ -0,0 +1,237 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include "os/os.h"
+#include "controller/phy.h"
+#include "controller/ble_ll.h"
+#include "controller/ble_ll_sched.h"
+#include "hal/hal_cputime.h"
+
+/* XXX: this is temporary. Not sure what I want to do here */
+struct cpu_timer g_ble_ll_sched_timer;
+
+/* XXX: TODO:
+ *  1) Add a "priority" scheme possibly. This would allow items to be
+ *  added if they overlapped.
+ *  2) Add some accounting to the schedule code to see how late we are
+ *  (min/max?)
+ */
+#define BLE_LL_CFG_SCHED_ITEMS      (8)
+#define BLE_LL_SCHED_POOL_SIZE      \
+    OS_MEMPOOL_SIZE(BLE_LL_CFG_SCHED_ITEMS, sizeof(struct ble_ll_sched_item))
+
+struct os_mempool g_ble_ll_sched_pool;
+os_membuf_t g_ble_ll_sched_mem[BLE_LL_SCHED_POOL_SIZE];
+
+/* Queue for timers */
+TAILQ_HEAD(ll_sched_qhead, ble_ll_sched_item) g_ble_ll_sched_q;
+
+/**
+ * Executes a schedule item by calling the schedule callback function.
+ * 
+ * @param sch Pointer to schedule item
+ * 
+ * @return int 0: schedule item is not over; otherwise schedule item is done.
+ */
+int
+ble_ll_sched_execute(struct ble_ll_sched_item *sch)
+{
+    int rc;
+
+    assert(sch->sched_cb);
+    rc = sch->sched_cb(sch);
+    return rc;
+}
+
+
+/**
+ * Allocate a schedule item
+ * 
+ * @return struct ble_ll_sched_item* 
+ */
+struct ble_ll_sched_item *
+ble_ll_sched_get_item(void)
+{
+    struct ble_ll_sched_item *sch;
+
+    sch = os_memblock_get(&g_ble_ll_sched_pool);
+    if (sch) {
+        memset(sch, 0, sizeof(struct ble_ll_sched_item));
+    }
+    return sch;
+}
+
+/**
+ * Free a schedule item
+ * 
+ * @param sch 
+ */
+void
+ble_ll_sched_free_item(struct ble_ll_sched_item *sch)
+{
+    os_error_t err;
+    err = os_memblock_put(&g_ble_ll_sched_pool, sch);
+    assert(err == OS_OK);
+}
+
+/**
+ * Add a schedule item to the schedule list
+ * 
+ * @param sch 
+ * 
+ * @return int 
+ */
+int
+ble_ll_sched_add(struct ble_ll_sched_item *sch)
+{
+    int rc;
+    os_sr_t sr;
+    struct ble_ll_sched_item *entry;
+
+    /* Determine if we are able to add this to the schedule */
+    OS_ENTER_CRITICAL(sr);
+
+    rc = 0;
+    if (TAILQ_EMPTY(&g_ble_ll_sched_q)) {
+        TAILQ_INSERT_HEAD(&g_ble_ll_sched_q, sch, link);
+    } else {
+        cputime_timer_stop(&g_ble_ll_sched_timer);
+        TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
+            if ((int32_t)(sch->start_time - entry->start_time) < 0) {
+                /* Make sure this event does not overlap current event */
+                if ((int32_t)(sch->end_time - entry->start_time) < 0) {
+                    TAILQ_INSERT_BEFORE(entry, sch, link);   
+                } else {
+                    rc = BLE_LL_SCHED_ERR_OVERLAP;
+                }
+                break;
+            } else {
+                /* Check for overlap */
+                if ((int32_t)(sch->start_time - entry->end_time) < 0) {
+                    rc = BLE_LL_SCHED_ERR_OVERLAP;
+                    break;
+                }
+            }
+        }
+        if (!entry) {
+            TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link);
+        }
+    }
+
+    OS_EXIT_CRITICAL(sr);
+
+    cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time);
+
+    return rc;
+}
+
+/**
+ * Remove a schedule item 
+ * 
+ * @param sched_type 
+ * 
+ * @return int 
+ */
+int
+ble_ll_sched_rmv(uint8_t sched_type)
+{
+    os_sr_t sr;
+    struct ble_ll_sched_item *entry;
+    struct ble_ll_sched_item *next;
+
+    OS_ENTER_CRITICAL(sr);
+
+    entry = TAILQ_FIRST(&g_ble_ll_sched_q);
+    if (entry) {
+        cputime_timer_stop(&g_ble_ll_sched_timer);
+        while (entry) {
+            next = TAILQ_NEXT(entry, link);
+            if (entry->sched_type == sched_type) {
+                TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link);
+                os_memblock_put(&g_ble_ll_sched_pool, entry);
+            } 
+            entry = next;
+        }
+
+        /* Start the timer if there is an item */
+        entry = TAILQ_FIRST(&g_ble_ll_sched_q);
+        if (entry) {
+            cputime_timer_start(&g_ble_ll_sched_timer, entry->start_time);
+        }
+    }
+
+    OS_EXIT_CRITICAL(sr);
+
+    return 0;
+}
+
+/**
+ * Run the BLE scheduler. Iterate through all items on the schedule queue.
+ *  
+ * Context: interrupt (scheduler) 
+ * 
+ * @return int 
+ */
+void
+ble_ll_sched_run(void *arg)
+{
+    int rc;
+    struct ble_ll_sched_item *sch;
+
+    /* Look through schedule queue */
+    while ((sch = TAILQ_FIRST(&g_ble_ll_sched_q)) != NULL) {
+        /* Make sure we have passed the start time of the first event */
+        if ((int32_t)(cputime_get32() - sch->start_time) >= 0) {
+            /* Execute the schedule item */
+            rc = ble_ll_sched_execute(sch);
+            if (rc) {
+                TAILQ_REMOVE(&g_ble_ll_sched_q, sch, link);
+                os_memblock_put(&g_ble_ll_sched_pool, sch);
+            } else {
+                /* Event is not over; schedule next wakeup time */
+                cputime_timer_start(&g_ble_ll_sched_timer, sch->next_wakeup);
+                break;
+            }
+        } else {
+            cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time);
+            break;
+        }
+    }
+}
+
+/**
+ * Initialize the scheduler. Should only be called once and should be called 
+ * before any of the scheduler API are called. 
+ * 
+ * @return int 
+ */
+int
+ble_ll_sched_init(void)
+{
+    os_error_t err;
+
+    err = os_mempool_init(&g_ble_ll_sched_pool, BLE_LL_CFG_SCHED_ITEMS, 
+                          sizeof(struct ble_ll_sched_item), 
+                          g_ble_ll_sched_mem, "ll_sched");
+    assert(err == OS_OK);
+
+    /* Start cputimer for the scheduler */
+    cputime_timer_init(&g_ble_ll_sched_timer, ble_ll_sched_run, NULL);
+
+    return err;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/36623dd5/net/nimble/controller/src/ll.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ll.c b/net/nimble/controller/src/ll.c
deleted file mode 100644
index ea25f6d..0000000
--- a/net/nimble/controller/src/ll.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <stdint.h>
-#include <assert.h>
-#include <string.h>
-#include "os/os.h"
-#include "nimble/ble.h"
-#include "controller/phy.h"
-#include "controller/ll.h"
-#include "controller/ll_adv.h"
-#include "controller/ll_sched.h"
-#include "controller/ll_scan.h"
-#include "controller/ll_hci.h"
-
-/* XXX: use the sanity task! */
-
-/* Connection related define */
-#define BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS  (27)
-#define BLE_LL_CONN_INIT_MAX_REMOTE_TIME    (238)
-
-/* The global BLE LL data object */
-struct ll_obj g_ll_data;
-
-/* Global link layer statistics */
-struct ll_stats g_ll_stats;
-
-/* The BLE LL task data structure */
-#define BLE_LL_TASK_PRI     (OS_TASK_PRI_HIGHEST)
-#define BLE_LL_STACK_SIZE   (128)
-struct os_task g_ll_task;
-os_stack_t g_ll_stack[BLE_LL_STACK_SIZE];
-
-/* XXX: this is just temporary; used to calculate the channel index */
-struct ll_sm_connection
-{
-    /* Data channel index for connection */
-    uint8_t unmapped_chan;
-    uint8_t last_unmapped_chan;
-    uint8_t num_used_channels;
-
-    /* Flow control */
-    uint8_t tx_seq;
-    uint8_t next_exp_seq;
-
-    /* Parameters kept by the link-layer per connection */
-    uint8_t max_tx_octets;
-    uint8_t max_rx_octets;
-    uint8_t max_tx_time;
-    uint8_t max_rx_time;
-    uint8_t remote_max_tx_octets;
-    uint8_t remote_max_rx_octets;
-    uint8_t remote_max_tx_time;
-    uint8_t remote_max_rx_time;
-    uint8_t effective_max_tx_octets;
-    uint8_t effective_max_rx_octets;
-    uint8_t effective_max_tx_time;
-    uint8_t effective_max_rx_time;
-
-    /* The connection request data */
-    struct ble_conn_req_data req_data; 
-};
-
-uint8_t
-ll_next_data_channel(struct ll_sm_connection *cnxn)
-{
-    int     i;
-    int     j;
-    uint8_t curchan;
-    uint8_t remap_index;
-    uint8_t bitpos;
-    uint8_t cntr;
-    uint8_t mask;
-    uint8_t usable_chans;
-
-    /* Get next un mapped channel */
-    curchan = (cnxn->last_unmapped_chan + cnxn->req_data.hop_inc) % 
-              BLE_PHY_NUM_DATA_CHANS;
-
-    /* Set the current unmapped channel */
-    cnxn->unmapped_chan = curchan;
-
-    /* Is this a valid channel? */
-    bitpos = 1 << (curchan & 0x07);
-    if ((cnxn->req_data.chanmap[curchan >> 3] & bitpos) == 0) {
-
-        /* Calculate remap index */
-        remap_index = curchan % cnxn->num_used_channels;
-
-        /* Iterate through channel map to find this channel */
-        cntr = 0;
-        for (i = 0; i < 5; i++) {
-            usable_chans = cnxn->req_data.chanmap[i];
-            if (usable_chans != 0) {
-                mask = 0x01;
-                for (j = 0; j < 8; j++) {
-                    if (usable_chans & mask) {
-                        if (cntr == remap_index) {
-                            return cntr;
-                        }
-                        ++cntr;
-                    }
-                    mask <<= 1;
-                }
-            }
-        }
-    }
-
-    return curchan;
-}
-
-/* Called when a connection gets initialized */
-int
-ble_init_conn_sm(struct ll_sm_connection *cnxn)
-{
-    cnxn->max_tx_time = g_ll_data.ll_params.conn_init_max_tx_time;
-    cnxn->max_rx_time = g_ll_data.ll_params.supp_max_rx_time;
-    cnxn->max_tx_octets = g_ll_data.ll_params.conn_init_max_tx_octets;
-    cnxn->max_rx_octets = g_ll_data.ll_params.supp_max_rx_octets;
-    cnxn->remote_max_rx_octets = BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS;
-    cnxn->remote_max_tx_octets = BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS;
-    cnxn->remote_max_rx_time = BLE_LL_CONN_INIT_MAX_REMOTE_TIME;
-    cnxn->remote_max_tx_time = BLE_LL_CONN_INIT_MAX_REMOTE_TIME;
-
-    return 0;
-}
-
-static void
-ble_ll_count_rx_pkts(uint8_t pdu_type)
-{
-    /* Count received packet types  */
-    switch (pdu_type) {
-    case BLE_ADV_PDU_TYPE_ADV_IND:
-        ++g_ll_stats.rx_adv_ind;
-        break;
-    case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
-        /* XXX: Do I want to count these if they are not for me? */
-        ++g_ll_stats.rx_adv_direct_ind;
-        break;
-    case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND:
-        ++g_ll_stats.rx_adv_nonconn_ind;
-        break;
-    case BLE_ADV_PDU_TYPE_SCAN_REQ:
-        /* XXX: Do I want to count these if they are not for me? */
-        ++g_ll_stats.rx_scan_reqs;
-        break;
-    case BLE_ADV_PDU_TYPE_SCAN_RSP:
-        ++g_ll_stats.rx_scan_rsps;
-        break;
-    case BLE_ADV_PDU_TYPE_CONNECT_REQ:
-        /* XXX: Do I want to count these if they are not for me? */
-        ++g_ll_stats.rx_connect_reqs;
-        break;
-    case BLE_ADV_PDU_TYPE_ADV_SCAN_IND:
-        ++g_ll_stats.rx_scan_ind;
-        break;
-    default:
-        ++g_ll_stats.rx_unk_pdu;
-        break;
-    }
-}
-
-
-int
-ble_ll_is_on_whitelist(uint8_t *addr, int addr_type)
-{
-    /* XXX: implement this */
-    return 1;
-}
-
-int
-ble_ll_is_resolvable_priv_addr(uint8_t *addr)
-{
-    /* XXX: implement this */
-    return 0;
-}
-
-/* Checks to see that the device is a valid random address */
-int
-ble_ll_is_valid_random_addr(uint8_t *addr)
-{
-    int i;
-    int rc;
-    uint16_t sum;
-    uint8_t addr_type;
-
-    /* Make sure all bits are neither one nor zero */
-    sum = 0;
-    for (i = 0; i < (BLE_DEV_ADDR_LEN -1); ++i) {
-        sum += addr[i];
-    }
-    sum += addr[5] & 0x3f;
-
-    if ((sum == 0) || (sum == ((5*255) + 0x3f))) {
-        return 0;
-    }
-
-    /* Get the upper two bits of the address */
-    rc = 1;
-    addr_type = addr[5] & 0xc0;
-    if (addr_type == 0xc0) {
-        /* Static random address. No other checks needed */
-    } else if (addr_type == 0x40) {
-        /* Resolvable */
-        sum = addr[3] + addr[4] + (addr[5] & 0x3f);
-        if ((sum == 0) || (sum == (255 + 255 + 0x3f))) {
-            rc = 0;
-        }
-    } else if (addr_type == 0) {
-        /* non-resolvable. Cant be equal to public */
-        if (!memcmp(g_dev_addr, addr, BLE_DEV_ADDR_LEN)) {
-            rc = 0;
-        }
-    } else {
-        /* Invalid upper two bits */
-        rc = 0;
-    }
-
-    return rc;
-}
-
-/**
- * Called from the HCI command parser when the set random address command 
- * is received. 
- *  
- * Context: Link Layer task (HCI command parser) 
- * 
- * @param addr Pointer to address
- * 
- * @return int 0: success
- */
-int
-ble_ll_set_random_addr(uint8_t *addr)
-{
-    int rc;
-
-    rc = BLE_ERR_INV_HCI_CMD_PARMS;
-    if (ble_ll_is_valid_random_addr(addr)) {
-        memcpy(g_random_addr, addr, BLE_DEV_ADDR_LEN);
-        rc = BLE_ERR_SUCCESS;
-    }
-
-    return rc;
-}
-
-int
-ble_ll_is_our_devaddr(uint8_t *addr, int addr_type)
-{
-    int rc;
-    uint8_t *our_addr;
-
-    rc = 0;
-    if (addr_type) {
-        our_addr = g_dev_addr;
-    } else {
-        our_addr = g_random_addr;
-    }
-
-    rc = 0;
-    if (!memcmp(our_addr, g_random_addr, BLE_DEV_ADDR_LEN)) {
-        rc = 1;
-    }
-
-    return rc;
-}
-
-/**
- * ll pdu tx time get 
- *  
- * Returns the number of usecs it will take to transmit a PDU of length 'len' 
- * bytes. Each byte takes 8 usecs. 
- * 
- * @param len The number of PDU bytes to transmit
- * 
- * @return uint16_t The number of usecs it will take to transmit a PDU of 
- *                  length 'len' bytes. 
- */
-uint16_t
-ll_pdu_tx_time_get(uint16_t len)
-{
-    len += BLE_LL_OVERHEAD_LEN;
-    len = len << 3;
-    return len;
-}
-
-/**
- * ll rx pkt in proc
- *  
- * Process received packet from PHY 
- *  
- * Callers: LL task. 
- *  
- */
-void
-ll_rx_pkt_in_proc(void)
-{
-    os_sr_t sr;
-    uint8_t pdu_type;
-    uint8_t *rxbuf;
-    struct os_mbuf_pkthdr *pkthdr;
-    struct ble_mbuf_hdr *ble_hdr;
-    struct os_mbuf *m;
-
-    /* Drain all packets off the queue */
-    while (STAILQ_FIRST(&g_ll_data.ll_rx_pkt_q)) {
-        /* Get mbuf pointer from packet header pointer */
-        pkthdr = STAILQ_FIRST(&g_ll_data.ll_rx_pkt_q);
-        m = (struct os_mbuf *)((uint8_t *)pkthdr - sizeof(struct os_mbuf));
-
-        /* Remove from queue */
-        OS_ENTER_CRITICAL(sr);
-        STAILQ_REMOVE_HEAD(&g_ll_data.ll_rx_pkt_q, omp_next);
-        OS_EXIT_CRITICAL(sr);
-
-        /* XXX: need to check if this is an adv channel or data channel */
-
-        /* Count statistics */
-        rxbuf = m->om_data;
-        pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
-        ble_hdr = BLE_MBUF_HDR_PTR(m); 
-        if (ble_hdr->crcok) {
-            /* The total bytes count the PDU header and PDU payload */
-            g_ll_stats.rx_bytes += pkthdr->omp_len;
-            ++g_ll_stats.rx_crc_ok;
-            ble_ll_count_rx_pkts(pdu_type);
-        } else {
-            ++g_ll_stats.rx_crc_fail;
-        }
-
-        /* 
-         * XXX: The reason I dont bail earlier on bad CRC is that
-         * there may be some connection stuff I need to do with a packet
-         * that has failed the CRC.
-         */ 
-
-        /* Process the PDU */
-        switch (g_ll_data.ll_state) {
-        case BLE_LL_STATE_ADV:
-            /* XXX: implement this */
-            break;
-        case BLE_LL_STATE_SCANNING:
-            if (ble_hdr->crcok) {
-                ble_ll_scan_rx_pdu_proc(pdu_type, rxbuf, ble_hdr->rssi);
-            }
-
-            /* We need to re-enable the PHY if we are in idle state */
-            if (ble_phy_state_get() == BLE_PHY_STATE_IDLE) {
-                /* XXX: If this returns error, we will need to attempt to
-                   re-start scanning! */
-                ble_phy_rx();
-            }
-            break;
-        default:
-            /* XXX: implement */
-            assert(0);
-            break;
-        }
-
-        /* XXX: Free the mbuf for now */
-        os_mbuf_free(&g_mbuf_pool, m);
-    }
-}
-
-/**
- * ll rx pdu in 
- *  
- * Called to put a packet on the Link Layer receive packet queue. 
- * 
- * 
- * @param rxpdu Pointer to received PDU
- */
-void
-ll_rx_pdu_in(struct os_mbuf *rxpdu)
-{
-    struct os_mbuf_pkthdr *pkthdr;
-
-    pkthdr = OS_MBUF_PKTHDR(rxpdu);
-    STAILQ_INSERT_TAIL(&g_ll_data.ll_rx_pkt_q, pkthdr, omp_next);
-    os_eventq_put(&g_ll_data.ll_evq, &g_ll_data.ll_rx_pkt_ev);
-}
-
-/**
- * ll rx start
- * 
- * 
- * @param rxpdu 
- * 
- * @return int 
- *   < 0: A frame we dont want to receive.
- *   = 0: Continue to receive frame. Dont go from rx to tx
- *   > 1: Continue to receive frame and go from rx to idle when done
- */
-int
-ll_rx_start(struct os_mbuf *rxpdu)
-{
-    int rc;
-    uint8_t pdu_type;
-    uint8_t *rxbuf;
-
-    /* XXX: need to check if this is an adv channel or data channel */
-    rxbuf = rxpdu->om_data;
-    pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
-
-    switch (g_ll_data.ll_state) {
-    case BLE_LL_STATE_ADV:
-        /* If we get a scan request we must tell the phy to go from rx to tx */
-        if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
-            rc = 1;
-        } else if (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_REQ) {
-            rc = 0;
-        } else {
-            /* This is a frame we dont want. Just abort it */
-            rc = -1;
-        }
-        break;
-    case BLE_LL_STATE_SCANNING:
-        rc = ble_ll_scan_rx_pdu_start(pdu_type, rxpdu);
-        break;
-    default:
-        /* XXX: should we really assert here? What to do... */
-        rc = -1;
-        assert(0);
-        break;
-    }
-
-    return rc;
-}
-
-/**
- * ll rx end 
- *  
- * Called by the PHY when a receive packet has ended. 
- *  
- * NOTE: Called from interrupt context!
- * 
- * @param rxbuf 
- * 
- * @return int 
- *       < 0: Disable the phy after reception.
- *      == 0: Success. Do not disable the PHY.
- *       > 0: Do not disable PHY as that has already been done.
- */
-int
-ll_rx_end(struct os_mbuf *rxpdu, uint8_t crcok)
-{
-    int rc;
-    int badpkt;
-    uint8_t pdu_type;
-    uint8_t len;
-    uint16_t mblen;
-    uint8_t *rxbuf;
-
-    /* Set the rx buffer pointer to the start of the received data */
-    rxbuf = rxpdu->om_data;
-
-    /* XXX: need to check if this is an adv channel or data channel */
-    pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
-    len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
-
-    /* XXX: Should I do this at LL task context? */
-    /* If the CRC checks, make sure lengths check! */
-    badpkt = 0;
-    if (crcok) {
-        switch (pdu_type) {
-        case BLE_ADV_PDU_TYPE_SCAN_REQ:
-        case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
-            if (len != BLE_SCAN_REQ_LEN) {
-                badpkt = 1;
-            }
-            break;
-        case BLE_ADV_PDU_TYPE_SCAN_RSP:
-        case BLE_ADV_PDU_TYPE_ADV_IND:
-        case BLE_ADV_PDU_TYPE_ADV_SCAN_IND:
-        case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND:
-            if ((len < BLE_DEV_ADDR_LEN) || (len > BLE_ADV_SCAN_IND_MAX_LEN)) {
-                badpkt = 1;
-            }
-            break;
-        case BLE_ADV_PDU_TYPE_CONNECT_REQ:
-            if (len != BLE_CONNECT_REQ_LEN) {
-                badpkt = 1;
-            }
-            break;
-        default:
-            badpkt = 1;
-            break;
-        }
-    }
-
-    /* If this is a malformed packet, just kill it here */
-    if (badpkt) {
-        ++g_ll_stats.rx_malformed_pkts;
-        os_mbuf_free(&g_mbuf_pool, rxpdu);
-        return -1;
-    }
-
-    /* Setup the mbuf */
-    mblen = len + BLE_LL_PDU_HDR_LEN;
-    OS_MBUF_PKTHDR(rxpdu)->omp_len = mblen;
-    rxpdu->om_len = mblen;
-
-    rc = -1;
-    switch (g_ll_data.ll_state) {
-    case BLE_LL_STATE_ADV:
-        /* If we get a scan request*/
-        if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
-            /* Just bail if CRC is not good */
-            if (crcok) {
-                rc = ble_ll_adv_rx_scan_req(rxbuf);
-                if (rc) {
-                    /* XXX: One thing left to reconcile here. We have
-                     * the advertisement schedule element still running.
-                     * How to deal with the end of the advertising event?
-                     * Need to figure that out.
-                     */
-                }
-            }
-        } else {
-            if (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_REQ) {
-                rc = 0;
-                /* XXX: deal with this */
-            }
-        }
-        break;
-    case BLE_LL_STATE_SCANNING:
-        if (crcok) {
-            /* 
-             * NOTE: If this returns a positive number there was an error but
-             * there is no need to disable the PHY on return as that was
-             * done already.
-             */
-            rc = ble_ll_scan_rx_pdu_end(rxbuf);
-        }
-        break;
-    default:
-        assert(0);
-        break;
-    }
-
-    /* Hand packet up to higher layer */
-    ll_rx_pdu_in(rxpdu);
-
-    return rc;
-}
-
-void
-ll_task(void *arg)
-{
-    struct os_event *ev;
-
-    /* Init ble phy */
-    ble_phy_init();
-
-    /* Set output power to 1mW (0 dBm) */
-    ble_phy_txpwr_set(0);
-
-    /* Wait for an event */
-    while (1) {
-        ev = os_eventq_get(&g_ll_data.ll_evq);
-        switch (ev->ev_type) {
-        case OS_EVENT_T_TIMER:
-            break;
-        case BLE_LL_EVENT_HCI_CMD:
-            /* Process HCI command */
-            ble_ll_hci_cmd_proc(ev);
-            break;
-        case BLE_LL_EVENT_ADV_TXDONE:
-            ll_adv_tx_done_proc(ev->ev_arg);
-            break;
-        case BLE_LL_EVENT_SCAN_WIN_END:
-            ble_ll_scan_win_end_proc(ev->ev_arg);
-            break;
-        case BLE_LL_EVENT_RX_PKT_IN:
-            ll_rx_pkt_in_proc();
-            break;
-        default:
-            assert(0);
-            break;
-        }
-
-        /* XXX: we can possibly take any finished schedule items and
-           free them here. Have a queue for them. */
-    }
-}
-
-/**
- * ble ll state set
- *  
- * Called to set the current link layer state. 
- *  
- * Context: Interrupt and Link Layer task
- * 
- * @param ll_state 
- */
-void
-ble_ll_state_set(int ll_state)
-{
-    g_ll_data.ll_state = ll_state;
-}
-
-/**
- * ble ll event send
- *  
- * Send an event to the Link Layer task 
- * 
- * @param ev Event to add to the Link Layer event queue.
- */
-void
-ble_ll_event_send(struct os_event *ev)
-{
-    os_eventq_put(&g_ll_data.ll_evq, ev);
-}
-
-/**
- * Initialize the Link Layer. Should be called only once 
- * 
- * @return int 
- */
-int
-ll_init(void)
-{
-    /* Initialize the receive queue */
-    STAILQ_INIT(&g_ll_data.ll_rx_pkt_q);
-
-    /* Initialize eventq */
-    os_eventq_init(&g_ll_data.ll_evq);
-
-    /* Initialize receive packet (from phy) event */
-    g_ll_data.ll_rx_pkt_ev.ev_type = BLE_LL_EVENT_RX_PKT_IN;
-
-    /* Initialize LL HCI */
-    ble_ll_hci_init();
-
-    /* Init the scheduler */
-    ll_sched_init();
-
-    /* Initialize advertiser */
-    ll_adv_init();
-
-    /* Initialize a scanner */
-    ble_ll_scan_init();
-
-    /* Initialize the LL task */
-    os_task_init(&g_ll_task, "ble_ll", ll_task, NULL, BLE_LL_TASK_PRI, 
-                 OS_WAIT_FOREVER, g_ll_stack, BLE_LL_STACK_SIZE);
-
-    return 0;
-}
-