Exemplo n.º 1
0
/**
 * Turn advertising on/off.
 *
 * Context: Link Layer task
 *
 * @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) {
        ble_ll_adv_sm_stop(advsm);
    } else {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return rc;
}
Exemplo n.º 2
0
/**
 * Reset the advertising state machine.
 *
 * Context: Link Layer task
 *
 */
void
ble_ll_adv_reset(void)
{
    struct ble_ll_adv_sm *advsm;
    advsm = &g_ble_ll_adv_sm;

    /* Stop advertising state machine */
    ble_ll_adv_sm_stop(advsm);

    /* re-initialize the advertiser state machine */
    ble_ll_adv_init();
}
/**
 * Called when a connect request has been received.
 *
 * Context: Link Layer
 *
 * @param rxbuf
 * @param flags
 *
 * @return 0: no connection started. 1: connection started
 */
int
ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr)
{
    int valid;
    uint8_t pyld_len;
    uint8_t *inita;
    uint32_t endtime;
    struct ble_ll_adv_sm *advsm;

    /* Check filter policy. */
    valid = 0;
    advsm = &g_ble_ll_adv_sm;
    if (advsm->adv_filter_policy & 2) {
        if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_DEVMATCH) {
            /* valid connection request received */
            valid = 1;
        }
    } else {
        /* If this is for us? */
        if (!ble_ll_adv_addr_cmp(rxbuf)) {
            /*
             * Only accept connect requests from the desired address if we
             * are doing directed advertising
             */
            if ((advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) ||
                (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) {
                /* XXX: not sure if this works if address is random */
                /* Compare addresses */
                inita = rxbuf + BLE_LL_PDU_HDR_LEN;
                if (!memcmp(advsm->initiator_addr, inita, BLE_DEV_ADDR_LEN)) {
                    valid = 1;
                }
            } else {
                valid = 1;
            }
        }
    }

    if (valid) {
        /* Try to start slave connection. If successful, stop advertising */
        pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
        endtime = hdr->beg_cputime + BLE_TX_DUR_USECS_M(pyld_len);
        valid = ble_ll_conn_slave_start(rxbuf, endtime);
        if (valid) {
            ble_ll_adv_sm_stop(advsm);
        }
    }

    return valid;
}
/**
 * Reset the advertising state machine.
 *
 * Context: Link Layer task
 *
 */
void
ble_ll_adv_reset(void)
{
    struct ble_ll_adv_sm *advsm;
    advsm = &g_ble_ll_adv_sm;

    /* Stop advertising state machine */
    ble_ll_adv_sm_stop(advsm);

    /* Free scan pdu's */
    os_mbuf_free_chain(advsm->scan_rsp_pdu);

    /* re-initialize the advertiser state machine */
    ble_ll_adv_init();
}
Exemplo n.º 5
0
/**
 * Called when a connect request has been received.
 *
 * Context: Link Layer
 *
 * @param rxbuf
 * @param flags
 *
 * @return 0: no connection started. 1: connection started
 */
int
ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr)
{
    int valid;
    uint8_t pyld_len;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    uint8_t resolved;
#endif
    uint8_t addr_type;
    uint8_t *inita;
    uint8_t *ident_addr;
    uint32_t endtime;
    struct ble_ll_adv_sm *advsm;

    /* Check filter policy. */
    valid = 0;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    resolved = BLE_MBUF_HDR_RESOLVED(hdr);
#endif
    advsm = &g_ble_ll_adv_sm;
    inita = rxbuf + BLE_LL_PDU_HDR_LEN;
    if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_DEVMATCH) {

        valid = 1;
        if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) {
            addr_type = BLE_ADDR_TYPE_RANDOM;
        } else {
            addr_type = BLE_ADDR_TYPE_PUBLIC;
        }

        /*
         * Only accept connect requests from the desired address if we
         * are doing directed advertising
         */
        if ((advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) ||
            (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) {
            ident_addr = inita;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
            if (resolved) {
                ident_addr = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_identity_addr;
                addr_type = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_addr_type;
            }
#endif
            if ((addr_type != advsm->peer_addr_type) ||
                memcmp(advsm->peer_addr, ident_addr, BLE_DEV_ADDR_LEN)) {
                valid = 0;
            }
        }
    }

    if (valid) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
        if (resolved) {
            /* Retain the resolvable private address that we received. */
            memcpy(advsm->adv_rpa, inita, BLE_DEV_ADDR_LEN);

            /*
             * Overwrite received inita with identity address since that
             * is used from now on.
             */
            memcpy(inita,
                   g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_identity_addr,
                   BLE_DEV_ADDR_LEN);

            /* Peer address type is an identity address */
            addr_type = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_addr_type;
            addr_type += 2;
        }
#endif

        /* Try to start slave connection. If successful, stop advertising */
        pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
        endtime = hdr->beg_cputime + BLE_TX_DUR_USECS_M(pyld_len);
        valid = ble_ll_conn_slave_start(rxbuf, endtime, addr_type);
        if (valid) {
            ble_ll_adv_sm_stop(advsm);
        }
    }

    return valid;
}