/** * 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; }
/** * Start the advertising state machine. This is called when the host sends * the "enable advertising" command and is not called again while in the * advertising state. * * 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; /* * This is not in the specification. I will reject the command with a * command disallowed error if no random address has been sent by the * host. All the parameter errors refer to the command * parameter (which in this case is just enable or disable) so that * is why I chose command disallowed. */ if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) { if (!ble_ll_is_valid_random_addr(g_random_addr)) { return BLE_ERR_CMD_DISALLOWED; } } /* Set flag telling us that advertising is enabled */ advsm->enabled = 1; /* Determine the advertising interval we will use */ if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) { /* Set it to max. allowed for high duty cycle advertising */ advsm->adv_itvl_usecs = BLE_LL_ADV_PDU_ITVL_HD_MS_MAX; } else { advsm->adv_itvl_usecs = (uint32_t)advsm->adv_itvl_max; advsm->adv_itvl_usecs *= BLE_LL_ADV_ITVL; } /* 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; /* * Schedule advertising. We set the initial schedule start and end * times to the earliest possible start/end. */ ble_ll_adv_set_sched(advsm, 1); ble_ll_sched_adv_new(&advsm->adv_sch); return BLE_ERR_SUCCESS; }
/** * Start the advertising state machine. This is called when the host sends * the "enable advertising" command and is not called again while in the * advertising state. * * 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; uint8_t *addr; uint8_t *evbuf; /* * This is not in the specification. I will reject the command with a * command disallowed error if no random address has been sent by the * host. All the parameter errors refer to the command * parameter (which in this case is just enable or disable) so that * is why I chose command disallowed. */ if (advsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) { if (!ble_ll_is_valid_random_addr(g_random_addr)) { return BLE_ERR_CMD_DISALLOWED; } } /* * Get an event with which to send the connection complete event if * this is connectable */ switch (advsm->adv_type) { case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD: case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD: case BLE_HCI_ADV_TYPE_ADV_IND: /* We expect this to be NULL but if not we wont allocate one... */ if (advsm->conn_comp_ev == NULL) { evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (!evbuf) { return BLE_ERR_MEM_CAPACITY; } advsm->conn_comp_ev = evbuf; } break; default: break; } /* Set advertising address */ if ((advsm->own_addr_type & 1) == 0) { addr = g_dev_addr; advsm->adv_txadd = 0; } else { addr = g_random_addr; advsm->adv_txadd = 1; } memcpy(advsm->adva, addr, BLE_DEV_ADDR_LEN); if (advsm->adv_directed) { memcpy(advsm->initiator_addr, advsm->peer_addr, BLE_DEV_ADDR_LEN); if (advsm->peer_addr_type & 1) { advsm->adv_rxadd = 1; } else { advsm->adv_rxadd = 0; } } /* This will generate an RPA for both initiator addr and adva */ #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1) ble_ll_adv_chk_rpa_timeout(advsm); #endif /* Set flag telling us that advertising is enabled */ advsm->enabled = 1; /* Determine the advertising interval we will use */ if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) { /* Set it to max. allowed for high duty cycle advertising */ advsm->adv_itvl_usecs = BLE_LL_ADV_PDU_ITVL_HD_MS_MAX; } else { advsm->adv_itvl_usecs = (uint32_t)advsm->adv_itvl_max; advsm->adv_itvl_usecs *= BLE_LL_ADV_ITVL; } /* Set first advertising channel */ adv_chan = ble_ll_adv_first_chan(advsm); advsm->adv_chan = adv_chan; /* * Schedule advertising. We set the initial schedule start and end * times to the earliest possible start/end. */ ble_ll_adv_set_sched(advsm, 1); ble_ll_sched_adv_new(&advsm->adv_sch); return BLE_ERR_SUCCESS; }