From fb63752c632b3b261c4327edcc2637230bfc6af5 Mon Sep 17 00:00:00 2001 From: yuvaramachandran_gurusamy Date: Wed, 12 Jun 2024 20:13:31 +0000 Subject: [PATCH] 1) RDKTV-31210 - Had to reconnect to Wifi, Post overnight Deepsleep. 2) RDKTV-30775 - [Element 4K UHD 50" TV] [Intermittent] Wi-Fi connection process is taking 4-5 mins when ever switching from one ssid to another ssid 3) RDKTV-31401 - [A4K] Miracast - Device is unable to cast from the source Signed-off-by: yuvaramachandran_gurusamy --- .../MiracastService/MiracastController.cpp | 106 ++-- Miracast/MiracastService/MiracastController.h | 7 +- Miracast/MiracastService/MiracastService.cpp | 542 ++++++++++++++++-- Miracast/MiracastService/MiracastService.h | 46 +- Miracast/MiracastService/P2P/MiracastP2P.cpp | 13 +- Miracast/common/MiracastCommon.h | 8 +- Tests/L1Tests/tests/test_MiracastService.cpp | 124 ++++ 7 files changed, 773 insertions(+), 73 deletions(-) diff --git a/Miracast/MiracastService/MiracastController.cpp b/Miracast/MiracastService/MiracastController.cpp index 8c0ec79180..1e056d00bd 100644 --- a/Miracast/MiracastService/MiracastController.cpp +++ b/Miracast/MiracastService/MiracastController.cpp @@ -487,12 +487,12 @@ void MiracastController::checkAndInitiateP2PBackendDiscovery(void) { MIRACASTLOG_INFO("!!! BACKEND P2P DISCOVERY HAS BEEN STARTED !!!"); /* Enabled the Device Discovery to allow other device to cast */ - discover_devices(); + discover_devices(false); } else { MIRACASTLOG_INFO("!!! BACKEND P2P DISCOVERY HAS DISABLED !!!"); - stop_discover_devices(); + stop_discover_devices(false); } } @@ -538,23 +538,31 @@ MiracastError MiracastController::set_WFDParameters(void) return ret; } -MiracastError MiracastController::discover_devices(void) +MiracastError MiracastController::discover_devices(bool isNotificationRequired) { MIRACASTLOG_TRACE("Entering..."); MiracastError ret = MIRACAST_FAIL; if (nullptr != m_p2p_ctrl_obj){ ret = m_p2p_ctrl_obj->discover_devices(); + if ((nullptr != m_notify_handler) && (isNotificationRequired)) + { + m_notify_handler->onStateChange(MIRACAST_SERVICE_STATE_DISCOVERABLE); + } } MIRACASTLOG_TRACE("Exiting..."); return ret; } -MiracastError MiracastController::stop_discover_devices(void) +MiracastError MiracastController::stop_discover_devices(bool isNotificationRequired) { MIRACASTLOG_TRACE("Entering..."); MiracastError ret = MIRACAST_FAIL; if (nullptr != m_p2p_ctrl_obj){ ret = m_p2p_ctrl_obj->stop_discover_devices(); + if ((nullptr != m_notify_handler) && (isNotificationRequired)) + { + m_notify_handler->onStateChange(MIRACAST_SERVICE_STATE_IDLE); + } } MIRACASTLOG_TRACE("Exiting..."); return ret; @@ -929,7 +937,8 @@ void MiracastController::Controller_Thread(void *args) sink_dev_ip = ""; std::string modelName = "Miracast-Source", authType = "pbc", - deviceType = "unknown"; + deviceType = "unknown", + result = ""; m_groupInfo = new GroupInfo; size_t found = event_buffer.find("client"); size_t found_space = event_buffer.find(" "); @@ -952,7 +961,7 @@ void MiracastController::Controller_Thread(void *args) std::size_t secondDash = m_groupInfo->SSID.find("-", firstDash + 1); if (secondDash != std::string::npos) { - std::string result = m_groupInfo->SSID.substr(secondDash + 1); + result = m_groupInfo->SSID.substr(secondDash + 1); if (!result.empty()) { modelName.clear(); @@ -1184,38 +1193,39 @@ void MiracastController::Controller_Thread(void *args) MIRACASTLOG_TRACE("CONTRLR_FW_MSG type received"); switch (controller_msgq_data.state) { - // Start and Stop Discovering initiated directly from Thunder request. So this is unused and commenting out here - #if 0 case CONTROLLER_START_DISCOVERING: - { - MIRACASTLOG_INFO("CONTROLLER_START_DISCOVERING Received\n"); - set_WFDParameters(); - discover_devices(); - m_start_discovering_enabled = true; - } - break; case CONTROLLER_STOP_DISCOVERING: - { - MIRACASTLOG_INFO("CONTROLLER_STOP_DISCOVERING Received\n"); - stop_session(true); - m_start_discovering_enabled = false; - } - break; - #endif case CONTROLLER_RESTART_DISCOVERING: { - std::string cached_mac_address = get_NewSourceMACAddress(), - mac_address = controller_msgq_data.source_dev_mac; - MIRACASTLOG_INFO("CONTROLLER_RESTART_DISCOVERING Received\n"); - m_connectionStatus = false; - - if ((!cached_mac_address.empty()) && ( 0 == mac_address.compare(cached_mac_address))) + if (CONTROLLER_START_DISCOVERING == controller_msgq_data.state) { - reset_NewSourceMACAddress(); - reset_NewSourceName(); - MIRACASTLOG_INFO("[%s] Cached Device info removed...",cached_mac_address.c_str()); + MIRACASTLOG_INFO("CONTROLLER_START_DISCOVERING Received\n"); + set_WFDParameters(); + discover_devices(); + m_start_discovering_enabled = true; + } + else if (CONTROLLER_STOP_DISCOVERING == controller_msgq_data.state) + { + MIRACASTLOG_INFO("CONTROLLER_STOP_DISCOVERING Received\n"); + stop_session(true); + m_start_discovering_enabled = false; + sleep(2); + } + else + { + std::string cached_mac_address = get_NewSourceMACAddress(), + mac_address = controller_msgq_data.source_dev_mac; + MIRACASTLOG_INFO("CONTROLLER_RESTART_DISCOVERING Received\n"); + m_connectionStatus = false; + + if ((!cached_mac_address.empty()) && ( 0 == mac_address.compare(cached_mac_address))) + { + reset_NewSourceMACAddress(); + reset_NewSourceName(); + MIRACASTLOG_INFO("[%s] Cached Device info removed...",cached_mac_address.c_str()); + } + restart_session(m_start_discovering_enabled); } - restart_session(m_start_discovering_enabled); new_thunder_req_client_connection_sent = false; another_thunder_req_client_connection_sent = false; session_restart_required = true; @@ -1422,6 +1432,38 @@ void MiracastController::switch_launch_request_context(std::string& source_dev_i MIRACASTLOG_TRACE("Exiting..."); } +void MiracastController::start_discoveryAsync(void) +{ + CONTROLLER_MSGQ_STRUCT controller_msgq_data = {0}; + MIRACASTLOG_TRACE("Entering..."); + MIRACASTLOG_INFO("MIRACAST_SERVICE_WFD_START"); + controller_msgq_data.state = CONTROLLER_START_DISCOVERING; + send_thundermsg_to_controller_thread(controller_msgq_data); + MIRACASTLOG_TRACE("Exiting..."); +} + +void MiracastController::stop_discoveryAsync(void) +{ + CONTROLLER_MSGQ_STRUCT controller_msgq_data = {0}; + MIRACASTLOG_TRACE("Entering..."); + MIRACASTLOG_INFO("MIRACAST_SERVICE_WFD_STOP"); + controller_msgq_data.state = CONTROLLER_STOP_DISCOVERING; + send_thundermsg_to_controller_thread(controller_msgq_data); + MIRACASTLOG_TRACE("Exiting..."); +} + +void MiracastController::restart_discoveryAsync(void) +{ + CONTROLLER_MSGQ_STRUCT controller_msgq_data = {0}; + MIRACASTLOG_TRACE("Entering..."); + MIRACASTLOG_INFO("MIRACAST_SERVICE_WFD_RESTART"); + controller_msgq_data.state = CONTROLLER_STOP_DISCOVERING; + send_thundermsg_to_controller_thread(controller_msgq_data); + controller_msgq_data.state = CONTROLLER_START_DISCOVERING; + send_thundermsg_to_controller_thread(controller_msgq_data); + MIRACASTLOG_TRACE("Exiting..."); +} + void MiracastController::set_WFDSourceMACAddress(std::string MAC_Addr) { m_connected_mac_addr = MAC_Addr; diff --git a/Miracast/MiracastService/MiracastController.h b/Miracast/MiracastService/MiracastController.h index d85917dc26..361f335d73 100644 --- a/Miracast/MiracastService/MiracastController.h +++ b/Miracast/MiracastService/MiracastController.h @@ -52,7 +52,7 @@ class MiracastController void event_handler(P2P_EVENTS eventId, void *data, size_t len ); - MiracastError discover_devices(); + MiracastError discover_devices(bool isNotificationRequired = true); MiracastError connect_device(std::string device_mac , std::string device_name ); std::string get_localIp(); @@ -76,7 +76,7 @@ class MiracastController void send_msgto_test_notifier_thread( MIRACAST_SERVICE_TEST_NOTIFIER_MSGQ_ST stMsgQ ); #endif /* ENABLE_MIRACAST_SERVICE_TEST_NOTIFIER */ - MiracastError stop_discover_devices(); + MiracastError stop_discover_devices(bool isNotificationRequired = true); MiracastError set_WFDParameters(void); void restart_session_discovery(std::string& mac_address); void flush_current_session(void); @@ -106,6 +106,9 @@ class MiracastController void setP2PBackendDiscovery(bool is_enabled); void switch_launch_request_context(std::string& source_dev_ip,std::string& source_dev_mac,std::string& source_dev_name,std::string& sink_dev_ip); + void start_discoveryAsync(void); + void stop_discoveryAsync(void); + void restart_discoveryAsync(void); private: static MiracastController *m_miracast_ctrl_obj; diff --git a/Miracast/MiracastService/MiracastService.cpp b/Miracast/MiracastService/MiracastService.cpp index e581632451..04740cda63 100644 --- a/Miracast/MiracastService/MiracastService.cpp +++ b/Miracast/MiracastService/MiracastService.cpp @@ -46,6 +46,12 @@ const string WPEFramework::Plugin::MiracastService::METHOD_MIRACAST_STOP_CLIENT_ const string WPEFramework::Plugin::MiracastService::METHOD_MIRACAST_SET_UPDATE_PLAYER_STATE = "updatePlayerState"; const string WPEFramework::Plugin::MiracastService::METHOD_MIRACAST_SET_LOG_LEVEL = "setLogging"; +#ifdef UNIT_TESTING +const string WPEFramework::Plugin::MiracastService::METHOD_MIRACAST_GET_STATUS = "getStatus"; +const string WPEFramework::Plugin::MiracastService::METHOD_MIRACAST_SET_POWERSTATE = "setPowerState"; +const string WPEFramework::Plugin::MiracastService::METHOD_MIRACAST_SET_WIFISTATE = "setWiFiState"; +#endif /*UNIT_TESTING*/ + #ifdef ENABLE_MIRACAST_SERVICE_TEST_NOTIFIER const string WPEFramework::Plugin::MiracastService::METHOD_MIRACAST_TEST_NOTIFIER = "testNotifier"; #endif @@ -59,6 +65,8 @@ using namespace std; #define SERVER_DETAILS "127.0.0.1:9998" #define SYSTEM_CALLSIGN "org.rdk.System" #define SYSTEM_CALLSIGN_VER SYSTEM_CALLSIGN ".1" +#define WIFI_CALLSIGN "org.rdk.Wifi" +#define WIFI_CALLSIGN_VER WIFI_CALLSIGN ".1" #define SECURITY_TOKEN_LEN_MAX 1024 #define THUNDER_RPC_TIMEOUT 2000 @@ -66,6 +74,10 @@ using namespace std; #define EVT_ON_CLIENT_CONNECTION_ERROR "onClientConnectionError" #define EVT_ON_LAUNCH_REQUEST "onLaunchRequest" +static IARM_Bus_PWRMgr_PowerState_t m_powerState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY; +static bool m_IsTransitionFromDeepSleep = false; +static bool m_IsWiFiConnectingState = false; + namespace WPEFramework { namespace @@ -91,19 +103,25 @@ namespace WPEFramework MiracastService::MiracastService() : PluginHost::JSONRPC(), m_isServiceInitialized(false), - m_isServiceEnabled(false) + m_isServiceEnabled(false), + m_eService_state(MIRACAST_SERVICE_STATE_IDLE) { LOGINFO("Entering..!!!"); MiracastService::_instance = this; MIRACAST::logger_init("MiracastService"); - Register(METHOD_MIRACAST_SET_ENABLE, &MiracastService::setEnable, this); + Register(METHOD_MIRACAST_SET_ENABLE, &MiracastService::setEnableWrapper, this); Register(METHOD_MIRACAST_GET_ENABLE, &MiracastService::getEnable, this); Register(METHOD_MIRACAST_SET_P2P_BACKEND_DISCOVERY, &MiracastService::setP2PBackendDiscovery, this); Register(METHOD_MIRACAST_CLIENT_CONNECT, &MiracastService::acceptClientConnection, this); Register(METHOD_MIRACAST_STOP_CLIENT_CONNECT, &MiracastService::stopClientConnection, this); Register(METHOD_MIRACAST_SET_UPDATE_PLAYER_STATE, &MiracastService::updatePlayerState, this); Register(METHOD_MIRACAST_SET_LOG_LEVEL, &MiracastService::setLogging, this); + #ifdef UNIT_TESTING + Register(METHOD_MIRACAST_GET_STATUS, &MiracastService::getStatus, this); + Register(METHOD_MIRACAST_SET_POWERSTATE, &MiracastService::setPowerStateWrapper, this); + Register(METHOD_MIRACAST_SET_WIFISTATE, &MiracastService::setWiFiStateWrapper, this); + #endif /*UNIT_TESTING*/ #ifdef ENABLE_MIRACAST_SERVICE_TEST_NOTIFIER m_isTestNotifierEnabled = false; @@ -120,11 +138,18 @@ namespace WPEFramework delete m_SystemPluginObj; m_SystemPluginObj = nullptr; } + if (nullptr != m_WiFiPluginObj) + { + delete m_WiFiPluginObj; + m_WiFiPluginObj = nullptr; + } if (m_FriendlyNameMonitorTimerID) { g_source_remove(m_FriendlyNameMonitorTimerID); m_FriendlyNameMonitorTimerID = 0; } + remove_wifi_connection_state_timer(); + remove_miracast_connection_timer(); Unregister(METHOD_MIRACAST_SET_ENABLE); Unregister(METHOD_MIRACAST_GET_ENABLE); Unregister(METHOD_MIRACAST_STOP_CLIENT_CONNECT); @@ -135,8 +160,55 @@ namespace WPEFramework LOGINFO("Exiting..!!!"); } + const void MiracastService::InitializeIARM() + { + if (Utils::IARM::init()) + { + IARM_Result_t res; + IARM_Bus_PWRMgr_GetPowerState_Param_t param; + + IARM_CHECK( IARM_Bus_RegisterEventHandler(IARM_BUS_PWRMGR_NAME,IARM_BUS_PWRMGR_EVENT_MODECHANGED, pwrMgrModeChangeEventHandler) ); + // get power state: + res = IARM_Bus_Call(IARM_BUS_PWRMGR_NAME, + IARM_BUS_PWRMGR_API_GetPowerState, + (void *)¶m, + sizeof(param)); + if(IARM_RESULT_SUCCESS == res ) + { + LOGINFO("MiracastService::Current state is IARM: (%d) \n",param.curState); + setPowerState(param.curState); + } + } + } + + void MiracastService::DeinitializeIARM() + { + if (Utils::IARM::isConnected()) + { + IARM_Result_t res; + IARM_CHECK( IARM_Bus_RemoveEventHandler(IARM_BUS_PWRMGR_NAME,IARM_BUS_PWRMGR_EVENT_MODECHANGED, pwrMgrModeChangeEventHandler) ); + } + } + + void MiracastService::pwrMgrModeChangeEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) + { + if (nullptr == _instance) + { + LOGERR("#### MCAST-TRIAGE-NOK-PWR Miracast Service not enabled yet ####"); + return; + } + + if ((0 == strcmp(owner, IARM_BUS_PWRMGR_NAME)) && (IARM_BUS_PWRMGR_EVENT_MODECHANGED == eventId )) + { + IARM_Bus_PWRMgr_EventData_t *param = (IARM_Bus_PWRMgr_EventData_t *)data; + + lock_guard lck(_instance->m_DiscoveryStateMutex); + _instance->setPowerState(param->data.state.newState); + } + } + // Thunder plugins communication - void MiracastService::getSystemPlugin() + void MiracastService::getThunderPlugins() { MIRACASTLOG_INFO("Entering..!!!"); @@ -176,6 +248,16 @@ namespace WPEFramework { MIRACASTLOG_INFO("JSONRPC: %s: initialization ok", SYSTEM_CALLSIGN_VER); } + + m_WiFiPluginObj = new WPEFramework::JSONRPC::LinkType(_T(WIFI_CALLSIGN_VER), (_T("MiracastService")), false, query); + if (nullptr == m_WiFiPluginObj) + { + LOGERR("JSONRPC: %s: initialization failed", WIFI_CALLSIGN_VER); + } + else + { + MIRACASTLOG_INFO("JSONRPC: %s: initialization ok", WIFI_CALLSIGN_VER); + } } MIRACASTLOG_INFO("Exiting..!!!"); } @@ -194,14 +276,24 @@ namespace WPEFramework if (!m_isServiceInitialized) { MiracastError ret_code = MIRACAST_OK; + + InitializeIARM(); m_miracast_ctrler_obj = MiracastController::getInstance(ret_code, this,p2p_ctrl_iface); if (nullptr != m_miracast_ctrler_obj) { m_CurrentService = service; - getSystemPlugin(); + getThunderPlugins(); // subscribe for event - m_SystemPluginObj->Subscribe(1000, "onFriendlyNameChanged", &MiracastService::onFriendlyNameUpdateHandler, this); + if (nullptr != m_SystemPluginObj) + { + m_SystemPluginObj->Subscribe(1000, "onFriendlyNameChanged", &MiracastService::onFriendlyNameUpdateHandler, this); + } + if (nullptr != m_WiFiPluginObj) + { + m_WiFiPluginObj->Subscribe(1000, "onWIFIStateChanged", &MiracastService::onWIFIStateChangedHandler, this); + } + if ( false == updateSystemFriendlyName()) { m_FriendlyNameMonitorTimerID = g_timeout_add(2000, MiracastService::monitor_friendly_name_timercallback, this); @@ -258,6 +350,7 @@ namespace WPEFramework if (m_isServiceInitialized) { MiracastController::destroyInstance(); + DeinitializeIARM(); m_CurrentService = nullptr; m_miracast_ctrler_obj = nullptr; m_isServiceInitialized = false; @@ -278,7 +371,7 @@ namespace WPEFramework * @param: None. * @return Returns the success code of underlying method. */ - uint32_t MiracastService::setEnable(const JsonObject ¶meters, JsonObject &response) + uint32_t MiracastService::setEnableWrapper(const JsonObject ¶meters, JsonObject &response) { bool success = false; bool is_enabled = true; @@ -288,15 +381,26 @@ namespace WPEFramework { getBoolParameter("enabled", is_enabled); + lock_guard lck(m_DiscoveryStateMutex); + eMIRA_SERVICE_STATES current_state = getCurrentServiceState(); if (true == is_enabled) { if (!m_isServiceEnabled) { - m_miracast_ctrler_obj->set_enable(is_enabled); - success = true; - m_isServiceEnabled = is_enabled; + lock_guard lock(m_EventMutex); + if (m_IsTransitionFromDeepSleep) + { + LOGINFO("#### MCAST-TRIAGE-OK Enable Miracast discovery Async"); + m_miracast_ctrler_obj->restart_discoveryAsync(); + m_IsTransitionFromDeepSleep = false; + } + else + { + setEnable(true); + } + m_isServiceEnabled = true; response["message"] = "Successfully enabled the WFD Discovery"; - changeServiceState(MIRACAST_SERVICE_STATE_DISCOVERABLE); + success = true; } else { @@ -305,17 +409,33 @@ namespace WPEFramework } else { - if ( MIRACAST_SERVICE_STATE_PLAYER_LAUNCHED == getCurrentServiceState() ) + if ( MIRACAST_SERVICE_STATE_PLAYER_LAUNCHED == current_state ) { response["message"] = "Failed as MiracastPlayer already Launched"; } else if (m_isServiceEnabled) { - m_miracast_ctrler_obj->set_enable(is_enabled); - success = true; - m_isServiceEnabled = is_enabled; + lock_guard lock(m_EventMutex); + if (!m_IsTransitionFromDeepSleep) + { + if ( MIRACAST_SERVICE_STATE_RESTARTING_SESSION == current_state ) + { + m_miracast_ctrler_obj->stop_discoveryAsync(); + } + else + { + setEnable(false); + } + } + else + { + LOGINFO("#### MCAST-TRIAGE-OK Skipping Disable discovery as done by PwrMgr"); + } + m_isServiceEnabled = false; + remove_wifi_connection_state_timer(); + remove_miracast_connection_timer(); response["message"] = "Successfully disabled the WFD Discovery"; - changeServiceState(MIRACAST_SERVICE_STATE_IDLE); + success = true; } else { @@ -327,6 +447,7 @@ namespace WPEFramework { response["message"] = "Invalid parameter passed"; } + returnResponse(success); } @@ -343,6 +464,22 @@ namespace WPEFramework returnResponse(true); } + /** + * @brief This method used to Enable/Disable the Miracast/WFD Discovery. + * + * @param: None. + * @return Returns the success code of underlying method. + */ + void MiracastService::setEnable(bool isEnabled) + { + MIRACASTLOG_INFO("Entering..!!!"); + if ( nullptr != m_miracast_ctrler_obj ) + { + m_miracast_ctrler_obj->set_enable(isEnabled); + } + MIRACASTLOG_INFO("Exiting..!!!"); + } + /** * @brief This method used to Enable/Disable the Miracast P2P Backend Discovery. * @@ -414,19 +551,26 @@ namespace WPEFramework requestedStatus = parameters["requestStatus"].String(); if (("Accept" == requestedStatus) || ("Reject" == requestedStatus)) { + lock_guard lock(m_EventMutex); + eMIRA_SERVICE_STATES current_state = getCurrentServiceState(); success = true; - if ( MIRACAST_SERVICE_STATE_DIRECT_LAUCH_REQUESTED == getCurrentServiceState() ) + + remove_miracast_connection_timer(); + + if ( MIRACAST_SERVICE_STATE_DIRECT_LAUCH_WITH_CONNECTING == current_state) { if ("Accept" == requestedStatus) { MIRACASTLOG_INFO("#### Notifying Launch Request ####"); m_miracast_ctrler_obj->switch_launch_request_context(m_src_dev_ip, m_src_dev_mac, m_src_dev_name, m_sink_dev_ip ); + changeServiceState(MIRACAST_SERVICE_STATE_CONNECTION_ACCEPTED); } else { + changeServiceState(MIRACAST_SERVICE_STATE_CONNECTION_REJECTED); m_miracast_ctrler_obj->restart_session_discovery(m_src_dev_mac); m_miracast_ctrler_obj->m_ePlayer_state = MIRACAST_PLAYER_STATE_IDLE; - changeServiceState(MIRACAST_SERVICE_STATE_DISCOVERABLE); + changeServiceState(MIRACAST_SERVICE_STATE_RESTARTING_SESSION); MIRACASTLOG_INFO("#### Refreshing the Session ####"); } m_src_dev_ip.clear(); @@ -436,14 +580,28 @@ namespace WPEFramework } else { - m_miracast_ctrler_obj->accept_client_connection(requestedStatus); - changeServiceState(MIRACAST_SERVICE_STATE_CONNECTION_ACCEPTED); + if ( MIRACAST_SERVICE_STATE_CONNECTING == current_state ) + { + m_miracast_ctrler_obj->accept_client_connection(requestedStatus); + if ("Accept" == requestedStatus) + { + changeServiceState(MIRACAST_SERVICE_STATE_CONNECTION_ACCEPTED); + } + else + { + changeServiceState(MIRACAST_SERVICE_STATE_CONNECTION_REJECTED); + } + } + else + { + MIRACASTLOG_INFO("Ignoring '%s' as Session already Refreshed and Current State[%#08X]",requestedStatus.c_str(),current_state); + } } } else { response["message"] = "Supported 'requestStatus' parameter values are Accept or Reject"; - LOGERR("Unsupported param passed [%s].\n", requestedStatus.c_str()); + LOGERR("Unsupported param passed [%s]", requestedStatus.c_str()); } } else @@ -463,7 +621,10 @@ namespace WPEFramework returnIfStringParamNotFound(parameters, "name"); returnIfStringParamNotFound(parameters, "mac"); - if ( MIRACAST_SERVICE_STATE_APP_REQ_TO_ABORT_CONNECTION == getCurrentServiceState() ) + lock_guard lock(m_EventMutex); + eMIRA_SERVICE_STATES current_state = getCurrentServiceState(); + + if ( MIRACAST_SERVICE_STATE_CONNECTION_ACCEPTED != current_state ) { MIRACASTLOG_WARNING("stopClientConnection Already Received..!!!"); response["message"] = "stopClientConnection Already Received"; @@ -486,10 +647,11 @@ namespace WPEFramework cached_mac_address = mac; } - if ( MIRACAST_SERVICE_STATE_PLAYER_LAUNCHED != getCurrentServiceState() ) + if ( MIRACAST_SERVICE_STATE_PLAYER_LAUNCHED != current_state ) { changeServiceState(MIRACAST_SERVICE_STATE_APP_REQ_TO_ABORT_CONNECTION); m_miracast_ctrler_obj->restart_session_discovery(cached_mac_address); + changeServiceState(MIRACAST_SERVICE_STATE_RESTARTING_SESSION); success = true; } else @@ -525,6 +687,7 @@ namespace WPEFramework returnIfStringParamNotFound(parameters, "mac"); returnIfStringParamNotFound(parameters, "state"); + lock_guard lock(m_EventMutex); if (parameters.HasLabel("mac")) { getStringParameter("mac", mac); @@ -567,7 +730,6 @@ namespace WPEFramework } } m_miracast_ctrler_obj->m_ePlayer_state = MIRACAST_PLAYER_STATE_STOPPED; - changeServiceState(MIRACAST_SERVICE_STATE_DISCOVERABLE); } else if (player_state == "INITIATED" || player_state == "initiated") { @@ -587,6 +749,7 @@ namespace WPEFramework { // It will restart the discovering m_miracast_ctrler_obj->restart_session_discovery(mac); + changeServiceState(MIRACAST_SERVICE_STATE_RESTARTING_SESSION); } MIRACASTLOG_INFO("Player State set to [%s (%d)] for Source device [%s].", player_state.c_str(), (int)m_miracast_ctrler_obj->m_ePlayer_state, mac.c_str()); @@ -868,12 +1031,15 @@ namespace WPEFramework bool is_another_connect_request = false; MIRACASTLOG_INFO("Entering..!!!"); - if ( MIRACAST_SERVICE_STATE_PLAYER_LAUNCHED == getCurrentServiceState() ) + lock_guard lock(m_EventMutex); + eMIRA_SERVICE_STATES current_state = getCurrentServiceState(); + + if ( MIRACAST_SERVICE_STATE_PLAYER_LAUNCHED == current_state ) { is_another_connect_request = true; MIRACASTLOG_WARNING("Another Connect Request received while casting"); } - if ((MIRACAST_SERVICE_STATE_DIRECT_LAUCH_REQUESTED != getCurrentServiceState()) && + if ((MIRACAST_SERVICE_STATE_DIRECT_LAUCH_REQUESTED != current_state) && ((0 == access("/opt/miracast_autoconnect", F_OK))|| (0 == access("/opt/miracast_direct_request", F_OK)))) { @@ -887,6 +1053,7 @@ namespace WPEFramework MiracastCommon::execute_SystemCommand(commandBuffer); sleep(1); } + changeServiceState(MIRACAST_SERVICE_STATE_CONNECTING); memset(commandBuffer,0x00,sizeof(commandBuffer)); snprintf( commandBuffer, sizeof(commandBuffer), @@ -894,6 +1061,7 @@ namespace WPEFramework requestStatus.c_str()); MIRACASTLOG_INFO("AutoConnecting [%s - %s] by [%s]",client_name.c_str(),client_mac.c_str(),commandBuffer); MiracastCommon::execute_SystemCommand(commandBuffer); + changeServiceState(MIRACAST_SERVICE_STATE_CONNECTION_ACCEPTED); } else { @@ -901,6 +1069,18 @@ namespace WPEFramework params["mac"] = client_mac; params["name"] = client_name; sendNotify(EVT_ON_CLIENT_CONNECTION_REQUEST, params); + m_src_dev_mac = client_mac; + + if (MIRACAST_SERVICE_STATE_DIRECT_LAUCH_REQUESTED == current_state) + { + changeServiceState(MIRACAST_SERVICE_STATE_DIRECT_LAUCH_WITH_CONNECTING); + } + else + { + changeServiceState(MIRACAST_SERVICE_STATE_CONNECTING); + } + m_MiracastConnectionMonitorTimerID = g_timeout_add(40000, MiracastService::monitor_miracast_connection_timercallback, this); + MIRACASTLOG_INFO("Timer created to Monitor Miracast Connection Status [%u]",m_MiracastConnectionMonitorTimerID); } } @@ -908,7 +1088,14 @@ namespace WPEFramework { MIRACASTLOG_INFO("Entering..!!!"); - if ( MIRACAST_SERVICE_STATE_APP_REQ_TO_ABORT_CONNECTION != getCurrentServiceState() ) + lock_guard lock(m_EventMutex); + eMIRA_SERVICE_STATES current_state = getCurrentServiceState(); + + if ( MIRACAST_SERVICE_STATE_CONNECTION_ACCEPTED != current_state ) + { + MIRACASTLOG_INFO("Session already refreshed, So no need to report Error. Current state [%#08X]",current_state); + } + else { JsonObject params; params["mac"] = client_mac; @@ -916,11 +1103,6 @@ namespace WPEFramework params["error_code"] = std::to_string(error_code); params["reason"] = reasonDescription(error_code); sendNotify(EVT_ON_CLIENT_CONNECTION_ERROR, params); - changeServiceState(MIRACAST_SERVICE_STATE_DISCOVERABLE); - } - else - { - MIRACASTLOG_INFO("APP_REQ_TO_ABORT_CONNECTION has requested. So no need to notify..!!!"); } MIRACASTLOG_INFO("Exiting..!!!"); } @@ -950,7 +1132,7 @@ namespace WPEFramework bool return_value = false; MIRACASTLOG_INFO("Entering..!!!"); - getSystemPlugin(); + getThunderPlugins(); if (nullptr == m_SystemPluginObj) { @@ -1017,8 +1199,195 @@ namespace WPEFramework return timer_retry_state; } + void MiracastService::setWiFiState(DEVICE_WIFI_STATES wifiState) + { + MIRACASTLOG_INFO("Miracast WiFi State=%#08X", wifiState); + lock_guard lck(m_DiscoveryStateMutex); + if (m_isServiceEnabled) + { + switch(wifiState) + { + case DEVICE_WIFI_STATE_CONNECTING: + { + MIRACASTLOG_INFO("#### MCAST-TRIAGE-OK-WIFI DEVICE_WIFI_STATE [CONNECTING] ####"); + {lock_guard lock(m_EventMutex); + setEnable(false); + } + remove_wifi_connection_state_timer(); + m_IsWiFiConnectingState = true; + m_WiFiConnectedStateMonitorTimerID = g_timeout_add(30000, MiracastService::monitor_wifi_connection_state_timercallback, this); + MIRACASTLOG_INFO("Timer created to Monitor WiFi Connection Status [%u]",m_WiFiConnectedStateMonitorTimerID); + } + break; + case DEVICE_WIFI_STATE_CONNECTED: + case DEVICE_WIFI_STATE_FAILED: + { + MIRACASTLOG_INFO("#### MCAST-TRIAGE-OK-WIFI DEVICE_WIFI_STATE [%s] ####",( DEVICE_WIFI_STATE_CONNECTED == wifiState ) ? "CONNECTED" : "FAILED"); + if (m_IsWiFiConnectingState) + { + {lock_guard lock(m_EventMutex); + setEnable(true); + } + m_IsWiFiConnectingState = false; + } + remove_wifi_connection_state_timer(); + } + break; + default: + { + /* NOP */ + } + break; + } + } + } + + #ifdef UNIT_TESTING + /** + * @brief This method used to get the current status of Miracast. + * + * @param: None. + * @return Returns the success code of underlying method. + */ + uint32_t MiracastService::getStatus(const JsonObject ¶meters, JsonObject &response) + { + MIRACASTLOG_INFO("Entering..!!!"); + lock_guard lck(m_DiscoveryStateMutex); + lock_guard lock(m_EventMutex); + response["enabled"] = m_isServiceEnabled; + response["state"] = std::to_string(getCurrentServiceState()); + response["powerState"] = getPowerStateString(getCurrentPowerState()); + response["DeepSleepTransition"] = m_IsTransitionFromDeepSleep; + response["wifiState"] = m_IsWiFiConnectingState; + returnResponse(true); + } + + /** + * @brief This method used to get the set Power status to Miracast. + * + * @param: None. + * @return Returns the success code of underlying method. + */ + uint32_t MiracastService::setPowerStateWrapper(const JsonObject ¶meters, JsonObject &response) + { + string message; + uint32_t powerState; + MIRACASTLOG_INFO("Entering..!!!"); + parameters.ToString(message); + MIRACASTLOG_INFO("[Power State Changed Event], [%s]", message.c_str()); + + if (parameters.HasLabel("state")) + { + powerState = parameters["state"].Number(); + setPowerState(static_cast(powerState)); + } + returnResponse(true); + } + + /** + * @brief This method used to get the set WiFi status to Miracast. + * + * @param: None. + * @return Returns the success code of underlying method. + */ + uint32_t MiracastService::setWiFiStateWrapper(const JsonObject ¶meters, JsonObject &response) + { + string message; + uint32_t wifiState; + MIRACASTLOG_INFO("Entering..!!!"); + parameters.ToString(message); + MIRACASTLOG_INFO("[WiFi State Changed Event], [%s]", message.c_str()); + + if (parameters.HasLabel("state")) + { + wifiState = parameters["state"].Number(); + DEVICE_WIFI_STATES temp = static_cast(wifiState); + MIRACASTLOG_INFO("[WiFi State Changed Event], [%#08X][%#08X]", wifiState,temp); + setWiFiState(static_cast(wifiState)); + } + returnResponse(true); + } + #endif /*UNIT_TESTING*/ + + void MiracastService::onWIFIStateChangedHandler(const JsonObject ¶meters) + { + string message; + uint32_t wifiState; + parameters.ToString(message); + MIRACASTLOG_INFO("[WiFi State Changed Event], [%s]", message.c_str()); + + if (parameters.HasLabel("state")) + { + wifiState = parameters["state"].Number(); + setWiFiState(static_cast(wifiState)); + } + } + + gboolean MiracastService::monitor_wifi_connection_state_timercallback(gpointer userdata) + { + MIRACASTLOG_TRACE("Entering..!!!"); + MiracastService *self = (MiracastService *)userdata; + MIRACASTLOG_INFO("TimerCallback Triggered for Monitor WiFi Connection Status..."); + {lock_guard lck(self->m_DiscoveryStateMutex); + MIRACASTLOG_INFO("#### MCAST-TRIAGE-OK-WIFI Discovery[%u] WiFiConnectingState[%u] ####", + self->m_isServiceEnabled,m_IsWiFiConnectingState); + if (self->m_isServiceEnabled && m_IsWiFiConnectingState) + { + {lock_guard lock(self->m_EventMutex); + self->setEnable(true); + } + } + m_IsWiFiConnectingState = false; + } + MIRACASTLOG_TRACE("Exiting..!!!"); + return G_SOURCE_REMOVE; + } + + gboolean MiracastService::monitor_miracast_connection_timercallback(gpointer userdata) + { + MiracastService *self = (MiracastService *)userdata; + MIRACASTLOG_TRACE("Entering..!!!"); + lock_guard lock(self->m_EventMutex); + MIRACASTLOG_INFO("TimerCallback Triggered for Monitor Miracast Connection Expired and Restarting Session..."); + if (self->m_isServiceEnabled) + { + self->m_miracast_ctrler_obj->restart_session_discovery(self->m_src_dev_mac); + self->m_src_dev_mac.clear(); + self->changeServiceState(MIRACAST_SERVICE_STATE_RESTARTING_SESSION); + } + MIRACASTLOG_TRACE("Exiting..!!!"); + return G_SOURCE_REMOVE; + } + + void MiracastService::remove_wifi_connection_state_timer(void) + { + MIRACASTLOG_TRACE("Entering..!!!"); + if (m_WiFiConnectedStateMonitorTimerID) + { + MIRACASTLOG_INFO("Removing WiFi Connection Status Monitor Timer"); + g_source_remove(m_WiFiConnectedStateMonitorTimerID); + m_WiFiConnectedStateMonitorTimerID = 0; + } + m_IsWiFiConnectingState = false; + MIRACASTLOG_TRACE("Exiting..!!!"); + } + + void MiracastService::remove_miracast_connection_timer(void) + { + MIRACASTLOG_TRACE("Entering..!!!"); + if (m_MiracastConnectionMonitorTimerID) + { + MIRACASTLOG_INFO("Removing Miracast Connection Status Monitor Timer"); + g_source_remove(m_MiracastConnectionMonitorTimerID); + m_MiracastConnectionMonitorTimerID = 0; + } + MIRACASTLOG_TRACE("Exiting..!!!"); + } + void MiracastService::onMiracastServiceLaunchRequest(string src_dev_ip, string src_dev_mac, string src_dev_name, string sink_dev_ip, bool is_connect_req_reported ) { + lock_guard lock(m_EventMutex); + eMIRA_SERVICE_STATES current_state = getCurrentServiceState(); MIRACASTLOG_INFO("Entering[%u]..!!!",is_connect_req_reported); if ( !is_connect_req_reported ) @@ -1031,9 +1400,9 @@ namespace WPEFramework MIRACASTLOG_INFO("Direct Launch request has received. So need to notify connect Request"); onMiracastServiceClientConnectionRequest( src_dev_mac, src_dev_name ); } - else if ( MIRACAST_SERVICE_STATE_APP_REQ_TO_ABORT_CONNECTION == getCurrentServiceState() ) + else if ( MIRACAST_SERVICE_STATE_CONNECTION_ACCEPTED != current_state ) { - MIRACASTLOG_INFO("APP_REQ_TO_ABORT_CONNECTION has requested. So no need to notify Launch Request..!!!"); + MIRACASTLOG_INFO("Session already refreshed, So no need to notify Launch Request. Current state [%#08X]",current_state); //m_miracast_ctrler_obj->restart_session_discovery(); } else @@ -1066,11 +1435,34 @@ namespace WPEFramework changeServiceState(MIRACAST_SERVICE_STATE_PLAYER_LAUNCHED); } } + + void MiracastService::onStateChange(eMIRA_SERVICE_STATES state) + { + MIRACASTLOG_INFO("Entering state [%#08X]",state); + lock_guard lock(m_EventMutex); + switch (state) + { + case MIRACAST_SERVICE_STATE_IDLE: + case MIRACAST_SERVICE_STATE_DISCOVERABLE: + { + changeServiceState(state); + } + break; + default: + { + + } + break; + } + MIRACASTLOG_INFO("Exiting..."); + } + eMIRA_SERVICE_STATES MiracastService::getCurrentServiceState(void) { MIRACASTLOG_INFO("current state [%#08X]",m_eService_state); return m_eService_state; } + void MiracastService::changeServiceState(eMIRA_SERVICE_STATES eService_state) { eMIRA_SERVICE_STATES old_state = m_eService_state, @@ -1078,5 +1470,87 @@ namespace WPEFramework m_eService_state = eService_state; MIRACASTLOG_INFO("changing state [%#08X] -> [%#08X]",old_state,new_state); } + + std::string MiracastService::getPowerStateString(IARM_Bus_PWRMgr_PowerState_t pwrState) + { + std::string pwrStateStr = ""; + + switch (pwrState) + { + case IARM_BUS_PWRMGR_POWERSTATE_ON: + { + pwrStateStr = "ON"; + } + break; + case IARM_BUS_PWRMGR_POWERSTATE_OFF: + { + pwrStateStr = "OFF"; + } + break; + case IARM_BUS_PWRMGR_POWERSTATE_STANDBY: + case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_LIGHT_SLEEP: + { + pwrStateStr = "LIGHT_SLEEP"; + } + break; + case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP: + { + pwrStateStr = "DEEP_SLEEP"; + } + break; + default: + { + pwrStateStr = "UNKNOWN"; + } + break; + } + return pwrStateStr; + } + + IARM_Bus_PWRMgr_PowerState_t MiracastService::getCurrentPowerState(void) + { + MIRACASTLOG_INFO("current power state [%s]",getPowerStateString(m_powerState).c_str()); + return m_powerState; + } + + void MiracastService::setPowerState(IARM_Bus_PWRMgr_PowerState_t pwrState) + { + IARM_Bus_PWRMgr_PowerState_t old_pwr_state = m_powerState, + new_pwr_state = pwrState; + m_powerState = pwrState; + MIRACASTLOG_INFO("changing power state [%s] -> [%s]", + getPowerStateString(old_pwr_state).c_str(), + getPowerStateString(new_pwr_state).c_str()); + if (IARM_BUS_PWRMGR_POWERSTATE_ON == pwrState) + { + lock_guard lock(_instance->m_EventMutex); + if ((m_IsTransitionFromDeepSleep) && (_instance->m_isServiceEnabled)) + { + LOGINFO("#### MCAST-TRIAGE-OK-PWR Enable Miracast discovery from PwrMgr [%d]",_instance->m_isServiceEnabled); + _instance->m_miracast_ctrler_obj->restart_discoveryAsync(); + m_IsTransitionFromDeepSleep = false; + } + else if (!_instance->m_isServiceEnabled) + { + LOGINFO("#### MCAST-TRIAGE-OK-PWR Miracast discovery already Disabled [%d]. No need to enable it",_instance->m_isServiceEnabled); + } + } + else if (IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP == pwrState) + { + lock_guard lock(_instance->m_EventMutex); + if ( _instance->m_isServiceEnabled ) + { + LOGINFO("#### MCAST-TRIAGE-OK-PWR Miracast Discovery Disabled ####"); + _instance->setEnable(false); + } + else + { + LOGINFO("#### MCAST-TRIAGE-OK-PWR Miracast discovery already Disabled [%d]. No need to disable it",_instance->m_isServiceEnabled); + } + _instance->remove_wifi_connection_state_timer(); + _instance->remove_miracast_connection_timer(); + m_IsTransitionFromDeepSleep = true; + } + } } // namespace Plugin } // namespace WPEFramework diff --git a/Miracast/MiracastService/MiracastService.h b/Miracast/MiracastService/MiracastService.h index 8997ec15b0..c1678bdba6 100644 --- a/Miracast/MiracastService/MiracastService.h +++ b/Miracast/MiracastService/MiracastService.h @@ -24,6 +24,18 @@ #include "Module.h" #include +#include "libIARM.h" +#include "pwrMgr.h" + +typedef enum DeviceWiFiStates{ + DEVICE_WIFI_STATE_UNINSTALLED = 0, + DEVICE_WIFI_STATE_DISABLED = 1, + DEVICE_WIFI_STATE_DISCONNECTED = 2, + DEVICE_WIFI_STATE_PAIRING = 3, + DEVICE_WIFI_STATE_CONNECTING = 4, + DEVICE_WIFI_STATE_CONNECTED = 5, + DEVICE_WIFI_STATE_FAILED = 6 +}DEVICE_WIFI_STATES; using std::vector; namespace WPEFramework @@ -58,6 +70,11 @@ namespace WPEFramework static const string METHOD_MIRACAST_STOP_CLIENT_CONNECT; static const string METHOD_MIRACAST_SET_UPDATE_PLAYER_STATE; static const string METHOD_MIRACAST_SET_LOG_LEVEL; + #ifdef UNIT_TESTING + static const string METHOD_MIRACAST_GET_STATUS; + static const string METHOD_MIRACAST_SET_POWERSTATE; + static const string METHOD_MIRACAST_SET_WIFISTATE; + #endif /*UNIT_TESTING*/ #ifdef ENABLE_MIRACAST_SERVICE_TEST_NOTIFIER static const string METHOD_MIRACAST_TEST_NOTIFIER; @@ -74,6 +91,7 @@ namespace WPEFramework virtual void onMiracastServiceClientConnectionRequest(string client_mac, string client_name) override; virtual void onMiracastServiceClientConnectionError(string client_mac, string client_name , eMIRACAST_SERVICE_ERR_CODE error_code ) override; virtual void onMiracastServiceLaunchRequest(string src_dev_ip, string src_dev_mac, string src_dev_name, string sink_dev_ip, bool is_connect_req_reported ) override; + virtual void onStateChange(eMIRA_SERVICE_STATES state ) override; BEGIN_INTERFACE_MAP(MiracastService) INTERFACE_ENTRY(PluginHost::IPlugin) @@ -87,29 +105,53 @@ namespace WPEFramework private: bool m_isServiceInitialized; bool m_isServiceEnabled; + std::mutex m_DiscoveryStateMutex; + std::recursive_mutex m_EventMutex; guint m_FriendlyNameMonitorTimerID{0}; + guint m_WiFiConnectedStateMonitorTimerID{0}; + guint m_MiracastConnectionMonitorTimerID{0}; eMIRA_SERVICE_STATES m_eService_state; std::string m_src_dev_ip; std::string m_src_dev_mac; std::string m_src_dev_name; std::string m_sink_dev_ip; WPEFramework::JSONRPC::LinkType *m_SystemPluginObj = NULL; - uint32_t setEnable(const JsonObject ¶meters, JsonObject &response); + WPEFramework::JSONRPC::LinkType *m_WiFiPluginObj = NULL; + uint32_t setEnableWrapper(const JsonObject ¶meters, JsonObject &response); uint32_t getEnable(const JsonObject ¶meters, JsonObject &response); uint32_t setP2PBackendDiscovery(const JsonObject ¶meters, JsonObject &response); uint32_t acceptClientConnection(const JsonObject ¶meters, JsonObject &response); uint32_t stopClientConnection(const JsonObject ¶meters, JsonObject &response); uint32_t updatePlayerState(const JsonObject ¶meters, JsonObject &response); uint32_t setLogging(const JsonObject ¶meters, JsonObject &response); + #ifdef UNIT_TESTING + uint32_t getStatus(const JsonObject ¶meters, JsonObject &response); + uint32_t setPowerStateWrapper(const JsonObject ¶meters, JsonObject &response); + uint32_t setWiFiStateWrapper(const JsonObject ¶meters, JsonObject &response); + #endif /*UNIT_TESTING*/ std::string reasonDescription(eMIRACAST_SERVICE_ERR_CODE e); - void getSystemPlugin(); + void getThunderPlugins(); bool updateSystemFriendlyName(); void onFriendlyNameUpdateHandler(const JsonObject ¶meters); static gboolean monitor_friendly_name_timercallback(gpointer userdata); + void setWiFiState(DEVICE_WIFI_STATES wifiState); + void onWIFIStateChangedHandler(const JsonObject ¶meters); + static gboolean monitor_wifi_connection_state_timercallback(gpointer userdata); + void remove_wifi_connection_state_timer(void); + static gboolean monitor_miracast_connection_timercallback(gpointer userdata); + void remove_miracast_connection_timer(void); bool envGetValue(const char *key, std::string &value); eMIRA_SERVICE_STATES getCurrentServiceState(void); void changeServiceState(eMIRA_SERVICE_STATES eService_state); + IARM_Bus_PWRMgr_PowerState_t getCurrentPowerState(void); + void setPowerState(IARM_Bus_PWRMgr_PowerState_t pwrState); + std::string getPowerStateString(IARM_Bus_PWRMgr_PowerState_t pwrState); + void setEnable(bool isEnabled); + + const void InitializeIARM(); + void DeinitializeIARM(); + static void pwrMgrModeChangeEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); // We do not allow this plugin to be copied !! MiracastService(const MiracastService &) = delete; diff --git a/Miracast/MiracastService/P2P/MiracastP2P.cpp b/Miracast/MiracastService/P2P/MiracastP2P.cpp index 9e940fa53d..9a966e3d4d 100644 --- a/Miracast/MiracastService/P2P/MiracastP2P.cpp +++ b/Miracast/MiracastService/P2P/MiracastP2P.cpp @@ -458,10 +458,21 @@ MiracastError MiracastP2P::discover_devices(void) { MiracastError ret = MIRACAST_FAIL; std::string command, retBuffer; + std::string opt_flag_buffer = MiracastCommon::parse_opt_flag("/opt/miracast_custom_p2p_scan"); MIRACASTLOG_TRACE("Entering.."); /*Start Passive Scanning*/ - command = "P2P_EXT_LISTEN 200 1000"; + command = "P2P_EXT_LISTEN 0 0"; + ret = executeCommand(command, NON_GLOBAL_INTERFACE, retBuffer); + + if (!opt_flag_buffer.empty()) + { + command = "P2P_EXT_LISTEN " + opt_flag_buffer; + } + else + { + command = "P2P_EXT_LISTEN 200 1000"; + } ret = executeCommand(command, NON_GLOBAL_INTERFACE, retBuffer); if (ret != MIRACAST_OK) diff --git a/Miracast/common/MiracastCommon.h b/Miracast/common/MiracastCommon.h index 03c0242d2e..0b2bb2b088 100644 --- a/Miracast/common/MiracastCommon.h +++ b/Miracast/common/MiracastCommon.h @@ -126,7 +126,6 @@ typedef struct group_info typedef enum msg_type_e { P2P_MSG = 0x01, - RTSP_MSG, CONTRLR_FW_MSG } eMSG_TYPE; @@ -142,11 +141,15 @@ typedef enum emira_service_states_e { MIRACAST_SERVICE_STATE_IDLE, MIRACAST_SERVICE_STATE_DISCOVERABLE, + MIRACAST_SERVICE_STATE_RESTARTING_SESSION, + MIRACAST_SERVICE_STATE_CONNECTING, MIRACAST_SERVICE_STATE_CONNECTION_ACCEPTED, + MIRACAST_SERVICE_STATE_CONNECTION_REJECTED, MIRACAST_SERVICE_STATE_CONNECTION_ERROR, MIRACAST_SERVICE_STATE_PLAYER_LAUNCHED, MIRACAST_SERVICE_STATE_APP_REQ_TO_ABORT_CONNECTION, - MIRACAST_SERVICE_STATE_DIRECT_LAUCH_REQUESTED + MIRACAST_SERVICE_STATE_DIRECT_LAUCH_REQUESTED, + MIRACAST_SERVICE_STATE_DIRECT_LAUCH_WITH_CONNECTING } eMIRA_SERVICE_STATES; typedef enum miracast_player_states_e @@ -319,6 +322,7 @@ class MiracastServiceNotifier virtual void onMiracastServiceClientConnectionRequest(string client_mac, string client_name) = 0; virtual void onMiracastServiceClientConnectionError(string client_mac, string client_name , eMIRACAST_SERVICE_ERR_CODE error_code ) = 0; virtual void onMiracastServiceLaunchRequest(string src_dev_ip, string src_dev_mac, string src_dev_name, string sink_dev_ip, bool is_connect_req_reported ) = 0; + virtual void onStateChange(eMIRA_SERVICE_STATES state ) = 0; }; /** diff --git a/Tests/L1Tests/tests/test_MiracastService.cpp b/Tests/L1Tests/tests/test_MiracastService.cpp index ccaa9f41e7..a960fb9342 100644 --- a/Tests/L1Tests/tests/test_MiracastService.cpp +++ b/Tests/L1Tests/tests/test_MiracastService.cpp @@ -4,6 +4,7 @@ #include "MiracastService.h" #include "WrapsMock.h" #include "WpaCtrlMock.h" +#include "IarmBusMock.h" using ::testing::NiceMock; using namespace WPEFramework; @@ -75,6 +76,8 @@ class MiracastServiceTest : public ::testing::Test { ServiceMock service; WrapsImplMock *p_wrapsImplMock = nullptr; WpaCtrlApiImplMock *p_wpaCtrlImplMock = nullptr; + IarmBusImplMock *p_iarmBusImplMock = nullptr; + IARM_EventHandler_t pwrMgrEventHandler; MiracastServiceTest() : plugin(Core::ProxyType::Create()) @@ -87,6 +90,9 @@ class MiracastServiceTest : public ::testing::Test { p_wpaCtrlImplMock = new NiceMock ; WpaCtrlApi::setImpl(p_wpaCtrlImplMock); + p_iarmBusImplMock = new testing::NiceMock ; + IarmBus::setImpl(p_iarmBusImplMock); + EXPECT_CALL(service, QueryInterfaceByCallsign(::testing::_, ::testing::_)) .Times(::testing::AnyNumber()) .WillRepeatedly(::testing::Invoke([&](const uint32_t, const string& name) -> void* { return nullptr; })); @@ -100,6 +106,21 @@ class MiracastServiceTest : public ::testing::Test { .WillByDefault(::testing::Invoke([&](struct wpa_ctrl *ctrl) { return false; })); ON_CALL(*p_wrapsImplMock, system(::testing::_)) .WillByDefault(::testing::Invoke([&](const char* command) {return 0;})); + ON_CALL(*p_iarmBusImplMock, IARM_Bus_RegisterEventHandler(::testing::_, ::testing::_, ::testing::_)) + .WillByDefault(::testing::Invoke([&](const char* ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler){ + if ((string(IARM_BUS_PWRMGR_NAME) == string(ownerName)) && (eventId == IARM_BUS_PWRMGR_EVENT_MODECHANGED)) { + pwrMgrEventHandler = handler; + } + return IARM_RESULT_SUCCESS; + })); + ON_CALL(*p_iarmBusImplMock, IARM_Bus_Call) + .WillByDefault([](const char* ownerName, const char* methodName, void* arg, size_t argLen){ + if (strcmp(methodName, IARM_BUS_PWRMGR_API_GetPowerState) == 0){ + auto* param = static_cast(arg); + param->curState = IARM_BUS_PWRMGR_POWERSTATE_ON; + } + return IARM_RESULT_SUCCESS; + }); } virtual ~MiracastServiceTest() override { @@ -116,6 +137,13 @@ class MiracastServiceTest : public ::testing::Test { delete p_wrapsImplMock; p_wrapsImplMock = nullptr; } + + IarmBus::setImpl(nullptr); + if (p_iarmBusImplMock != nullptr) + { + delete p_iarmBusImplMock; + p_iarmBusImplMock = nullptr; + } } }; @@ -180,6 +208,8 @@ TEST_F(MiracastServiceTest, RegisteredMethods) EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("updatePlayerState"))); EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setLogging"))); EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setP2PBackendDiscovery"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getStatus"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setWiFiState"))); plugin->Deinitialize(nullptr); @@ -1922,4 +1952,98 @@ TEST_F(MiracastServiceEventTest, P2P_GOMode_AutoConnect) removeEntryFromFile("/etc/device.properties","WIFI_P2P_CTRL_INTERFACE=p2p0"); removeFile("/var/run/wpa_supplicant/p2p0"); removeFile("/opt/miracast_autoconnect"); +} + +TEST_F(MiracastServiceEventTest, powerStateChange) +{ + IARM_Bus_PWRMgr_EventData_t param; + createFile("/etc/device.properties","WIFI_P2P_CTRL_INTERFACE=p2p0"); + createFile("/var/run/wpa_supplicant/p2p0","p2p0"); + + EXPECT_EQ(string(""), plugin->Initialize(&service)); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setEnable"), _T("{\"enabled\": true}"), response)); + + param.data.state.curState = IARM_BUS_PWRMGR_POWERSTATE_ON; + param.data.state.newState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP; + pwrMgrEventHandler(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_EVENT_MODECHANGED, ¶m, 0); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":true,\"state\":\"0\",\"powerState\":\"DEEP_SLEEP\",\"DeepSleepTransition\":true,\"wifiState\":false,\"success\":true}")); + + param.data.state.curState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP; + param.data.state.newState = IARM_BUS_PWRMGR_POWERSTATE_ON; + pwrMgrEventHandler(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_EVENT_MODECHANGED, ¶m, 0); + sleep(5); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":true,\"state\":\"1\",\"powerState\":\"ON\",\"DeepSleepTransition\":false,\"wifiState\":false,\"success\":true}")); + + param.data.state.curState = IARM_BUS_PWRMGR_POWERSTATE_ON; + param.data.state.newState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP; + pwrMgrEventHandler(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_EVENT_MODECHANGED, ¶m, 0); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":true,\"state\":\"0\",\"powerState\":\"DEEP_SLEEP\",\"DeepSleepTransition\":true,\"wifiState\":false,\"success\":true}")); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setEnable"), _T("{\"enabled\": false}"), response)); + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":false,\"state\":\"0\",\"powerState\":\"DEEP_SLEEP\",\"DeepSleepTransition\":true,\"wifiState\":false,\"success\":true}")); + + param.data.state.curState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP; + param.data.state.newState = IARM_BUS_PWRMGR_POWERSTATE_ON; + pwrMgrEventHandler(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_EVENT_MODECHANGED, ¶m, 0); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":false,\"state\":\"0\",\"powerState\":\"ON\",\"DeepSleepTransition\":true,\"wifiState\":false,\"success\":true}")); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setEnable"), _T("{\"enabled\": true}"), response)); + sleep(5); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":true,\"state\":\"1\",\"powerState\":\"ON\",\"DeepSleepTransition\":false,\"wifiState\":false,\"success\":true}")); + + plugin->Deinitialize(nullptr); + + removeEntryFromFile("/etc/device.properties","WIFI_P2P_CTRL_INTERFACE=p2p0"); + removeFile("/var/run/wpa_supplicant/p2p0"); +} + +TEST_F(MiracastServiceEventTest, wifiStateChange) +{ + createFile("/etc/device.properties","WIFI_P2P_CTRL_INTERFACE=p2p0"); + createFile("/var/run/wpa_supplicant/p2p0","p2p0"); + + EXPECT_EQ(string(""), plugin->Initialize(&service)); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setEnable"), _T("{\"enabled\": true}"), response)); + + // Setting WiFi Connecting State + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setWiFiState"), _T("{\"state\": 4 }"), response)); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":true,\"state\":\"0\",\"powerState\":\"ON\",\"DeepSleepTransition\":false,\"wifiState\":true,\"success\":true}")); + + // Setting WiFi Connected State + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setWiFiState"), _T("{\"state\": 5 }"), response)); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":true,\"state\":\"1\",\"powerState\":\"ON\",\"DeepSleepTransition\":false,\"wifiState\":false,\"success\":true}")); + + // Setting WiFi Connecting State + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setWiFiState"), _T("{\"state\": 4 }"), response)); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":true,\"state\":\"0\",\"powerState\":\"ON\",\"DeepSleepTransition\":false,\"wifiState\":true,\"success\":true}")); + + // Setting WiFi Connect Failed State + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setWiFiState"), _T("{\"state\": 6 }"), response)); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getStatus"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"enabled\":true,\"state\":\"1\",\"powerState\":\"ON\",\"DeepSleepTransition\":false,\"wifiState\":false,\"success\":true}")); + + plugin->Deinitialize(nullptr); + + removeEntryFromFile("/etc/device.properties","WIFI_P2P_CTRL_INTERFACE=p2p0"); + removeFile("/var/run/wpa_supplicant/p2p0"); } \ No newline at end of file