diff --git a/components/raop/CMakeLists.txt b/components/raop/CMakeLists.txt index b016d10e..7ae88a52 100644 --- a/components/raop/CMakeLists.txt +++ b/components/raop/CMakeLists.txt @@ -1,7 +1,7 @@ idf_component_register(SRC_DIRS . INCLUDE_DIRS . - PRIV_REQUIRES newlib freertos pthread platform_config mdns services codecs tools display + PRIV_REQUIRES newlib freertos pthread platform_config mdns services codecs tools display wifi-manager ) set_source_files_properties(raop.c diff --git a/components/raop/raop.c b/components/raop/raop.c index 05103a74..53679a78 100644 --- a/components/raop/raop.c +++ b/components/raop/raop.c @@ -111,7 +111,7 @@ extern char private_key[]; static void on_dmap_string(void *ctx, const char *code, const char *name, const char *buf, size_t len); /*----------------------------------------------------------------------------*/ -struct raop_ctx_s *raop_create(struct in_addr host, char *name, +struct raop_ctx_s *raop_create(uint32_t host, char *name, unsigned char mac[6], int latency, raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) { struct raop_ctx_s *ctx = malloc(sizeof(struct raop_ctx_s)); @@ -150,7 +150,7 @@ struct raop_ctx_s *raop_create(struct in_addr host, char *name, #ifdef WIN32 ctx->svr = glmDNSServer; #endif - ctx->host = host; + ctx->host.s_addr = host; ctx->sock = socket(AF_INET, SOCK_STREAM, 0); ctx->cmd_cb = cmd_cb; ctx->data_cb = data_cb; @@ -162,7 +162,7 @@ struct raop_ctx_s *raop_create(struct in_addr host, char *name, } memset(&addr, 0, sizeof(addr)); - addr.sin_addr.s_addr = host.s_addr; + addr.sin_addr.s_addr = host; addr.sin_family = AF_INET; #ifdef WIN32 ctx->port = 0; @@ -196,7 +196,7 @@ struct raop_ctx_s *raop_create(struct in_addr host, char *name, ESP_ERROR_CHECK( mdns_service_add(id, "_raop", "_tcp", ctx->port, txt, sizeof(txt) / sizeof(mdns_txt_item_t)) ); ctx->xTaskBuffer = (StaticTask_t*) heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - ctx->thread = xTaskCreateStaticPinnedToCore( (TaskFunction_t) rtsp_thread, "RTSP_thread", RTSP_STACK_SIZE, ctx, + ctx->thread = xTaskCreateStaticPinnedToCore( (TaskFunction_t) rtsp_thread, "RTSP", RTSP_STACK_SIZE, ctx, ESP_TASK_PRIO_MIN + 2, ctx->xStack, ctx->xTaskBuffer, CONFIG_PTHREAD_TASK_CORE_DEFAULT); #endif diff --git a/components/raop/raop.h b/components/raop/raop.h index 15a8ba4b..07042b06 100644 --- a/components/raop/raop.h +++ b/components/raop/raop.h @@ -11,7 +11,7 @@ #include "platform.h" #include "raop_sink.h" -struct raop_ctx_s* raop_create(struct in_addr host, char *name, unsigned char mac[6], int latency, +struct raop_ctx_s* raop_create(uint32_t host, char *name, unsigned char mac[6], int latency, raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb); void raop_delete(struct raop_ctx_s *ctx); void raop_abort(struct raop_ctx_s *ctx); diff --git a/components/raop/raop_sink.c b/components/raop/raop_sink.c index 4f09211e..fe66b365 100644 --- a/components/raop/raop_sink.c +++ b/components/raop/raop_sink.c @@ -3,7 +3,6 @@ #include #include -#include "mdns.h" #include "nvs.h" #include "esp_netif.h" #include "esp_log.h" @@ -17,6 +16,7 @@ #include "display.h" #include "accessors.h" #include "log_util.h" +#include "network_services.h" #ifndef CONFIG_AIRPLAY_NAME #define CONFIG_AIRPLAY_NAME "ESP32-AirPlay" @@ -148,77 +148,36 @@ static bool cmd_handler(raop_event_t event, ...) { */ void raop_sink_deinit(void) { raop_delete(raop); - mdns_free(); } /**************************************************************************************** * Airplay sink startup */ -static bool raop_sink_start(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) { - const char *hostname = NULL; - char sink_name[64-6] = CONFIG_AIRPLAY_NAME; - tcpip_adapter_ip_info_t ipInfo = { }; - struct in_addr host; - tcpip_adapter_if_t ifs[] = { TCPIP_ADAPTER_IF_ETH, TCPIP_ADAPTER_IF_STA, TCPIP_ADAPTER_IF_AP }; - - // get various IP info - // it is possible to get the currently active interface with the following call: - // network_get_active_interface() - for (int i = 0; i < sizeof(ifs) / sizeof(tcpip_adapter_if_t); i++) - if (tcpip_adapter_get_ip_info(ifs[i], &ipInfo) == ESP_OK && ipInfo.ip.addr != IPADDR_ANY) { - tcpip_adapter_get_hostname(ifs[i], &hostname); - break; - } - - if (!hostname) { - LOG_INFO( "no hostname/IP found, can't start AirPlay"); - return false; - } - - host.s_addr = ipInfo.ip.addr; - - // initialize mDNS - ESP_ERROR_CHECK( mdns_init() ); - ESP_ERROR_CHECK( mdns_hostname_set(hostname) ); - - char * sink_name_buffer= (char *)config_alloc_get(NVS_TYPE_STR,"airplay_name"); - if (sink_name_buffer != NULL){ - memset(sink_name, 0x00, sizeof(sink_name)); - strncpy(sink_name,sink_name_buffer,sizeof(sink_name)-1 ); - free(sink_name_buffer); - } - - LOG_INFO( "mdns hostname for ip %s set to: [%s] with servicename %s", inet_ntoa(host), hostname, sink_name); - - // create RAOP instance, latency is set by controller +static void raop_sink_start(nm_state_t state_id, int sub_state) { + esp_netif_t* netif; + esp_netif_ip_info_t ipInfo = { }; uint8_t mac[6]; - esp_read_mac(mac, ESP_MAC_WIFI_STA); - cmd_handler_chain = cmd_cb; - raop = raop_create(host, sink_name, mac, 0, cmd_handler, data_cb); - - return true; -} + char* sink_name = (char*) config_alloc_get_default(NVS_TYPE_STR, "airplay_name", CONFIG_AIRPLAY_NAME, 0); -/**************************************************************************************** - * Airplay sink timer handler - */ -static void raop_start_handler( TimerHandle_t xTimer ) { - if (raop_sink_start(raop_cbs.cmd, raop_cbs.data)) { - xTimerDelete(xTimer, portMAX_DELAY); - } -} + netif = network_get_active_interface(); + esp_netif_get_ip_info(netif, &ipInfo); + esp_netif_get_mac(netif, mac); + cmd_handler_chain = raop_cbs.cmd; + + LOG_INFO( "Starting Airplay for ip %s with servicename %s", inet_ntoa(ipInfo.ip.addr), sink_name); + raop = raop_create(ipInfo.ip.addr, sink_name, mac, 0, cmd_handler, raop_cbs.data); + free(sink_name); +} /**************************************************************************************** * Airplay sink initialization */ void raop_sink_init(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) { - if (!raop_sink_start(cmd_cb, data_cb)) { - raop_cbs.cmd = cmd_cb; - raop_cbs.data = data_cb; - TimerHandle_t timer = xTimerCreate("raopStart", 5000 / portTICK_RATE_MS, pdTRUE, NULL, raop_start_handler); - xTimerStart(timer, portMAX_DELAY); - LOG_INFO( "Delaying AirPlay start"); - } + raop_cbs.cmd = cmd_cb; + raop_cbs.data = data_cb; + + network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE, WIFI_CONNECTED_STATE, "raop_sink_start", raop_sink_start); + network_register_state_callback(NETWORK_ETH_ACTIVE_STATE, ETH_ACTIVE_CONNECTED_STATE, "raop_sink_start", raop_sink_start); } /**************************************************************************************** diff --git a/components/services/buttons.c b/components/services/buttons.c index fafb8668..6d240a66 100644 --- a/components/services/buttons.c +++ b/components/services/buttons.c @@ -84,7 +84,7 @@ static void common_task_init(void) { if (!common_queue_set) { common_queue_set = xQueueCreateSet(BUTTON_QUEUE_LEN + 1); - xTaskCreateStatic( (TaskFunction_t) buttons_task, "buttons_thread", BUTTON_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 2, xStack, &xTaskBuffer); + xTaskCreateStatic( (TaskFunction_t) buttons_task, "buttons", BUTTON_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 2, xStack, &xTaskBuffer); } } diff --git a/components/spotify/Shim.cpp b/components/spotify/Shim.cpp index bcb110cc..512c1824 100644 --- a/components/spotify/Shim.cpp +++ b/components/spotify/Shim.cpp @@ -104,7 +104,7 @@ static void cspotTask(void *pvParameters) { session->connectWithRandomAp(); auto token = session->authenticate(cspot.blob); - ESP_LOGI(TAG, "Creating Spotify(CSpot) player"); + ESP_LOGI(TAG, "Creating Spotify (using CSpot) player"); // Auth successful if (token.size() > 0 && cspot.cHandler(CSPOT_SETUP, 44100)) { diff --git a/components/spotify/cspot/src/ZeroconfAuthenticator.cpp b/components/spotify/cspot/src/ZeroconfAuthenticator.cpp index 9da1fc08..9e8458e9 100644 --- a/components/spotify/cspot/src/ZeroconfAuthenticator.cpp +++ b/components/spotify/cspot/src/ZeroconfAuthenticator.cpp @@ -59,8 +59,6 @@ void ZeroconfAuthenticator::registerZeroconf() const char* service = "_spotify-connect._tcp"; #ifdef ESP_PLATFORM - mdns_init(); - mdns_hostname_set("cspot"); mdns_txt_item_t serviceTxtData[3] = { {"VERSION", "1.0"}, {"CPath", "/spotify_info"}, diff --git a/components/spotify/cspot_sink.c b/components/spotify/cspot_sink.c index 48d6bcc6..69722478 100644 --- a/components/spotify/cspot_sink.c +++ b/components/spotify/cspot_sink.c @@ -3,19 +3,16 @@ #include #include -#include "mdns.h" #include "nvs.h" -#include "tcpip_adapter.h" -// IDF-V4++ #include "esp_netif.h" #include "esp_log.h" #include "esp_console.h" #include "esp_pthread.h" #include "esp_system.h" -#include "freertos/timers.h" #include "platform_config.h" #include "audio_controls.h" #include "display.h" #include "accessors.h" +#include "network_services.h" #include "cspot_private.h" #include "cspot_sink.h" @@ -138,59 +135,28 @@ static bool cmd_handler(cspot_event_t event, ...) { return true; } -/**************************************************************************************** - * CSpot sink de-initialization - */ -void cspot_sink_deinit(void) { - mdns_free(); -} - /**************************************************************************************** * CSpot sink startup */ -static bool cspot_sink_start(cspot_cmd_vcb_t cmd_cb, cspot_data_cb_t data_cb) { - const char *hostname = NULL; - tcpip_adapter_ip_info_t ipInfo = { }; - tcpip_adapter_if_t ifs[] = { TCPIP_ADAPTER_IF_ETH, TCPIP_ADAPTER_IF_STA, TCPIP_ADAPTER_IF_AP }; - - // get various IP info - for (int i = 0; i < sizeof(ifs) / sizeof(tcpip_adapter_if_t); i++) - if (tcpip_adapter_get_ip_info(ifs[i], &ipInfo) == ESP_OK && ipInfo.ip.addr != IPADDR_ANY) { - tcpip_adapter_get_hostname(ifs[i], &hostname); - break; - } - - if (!hostname) { - ESP_LOGI(TAG, "No hostname/IP found, can't start CSpot (will retry)"); - return false; - } - - cmd_handler_chain = cmd_cb; - cspot = cspot_create(hostname, cmd_handler, data_cb); - - return true; -} +static void cspot_sink_start(nm_state_t state_id, int sub_state) { + const char *hostname; -/**************************************************************************************** - * CSpot sink timer handler - */ -static void cspot_start_handler( TimerHandle_t xTimer ) { - if (cspot_sink_start(cspot_cbs.cmd, cspot_cbs.data)) { - xTimerDelete(xTimer, portMAX_DELAY); - } -} + cmd_handler_chain = cspot_cbs.cmd; + network_get_hostname(&hostname); + + ESP_LOGI(TAG, "Starting Spotify (CSpot) servicename %s", hostname); + cspot = cspot_create(hostname, cmd_handler, cspot_cbs.data); +} /**************************************************************************************** * CSpot sink initialization */ void cspot_sink_init(cspot_cmd_vcb_t cmd_cb, cspot_data_cb_t data_cb) { - if (!cspot_sink_start(cmd_cb, data_cb)) { - cspot_cbs.cmd = cmd_cb; - cspot_cbs.data = data_cb; - TimerHandle_t timer = xTimerCreate("cspotStart", 5000 / portTICK_RATE_MS, pdTRUE, NULL, cspot_start_handler); - xTimerStart(timer, portMAX_DELAY); - ESP_LOGI(TAG, "Delaying CSPOT start"); - } + cspot_cbs.cmd = cmd_cb; + cspot_cbs.data = data_cb; + + network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE, WIFI_CONNECTED_STATE, "cspot_sink_start", cspot_sink_start); + network_register_state_callback(NETWORK_ETH_ACTIVE_STATE, ETH_ACTIVE_CONNECTED_STATE, "cspot_sink_start", cspot_sink_start); } /**************************************************************************************** diff --git a/components/spotify/cspot_sink.h b/components/spotify/cspot_sink.h index 9916d3ea..5a4109b3 100644 --- a/components/spotify/cspot_sink.h +++ b/components/spotify/cspot_sink.h @@ -32,7 +32,7 @@ void cspot_sink_init(cspot_cmd_vcb_t cmd_cb, cspot_data_cb_t data_cb); /** * @brief deinit sink mode (need to be provided) */ -void cspot_sink_deinit(void); +#define cspot_sink_deinit() /** * @brief force disconnection diff --git a/components/wifi-manager/network_manager.h b/components/wifi-manager/network_manager.h index 356ff6e6..9734960b 100644 --- a/components/wifi-manager/network_manager.h +++ b/components/wifi-manager/network_manager.h @@ -9,74 +9,12 @@ #include "freertos/event_groups.h" #include "hsm.h" #include "esp_log.h" +#include "network_services.h" #ifdef __cplusplus extern "C" { #endif -/* - * --------------------- ENUMERATION --------------------- - */ -//#define ADD_ROOT(NAME, HANDLER, ENTRY, EXIT, CHILD) -//#define ADD_ROOT(NAME, HANDLER, ENTRY, EXIT, CHILD) -//#define ADD_LEAF(NAME, HANDLER, ENTRY, EXIT, PARENT, LEVEL) - -#define ALL_NM_STATE \ - ADD_ROOT_LEAF(NETWORK_INSTANTIATED_STATE)\ - ADD_ROOT_LEAF(NETWORK_INITIALIZING_STATE)\ - ADD_ROOT(NETWORK_ETH_ACTIVE_STATE, Eth_Active_State)\ - ADD_ROOT(NETWORK_WIFI_ACTIVE_STATE, Wifi_Active_State)\ - ADD_ROOT(NETWORK_WIFI_CONFIGURING_ACTIVE_STATE, Wifi_Configuring_State) - -#define ALL_ETH_STATE(PARENT, LEVEL)\ - ADD_LEAF(ETH_STARTING_STATE,PARENT,LEVEL)\ - ADD_LEAF(ETH_ACTIVE_LINKUP_STATE,PARENT,LEVEL)\ - ADD_LEAF(ETH_ACTIVE_LINKDOWN_STATE,PARENT,LEVEL)\ - ADD_LEAF(ETH_ACTIVE_CONNECTED_STATE,PARENT,LEVEL)\ - ADD_LEAF(ETH_CONNECTING_NEW_STATE,PARENT,LEVEL) - -#define ALL_WIFI_STATE(PARENT, LEVEL)\ - ADD_LEAF(WIFI_INITIALIZING_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_CONNECTING_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_CONNECTING_NEW_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_CONNECTING_NEW_FAILED_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_CONNECTED_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_USER_DISCONNECTED_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_LOST_CONNECTION_STATE,PARENT,LEVEL) - -#define ALL_WIFI_CONFIGURING_STATE(PARENT, LEVEL)\ - ADD_LEAF(WIFI_CONFIGURING_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_CONFIGURING_CONNECT_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_CONFIGURING_CONNECT_SUCCESS_STATE,PARENT,LEVEL)\ - ADD_LEAF(WIFI_CONFIGURING_CONNECT_SUCCESS_GOTOSTA_STATE,PARENT,LEVEL) - - -#define ADD_ROOT(name, ...) name, -#define ADD_ROOT_LEAF(name, ...) name, -#define ADD_LEAF(name, ...) name, -typedef enum { - ALL_NM_STATE - TOTAL_NM_STATE -} nm_state_t; -typedef enum { - ALL_WIFI_STATE(,) - TOTAL_WIFI_ACTIVE_STATE -} mn_wifi_active_state_t; -typedef enum { - ALL_ETH_STATE(,) - TOTAL_ETH_ACTIVE_STATE -} mn_eth_active_state_t; -typedef enum { - ALL_WIFI_CONFIGURING_STATE(,) - TOTAL_WIFI_CONFIGURING_STATE -} mn_wifi_configuring_state_t; - -#undef ADD_STATE -#undef ADD_ROOT -#undef ADD_ROOT_LEAF -#undef ADD_LEAF - -typedef void (*network_status_reached_cb)(nm_state_t state_id, int sub_state ); //! List of oven events #define ALL_NM_EVENTS \ ADD_FIRST_EVENT(EN_LINK_UP) \ @@ -369,11 +307,7 @@ void network_manager_initialise_mdns(); /** * @brief Register a callback to a custom function when specific network manager states are reached. */ -esp_err_t network_register_state_callback(nm_state_t state, int sub_state, const char* from, network_status_reached_cb cb); bool network_is_wifi_prioritized(); -esp_netif_t * network_get_active_interface(); -esp_err_t network_get_hostname( const char **hostname); -esp_err_t network_get_ip_info(tcpip_adapter_ip_info_t* ipInfo); void network_set_timer(uint16_t duration); void network_set_hostname(esp_netif_t * netif); esp_err_t network_get_ip_info_for_netif(esp_netif_t* netif, tcpip_adapter_ip_info_t* ipInfo); diff --git a/components/wifi-manager/network_services.h b/components/wifi-manager/network_services.h new file mode 100644 index 00000000..4c8d23f9 --- /dev/null +++ b/components/wifi-manager/network_services.h @@ -0,0 +1,75 @@ +#pragma once + +#include "esp_netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ADD_ROOT(name, ...) name, +#define ADD_ROOT_LEAF(name, ...) name, +#define ADD_LEAF(name, ...) name, + +#define ALL_NM_STATE \ + ADD_ROOT_LEAF(NETWORK_INSTANTIATED_STATE)\ + ADD_ROOT_LEAF(NETWORK_INITIALIZING_STATE)\ + ADD_ROOT(NETWORK_ETH_ACTIVE_STATE, Eth_Active_State)\ + ADD_ROOT(NETWORK_WIFI_ACTIVE_STATE, Wifi_Active_State)\ + ADD_ROOT(NETWORK_WIFI_CONFIGURING_ACTIVE_STATE, Wifi_Configuring_State) + +#define ALL_ETH_STATE(PARENT, LEVEL)\ + ADD_LEAF(ETH_STARTING_STATE,PARENT,LEVEL)\ + ADD_LEAF(ETH_ACTIVE_LINKUP_STATE,PARENT,LEVEL)\ + ADD_LEAF(ETH_ACTIVE_LINKDOWN_STATE,PARENT,LEVEL)\ + ADD_LEAF(ETH_ACTIVE_CONNECTED_STATE,PARENT,LEVEL)\ + ADD_LEAF(ETH_CONNECTING_NEW_STATE,PARENT,LEVEL) + +#define ALL_WIFI_STATE(PARENT, LEVEL)\ + ADD_LEAF(WIFI_INITIALIZING_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_CONNECTING_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_CONNECTING_NEW_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_CONNECTING_NEW_FAILED_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_CONNECTED_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_USER_DISCONNECTED_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_LOST_CONNECTION_STATE,PARENT,LEVEL) + +#define ALL_WIFI_CONFIGURING_STATE(PARENT, LEVEL)\ + ADD_LEAF(WIFI_CONFIGURING_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_CONFIGURING_CONNECT_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_CONFIGURING_CONNECT_SUCCESS_STATE,PARENT,LEVEL)\ + ADD_LEAF(WIFI_CONFIGURING_CONNECT_SUCCESS_GOTOSTA_STATE,PARENT,LEVEL) + +typedef enum { + ALL_NM_STATE + TOTAL_NM_STATE +} nm_state_t; +typedef enum { + ALL_WIFI_STATE(,) + TOTAL_WIFI_ACTIVE_STATE +} mn_wifi_active_state_t; +typedef enum { + ALL_ETH_STATE(,) + TOTAL_ETH_ACTIVE_STATE +} mn_eth_active_state_t; +typedef enum { + ALL_WIFI_CONFIGURING_STATE(,) + TOTAL_WIFI_CONFIGURING_STATE +} mn_wifi_configuring_state_t; + +#undef ADD_STATE +#undef ADD_ROOT +#undef ADD_ROOT_LEAF +#undef ADD_LEAF + +typedef void (*network_status_reached_cb)(nm_state_t state_id, int sub_state); + +esp_err_t network_register_state_callback(nm_state_t state, int sub_state, const char* from, network_status_reached_cb cb); +esp_netif_t * network_get_active_interface(); +esp_err_t network_get_hostname(const char **hostname); +esp_err_t network_get_ip_info(tcpip_adapter_ip_info_t* ipInfo); + +#ifdef __cplusplus +} +#endif + + diff --git a/main/esp_app_main.c b/main/esp_app_main.c index a1233c60..869b6a12 100644 --- a/main/esp_app_main.c +++ b/main/esp_app_main.c @@ -76,6 +76,7 @@ const char * str_or_null(const char * str) { return (str?str:null_string_placeho bool is_recovery_running; void cb_connection_got_ip(nm_state_t new_state, int sub_state){ + const char *hostname; static ip4_addr_t ip; tcpip_adapter_ip_info_t ipInfo; network_get_ip_info(&ipInfo); @@ -86,11 +87,18 @@ void cb_connection_got_ip(nm_state_t new_state, int sub_state){ } esp_restart(); } - ip.addr = ipInfo.ip.addr; - ESP_LOGI(TAG, "Network connected!"); + + // initializing mDNS + network_get_hostname(&hostname); + mdns_init(); + mdns_hostname_set(hostname); + + ESP_LOGI(TAG, "Network connected and mDNS initialized with %s", hostname); + messaging_post_message(MESSAGING_INFO,MESSAGING_CLASS_SYSTEM,"Network connected"); xEventGroupSetBits(network_event_group, CONNECTED_BIT); bNetworkConnected=true; + led_unpush(LED_GREEN); if(is_recovery_running){ // when running in recovery, send a LMS discovery message