#include #include #include #define MODULE usb_cdc_test_module #include #include #include #include #include #include "ble_serial_tx_event.h" #include "usb_cdc_tx_event.h" #include "usb_device_state_event.h" LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); #define USB_CDC_TEST_PERIOD K_SECONDS(1) static const uint8_t hello_message[] = "hello\r\n"; static const uint8_t ble_hello_message[] = "ble_hello\r\n"; static struct k_work_delayable hello_work; static bool initialized; static bool running; static bool usb_active; static bool ble_active; static void submit_hello_message(void) { struct usb_cdc_tx_event *event = new_usb_cdc_tx_event(sizeof(hello_message) - 1U); memcpy(event->dyndata.data, hello_message, sizeof(hello_message) - 1U); APP_EVENT_SUBMIT(event); } static void submit_ble_hello_message(void) { struct ble_serial_tx_event *event = new_ble_serial_tx_event(sizeof(ble_hello_message) - 1U); memcpy(event->dyndata.data, ble_hello_message, sizeof(ble_hello_message) - 1U); APP_EVENT_SUBMIT(event); } static void hello_work_handler(struct k_work *work) { ARG_UNUSED(work); if (!running) { return; } if (usb_active) { submit_hello_message(); } if (ble_active) { submit_ble_hello_message(); } k_work_reschedule(&hello_work, USB_CDC_TEST_PERIOD); } static int module_init(void) { k_work_init_delayable(&hello_work, hello_work_handler); return 0; } static int module_start(void) { if (running) { return 0; } running = true; if (usb_active || ble_active) { k_work_reschedule(&hello_work, USB_CDC_TEST_PERIOD); } return 0; } static void module_pause(void) { if (!running) { return; } k_work_cancel_delayable(&hello_work); running = false; } static bool handle_usb_device_state_event(const struct usb_device_state_event *event) { bool new_usb_active = (event->state == USB_DEVICE_STATE_ACTIVE); if (new_usb_active == usb_active) { return false; } usb_active = new_usb_active; if (!running) { return false; } if (usb_active) { k_work_reschedule(&hello_work, USB_CDC_TEST_PERIOD); } else { k_work_cancel_delayable(&hello_work); } return false; } static bool handle_ble_peer_event(const struct ble_peer_event *event) { bool new_ble_active = ble_active; switch (event->state) { case PEER_STATE_CONNECTED: new_ble_active = false; break; case PEER_STATE_SECURED: new_ble_active = true; break; case PEER_STATE_DISCONNECTED: new_ble_active = false; break; default: return false; } if (new_ble_active == ble_active) { return false; } ble_active = new_ble_active; if (!running) { return false; } if (usb_active || ble_active) { k_work_reschedule(&hello_work, USB_CDC_TEST_PERIOD); } else { k_work_cancel_delayable(&hello_work); } return false; } static bool app_event_handler(const struct app_event_header *aeh) { if (is_usb_device_state_event(aeh)) { return handle_usb_device_state_event(cast_usb_device_state_event(aeh)); } if (is_ble_peer_event(aeh)) { return handle_ble_peer_event(cast_ble_peer_event(aeh)); } if (is_module_state_event(aeh)) { const struct module_state_event *event = cast_module_state_event(aeh); if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) { int err; if (!initialized) { err = module_init(); if (err) { module_set_state(MODULE_STATE_ERROR); return false; } initialized = true; } err = module_start(); if (err) { module_set_state(MODULE_STATE_ERROR); } else { module_set_state(MODULE_STATE_READY); } } return false; } if (is_power_down_event(aeh)) { if (initialized) { module_pause(); module_set_state(MODULE_STATE_STANDBY); } return false; } if (is_wake_up_event(aeh)) { if (initialized) { int err = module_start(); if (err) { module_set_state(MODULE_STATE_ERROR); } else { module_set_state(MODULE_STATE_READY); } } return false; } return false; } APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); APP_EVENT_SUBSCRIBE(MODULE, ble_peer_event); APP_EVENT_SUBSCRIBE(MODULE, usb_device_state_event); APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);