/** * init_tasks * * Called by main.c after sysinit(). This function performs initializations * that are required before tasks are running. * * @return int 0 success; error otherwise. */ static void init_tasks(void) { os_stack_t *pstack; /* Initialize global test semaphore */ os_sem_init(&g_test_sem, 0); pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE); assert(pstack); os_task_init(&task1, "task1", task1_handler, NULL, TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE); pstack = malloc(sizeof(os_stack_t)*TASK2_STACK_SIZE); assert(pstack); os_task_init(&task2, "task2", task2_handler, NULL, TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE); pstack = malloc(sizeof(os_stack_t)*TASK3_STACK_SIZE); assert(pstack); os_task_init(&task3, "task3", task3_handler, NULL, TASK3_PRIO, OS_WAIT_FOREVER, pstack, TASK3_STACK_SIZE); /* Initialize eventq and designate it as the default. Packages that need * to schedule work items will piggyback on this eventq. Example packages * which do this are sys/shell and mgmt/newtmgr. */ os_eventq_init(&slinky_oic_evq); os_eventq_dflt_set(&slinky_oic_evq); mgmt_evq_set(&slinky_oic_evq); }
/** * BLE test task * * @param arg */ void prphtest_task_handler(void *arg) { struct ble_hs_adv_fields fields; struct os_callout_func *cf; struct os_event *ev; int rc; /* We are initialized */ console_printf("ADVERTISER\n"); /* Initialize eventq */ os_eventq_init(&g_prphtest_evq); /* Init prphtest variables */ g_prphtest_state = 0; g_next_os_time = os_time_get(); ble_gap_conn_set_cb(prphtest_on_connect, NULL); prphtest_register_attrs(); memset(&fields, 0, sizeof fields); fields.name = (uint8_t *)"nimble"; fields.name_len = 6; fields.name_is_complete = 1; rc = ble_gap_conn_set_adv_fields(&fields); assert(rc == 0); rc = ble_gap_conn_advertise(BLE_GAP_DISC_MODE_NON, BLE_GAP_CONN_MODE_UND, NULL, 0); assert(rc == 0); while (1) { ev = os_eventq_get(&g_prphtest_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 ocf_init_tasks(void) { int rc; rc = os_task_init(&ocf_main_task, "ocf", ocf_main_task_handler, NULL, OCF_MAIN_TASK_PRIO, OS_WAIT_FOREVER, ocf_stack, OCF_MAIN_TASK_STACK_SIZE); assert(rc == 0); /* Initialize eventq */ os_eventq_init(&ocf_main_evq); /* Set the default eventq for packages that lack a dedicated task. */ os_eventq_dflt_set(&ocf_main_evq); oc_main_init(&ocf_handler); }
/** * main * * The main function for the project. This function initializes the os, calls * init_tasks to initialize tasks (and possibly other objects), then starts the * OS. We should not return from os start. * * @return int NOTE: this function should never return! */ int main(void) { struct ble_hs_cfg cfg; uint32_t seed; int rc; int i; /* Initialize OS */ os_init(); /* Set cputime to count at 1 usec increments */ rc = cputime_init(1000000); assert(rc == 0); /* Seed random number generator with least significant bytes of device * address. */ seed = 0; for (i = 0; i < 4; ++i) { seed |= g_dev_addr[i]; seed <<= 8; } srand(seed); /* Initialize msys mbufs. */ rc = os_mempool_init(&bleprph_mbuf_mpool, MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE, bleprph_mbuf_mpool_data, "bleprph_mbuf_data"); assert(rc == 0); rc = os_mbuf_pool_init(&bleprph_mbuf_pool, &bleprph_mbuf_mpool, MBUF_MEMBLOCK_SIZE, MBUF_NUM_MBUFS); assert(rc == 0); rc = os_msys_register(&bleprph_mbuf_pool); assert(rc == 0); /* Initialize the logging system. */ log_init(); log_console_handler_init(&bleprph_log_console_handler); log_register("bleprph", &bleprph_log, &bleprph_log_console_handler); os_task_init(&bleprph_task, "bleprph", bleprph_task_handler, NULL, BLEPRPH_TASK_PRIO, OS_WAIT_FOREVER, bleprph_stack, BLEPRPH_STACK_SIZE); /* Initialize the BLE LL */ rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE); assert(rc == 0); /* Initialize the BLE host. */ cfg = ble_hs_cfg_dflt; cfg.max_hci_bufs = 3; cfg.max_connections = 1; cfg.max_attrs = 42; cfg.max_services = 5; cfg.max_client_configs = 6; cfg.max_gattc_procs = 2; cfg.max_l2cap_chans = 3; cfg.max_l2cap_sig_procs = 1; cfg.sm_bonding = 1; cfg.sm_our_key_dist = BLE_L2CAP_SM_PAIR_KEY_DIST_ENC; cfg.sm_their_key_dist = BLE_L2CAP_SM_PAIR_KEY_DIST_ENC; /* Initialize eventq */ os_eventq_init(&bleprph_evq); rc = ble_hs_init(&bleprph_evq, &cfg); assert(rc == 0); /* Initialize the console (for log output). */ rc = console_init(NULL); assert(rc == 0); /* Register GATT attributes (services, characteristics, and * descriptors). */ gatt_svr_init(); /* Start the OS */ os_start(); /* os start should never return. If it does, this should be an error */ assert(0); return 0; }
/** * 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; } } }
/** * Initializes the host portion of the BLE stack. */ int ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg) { int rc; ble_hs_free_mem(); if (app_evq == NULL) { rc = BLE_HS_EINVAL; goto err; } ble_hs_parent_evq = app_evq; ble_hs_cfg_init(cfg); log_init(); log_console_handler_init(&ble_hs_log_console_handler); log_register("ble_hs", &ble_hs_log, &ble_hs_log_console_handler); ble_hs_hci_cmd_buf = malloc(OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs, HCI_CMD_BUF_SIZE)); if (ble_hs_hci_cmd_buf == NULL) { rc = BLE_HS_ENOMEM; goto err; } /* Create memory pool of command buffers */ rc = os_mempool_init(&g_hci_cmd_pool, ble_hs_cfg.max_hci_bufs, HCI_CMD_BUF_SIZE, ble_hs_hci_cmd_buf, "HCICmdPool"); assert(rc == 0); ble_hs_hci_os_event_buf = malloc(OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs, HCI_OS_EVENT_BUF_SIZE)); if (ble_hs_hci_os_event_buf == NULL) { rc = BLE_HS_ENOMEM; goto err; } /* Create memory pool of OS events */ rc = os_mempool_init(&g_hci_os_event_pool, ble_hs_cfg.max_hci_bufs, HCI_OS_EVENT_BUF_SIZE, ble_hs_hci_os_event_buf, "HCIOsEventPool"); assert(rc == 0); /* Initialize eventq */ os_eventq_init(&ble_hs_evq); /* Initialize stats. */ rc = stats_module_init(); if (rc != 0) { rc = BLE_HS_EOS; goto err; } ble_hci_cmd_init(); rc = ble_hs_conn_init(); if (rc != 0) { goto err; } rc = ble_l2cap_init(); if (rc != 0) { goto err; } rc = ble_att_init(); if (rc != 0) { goto err; } rc = ble_att_svr_init(); if (rc != 0) { goto err; } rc = ble_gap_init(); if (rc != 0) { goto err; } rc = ble_gattc_init(); if (rc != 0) { goto err; } rc = ble_gatts_init(); if (rc != 0) { goto err; } os_mqueue_init(&ble_hs_rx_q, NULL); os_mqueue_init(&ble_hs_tx_q, NULL); rc = stats_init_and_reg( STATS_HDR(ble_hs_stats), STATS_SIZE_INIT_PARMS(ble_hs_stats, STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_hs_stats), "ble_hs"); if (rc != 0) { rc = BLE_HS_EOS; goto err; } os_callout_func_init(&ble_hs_heartbeat_timer, ble_hs_parent_evq, ble_hs_heartbeat, NULL); os_callout_func_init(&ble_hs_event_co, &ble_hs_evq, ble_hs_event_handle, NULL); rc = os_mutex_init(&ble_hs_mutex); if (rc != 0) { rc = BLE_HS_EOS; goto err; } return 0; err: ble_hs_free_mem(); return rc; }
/** * Initialize the Link Layer. Should be called only once * * @return int */ void ble_ll_init(void) { int rc; uint8_t features; struct ble_ll_obj *lldata; /* Get pointer to global data object */ lldata = &g_ble_ll_data; /* Set acl pkt size and number */ lldata->ll_num_acl_pkts = MYNEWT_VAL(BLE_ACL_BUF_COUNT); lldata->ll_acl_pkt_size = MYNEWT_VAL(BLE_ACL_BUF_SIZE); /* Initialize eventq */ os_eventq_init(&lldata->ll_evq); /* Initialize the transmit (from host) and receive (from phy) queues */ STAILQ_INIT(&lldata->ll_tx_pkt_q); STAILQ_INIT(&lldata->ll_rx_pkt_q); /* Initialize transmit (from host) and receive packet (from phy) event */ lldata->ll_rx_pkt_ev.ev_cb = ble_ll_event_rx_pkt; lldata->ll_tx_pkt_ev.ev_cb = ble_ll_event_tx_pkt; lldata->ll_dbuf_overflow_ev.ev_cb = ble_ll_event_dbuf_overflow; /* Initialize the HW error timer */ os_callout_init(&g_ble_ll_data.ll_hw_err_timer, &g_ble_ll_data.ll_evq, ble_ll_hw_err_timer_cb, NULL); /* Initialize wait for response timer */ os_cputime_timer_init(&g_ble_ll_data.ll_wfr_timer, ble_ll_wfr_timer_exp, NULL); ble_ll_hci_os_event_buf = malloc( OS_MEMPOOL_BYTES(16, sizeof (struct os_event))); SYSINIT_PANIC_ASSERT(ble_ll_hci_os_event_buf != NULL); /* Create memory pool of OS events */ rc = os_mempool_init(&g_ble_ll_hci_ev_pool, 16, sizeof (struct os_event), ble_ll_hci_os_event_buf, "g_ble_ll_hci_ev_pool"); SYSINIT_PANIC_ASSERT(rc == 0); /* 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 connection module */ ble_ll_conn_module_init(); /* Set the supported features. NOTE: we always support extended reject. */ features = BLE_LL_FEAT_EXTENDED_REJ; #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) == 1) features |= BLE_LL_FEAT_DATA_LEN_EXT; #endif #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_CONN_PARAM_REQ) == 1) features |= BLE_LL_FEAT_CONN_PARM_REQ; #endif #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG) == 1) features |= BLE_LL_FEAT_SLAVE_INIT; #endif #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1) features |= BLE_LL_FEAT_LE_ENCRYPTION; #endif #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1) features |= (BLE_LL_FEAT_LL_PRIVACY | BLE_LL_FEAT_EXT_SCAN_FILT); ble_ll_resolv_init(); #endif #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) == 1) features |= BLE_LL_FEAT_LE_PING; #endif /* Initialize random number generation */ ble_ll_rand_init(); /* XXX: This really doesn't belong here, as the address probably has not * been set yet. */ ble_ll_seed_prng(); lldata->ll_supp_features = features; /* Initialize the LL task */ os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL, MYNEWT_VAL(BLE_LL_PRIO), OS_WAIT_FOREVER, g_ble_ll_stack, BLE_LL_STACK_SIZE); rc = stats_init_and_reg(STATS_HDR(ble_ll_stats), STATS_SIZE_INIT_PARMS(ble_ll_stats, STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_ll_stats), "ble_ll"); SYSINIT_PANIC_ASSERT(rc == 0); ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL, ble_ll_hci_acl_rx, NULL); }
/** * main * * The main task for the project. This function initializes the packages, * then starts serving events from default event queue. * * @return int NOTE: this function should never return! */ int main(void) { int rc; /* Initialize OS */ sysinit(); /* Dummy device address */ #if BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER g_dev_addr[0] = 0x00; g_dev_addr[1] = 0x00; g_dev_addr[2] = 0x00; g_dev_addr[3] = 0x88; g_dev_addr[4] = 0x88; g_dev_addr[5] = 0x08; g_bletest_cur_peer_addr[0] = 0x00; g_bletest_cur_peer_addr[1] = 0x00; g_bletest_cur_peer_addr[2] = 0x00; g_bletest_cur_peer_addr[3] = 0x99; g_bletest_cur_peer_addr[4] = 0x99; g_bletest_cur_peer_addr[5] = 0x09; #else g_dev_addr[0] = 0x00; g_dev_addr[1] = 0x00; g_dev_addr[2] = 0x00; g_dev_addr[3] = 0x99; g_dev_addr[4] = 0x99; g_dev_addr[5] = 0x09; g_bletest_cur_peer_addr[0] = 0x00; g_bletest_cur_peer_addr[1] = 0x00; g_bletest_cur_peer_addr[2] = 0x00; g_bletest_cur_peer_addr[3] = 0x88; g_bletest_cur_peer_addr[4] = 0x88; g_bletest_cur_peer_addr[5] = 0x08; #endif log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL, LOG_SYSLEVEL); /* Set the led pin as an output */ g_led_pin = LED_BLINK_PIN; hal_gpio_init_out(g_led_pin, 1); /* Initialize eventq for bletest task */ os_eventq_init(&g_bletest_evq); rc = os_task_init(&bletest_task, "bletest", bletest_task_handler, NULL, BLETEST_TASK_PRIO, OS_WAIT_FOREVER, bletest_stack, BLETEST_STACK_SIZE); assert(rc == 0); while (1) { os_eventq_run(os_eventq_dflt_get()); } /* Never returns */ /* os start should never return. If it does, this should be an error */ assert(0); return rc; }