/** * BLE test task * * @param arg */ void bletest_task_handler(void *arg) { int rc; uint64_t event_mask; struct os_event *ev; struct os_callout_func *cf; /* Set LED blink rate */ g_bletest_led_rate = OS_TICKS_PER_SEC / 20; /* Wait one second before starting test task */ os_time_delay(OS_TICKS_PER_SEC); /* Initialize eventq */ os_eventq_init(&g_bletest_evq); /* Initialize the host timer */ os_callout_func_init(&g_bletest_timer, &g_bletest_evq, bletest_timer_cb, NULL); /* Send the reset command first */ rc = host_hci_cmd_send(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_RESET, 0, NULL); assert(rc == 0); host_hci_outstanding_opcode = 0; #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER) /* Initialize the advertiser */ console_printf("Starting BLE test task as advertiser\n"); bletest_init_advertising(); #endif #if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER) /* Initialize the scanner */ console_printf("Starting BLE test task as scanner\n"); bletest_init_scanner(); #endif #if (BLETEST_CFG_ROLE == BLETEST_ROLE_INITIATOR) /* Initialize the scanner */ console_printf("Starting BLE test task as initiator\n"); bletest_init_initiator(); #endif /* Set the event mask we want to display */ event_mask = 0x7FF; rc = host_hci_cmd_le_set_event_mask(event_mask); assert(rc == 0); host_hci_outstanding_opcode = 0; /* Turn on all events */ event_mask = 0xffffffffffffffff; rc = host_hci_cmd_set_event_mask(event_mask); assert(rc == 0); host_hci_outstanding_opcode = 0; /* Turn on all events */ rc = host_hci_cmd_rd_local_version(); assert(rc == 0); host_hci_outstanding_opcode = 0; /* Wait some time before starting */ os_time_delay(OS_TICKS_PER_SEC); /* Init bletest variables */ g_bletest_state = 0; g_next_os_time = os_time_get(); /* Begin advertising if we are an advertiser */ #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER) rc = host_hci_cmd_le_set_adv_enable(1); assert(rc == 0); host_hci_outstanding_opcode = 0; #endif bletest_timer_cb(NULL); while (1) { ev = os_eventq_get(&g_bletest_evq); switch (ev->ev_type) { case OS_EVENT_T_TIMER: cf = (struct os_callout_func *)ev; assert(cf->cf_func); cf->cf_func(cf->cf_arg); break; default: assert(0); break; } } }
static void bletest_execute_advertiser(void) { int i; #if (BLETEST_CONCURRENT_CONN_TEST == 1) #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1) uint16_t mask; uint16_t reply_handle; #endif #endif int rc; uint16_t handle; struct os_mbuf *om; #if (BLETEST_THROUGHPUT_TEST == 1) os_sr_t sr; uint16_t completed_pkts; #endif /* See if we should start advertising again */ if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) { handle = g_bletest_current_conns + 1; if (ble_ll_conn_find_active_conn(handle)) { /* Set LED to slower blink rate */ g_bletest_led_rate = OS_TICKS_PER_SEC; #if (BLETEST_THROUGHPUT_TEST == 1) /* Set next os time to 10 seconds after 1st connection */ if (g_next_os_time == 0) { g_next_os_time = os_time_get() + (10 * OS_TICKS_PER_SEC); g_bletest_handle = handle; } #endif /* advertising better be stopped! */ assert(ble_ll_adv_enabled() == 0); /* Send the remote used features command */ rc = bletest_hci_le_read_rem_used_feat(handle); if (rc) { return; } /* Send the remote read version command */ rc = bletest_hci_rd_rem_version(handle); if (rc) { return; } /* set conn update time */ g_bletest_conn_upd_time = os_time_get() + (OS_TICKS_PER_SEC * 5); g_bletest_start_update = 1; /* Add to current connections */ ++g_bletest_current_conns; /* Move to next connection */ if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) { /* restart initiating */ g_bletest_cur_peer_addr[5] += 1; g_dev_addr[5] += 1; #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT) bletest_init_advertising(0,0); bletest_hci_le_set_multi_adv_enable(1, 0); #else bletest_init_advertising(); bletest_hci_le_set_adv_enable(1); #endif } } else { /* If we failed to start advertising we should keep trying */ if (ble_ll_adv_enabled() == 0) { #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT) bletest_hci_le_set_multi_adv_enable(1, 0); #else bletest_hci_le_set_adv_enable(1); #endif } } } #if 0 if (g_bletest_start_update) { if ((int32_t)(os_time_get() - g_bletest_conn_upd_time) >= 0) { bletest_send_conn_update(1); g_bletest_start_update = 0; } } #endif #if (BLETEST_CONCURRENT_CONN_TEST == 1) /* See if it is time to hand a data packet to the connection */ if ((int32_t)(os_time_get() - g_next_os_time) >= 0) { #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1) /* Do we need to send a LTK reply? */ mask = 1; reply_handle = 1; while (g_bletest_ltk_reply_handle && mask) { if (g_bletest_ltk_reply_handle & mask) { bletest_send_ltk_req_reply(reply_handle); //bletest_send_ltk_req_neg_reply(reply_handle); g_bletest_ltk_reply_handle &= ~mask; } ++reply_handle; mask <<= 1; } #endif if (g_bletest_current_conns) { for (i = 0; i < g_bletest_current_conns; ++i) { if ((g_last_handle_used == 0) || (g_last_handle_used > g_bletest_current_conns)) { g_last_handle_used = 1; } handle = g_last_handle_used; if (ble_ll_conn_find_active_conn(handle)) { om = bletest_send_packet(handle); if (om) { /* Increment last handle used */ ++g_last_handle_used; } } else { ++g_last_handle_used; } } } g_next_os_time = os_time_get() + OS_TICKS_PER_SEC; } #endif #if (BLETEST_THROUGHPUT_TEST == 1) /* Nothing to do if no connections */ if (!g_bletest_current_conns) { return; } /* See if it is time to start throughput testing */ if ((int32_t)(os_time_get() - g_next_os_time) >= 0) { /* Keep window full */ OS_ENTER_CRITICAL(sr); completed_pkts = g_bletest_completed_pkts; g_bletest_completed_pkts = 0; OS_EXIT_CRITICAL(sr); assert(g_bletest_outstanding_pkts >= completed_pkts); g_bletest_outstanding_pkts -= completed_pkts; while (g_bletest_outstanding_pkts < 20) { om = bletest_send_packet(g_bletest_handle); if (om) { ++g_bletest_outstanding_pkts; } } } #endif /* XXX: throughput test */ }
static void bletest_execute_advertiser(void) { int i,j; int rc; uint16_t handle; uint16_t pktlen; struct os_mbuf *om; /* See if we should start advertising again */ if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) { handle = g_bletest_current_conns + 1; if (ble_ll_conn_find_active_conn(handle)) { /* Set LED to slower blink rate */ g_bletest_led_rate = OS_TICKS_PER_SEC; /* advertising better be stopped! */ assert(ble_ll_adv_enabled() == 0); /* Send the remote used features command */ rc = host_hci_cmd_le_read_rem_used_feat(handle); host_hci_outstanding_opcode = 0; assert(rc == 0); /* Send the remote used features command */ rc = host_hci_cmd_rd_rem_version(handle); host_hci_outstanding_opcode = 0; assert(rc == 0); /* set conn update time */ g_bletest_conn_upd_time = os_time_get() + (OS_TICKS_PER_SEC * 5); g_bletest_start_update = 1; /* Add to current connections */ ++g_bletest_current_conns; /* Move to next connection */ if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) { /* restart initiating */ g_bletest_cur_peer_addr[5] += 1; g_dev_addr[5] += 1; bletest_init_advertising(); rc = host_hci_cmd_le_set_adv_enable(1); host_hci_outstanding_opcode = 0; assert(rc == 0); } } } #if 0 if (g_bletest_start_update) { if ((int32_t)(os_time_get() - g_bletest_conn_upd_time) >= 0) { bletest_send_conn_update(1); g_bletest_start_update = 0; } } #endif /* See if it is time to hand a data packet to the connection */ if ((int32_t)(os_time_get() - g_next_os_time) >= 0) { if (g_bletest_current_conns) { for (i = 0; i < g_bletest_current_conns; ++i) { if ((g_last_handle_used == 0) || (g_last_handle_used > g_bletest_current_conns)) { g_last_handle_used = 1; } handle = g_last_handle_used; if (ble_ll_conn_find_active_conn(handle)) { om = bletest_get_packet(); if (om) { /* set payload length */ pktlen = BLETEST_PKT_SIZE; om->om_len = BLETEST_PKT_SIZE + 4; /* Put the HCI header in the mbuf */ htole16(om->om_data, handle); htole16(om->om_data + 2, om->om_len); /* Place L2CAP header in packet */ htole16(om->om_data + 4, pktlen); om->om_data[6] = 0; om->om_data[7] = 0; /* Fill with incrementing pattern (starting from 1) */ for (j = 0; j < pktlen; ++j) { om->om_data[8 + j] = (uint8_t)(j + 1); } /* Add length */ om->om_len += 4; OS_MBUF_PKTHDR(om)->omp_len = om->om_len; ble_hci_transport_host_acl_data_send(om); /* Increment last handle used */ ++g_last_handle_used; } } } } g_next_os_time += OS_TICKS_PER_SEC; } }
/** * BLE test task * * @param arg */ void bletest_task_handler(void *arg) { int rc; uint64_t rand64; uint64_t event_mask; /* Set LED blink rate */ g_bletest_led_rate = OS_TICKS_PER_SEC / 20; /* Wait one second before starting test task */ os_time_delay(OS_TICKS_PER_SEC); /* Initialize the host timer */ os_callout_init(&g_bletest_timer, &g_bletest_evq, bletest_timer_cb, NULL); ble_hs_dbg_set_sync_state(BLE_HS_SYNC_STATE_GOOD); /* Send the reset command first */ rc = bletest_hci_reset_ctlr(); assert(rc == 0); #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER) /* Initialize the advertiser */ console_printf("Starting BLE test task as advertiser\n"); #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT) /* Start up all advertising instances except default one */ bletest_init_adv_instances(); /* Start advertising on instance 0 at 0 dbm */ bletest_init_advertising(0, 0); #else bletest_init_advertising(); #endif #endif #if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER) /* Initialize the scanner */ console_printf("Starting BLE test task as scanner\n"); bletest_init_scanner(); #endif #if (BLETEST_CFG_ROLE == BLETEST_ROLE_INITIATOR) /* Initialize the scanner */ console_printf("Starting BLE test task as initiator\n"); bletest_init_initiator(); #endif /* Read unique HW id */ rc = hal_bsp_hw_id((void *)&g_bletest_hw_id[0], sizeof(g_bletest_hw_id)); assert(rc == 16); console_printf("HW id=%04x%04x%04x%04x\n", (unsigned int)g_bletest_hw_id[0], (unsigned int)g_bletest_hw_id[1], (unsigned int)g_bletest_hw_id[2], (unsigned int)g_bletest_hw_id[3]); /* Set the event mask we want to display */ event_mask = 0x7FF; rc = bletest_hci_le_set_event_mask(event_mask); assert(rc == 0); /* Turn on all events */ event_mask = 0xffffffffffffffff; rc = bletest_hci_set_event_mask(event_mask); assert(rc == 0); /* Read device address */ rc = bletest_hci_rd_bd_addr(); assert(rc == 0); /* Read local features */ rc = bletest_hci_rd_local_feat(); assert(rc == 0); /* Read local commands */ rc = bletest_hci_rd_local_supp_cmd(); assert(rc == 0); /* Read version */ rc = bletest_hci_rd_local_version(); assert(rc == 0); /* Read supported states */ rc = bletest_hci_le_read_supp_states(); assert(rc == 0); /* Read maximum data length */ rc = bletest_hci_le_rd_max_datalen(); assert(rc == 0); #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) == 1) /* Read suggested data length */ rc = bletest_hci_le_rd_sugg_datalen(); assert(rc == 0); /* write suggested default data length */ rc = bletest_hci_le_write_sugg_datalen(BLETEST_CFG_SUGG_DEF_TXOCTETS, BLETEST_CFG_SUGG_DEF_TXTIME); assert(rc == 0); /* Read suggested data length */ rc = bletest_hci_le_rd_sugg_datalen(); assert(rc == 0); /* Set data length (note: we know there is no connection; just a test) */ rc = bletest_hci_le_set_datalen(0x1234, BLETEST_CFG_SUGG_DEF_TXOCTETS, BLETEST_CFG_SUGG_DEF_TXTIME); assert(rc != 0); #endif /* Encrypt a block */ #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1) rc = bletest_hci_le_encrypt((uint8_t *)g_ble_ll_encrypt_test_key, (uint8_t *)g_ble_ll_encrypt_test_plain_text); assert(rc == 0); #endif /* Get a random number */ rc = ble_hs_hci_util_rand(&rand64, 8); assert(rc == 0); /* Wait some time before starting */ os_time_delay(OS_TICKS_PER_SEC); /* Init state */ g_bletest_state = 0; /* Begin advertising if we are an advertiser */ #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER) #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT) rc = bletest_hci_le_set_multi_adv_enable(1, 0); assert(rc == 0); #else rc = bletest_hci_le_set_adv_enable(1); assert(rc == 0); #endif #endif bletest_timer_cb(NULL); while (1) { os_eventq_run(&g_bletest_evq); } }