diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 66a15a7a..f71307d6 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -73,7 +73,7 @@ set (GDIAL_EXEC_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/gdial-rest.c ${CMAKE_CURRENT_SOURCE_DIR}/gdial-ssdp.c ${CMAKE_CURRENT_SOURCE_DIR}/gdial-shield.c - ${CMAKE_CURRENT_SOURCE_DIR}/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/gdialservice.cpp ) link_directories ( @@ -82,7 +82,12 @@ link_directories ( ${SOUP_LIBRARY_DIRS} ) -add_executable (gdial-server ${GDIAL_EXEC_SOURCE_FILES}) +add_library(gdial-server SHARED ${GDIAL_EXEC_SOURCE_FILES}) + +set_target_properties(${MODULE_NAME} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) +set_source_files_properties(gdialservice.cpp PROPERTIES COMPILE_FLAGS "-fpermissive") target_link_libraries (gdial-server ${GLIB_LIBRARIES} @@ -93,3 +98,7 @@ target_link_libraries (gdial-server gdial-plat uuid ) + +add_executable (gdial-server-ut gdialserver_ut.cpp) + +target_link_libraries (gdial-server-ut gdial-plat gdial-server) \ No newline at end of file diff --git a/server/gdial-app.c b/server/gdial-app.c index 91aa7c97..e22bd114 100644 --- a/server/gdial-app.c +++ b/server/gdial-app.c @@ -26,7 +26,7 @@ #include "gdial-util.h" #include "gdial-plat-app.h" #include "gdial-app.h" - +#include "gdialservicelogging.h" typedef struct _GDialAppPrivate { gpointer state_cb_data; @@ -81,7 +81,7 @@ static void gdial_app_dispose(GObject *gobject) { } application_instances_ = g_list_remove(application_instances_, gobject); - g_print("After dispose has %d app instances created\r\n", g_list_length(application_instances_)); + GDIAL_LOGINFO("After dispose has %d app instances created", g_list_length(application_instances_)); G_OBJECT_CLASS (gdial_app_parent_class)->dispose (gobject); } @@ -91,6 +91,7 @@ static void gdial_plat_app_state_cb(gint instance_id, GDialAppState state, void GDialApp *app = gdial_app_find_instance_by_instance_id(instance_id); g_return_if_fail (app != NULL); GDialAppPrivate *priv = gdial_app_get_instance_private(app); + GDIAL_LOGINFO("instance_id[%d] state[%x] data[%p]", instance_id, state, user_data); g_signal_emit(app, gdial_app_signals[SIGNAL_STATE_CHANGED], 0, app, priv->state_cb_data); } @@ -171,7 +172,6 @@ static void gdial_app_class_init (GDialAppClass *klass) { G_TYPE_NONE, 1, /* return type, arg num */ G_TYPE_POINTER); /* arg types */ - gdial_plat_init(g_main_context_default()); gdial_plat_application_set_state_cb(gdial_plat_app_state_cb, NULL); } @@ -201,9 +201,11 @@ static int compare_versions(const char *version1, const char *version2) { } GDialApp *gdial_app_new(const gchar *app_name) { - GDialApp *app = (GDialApp*)g_object_new(GDIAL_TYPE_APP, GDIAL_APP_NAME, app_name, NULL); - g_print("After create has %d app %s instances created\r\n", g_list_length(application_instances_), app_name); + GDIAL_LOGTRACE("Entering ..."); + GDialApp *app = (GDialApp*)g_object_new(GDIAL_TYPE_APP, GDIAL_APP_NAME, app_name, NULL); + GDIAL_LOGINFO("After create has %d app %s instances created", g_list_length(application_instances_), app_name); gdial_app_refresh_additional_dial_data(app); + GDIAL_LOGTRACE("Exiting ..."); return app; }; @@ -295,6 +297,7 @@ const gchar *gdial_app_state_to_string(GDialAppState state) { void gdial_app_force_shutdown(GDialApp *app) { g_warn_if_reached(); + GDIAL_LOGINFO("App[%p]",app); } gchar *gdial_app_get_launch_payload(GDialApp *app) { @@ -339,6 +342,7 @@ void gdial_app_set_additional_dial_data(GDialApp *app, GHashTable *additional_di gdial_app_write_additional_dial_data(app->name, query_str, length); } g_free(query_str); + query_str = NULL; } GHashTable *gdial_app_get_additional_dial_data(GDialApp *app) { @@ -350,6 +354,8 @@ GHashTable *gdial_app_get_additional_dial_data(GDialApp *app) { void gdial_app_refresh_additional_dial_data(GDialApp *app) { g_return_if_fail(app && app->name && strlen(app->name)); + GDIAL_LOGTRACE("Entering ..."); + GDialAppPrivate *priv = gdial_app_get_instance_private(app); if(priv->additional_dial_data) { g_hash_table_destroy(priv->additional_dial_data); @@ -361,10 +367,15 @@ void gdial_app_refresh_additional_dial_data(GDialApp *app) { if (data) { /* we are ready to convert to hashtable*/ gdial_util_str_str_hashtable_from_string(data, length, priv->additional_dial_data); - g_print("gdial_app_refresh_additional_dial_data [%s]\r\n", data); - g_free(data); + GDIAL_LOGINFO("gdial_app_refresh_additional_dial_data [%s]", data); } } + if (data) { + g_free(data); + data = NULL; + } + + GDIAL_LOGTRACE("Exiting ..."); } void gdial_app_clear_additional_dial_data(GDialApp *app) { @@ -403,7 +414,7 @@ GDIAL_STATIC gboolean gdial_app_write_additional_dial_data(const gchar *app_name if (!g_file_query_exists(gfile, NULL) || g_file_delete(gfile, NULL, &err) ) { GFileIOStream *gfile_ios = g_file_create_readwrite(gfile, G_FILE_CREATE_PRIVATE, NULL, &err); if (gfile_ios) { - if (g_output_stream_write(g_io_stream_get_output_stream(G_IO_STREAM(gfile_ios)), data, length, NULL, &err) == length) { + if (g_output_stream_write(g_io_stream_get_output_stream(G_IO_STREAM(gfile_ios)), data, length, NULL, &err) == (gssize)length) { result = TRUE; } else { @@ -421,6 +432,7 @@ GDIAL_STATIC gboolean gdial_app_write_additional_dial_data(const gchar *app_name } g_object_unref(gfile); g_free(filename); + filename = NULL; return result; } @@ -431,6 +443,8 @@ GDIAL_STATIC gboolean gdial_app_read_additional_dial_data(const gchar *app_name, *data = NULL; *length = 0; + GDIAL_LOGTRACE("Entering ..."); + gchar *filename = g_build_filename(GDIAL_APP_DIAL_DATA_DIR, app_name, NULL); g_return_val_if_fail(filename && strlen(filename), FALSE); @@ -450,7 +464,7 @@ GDIAL_STATIC gboolean gdial_app_read_additional_dial_data(const gchar *app_name, g_object_unref(gfile_ios); } else { - g_printerr("file %s file is not readable\n", filename); + GDIAL_LOGERROR("file %s file is not readable", filename); } g_object_unref(gfile_info); } @@ -459,11 +473,14 @@ GDIAL_STATIC gboolean gdial_app_read_additional_dial_data(const gchar *app_name, } } else { - g_printerr("file %s does not exist\n", filename); + GDIAL_LOGERROR("file %s does not exist", filename); } g_object_unref(gfile); g_free(filename); + filename = NULL; + + GDIAL_LOGTRACE("Exiting ..."); return result; } @@ -483,6 +500,7 @@ GDIAL_STATIC gboolean gdial_app_remove_additional_dial_data_file(const gchar *ap } g_object_unref(gfile); g_free(filename); + filename = NULL; return result; } @@ -491,7 +509,7 @@ gchar * gdial_app_state_response_new(GDialApp *app, const gchar *dial_ver, const { GDialAppState state = app->state; if(compare_versions(client_dial_version, "2.1") < 0) { - g_print("gdial_app_state_response_new client: %s less than 2.1\n", (client_dial_version != NULL) ? client_dial_version : "-- none --"); + GDIAL_LOGINFO("gdial_app_state_response_new client: %s less than 2.1", (client_dial_version != NULL) ? client_dial_version : "-- none --"); state = (state == GDIAL_APP_STATE_HIDE) ? GDIAL_APP_STATE_STOPPED : state; } diff --git a/server/gdial-debug.h b/server/gdial-debug.h index a5396efa..1856e6da 100644 --- a/server/gdial-debug.h +++ b/server/gdial-debug.h @@ -21,6 +21,8 @@ #define GDIAL_DEBUG_H_ #include +#include "gdialservicelogging.h" + G_BEGIN_DECLS #define GDIAL_PERF_ENABLE 1 @@ -36,7 +38,7 @@ if ((avg) > 0) {\ time_hist_total+=time_hist[(counter-1)%(avg)];\ time_hist_total-=time_hist[counter%(avg)];\ double average = (time_hist_total) / (counter > (avg) ? (avg) : counter);\ - g_printerr("time__ used average %0.3fms for %ld requests (total=%0.3fms)\r\n", average/1000, counter, time_hist_total/1000);\ + GDIAL_LOGERROR("time__ used average %0.3fms for %ld requests (total=%0.3fms)\r\n", average/1000, counter, time_hist_total/1000);\ } #else #define GDIAL_PERF_TIME_BEGIN() @@ -49,7 +51,7 @@ if ((avg) > 0) {\ time_t t;\ t = time(NULL);\ strftime(timestamp_, sizeof(timestamp_), "%FT%T", localtime(&t));\ - g_print("[%s] "format, timestamp_, __VA_ARGS__);\ + GDIAL_LOGINFO("[%s] "format, timestamp_, __VA_ARGS__);\ } #define g_warn_msg_if_fail(expr, format, ...)\ @@ -59,7 +61,7 @@ do {\ GString *msg_buf = g_string_new("");\ g_string_printf(msg_buf, "\r\nFailed Condition: [%s] - Error Message: "format, #expr, __VA_ARGS__);\ gchar *msg = g_string_free(msg_buf, FALSE);\ - g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);\ + GDIAL_LOGWARNING("%s", msg); /*g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);*/ \ g_free(msg);\ }\ } while (0) diff --git a/server/gdial-rest.c b/server/gdial-rest.c index cbb8163f..90224a1c 100644 --- a/server/gdial-rest.c +++ b/server/gdial-rest.c @@ -35,6 +35,7 @@ #include "gdial-plat-dev.h" #include "gdial-plat-app.h" #include "gdial-rest-builder.h" +#include "gdialservicelogging.h" typedef struct _GDialRestServerPrivate { GList *registered_apps; @@ -75,7 +76,7 @@ static gboolean gdial_soup_message_security_check(SoupMessage *msg) { } static void gdial_soup_message_set_http_error(SoupMessage *msg, guint state_code) { - g_printerr("%s::uri=%s::state_code=%d\r\n", __FUNCTION__, soup_uri_get_path(soup_message_get_uri(msg)), state_code); + GDIAL_LOGERROR("uri[%s] state_code[%d]", soup_uri_get_path(soup_message_get_uri(msg)), state_code); soup_message_headers_replace(msg->response_headers, "Connection", "close"); soup_message_set_status(msg, state_code); return; @@ -158,7 +159,7 @@ GDIAL_STATIC gboolean gdial_rest_server_should_relaunch_app(GDialApp *app, const */ g_return_val_if_fail(app != NULL && app->name != NULL, TRUE); if (gdial_app_state(app) != GDIAL_APP_ERROR_NONE || GDIAL_APP_GET_STATE(app) == GDIAL_APP_STATE_STOPPED) { - g_print("app [%s] state is stopped, relaunch required\r\n", app->name); + GDIAL_LOGINFO("app [%s] state is stopped, relaunch required", app->name); return TRUE; } @@ -170,7 +171,7 @@ GDIAL_STATIC gboolean gdial_rest_server_should_relaunch_app(GDialApp *app, const if ((cached_payload != NULL) && (payload != NULL)) { int changed = g_strcmp0(cached_payload, payload); if (changed) { - g_print("relaunch requred due to payload change [%s] vs [%s]\r\n", cached_payload, payload); + GDIAL_LOGINFO("relaunch requred due to payload change [%s] vs [%s]", cached_payload, payload); } return changed; } @@ -294,7 +295,7 @@ GDIAL_STATIC gchar *gdial_rest_server_new_additional_data_url(guint listening_po static void gdial_rest_app_state_changed_cb(GDialApp *app, gpointer signal_param_user_data, gpointer user_data) { GDialRestServer *gdial_rest_server = (GDIAL_REST_SERVER(user_data)); g_return_if_fail(gdial_rest_server_is_app_registered(gdial_rest_server, app->name)); - g_print("gdial_rest_app_state_changed_cb : [%s].state = %d\r\n", app->name, app->state); + GDIAL_LOGINFO("gdial_rest_app_state_changed_cb : [%s].state = %d data[%p]", app->name, app->state, signal_param_user_data); } static void gdial_rest_server_handle_OPTIONS(SoupMessage *msg, const gchar *allow_methods) { @@ -324,7 +325,7 @@ static GDialApp *gdial_rest_server_check_instance(GDialApp *app, const gchar *in g_return_val_if_fail(app == app_by_instance, app); } else { - g_printerr("invalid instance %s %d\r\n", instance, instance_id); + GDIAL_LOGERROR("invalid instance %s %d", instance, instance_id); } } else { @@ -351,7 +352,7 @@ static void gdial_rest_server_handle_POST_hide(SoupMessage *msg, GDialApp *app) gdial_rest_server_http_return_if_fail(FALSE, msg, SOUP_STATUS_NOT_IMPLEMENTED); } else { - g_printerr("gdial_app_hide(%s) failed\r\n", app->name); + GDIAL_LOGERROR("gdial_app_hide(%s) failed", app->name); gdial_rest_server_http_return_if_fail(FALSE, msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); } if(current_state == GDIAL_APP_STATE_STOPPED) { @@ -373,7 +374,7 @@ static void gdial_rest_server_handle_DELETE(SoupMessage *msg, GHashTable *query, g_warn_if_fail(gdial_app_state(app) == GDIAL_APP_ERROR_NONE && GDIAL_APP_GET_STATE(app) == GDIAL_APP_STATE_STOPPED); } else { - g_printerr("gdial_app_stop(%s) failed, force shutdown\r\n", app->name); + GDIAL_LOGERROR("gdial_app_stop(%s) query(%p) failed, force shutdown", app->name,query); gdial_app_force_shutdown(app); } @@ -384,6 +385,7 @@ static void gdial_rest_server_handle_DELETE(SoupMessage *msg, GHashTable *query, } static void gdial_rest_server_handle_POST(GDialRestServer *gdial_rest_server, SoupMessage* msg, GHashTable *query, const gchar *app_name) { + GDIAL_LOGTRACE("Entering ..."); GDialAppRegistry *app_registry = gdial_rest_server_find_app_registry(gdial_rest_server, app_name); gdial_rest_server_http_return_if_fail(app_registry, msg, SOUP_STATUS_NOT_FOUND); if (msg->request_body && msg->request_body->data && msg->request_body->length) { @@ -393,7 +395,7 @@ static void gdial_rest_server_handle_POST(GDialRestServer *gdial_rest_server, So guint listening_port = soup_address_get_port(soup_message_get_address(msg)); gdial_rest_server_http_return_if_fail(listening_port != 0, msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - g_printerr("Starting the app with payload %.*s\n", (int)msg->request_body->length, msg->request_body->data); + GDIAL_LOGERROR("Starting the app with payload %.*s", (int)msg->request_body->length, msg->request_body->data); GDialApp *app = gdial_app_find_instance_by_name(app_registry->name); gboolean new_app_instance = FALSE; gboolean first_instance_created = FALSE; @@ -404,7 +406,7 @@ static void gdial_rest_server_handle_POST(GDialRestServer *gdial_rest_server, So * Reuse app instance as is, but do not update refcnt * per DIAL 2.1 recommendation, push relaunch decision to application platform, */ - g_printerr("POST request received for running app [%s]\r\n", app->name); + GDIAL_LOGERROR("POST request received for running app [%s]", app->name); new_app_instance = TRUE; first_instance_created = FALSE; current_state = GDIAL_APP_GET_STATE(app); @@ -423,13 +425,13 @@ static void gdial_rest_server_handle_POST(GDialRestServer *gdial_rest_server, So additional_data_url = gdial_rest_server_new_additional_data_url(listening_port, app_registry->name, FALSE); } gchar *additional_data_url_safe = soup_uri_encode(additional_data_url, NULL); - g_print("additionalDataUrl = %s, %s\r\n", additional_data_url, additional_data_url_safe); + GDIAL_LOGINFO("additionalDataUrl = %s, %s", additional_data_url, additional_data_url_safe); g_signal_connect_object(app, "state-changed", G_CALLBACK(gdial_rest_app_state_changed_cb), gdial_rest_server, 0); const gchar *query_str = soup_uri_get_query(soup_message_get_uri(msg)); gchar *query_str_safe = NULL; const int use_query_directly_from_soup = 1; if(query_str && strlen(query_str)) { - g_print("query = %s\r\n", query_str); + GDIAL_LOGINFO("query = %s", query_str); if (!use_query_directly_from_soup) { char *tmp = soup_uri_encode(query_str, NULL); // note that we later g_free(query_str_safe) which doesn't necessarily work with malloc'ed memory (seems to depend on glib version) @@ -494,7 +496,7 @@ static void gdial_rest_server_handle_POST(GDialRestServer *gdial_rest_server, So * If relaunch is needed it is better to leave it to the app. */ if(msg->request_body && msg->request_body->data) { - g_print("POST request payload = [%s]\r\n", msg->request_body->data); + GDIAL_LOGINFO("POST request payload = [%s]", msg->request_body->data); gdial_app_set_launch_payload(app, msg->request_body->data); } } @@ -508,10 +510,12 @@ static void gdial_rest_server_handle_POST(GDialRestServer *gdial_rest_server, So gdial_rest_server_http_return_if(start_error == GDIAL_APP_ERROR_UNAUTH, msg, SOUP_STATUS_UNAUTHORIZED); gdial_rest_server_http_return_if(TRUE, msg, SOUP_STATUS_SERVICE_UNAVAILABLE); } + GDIAL_LOGTRACE("Exiting ..."); } static void gdial_rest_server_handle_GET_app(GDialRestServer *gdial_rest_server, SoupMessage *msg, GHashTable *query, const gchar *app_name, gint instance_id) { gchar *client_dial_version_str = NULL; + GDIAL_LOGTRACE("Entering ..."); if (query) { client_dial_version_str = g_hash_table_lookup(query, "clientDialVer"); } @@ -542,7 +546,7 @@ static void gdial_rest_server_handle_GET_app(GDialRestServer *gdial_rest_server, app_state = app->state; if (app_state != GDIAL_APP_STATE_STOPPED) { g_signal_connect_object(app, "state-changed", G_CALLBACK(gdial_rest_app_state_changed_cb), gdial_rest_server, 0); - g_print("creating app instance from state %d \r\n", app_state); + GDIAL_LOGINFO("creating app instance from state %d ", app_state); } } @@ -555,29 +559,36 @@ static void gdial_rest_server_handle_GET_app(GDialRestServer *gdial_rest_server, GET_APP_response_builder_set_additionalData(builder, " "); gsize response_len = 0; gchar *response_str = GET_APP_response_builder_build(builder, &response_len); - //g_printf("############ response_str ##########\r\n%s\r\n", response_str); + //g_printf("############ response_str ##########%s", response_str); soup_message_set_response(msg, "text/xml", SOUP_MEMORY_TAKE, response_str, response_len); GET_APP_response_builder_destroy(builder); #else int response_len = 0; - gchar *allow_stop = (gchar*)g_hash_table_lookup(app_registry->properties,"allowStop"); + gchar *allow_stop = NULL; + + if (app_registry->properties) + { + allow_stop = (gchar*)g_hash_table_lookup(app_registry->properties,"allowStop"); + } if(allow_stop == NULL) { allow_stop = "false"; } - g_print("server_register_application allowStop:%s\n",allow_stop); + GDIAL_LOGINFO("server_register_application allowStop:%s",allow_stop); gchar *response_str = gdial_app_state_response_new(app, GDIAL_PROTOCOL_VERSION_STR, client_dial_version_str, GDIAL_PROTOCOL_XMLNS_SCHEMA, &response_len); #endif soup_message_set_response(msg, "text/xml; charset=utf-8", SOUP_MEMORY_TAKE, response_str, response_len); if (app_state == GDIAL_APP_STATE_STOPPED) { - g_print("deleting app instance from state %d \r\n", app_state); + GDIAL_LOGINFO("deleting app instance from state %d ", app_state); g_object_unref(app); } + GDIAL_LOGTRACE("Exiting ..."); } static void gdial_rest_server_handle_POST_dial_data(GDialRestServer *gdial_rest_server, SoupMessage* msg, GHashTable *query, const gchar *app_name) { /* * All instances of same app shares same additonalDataUrl */ + GDIAL_LOGTRACE("Entering ..."); if(msg->request_body && msg->request_body->data && msg->request_body->length) { gdial_rest_server_http_return_if_fail(msg->request_body->length < GDIAL_APP_DIAL_DATA_MAX_LEN, msg, SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE); gdial_rest_server_http_return_if_fail(!gdial_rest_server_is_bad_payload(msg->request_body->data, msg->request_body->length), msg, SOUP_STATUS_BAD_REQUEST); @@ -588,7 +599,7 @@ static void gdial_rest_server_handle_POST_dial_data(GDialRestServer *gdial_rest_ GDialApp *app = gdial_app_find_instance_by_name(app_name); if(app == NULL) { - g_print("gdial_rest_server_handle_POST_dial_data creating app instance \n"); + GDIAL_LOGINFO("gdial_rest_server_handle_POST_dial_data creating app instance [%p] ",gdial_rest_server); app = gdial_app_new(app_name); } gdial_rest_server_http_return_if_fail(app, msg, SOUP_STATUS_NOT_FOUND); @@ -616,7 +627,7 @@ static void gdial_rest_server_handle_POST_dial_data(GDialRestServer *gdial_rest_ } } else { - printf("clear [%s] dial_data\r\n", app_name); + GDIAL_LOGINFO("clear [%s] dial_data", app_name); GHashTable* empty = g_hash_table_new(NULL, NULL); gdial_app_set_additional_dial_data(app, empty); g_hash_table_destroy(empty); @@ -624,6 +635,7 @@ static void gdial_rest_server_handle_POST_dial_data(GDialRestServer *gdial_rest_ gdial_soup_message_headers_set_Allow_Origin(msg, TRUE); soup_message_set_status(msg, SOUP_STATUS_OK); + GDIAL_LOGTRACE("Exiting ..."); } inline static void gdial_rest_http_server_system_callback(SoupServer *server, @@ -640,7 +652,7 @@ inline static void gdial_rest_http_server_system_callback(SoupServer *server, } else if (msg->method == SOUP_METHOD_PUT) { gchar *value = g_hash_table_lookup(query,"rest_enable"); - g_print_with_timestamp("gdial_rest_http_server_system_callback emit SIGNAL_REST_ENABLE value:%s \r\n",(gchar *)value); + g_print_with_timestamp("gdial_rest_http_server_system_callback emit SIGNAL_REST_ENABLE value:%s ",(gchar *)value); g_signal_emit(gdial_rest_server, gdial_rest_server_signals[SIGNAL_REST_ENABLE], 0,value); } soup_message_set_status(msg, SOUP_STATUS_OK); @@ -650,7 +662,7 @@ static void gdial_local_rest_http_server_callback(SoupServer *server, SoupMessage *msg, const gchar *path, GHashTable *query, SoupClientContext *client, gpointer user_data) { gchar *remote_address_str = g_inet_address_to_string(g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(soup_client_context_get_remote_address(client)))); - g_print_with_timestamp("gdial_local_rest_http_server_callback() %s path=%s recv from [%s], in thread %lx\r\n", msg->method, path, remote_address_str, pthread_self()); + g_print_with_timestamp("gdial_local_rest_http_server_callback() %s path=%s recv from [%s], in thread %lx", msg->method, path, remote_address_str, pthread_self()); g_free(remote_address_str); GDialRestServer *gdial_rest_server = (GDIAL_REST_SERVER(user_data)); gchar **elements = g_strsplit(&path[1], "/", 4); @@ -664,7 +676,7 @@ static void gdial_local_rest_http_server_callback(SoupServer *server, for (i = 0; elements[i] != NULL; i++) { /* do not allow any element to be empty, stop on first one */ if ((strlen(elements[i])) == 0) { - g_printerr("Warn: empty elements in URI path\r\n"); + GDIAL_LOGWARNING("Warn: empty elements in URI path"); continue; } if (j == 0) g_strlcpy(base, elements[i], sizeof(base)); @@ -675,7 +687,7 @@ static void gdial_local_rest_http_server_callback(SoupServer *server, } g_strfreev(elements); const int element_num = j; - printf("there are %d non-empty elems\r\n", element_num); + GDIAL_LOGINFO("there are %d non-empty elems", element_num); if(element_num == 3 && g_strcmp0(instance,"dial_data") == 0) { GDialAppRegistry *app_registry = gdial_rest_server_find_app_registry(gdial_rest_server, app_name); @@ -699,7 +711,7 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, SoupMessage *msg, const gchar *path, GHashTable *query, SoupClientContext *client, gpointer user_data) { gchar *remote_address_str = g_inet_address_to_string(g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(soup_client_context_get_remote_address(client)))); - g_print_with_timestamp("gdial_rest_http_server_apps_callback() %s path=%s recv from [%s], in thread %lx\r\n", msg->method, path, remote_address_str, pthread_self()); + g_print_with_timestamp("gdial_rest_http_server_apps_callback() %s path=%s recv from [%s], in thread %lx", msg->method, path, remote_address_str, pthread_self()); g_free(remote_address_str); gdial_rest_server_http_return_if_fail(server && msg && path && client && user_data, msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); @@ -752,7 +764,7 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, for (i = 0; elements[i] != NULL; i++) { /* do not allow any element to be empty, stop on first one */ if ((strlen(elements[i])) == 0) { - g_printerr("Warn: empty elements in URI path\r\n"); + GDIAL_LOGWARNING("Warn: empty elements in URI path"); //invalid_uri = invalid_uri || TRUE; //break; continue; @@ -765,13 +777,13 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, } const int element_num = j; - printf("there are %d non-empty elems\r\n", element_num); + GDIAL_LOGINFO("there are %d non-empty elems", element_num); /* * Make sure path remains same as given */ const gchar *copied_str[] = {base, app_name, instance, last_elem}; i = 0; j = 0; - while (i < element_num && i < sizeof(copied_str)/sizeof(copied_str[0])) { + while (i < element_num && (unsigned int)i < sizeof(copied_str)/sizeof(copied_str[0])) { if (strlen(elements[j]) == 0) { j++; continue; @@ -798,9 +810,9 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, } const gchar *header_origin = soup_message_headers_get_one(msg->request_headers, "Origin"); - g_printerr("Origin %s, Host: %s, Method: %s\r\n", header_origin, header_host, msg->method); + GDIAL_LOGERROR("Origin %s, Host: %s, Method: %s", header_origin, header_host, msg->method); if (!gdial_rest_server_is_allowed_origin(gdial_rest_server, header_origin, app_name)) { - gdial_rest_server_http_print_and_return_if_fail(FALSE, msg, SOUP_STATUS_FORBIDDEN, "origin %s is not allowed\r\n", header_origin); + gdial_rest_server_http_print_and_return_if_fail(FALSE, msg, SOUP_STATUS_FORBIDDEN, "origin %s is not allowed", header_origin); } /* * element_num == 2: @@ -817,7 +829,7 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, */ if (element_num == 2) { // URL ends with app name - g_print("app_name is %s\r\n", app_name); + GDIAL_LOGINFO("app_name is %s", app_name); if (!header_host || !gdial_rest_server_is_allowed_origin(gdial_rest_server, header_origin, app_name)) { gdial_rest_server_http_return_if_fail(FALSE, msg, SOUP_STATUS_FORBIDDEN); } @@ -840,7 +852,7 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, else if (element_num == 3) { if (g_strcmp0(last_elem, &GDIAL_REST_HTTP_DIAL_DATA_URI[1]) ==0) { // URL ends with dial_data, only accepted when originating from localhost - g_print("for [%s] app_name is %s\r\n", last_elem, app_name); + GDIAL_LOGINFO("for [%s] app_name is %s", last_elem, app_name); GSocketAddress *remote_address = soup_client_context_get_remote_address(client); GError *error = NULL; struct sockaddr_in saddr; @@ -856,7 +868,7 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, } else { // URL ends with .../run or some app specific instance Id .../ - g_print("for instance [%s] app_name is %s\r\n", last_elem, app_name); + GDIAL_LOGINFO("for instance [%s] app_name is %s", last_elem, app_name); if (!header_host || !gdial_rest_server_is_allowed_origin(gdial_rest_server, header_origin, app_name)) { gdial_rest_server_http_return_if_fail(FALSE, msg, SOUP_STATUS_FORBIDDEN); } @@ -870,7 +882,7 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, gdial_rest_server_handle_DELETE(msg, query, app); } else { - g_printerr("app to delete is not found\r\n"); + GDIAL_LOGWARNING("app to delete is not found"); gdial_soup_message_set_http_error(msg, SOUP_STATUS_NOT_FOUND); } } @@ -885,7 +897,7 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, else if (element_num == 4) { if (g_strcmp0(last_elem, &GDIAL_REST_HTTP_HIDE_URI[1]) == 0) { // URL ends with hide - g_print("for [%s] app_name is %s, instance is %s\r\n", last_elem, app_name, instance); + GDIAL_LOGINFO("for [%s] app_name is %s, instance is %s", last_elem, app_name, instance); if (msg->method == SOUP_METHOD_OPTIONS) { gdial_rest_server_handle_OPTIONS(msg, "POST, OPTIONS"); } @@ -897,7 +909,7 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, gdial_rest_server_handle_POST_hide(msg, app); } else { - g_printerr("app to hide is not found\r\n"); + GDIAL_LOGWARNING("app to hide is not found"); gdial_rest_server_http_return_if_fail(FALSE, msg, SOUP_STATUS_NOT_FOUND); } } @@ -919,7 +931,10 @@ static void gdial_rest_http_server_apps_callback(SoupServer *server, static void gdial_rest_server_dispose(GObject *object) { GDialRestServerPrivate *priv = gdial_rest_server_get_instance_private(GDIAL_REST_SERVER(object)); soup_server_remove_handler(priv->soup_instance, GDIAL_REST_HTTP_APPS_URI); - if(GDIAL_REST_HTTP_APPS_URI) g_free(GDIAL_REST_HTTP_APPS_URI); + if(GDIAL_REST_HTTP_APPS_URI) { + g_free(GDIAL_REST_HTTP_APPS_URI); + GDIAL_REST_HTTP_APPS_URI = NULL; + } g_object_unref(priv->soup_instance); g_object_unref(priv->local_soup_instance); while (priv->registered_apps) { @@ -960,12 +975,12 @@ static void gdial_rest_server_set_property (GObject *object, guint property_id, { if(g_value_get_boolean(value)) { - g_print("gdial_rest_server_set_property add handler\n"); + GDIAL_LOGINFO("gdial_rest_server_set_property add handler"); soup_server_add_handler(priv->soup_instance, GDIAL_REST_HTTP_APPS_URI, gdial_rest_http_server_apps_callback, object, NULL); } else { - g_print("gdial_rest_server_set_property remove handler\n"); + GDIAL_LOGINFO("gdial_rest_server_set_property remove handler"); soup_server_remove_handler(priv->soup_instance, GDIAL_REST_HTTP_APPS_URI); } } @@ -1044,7 +1059,7 @@ GDialRestServer *gdial_rest_server_new(SoupServer *rest_http_server,SoupServer * */ soup_server_add_handler(rest_http_server, "/apps/system", gdial_rest_http_server_system_callback, object, NULL); #endif - g_print("gdial_local_rest_http_server_callback add handler\n"); + GDIAL_LOGINFO("gdial_local_rest_http_server_callback add handler"); GDIAL_REST_HTTP_APPS_URI = g_strdup_printf("/%s", random_id); soup_server_add_handler(local_rest_http_server, GDIAL_REST_HTTP_APPS_URI, gdial_local_rest_http_server_callback, object, NULL); @@ -1054,6 +1069,7 @@ GDialRestServer *gdial_rest_server_new(SoupServer *rest_http_server,SoupServer * gboolean gdial_rest_server_register_app(GDialRestServer *self, const gchar *app_name, const GList *app_prefixes, GHashTable *properties, gboolean is_singleton, gboolean use_additional_data, const GList *allowed_origins) { g_return_val_if_fail(self != NULL && app_name != NULL, FALSE); + GDIAL_LOGTRACE("Entering ..."); /* *@TODO: support multiple app instances. */ @@ -1066,6 +1082,7 @@ gboolean gdial_rest_server_register_app(GDialRestServer *self, const gchar *app_ * *@TODO: check params. If identical to previous registraiton, return TRUE; */ + GDIAL_LOGTRACE("Exiting ..."); return FALSE; } @@ -1087,6 +1104,7 @@ gboolean gdial_rest_server_register_app(GDialRestServer *self, const gchar *app_ } g_return_val_if_fail(priv->registered_apps != NULL, FALSE); g_return_val_if_fail(gdial_rest_server_is_app_registered(self, app_name), FALSE); + GDIAL_LOGTRACE("Exiting ..."); return TRUE; } @@ -1119,7 +1137,9 @@ gboolean gdial_rest_server_register_app_registry(GDialRestServer *self, GDialApp gboolean gdial_rest_server_unregister_all_apps(GDialRestServer *self) { g_return_val_if_fail(self != NULL, FALSE); - g_print("Inside gdial_rest_server_unregister_all_apps\n"); + GDIAL_LOGTRACE("Entering ..."); + + GDIAL_LOGINFO("Inside gdial_rest_server_unregister_all_apps"); GDialRestServerPrivate *priv = gdial_rest_server_get_instance_private(self); GList *registered_apps_head = priv->registered_apps; /*Stopping all registread Apps*/ @@ -1131,7 +1151,7 @@ gboolean gdial_rest_server_unregister_all_apps(GDialRestServer *self) { g_warn_if_fail(gdial_app_state(app) == GDIAL_APP_ERROR_NONE && GDIAL_APP_GET_STATE(app) == GDIAL_APP_STATE_STOPPED); } else { - g_printerr("gdial_app_stop(%s) failed, force shutdown\r\n", app->name); + GDIAL_LOGERROR("gdial_app_stop(%s) failed, force shutdown", app->name); gdial_app_force_shutdown(app); } g_object_unref(app); @@ -1143,6 +1163,7 @@ gboolean gdial_rest_server_unregister_all_apps(GDialRestServer *self) { while (priv->registered_apps) { priv->registered_apps = gdial_rest_server_registered_apps_clear(priv->registered_apps, priv->registered_apps); } + GDIAL_LOGTRACE("Exiting ..."); return TRUE; } diff --git a/server/gdial-shield.c b/server/gdial-shield.c index 3316cd27..6fd606fb 100644 --- a/server/gdial-shield.c +++ b/server/gdial-shield.c @@ -34,93 +34,115 @@ static GHashTable *active_conns_ = NULL; static void soup_message_weak_ref_callback(gpointer user_data, GObject *obj); static void server_request_remove_callback (SoupMessage *msg) { + GDIAL_LOGTRACE("Entering ..."); DialShieldConnectionContext * conn_context = (DialShieldConnectionContext *) g_hash_table_lookup(active_conns_, msg); if (conn_context) { if (conn_context->read_timeout_source != 0) { - g_print_with_timestamp("server_request_remove_callback tid=[%lx] msg=%p timeout source %d removed\r\n", + g_print_with_timestamp("server_request_remove_callback tid=[%lx] msg=%p timeout source %d removed", pthread_self(), msg, conn_context->read_timeout_source); g_source_remove(conn_context->read_timeout_source); } g_hash_table_remove(active_conns_, msg); g_free(conn_context); + conn_context = NULL; } + GDIAL_LOGTRACE("Exiting ..."); } static gboolean soup_message_read_timeout_callback(gpointer user_data) { SoupMessage *msg = (SoupMessage*)user_data; + GDIAL_LOGTRACE("Entering ..."); DialShieldConnectionContext * conn_context = (DialShieldConnectionContext *)g_hash_table_lookup(active_conns_, msg); - g_print_with_timestamp("soup_message_read_timeout_callback tid=[%lx] msg=%p\r\n", pthread_self(), msg); + g_print_with_timestamp("soup_message_read_timeout_callback tid=[%lx] msg=%p", pthread_self(), msg); if (conn_context) { conn_context->read_timeout_source = 0; g_socket_close(conn_context->read_gsocket, NULL);//this will trigger abort callback } + GDIAL_LOGTRACE("Exiting ..."); return G_SOURCE_REMOVE;; } static void server_request_read_callback (SoupServer *server, SoupMessage *msg, SoupClientContext *context, gpointer data) { - g_print_with_timestamp("server_request_read_callback tid=[%lx] msg=%p\r\n", pthread_self(), msg); + GDIAL_LOGTRACE("Entering ..."); + g_print_with_timestamp("server_request_read_callback tid=[%lx] msg=%p", pthread_self(), msg); g_object_weak_unref(G_OBJECT(msg), (GWeakNotify)soup_message_weak_ref_callback, msg); server_request_remove_callback(msg); + GDIAL_LOGTRACE("Exiting ..."); } static void server_request_finished_callback (SoupServer *server, SoupMessage *msg, SoupClientContext *context, gpointer data) { + GDIAL_LOGTRACE("!!!"); } static void server_request_aborted_callback (SoupServer *server, SoupMessage *msg, SoupClientContext *context, gpointer data) { - g_print_with_timestamp("server_request_aborted_callback tid=[%lx] msg=%p\r\n", pthread_self(), msg); + GDIAL_LOGTRACE("Entering ..."); + g_print_with_timestamp("server_request_aborted_callback tid=[%lx] msg=%p", pthread_self(), msg); + g_object_weak_unref(G_OBJECT(msg), (GWeakNotify)soup_message_weak_ref_callback, msg); server_request_remove_callback(msg); + GDIAL_LOGTRACE("Exiting ..."); } static void soup_message_weak_ref_callback(gpointer user_data, GObject *obj) { SoupMessage *msg0=(SoupMessage*)obj; SoupMessage *msg=(SoupMessage*)user_data; + GDIAL_LOGTRACE("Entering ..."); assert(msg0==msg); - g_print_with_timestamp("soup_message_weak_ref_callback tid=[%lx] msg=%p\r\n", pthread_self(), msg); + g_print_with_timestamp("soup_message_weak_ref_callback tid=[%lx] msg=%p", pthread_self(), msg); server_request_remove_callback(msg); + GDIAL_LOGTRACE("Exiting ..."); } static void server_request_started_callback (SoupServer *server, SoupMessage *msg, SoupClientContext *context, gpointer data) { static const int throttle = GDIAL_THROTTLE_DELAY_US; + GDIAL_LOGTRACE("Entering ..."); DialShieldConnectionContext *conn_context = g_new(DialShieldConnectionContext, 1); guint read_timeout_source = g_timeout_add(2000, (GSourceFunc)soup_message_read_timeout_callback, msg); conn_context->read_gsocket = soup_client_context_get_gsocket(context); conn_context->read_timeout_source = read_timeout_source; - g_print_with_timestamp("server_request_started_callback tid=[%lx] msg=%p timeout source %d added with socket fd = %d\r\n", + g_print_with_timestamp("server_request_started_callback tid=[%lx] msg=%p timeout source %d added with socket fd = %d", pthread_self(), msg, read_timeout_source, g_socket_get_fd(conn_context->read_gsocket)); g_hash_table_insert(active_conns_, msg, conn_context); g_object_weak_ref(G_OBJECT(msg), (GWeakNotify)soup_message_weak_ref_callback, msg); usleep(throttle); + GDIAL_LOGTRACE("Exiting ..."); } void gdial_shield_init(void) { + GDIAL_LOGTRACE("Entering ..."); active_conns_ = g_hash_table_new(g_direct_hash, g_direct_equal); + GDIAL_LOGTRACE("Exiting ..."); } void gdial_shield_server(SoupServer *server) { g_return_if_fail(server != NULL); + GDIAL_LOGTRACE("Entering ..."); g_signal_connect(server, "request_started", G_CALLBACK(server_request_started_callback), NULL); g_signal_connect(server, "request_read", G_CALLBACK(server_request_read_callback), NULL); g_signal_connect(server, "request_finished",G_CALLBACK(server_request_finished_callback), NULL); g_signal_connect(server, "request_aborted", G_CALLBACK(server_request_aborted_callback), NULL); + GDIAL_LOGTRACE("Exiting ..."); } void gdial_shield_term(void) { GHashTableIter iter; gpointer key, value; - printf("gdial_shield_term: hash_table_size start= %d\r\n", g_hash_table_size(active_conns_)); + GDIAL_LOGTRACE("Entering ..."); + g_return_if_fail(active_conns_ != NULL); + GDIAL_LOGINFO("gdial_shield_term: hash_table_size start= %d", g_hash_table_size(active_conns_)); g_hash_table_iter_init(&iter, (GHashTable *)active_conns_); while (g_hash_table_iter_next(&iter, &key, &value)) { SoupMessage *msg = (SoupMessage *)key; server_request_remove_callback(msg); } - printf("gdial_shield_term: hash_table_size end= %d\r\n", g_hash_table_size(active_conns_)); + GDIAL_LOGINFO("gdial_shield_term: hash_table_size end= %d", g_hash_table_size(active_conns_)); g_hash_table_unref(active_conns_); active_conns_ = NULL; + GDIAL_LOGTRACE("Exiting ..."); } diff --git a/server/gdial-shield.h b/server/gdial-shield.h index 77156e64..1746b263 100644 --- a/server/gdial-shield.h +++ b/server/gdial-shield.h @@ -23,8 +23,10 @@ #include #include "gdial-config.h" +extern "C" { void gdial_shield_init(void); void gdial_shield_server(SoupServer *server); void gdial_shield_term(void); +} #endif diff --git a/server/gdial-ssdp.c b/server/gdial-ssdp.c index 4570d94d..b0898f01 100644 --- a/server/gdial-ssdp.c +++ b/server/gdial-ssdp.c @@ -28,6 +28,7 @@ #include "gdial-plat-util.h" #include "gdial-plat-dev.h" #include "gdial-ssdp.h" +#include "gdialservicelogging.h" #define MAX_POWERON_TIME 10 static SoupServer *ssdp_http_server_ = NULL; @@ -81,7 +82,7 @@ static void ssdp_http_server_callback(SoupServer *server, SoupMessage *msg, cons if (!msg || !msg->method || msg->method != SOUP_METHOD_GET) { soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST); GDIAL_CHECK("GET_method_only"); - GDIAL_DEBUG("warning: SSDP HTTP Method is not GET\r\n"); + GDIAL_DEBUG("warning: SSDP HTTP Method is not GET"); return; } /* @@ -106,6 +107,7 @@ static void ssdp_http_server_callback(SoupServer *server, SoupMessage *msg, cons gchar *application_url_str = g_strdup_printf("http://%s:%d/%s/", iface_ipv4_address, GDIAL_REST_HTTP_PORT,app_random_uuid); soup_message_headers_replace (msg->response_headers, "Application-URL", application_url_str); g_free(application_url_str); + application_url_str = NULL; soup_message_set_response(msg, "text/xml; charset=utf-8", SOUP_MEMORY_STATIC, dd_xml_response_str_, dd_xml_response_str_len); soup_message_set_status(msg, SOUP_STATUS_OK); GDIAL_CHECK("Content-Type:text/xml"); @@ -116,13 +118,14 @@ void gdial_ssdp_networkstandbymode_handler(const bool nwstandby) { if(ssdp_client_){ if(nwstandby){ - g_print("gdial_ssdp_networkstandbymode_handler add WAKEUP header\n "); + GDIAL_LOGINFO("gdial_ssdp_networkstandbymode_handler add WAKEUP header "); gchar *dial_ssdp_WAKEUP = g_strdup_printf(DIAL_SSDP_WAKEUP_FMT,gdial_plat_util_get_iface_mac_addr(gdial_options_->iface_name),MAX_POWERON_TIME); gssdp_client_append_header(ssdp_client_, "WAKEUP", dial_ssdp_WAKEUP); g_free(dial_ssdp_WAKEUP); + dial_ssdp_WAKEUP = NULL; } else{ - g_print("gdial_ssdp_networkstandbymode_handler remove WAKEUP header \n "); + GDIAL_LOGINFO("gdial_ssdp_networkstandbymode_handler remove WAKEUP header "); gssdp_client_remove_header(ssdp_client_, "WAKEUP"); } } @@ -136,6 +139,8 @@ int gdial_ssdp_new(SoupServer *ssdp_http_server, GDialOptions *options, const gc g_return_val_if_fail(options->iface_name != NULL, -1); gdial_options_ = options; + GDIAL_LOGINFO("gdial_options_->friendly_name[%p]",gdial_options_->friendly_name); + if (gdial_options_->friendly_name == NULL) gdial_options_->friendly_name = g_strdup(GDIAL_SSDP_FRIENDLY_DEFAULT); if (gdial_options_->manufacturer== NULL) gdial_options_->manufacturer = g_strdup(GDIAL_SSDP_MANUFACTURER_DEFAULT); if (gdial_options_->model_name== NULL) gdial_options_->model_name = g_strdup(GDIAL_SSDP_MODELNAME_DEFAULT); @@ -156,14 +161,12 @@ int gdial_ssdp_new(SoupServer *ssdp_http_server, GDialOptions *options, const gc gdial_options_->iface_name, &error); if (!ssdp_client || error) { - g_printerr("%s\r\n", error->message); + GDIAL_LOGERROR("%s", error->message); g_error_free(error); return EXIT_FAILURE; } gdail_plat_dev_register_nwstandbymode_cb(gdial_ssdp_networkstandbymode_handler); - bool nwstandby_mode = gdial_plat_dev_get_nwstandby_mode(); - g_print("gdial_ssdp_new nwstandby_mode:%d \n",nwstandby_mode); /* * setup configurable headers. * header "SERVER" is populated by gssdp. @@ -171,14 +174,17 @@ int gdial_ssdp_new(SoupServer *ssdp_http_server, GDialOptions *options, const gc * header "CACHE-CONTROL" is mandatory, set by gssdp, default 1800 */ gssdp_client_append_header(ssdp_client, "BOOTID.UPNP.ORG", "1"); - if(gdial_options_->feature_wolwake && nwstandby_mode) { - g_print("WOL Wake feature is enabled"); + + /* feature_wolwake should be handled gdialservice users*/ + if(gdial_options_->feature_wolwake) { + GDIAL_LOGINFO("WOL Wake feature is enabled"); gchar *dial_ssdp_WAKEUP = g_strdup_printf(DIAL_SSDP_WAKEUP_FMT,gdial_plat_util_get_iface_mac_addr(gdial_options_->iface_name),MAX_POWERON_TIME); gssdp_client_append_header(ssdp_client, "WAKEUP", dial_ssdp_WAKEUP); g_free(dial_ssdp_WAKEUP); + dial_ssdp_WAKEUP = NULL; } else { - g_print("WOL Wake feature is disabled"); + GDIAL_LOGINFO("WOL Wake feature is disabled"); } GDIAL_CHECK("EXT"); GDIAL_CHECK("CACHE-CONTROL"); @@ -191,7 +197,9 @@ int gdial_ssdp_new(SoupServer *ssdp_http_server, GDialOptions *options, const gc gssdp_resource_group_add_resource_simple (ssdp_resource_group, dial_ssdp_ST_target, dial_ssdp_USN, dial_ssdp_LOCATION); gssdp_resource_group_set_available (ssdp_resource_group, FALSE); g_free(dial_ssdp_USN); + dial_ssdp_USN = NULL; g_free(dial_ssdp_LOCATION); + dial_ssdp_LOCATION = NULL; ssdp_resource_group_ = ssdp_resource_group; @@ -206,29 +214,72 @@ int gdial_ssdp_new(SoupServer *ssdp_http_server, GDialOptions *options, const gc } int gdial_ssdp_destroy() { - soup_server_remove_handler(ssdp_http_server_, "/dd.xml"); - gssdp_resource_group_remove_resource(ssdp_resource_group_, ssdp_resource_id_); - - if (dd_xml_response_str_) { - g_free(dd_xml_response_str_); + GDIAL_LOGTRACE("Entering ..."); + if (ssdp_http_server_) + { + soup_server_remove_handler(ssdp_http_server_, "/dd.xml"); } - if (gdial_options_->friendly_name != NULL) g_free(gdial_options_->friendly_name); - if (gdial_options_->uuid != NULL) g_free(gdial_options_->uuid); - if (gdial_options_->iface_name != NULL) g_free(gdial_options_->iface_name); - if (app_random_uuid) g_free(app_random_uuid); - - gssdp_client_clear_headers(ssdp_client_); - g_object_unref(ssdp_http_server_); - g_object_unref(ssdp_resource_group_); - g_object_unref(ssdp_client_); + if (ssdp_resource_group_) + { + gssdp_resource_group_remove_resource(ssdp_resource_group_, ssdp_resource_id_); + ssdp_resource_id_ = 0; + } + if (dd_xml_response_str_) + { + g_free(dd_xml_response_str_); + dd_xml_response_str_ = NULL; + } + if (gdial_options_) + { + if (gdial_options_->friendly_name != NULL) + { + g_free(gdial_options_->friendly_name); + gdial_options_->friendly_name = NULL; + } + if (gdial_options_->uuid != NULL) + { + g_free(gdial_options_->uuid); + gdial_options_->uuid = NULL; + } + if (gdial_options_->iface_name != NULL) + { + g_free(gdial_options_->iface_name); + gdial_options_->iface_name = NULL; + } + gdial_options_ = NULL; + } + if (app_random_uuid != NULL) { + g_free(app_random_uuid); + app_random_uuid = NULL; + } + if (ssdp_client_) + { + gssdp_client_clear_headers(ssdp_client_); + } + if (ssdp_http_server_) + { + g_object_unref(ssdp_http_server_); + ssdp_http_server_ = NULL; + } + if (ssdp_resource_group_) + { + g_object_unref(ssdp_resource_group_); + ssdp_resource_group_ = NULL; + } + if (ssdp_client_) + { + g_object_unref(ssdp_client_); + ssdp_client_ = NULL; + } + GDIAL_LOGTRACE("Exiting ..."); return 0; } int gdial_ssdp_set_available(bool activation_status, const gchar *friendlyname) { - g_print("gdial_ssdp_set_available activation_status :%d \n ",activation_status); + GDIAL_LOGINFO("gdial_ssdp_set_available activation_status :%d ",activation_status); gdial_ssdp_set_friendlyname(friendlyname); if(ssdp_resource_group_) gssdp_resource_group_set_available (ssdp_resource_group_, activation_status); return 0; @@ -240,7 +291,7 @@ int gdial_ssdp_set_friendlyname(const gchar *friendlyname) { if (app_friendly_name != NULL) g_free(app_friendly_name); app_friendly_name = g_strdup(friendlyname); - g_print("gdial_ssdp_set_friendlyname app_friendly_name :%s \n ",app_friendly_name); + GDIAL_LOGINFO("gdial_ssdp_set_friendlyname app_friendly_name :%s ",app_friendly_name); if (dd_xml_response_str_!= NULL){ g_free(dd_xml_response_str_); dd_xml_response_str_ = NULL; diff --git a/server/gdial-util.c b/server/gdial-util.c index 7242cf85..7eefae4e 100644 --- a/server/gdial-util.c +++ b/server/gdial-util.c @@ -22,6 +22,7 @@ #include #include "gdial-config.h" #include "gdial-util.h" +#include "gdialservicelogging.h" gchar *gdial_util_str_str_hashtable_to_string(const GHashTable *ht, const gchar *delimiter, gboolean newline, gsize *length) { @@ -58,7 +59,8 @@ gboolean gdial_util_str_str_hashtable_from_string(const gchar *ht_str, gsize len g_return_val_if_fail(ht_str != NULL && ht != NULL, FALSE); char key[GDIAL_APP_DIAL_DATA_MAX_KV_LEN+1] = {0}; char value[GDIAL_APP_DIAL_DATA_MAX_KV_LEN+1] = {0}; - int used = 0, ret = 0; + gsize used = 0; + int ret = 0; while( used < length && (ret = sscanf(&ht_str[used], "%"GDIAL_APP_DIAL_DATA_MAX_KV_LEN_STR"s %"GDIAL_APP_DIAL_DATA_MAX_KV_LEN_STR"s""\r\n", key, value)) > 0) { g_hash_table_insert(ht, g_strdup(key), g_strdup(value)); @@ -127,7 +129,7 @@ gboolean gdial_util_str_str_hashtable_equal(const GHashTable *ht1, const GHashTa if ((value1 == value2) || (value1 && value2 && g_strcmp0(value2, value1) == 0)) { } else { - g_printerr("breaking equal at key %s\r\n", (char *)key); + GDIAL_LOGERROR("breaking equal at key %s", (char *)key); return FALSE; } } diff --git a/server/gdialserver_ut.cpp b/server/gdialserver_ut.cpp new file mode 100644 index 00000000..580569c6 --- /dev/null +++ b/server/gdialserver_ut.cpp @@ -0,0 +1,256 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "gdialservice.h" +#include "gdialservicelogging.h" + +class gdialServiceTest: public GDialNotifier +{ + public: + gdialServiceTest(const std::vector& args) + { + service = gdialService::getInstance(this,args,"GDialUT"); + } + + ~gdialServiceTest() + { + gdialService::destroyInstance(); + service = nullptr; + } + + void ActivationChanged(bool status) + { + GDIAL_LOGINFO("Entering ..."); + std::string activation = status ? "true" : "false"; + service->ActivationChanged(activation,"SampleTest"); + GDIAL_LOGINFO("Exiting ..."); + } + + void RegisterApplications(void) + { + RegisterAppEntryList *appReqList = new RegisterAppEntryList; + GDIAL_LOGINFO("[%p] Freeing appConfigList",appReqList); + for (int i=0; i < 9;i++) + { + RegisterAppEntry* appReq = new RegisterAppEntry; + std::string Names; + std::string prefixes; + std::string cors; + int allowStop = 0; + + + switch(i) + { + case 0: + { + Names = "Netflix"; + prefixes = ""; + cors = ".netflix.com"; + allowStop = 0; + } + break; + case 1: + { + Names = "YouTube"; + prefixes = ""; + cors = ".youtube.com"; + allowStop = 0; + } + break; + case 2: + { + Names = "YouTubeTV"; + prefixes = ""; + cors = ".youtube.com"; + allowStop = 0; + } + break; + case 3: + { + Names = "YouTubeKids"; + prefixes = ""; + cors = ".youtube.com"; + allowStop = 0; + } + break; + case 4: + { + Names = "AmazonInstantVideo"; + prefixes = ""; + cors = ".amazonprime.com"; + allowStop = 0; + } + break; + case 5: + { + Names = "com.spotify.Spotify.TV"; + prefixes = "com.spotify"; + cors = ".spotify.com"; + allowStop = 0; + } + break; + case 6: + { + Names = "com.apple.appletv"; + prefixes = "com.apple"; + cors = "tv.apple.com"; + allowStop = 0; + } + break; + case 7: + { + Names = "Pairing"; + prefixes = ""; + cors = ".comcast.com"; + allowStop = 0; + } + break; + case 8: + default: + { + Names = "Hello"; + prefixes = "Hello"; + cors = "Hello"; + allowStop = 0; + } + break; + } + + appReq->Names = Names; + appReq->prefixes = prefixes; + appReq->cors = prefixes; + appReq->allowStop = allowStop; + + appReqList->pushBack(appReq); + } + service->RegisterApplications(appReqList); + } + + virtual void onApplicationLaunchRequestWithLaunchParam(string appName,string strPayLoad, string strQuery, string strAddDataUrl) override + { + GDIAL_LOGINFO("App:%s payload:%s query_string:%s additional_data_url:%s", + appName.c_str(), + strPayLoad.c_str(), + strQuery.c_str(), + strAddDataUrl.c_str()); + } + + virtual void onApplicationLaunchRequest(string appName, string parameter) override + { + GDIAL_LOGINFO("App:%s parameter:%s",appName.c_str(),parameter.c_str()); + } + + virtual void onApplicationStopRequest(string appName, string appID) override + { + GDIAL_LOGINFO("App:%s appID:%s",appName.c_str(),appID.c_str()); + } + + virtual void onApplicationHideRequest(string appName, string appID) override + { + GDIAL_LOGINFO("App:%s appID:%s",appName.c_str(),appID.c_str()); + } + + virtual void onApplicationResumeRequest(string appName, string appID) override + { + GDIAL_LOGINFO("App:%s appID:%s",appName.c_str(),appID.c_str()); + } + + virtual void onApplicationStateRequest(string appName, string appID) override + { + GDIAL_LOGINFO("App:%s appID:%s",appName.c_str(),appID.c_str()); + } + + virtual void onStopped() override + { + GDIAL_LOGINFO("~~~~~~~~~~~"); + } + + virtual void updatePowerState(string powerState) override + { + GDIAL_LOGINFO("powerState : %s",powerState.c_str()); + } + private: + gdialService* service{nullptr}; +}; + +std::atomic running(true); + +void signalHandler(int signum) +{ + GDIAL_LOGINFO("Interrupt signal:%d",signum); + running = false; +} + +int main(int argc, char *argv[]) +{ + std::signal(SIGINT, signalHandler); + std::vector gdial_args; + for (int i = 1; i < argc; ++i) + { + gdial_args.push_back(argv[i]); + } + gdialServiceTest* testObject = new gdialServiceTest(gdial_args); + + std::string input; + GDIAL_LOGINFO("Enter commands (type 'q' to quit):"); + + while (running) { + std::cout << "> "; + std::getline(std::cin, input); + + if (input == "q") { + GDIAL_LOGINFO("Exiting ..."); + break; + } + + if (input == "restart") { + GDIAL_LOGINFO("Restarting"); + if (nullptr != testObject) + { + delete testObject; + testObject = nullptr; + } + testObject = new gdialServiceTest(gdial_args); + } + else if (input == "enable") { + GDIAL_LOGINFO("Activation enabled"); + testObject->ActivationChanged(true); + } + else if (input == "disable") { + GDIAL_LOGINFO("Activation disabled"); + testObject->ActivationChanged(false); + } + else if (input == "register") + { + GDIAL_LOGINFO("RegisterApps"); + testObject->RegisterApplications(); + } + else{ + GDIAL_LOGINFO("Unknown option: "); + } + } + delete testObject; + + return 0; +} \ No newline at end of file diff --git a/server/gdialservice.cpp b/server/gdialservice.cpp new file mode 100644 index 00000000..3e468b96 --- /dev/null +++ b/server/gdialservice.cpp @@ -0,0 +1,1084 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2023 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "gdial-config.h" +#include "gdial-debug.h" +#include "gdial-options.h" +#include "gdial-shield.h" +#include "gdial-ssdp.h" +#include "gdial-rest.h" +#include "gdial-plat-util.h" +#include "gdial-plat-dev.h" +#include "gdial-plat-app.h" +#include "gdial_app_registry.h" +#include +#include +#include "gdialservice.h" +#include "gdialserviceimpl.h" +#include "gdialservicelogging.h" + +gdialService *m_gdialService{nullptr}; +gdialServiceImpl *m_gdialServiceImpl{nullptr}; + +static const char *dial_specification_copyright = "Copyright (c) 2017 Netflix, Inc. All rights reserved."; + +#define MAX_UUID_SIZE 64 +#define UUID_FILE_PATH "/opt/.dial_uuid.txt" + +static GDialOptions options_; + +static GOptionEntry option_entries_[] = { + { + FRIENDLY_NAME_OPTION_LONG, + FRIENDLY_NAME_OPTION, + 0, G_OPTION_ARG_STRING, &options_.friendly_name, + FRIENDLY_NAME_DESCRIPTION, NULL + }, + { + MANUFACTURER_OPTION_LONG, + MANUFACTURER_OPTION, + 0, G_OPTION_ARG_STRING, &options_.manufacturer, + MANUFACTURER_DESCRIPTION, NULL + }, + { + MODELNAME_OPTION_LONG, + MODELNAME_OPTION, + 0, G_OPTION_ARG_STRING, &options_.model_name, + MODELNAME_DESCRIPTION, NULL + }, + { + UUID_OPTION_LONG, + UUID_OPTION, + 0, G_OPTION_ARG_STRING, &options_.uuid, + UUID_DESCRIPTION, NULL + }, + { + WAKE_OPTION_LONG, + WAKE_OPTION, + 0, G_OPTION_ARG_STRING, &options_.wake, + WAKE_DESCRIPTION, NULL + }, + { + IFNAME_OPTION_LONG, + IFNAME_OPTION, + 0, G_OPTION_ARG_STRING, &options_.iface_name, + IFNAME_DESCRIPTION, NULL + }, + { + APP_LIST_OPTION_LONG, + APP_LIST_OPTION, + 0, G_OPTION_ARG_STRING, &options_.app_list, + APP_LIST_DESCRIPTION, NULL + }, + { + FEATURE_FRIENDLYNAME_OPTION_LONG, + 0, + 0, G_OPTION_ARG_NONE, &options_.feature_friendlyname, + FEATURE_FRIENDLYNAME_DESCRIPTION, NULL + }, + { + FEATURE_WOLWAKE_OPTION_LONG, + 0, + 0, G_OPTION_ARG_NONE, &options_.feature_wolwake, + FEATURE_WOLWAKE_DESCRIPTION, NULL + }, + { NULL } +}; + +static const gchar *iface_ipv4_address_ = NULL; + +static void signal_handler_rest_server_invalid_uri(GDialRestServer *dial_rest_server, const gchar *signal_message, gpointer user_data) { + g_return_if_fail(dial_rest_server && signal_message); + GDIAL_LOGERROR("signal invalid-uri: [%s]", signal_message); +} + +static void signal_handler_rest_server_gmainloop_quit(GDialRestServer *dial_rest_server, const gchar *signal_message, gpointer user_data) { + g_return_if_fail(dial_rest_server && signal_message); + GDIAL_LOGERROR("signal gmainloop-quit: [%s]", signal_message); + GDIAL_LOGINFO("Exiting DIAL Protocol | %s ", dial_specification_copyright); + //g_main_loop_quit(m_gdialServiceImpl->m_main_loop); +} +static GDialRestServer *dial_rest_server = NULL; + +static void server_activation_handler(gboolean status, const gchar *friendlyname) +{ + GDIAL_LOGINFO("server_activation_handler status :%d ",status); + gdial_ssdp_set_available(status,friendlyname); + if(dial_rest_server) + { + g_object_set(dial_rest_server,"enable" ,status, NULL); + } +} + +static void server_register_application(gpointer data) +{ + GList* g_app_list = (GList*) data; + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("server_register_application callback "); + if(g_app_list) { + GDIAL_LOGINFO("server_register_application appList :%d", g_list_length (g_app_list)); + } + + /*Remove all existing registered Apps*/ + gdial_rest_server_unregister_all_apps(dial_rest_server); + while(g_app_list) { + gdial_rest_server_register_app_registry (dial_rest_server, (GDialAppRegistry *)g_app_list->data); + g_app_list = g_app_list->next; + } + + if (!options_.app_list) { + GDIAL_LOGINFO(" No application is enabled from cmdline so ignore system app "); + } + else{ + size_t app_list_len = strlen(options_.app_list); + gchar *app_list_low = g_ascii_strdown(options_.app_list, app_list_len); + if (g_strstr_len(app_list_low, app_list_len , "system")) { + GDIAL_LOGINFO("Register system app - enabled from cmdline"); + gdial_rest_server_register_app(dial_rest_server, "system", NULL, NULL, TRUE, TRUE, NULL); + } + else { + GDIAL_LOGINFO("Dont register system app - not enabled from cmdline"); + } + } + GDIAL_LOGTRACE("Exiting ..."); +} + +static void server_friendlyname_handler(const gchar * friendlyname) +{ + gdial_ssdp_set_friendlyname(friendlyname); +} + +static void server_powerstate_handler(const gchar * powerState) +{ + gdialServiceImpl::getInstance()->updatePowerState(std::string(powerState)); +} + +static void signal_handler_rest_server_rest_enable(GDialRestServer *dial_rest_server, const gchar *signal_message, gpointer user_data) { + GDIAL_LOGINFO(" signal_handler_rest_server_rest_enable received signal :%s ",signal_message ); + if(!strcmp(signal_message,"true")) + { + server_activation_handler(1, ""); + } + else + { + server_activation_handler(0, ""); + } +} + +static void gdial_http_server_throttle_callback(SoupServer *server, + SoupMessage *msg, const gchar *path, GHashTable *query, + SoupClientContext *client, gpointer user_data) +{ + GDIAL_LOGINFO("gdial_http_server_throttle_callback "); + soup_message_headers_replace(msg->response_headers, "Connection", "close"); + soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); +} + +static void gdial_quit_thread(int signum) +{ + GDIAL_LOGINFO("Exiting DIAL Server thread %d ",signum); + server_activation_handler(0, ""); + usleep(50000); //Sleeping 50 ms to allow existing request to finish processing. + //GDIAL_LOGINFO(" calling g_main_loop_quit loop_: %p ",m_gdialServiceImpl->m_main_loop); + //if(m_gdialServiceImpl->m_main_loop)g_main_loop_quit(m_gdialServiceImpl->m_main_loop); +} + +static SoupServer * m_servers[3] = {NULL,NULL,NULL}; + +int gdialServiceImpl::start_GDialServer(int argc, char *argv[]) +{ + GError *error = NULL; + int returnValue = EXIT_FAILURE; + GDIAL_LOGTRACE("Entering ..."); + GOptionContext *option_context = g_option_context_new(NULL); + g_option_context_add_main_entries(option_context, option_entries_, NULL); + + if (!g_option_context_parse (option_context, &argc, &argv, &error)) + { + GDIAL_LOGERROR ("%s", error->message); + g_error_free(error); + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; + } + + if (!options_.iface_name) + { + options_.iface_name = g_strdup(GDIAL_IFACE_NAME_DEFAULT); + GDIAL_LOGWARNING("Interface Name not given, so [%s] used",GDIAL_IFACE_NAME_DEFAULT); + } + + #define MAX_RETRY 3 + for(int i=1;i<=MAX_RETRY;i++) + { + iface_ipv4_address_ = gdial_plat_util_get_iface_ipv4_addr(options_.iface_name); + if (!iface_ipv4_address_) + { + GDIAL_LOGWARNING("Warning: interface %s does not have IP", options_.iface_name); + if(i >= MAX_RETRY ) + { + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; + } + sleep(2); + } + else + { + break; + } + } + + //m_main_loop_context = g_main_context_default(); + m_main_loop_context = g_main_context_new(); + g_main_context_push_thread_default(m_main_loop_context); + m_main_loop = g_main_loop_new(m_main_loop_context, FALSE); + gdial_plat_init(m_main_loop_context); + + gdail_plat_register_activation_cb(server_activation_handler); + gdail_plat_register_friendlyname_cb(server_friendlyname_handler); + gdail_plat_register_registerapps_cb (server_register_application); + gdail_plat_dev_register_powerstate_cb(server_powerstate_handler); + + SoupServer * rest_http_server = soup_server_new(NULL); + SoupServer * ssdp_http_server = soup_server_new(NULL); + SoupServer * local_rest_http_server = soup_server_new(NULL); + soup_server_add_handler(rest_http_server, "/", gdial_http_server_throttle_callback, NULL, NULL); + soup_server_add_handler(ssdp_http_server, "/", gdial_http_server_throttle_callback, NULL, NULL); + + GSocketAddress *listen_address = g_inet_socket_address_new_from_string(iface_ipv4_address_, GDIAL_REST_HTTP_PORT); + SoupServerListenOptions option = 0; + gboolean success = soup_server_listen(rest_http_server, listen_address, option, &error); + g_object_unref (listen_address); + if (!success) + { + GDIAL_LOGERROR("%s", error->message); + g_error_free(error); + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; + } + else + { + listen_address = g_inet_socket_address_new_from_string(iface_ipv4_address_, GDIAL_SSDP_HTTP_PORT); + success = soup_server_listen(ssdp_http_server, listen_address, option, &error); + g_object_unref (listen_address); + if (!success) + { + GDIAL_LOGERROR("%s", error->message); + g_error_free(error); + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; + } + else + { + success = soup_server_listen_local(local_rest_http_server, GDIAL_REST_HTTP_PORT, SOUP_SERVER_LISTEN_IPV4_ONLY, &error); + if (!success) + { + GDIAL_LOGERROR("%s", error->message); + g_error_free(error); + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; + } + } + } + gchar uuid_str[MAX_UUID_SIZE] = {0}; + char * static_apps_location = getenv("XDIAL_STATIC_APPS_LOCATION"); + if (static_apps_location != NULL && strlen(static_apps_location)) + { + g_snprintf(uuid_str, MAX_UUID_SIZE, "%s", static_apps_location); + GDIAL_LOGINFO("static uuid_str :%s", uuid_str); + } + else + { + FILE *fuuid = fopen(UUID_FILE_PATH, "r"); + if (fuuid == NULL) + { + uuid_t random_uuid; + uuid_generate_random(random_uuid); + uuid_unparse(random_uuid, uuid_str); + GDIAL_LOGINFO("generated uuid_str :%s", uuid_str); + fuuid = fopen(UUID_FILE_PATH, "w"); + if (fuuid != NULL) + { + fprintf(fuuid, "%s", uuid_str); + fclose(fuuid); + } + } + else + { + fgets(uuid_str, sizeof(uuid_str), fuuid); + printf("Persistent uuid_str: %s", uuid_str); + fclose(fuuid); + } + } + + dial_rest_server = gdial_rest_server_new(rest_http_server,local_rest_http_server,uuid_str); + if (!options_.app_list) + { + GDIAL_LOGINFO("no application is enabled from cmdline "); + } + else + { + GDIAL_LOGINFO("app_list to be enabled from command line %s", options_.app_list); + size_t app_list_len = strlen(options_.app_list); + gchar *app_list_low = g_ascii_strdown(options_.app_list, app_list_len); + if (g_strstr_len(app_list_low, app_list_len, "netflix")) + { + GDIAL_LOGINFO("netflix is enabled from cmdline"); + GList *allowed_origins = g_list_prepend(NULL, ".netflix.com"); + gdial_rest_server_register_app(dial_rest_server, "Netflix", NULL, NULL, TRUE, TRUE, allowed_origins); + g_list_free(allowed_origins); + } + else + { + GDIAL_LOGINFO("netflix is not enabled from cmdline"); + } + + if (g_strstr_len(app_list_low, app_list_len, "youtube")) + { + GDIAL_LOGINFO("youtube is enabled from cmdline"); + GList *allowed_origins = g_list_prepend(NULL, ".youtube.com"); + gdial_rest_server_register_app(dial_rest_server, "YouTube", NULL, NULL, TRUE, TRUE, allowed_origins); + g_list_free(allowed_origins); + } + else + { + GDIAL_LOGINFO("youtube is not enabled from cmdline"); + } + + if (g_strstr_len(app_list_low, app_list_len, "youtubetv")) + { + GDIAL_LOGINFO("youtubetv is enabled from cmdline"); + GList *allowed_origins = g_list_prepend(NULL, ".youtube.com"); + gdial_rest_server_register_app(dial_rest_server, "YouTubeTV", NULL, NULL, TRUE, TRUE, allowed_origins); + g_list_free(allowed_origins); + } + else + { + GDIAL_LOGINFO("youtubetv is not enabled from cmdline"); + } + + if (g_strstr_len(app_list_low, app_list_len, "youtubekids")) + { + GDIAL_LOGINFO("youtubekids is enabled from cmdline"); + GList *allowed_origins = g_list_prepend(NULL, ".youtube.com"); + gdial_rest_server_register_app(dial_rest_server, "YouTubeKids", NULL, NULL, TRUE, TRUE, allowed_origins); + g_list_free(allowed_origins); + } + else + { + GDIAL_LOGINFO("youtubekids is not enabled from cmdline"); + } + + if (g_strstr_len(app_list_low, app_list_len, "amazoninstantvideo")) + { + GDIAL_LOGINFO("AmazonInstantVideo is enabled from cmdline"); + GList *allowed_origins = g_list_prepend(NULL, ".amazonprime.com"); + gdial_rest_server_register_app(dial_rest_server, "AmazonInstantVideo", NULL, NULL, TRUE, TRUE, allowed_origins); + g_list_free(allowed_origins); + } + else + { + GDIAL_LOGINFO("AmazonInstantVideo is not enabled from cmdline"); + } + + if (g_strstr_len(app_list_low, app_list_len, "spotify")) + { + GDIAL_LOGINFO("spotify is enabled from cmdline"); + GList *app_prefixes= g_list_prepend(NULL, "com.spotify"); + GList *allowed_origins = g_list_prepend(NULL, ".spotify.com"); + gdial_rest_server_register_app(dial_rest_server, "com.spotify.Spotify.TV", app_prefixes, NULL, TRUE, TRUE, allowed_origins); + g_list_free(allowed_origins); + g_list_free(app_prefixes); + } + else + { + GDIAL_LOGINFO("spotify is not enabled from cmdline"); + } + + if (g_strstr_len(app_list_low, app_list_len, "pairing")) + { + GDIAL_LOGINFO("pairing is enabled from cmdline"); + GList *allowed_origins = g_list_prepend(NULL, ".comcast.com"); + gdial_rest_server_register_app(dial_rest_server, "Pairing", NULL, NULL, TRUE, TRUE, allowed_origins); + g_list_free(allowed_origins); + } + else + { + GDIAL_LOGINFO("pairing is not enabled from cmdline"); + } + + if (g_strstr_len(app_list_low, app_list_len, "system")) + { + GDIAL_LOGINFO("system is enabled from cmdline"); + gdial_rest_server_register_app(dial_rest_server, "system", NULL, NULL, TRUE, TRUE, NULL); + } + else + { + GDIAL_LOGINFO("system is not enabled from cmdline"); + } + g_free(app_list_low); + app_list_low = NULL; + } + + g_signal_connect(dial_rest_server, "invalid-uri", G_CALLBACK(signal_handler_rest_server_invalid_uri), NULL); + g_signal_connect(dial_rest_server, "gmainloop-quit", G_CALLBACK(signal_handler_rest_server_gmainloop_quit), NULL); + g_signal_connect(dial_rest_server, "rest-enable", G_CALLBACK(signal_handler_rest_server_rest_enable), NULL); + + gdial_ssdp_new(ssdp_http_server, &options_,uuid_str); + gdial_shield_init(); + gdial_shield_server(rest_http_server); + gdial_shield_server(ssdp_http_server); + + m_servers[0] = local_rest_http_server; + m_servers[1] = rest_http_server; + m_servers[2] = ssdp_http_server; + + for (int i = 0; i < sizeof(m_servers)/sizeof(m_servers[0]); i++) + { + GSList *uris = soup_server_get_uris(m_servers[i]); + for (GSList *uri = uris; uri != NULL; uri = uri->next) + { + char *uri_string = soup_uri_to_string(uri->data, FALSE); + GDIAL_LOGINFO("Listening on %s", uri_string); + g_free(uri_string); + soup_uri_free(uri->data); + } + g_slist_free(uris); + } + + g_main_context_pop_thread_default(m_main_loop_context); + pthread_create(&m_gdialserver_main_thread, nullptr, gdialServiceImpl::mainThread, this); + pthread_create(&m_gdialserver_request_handler_thread, nullptr, gdialServiceImpl::requestHandlerThread, this); + pthread_create(&m_gdialserver_response_handler_thread, nullptr, gdialServiceImpl::responseHandlerThread, this); + + if (( 0 == m_gdialserver_main_thread ) || ( 0 == m_gdialserver_request_handler_thread ) || ( 0 == m_gdialserver_response_handler_thread )) + { + GDIAL_LOGERROR("Failed to create gdialserver thread"); + stop_GDialServer(); + } + else + { + returnValue = 0; + GDIAL_LOGINFO("Success ..."); + gdial_plat_application_service_notification(true,this); + GDIAL_LOGINFO("gdial_plat_application_service_notification done ..."); + } + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; +} + +bool gdialServiceImpl::stop_GDialServer() +{ + GDIAL_LOGTRACE("Entering ..."); + server_activation_handler(0, ""); + //Sleeping 50 ms to allow existing request to finish processing. + usleep(50000); + + GDIAL_LOGINFO("calling RequestHandlerThread to exit"); + { + m_RequestHandlerThreadExit = true; + std::unique_lock lk(m_RequestHandlerEventMutex); + m_RequestHandlerThreadRun = true; + m_RequestHandlerCV.notify_one(); + } + + GDIAL_LOGINFO("calling ResponseHandlerThread to exit"); + { + m_ResponseHandlerThreadExit = true; + std::unique_lock lk(m_ResponseHandlerEventMutex); + m_ResponseHandlerThreadRun = true; + m_ResponseHandlerCV.notify_one(); + } + + GDIAL_LOGINFO(" calling g_main_loop_quit loop_: %p ",m_main_loop); + if (m_main_loop) + { + g_main_loop_quit(m_main_loop); + } + if (m_gdialserver_main_thread) + { + pthread_join(m_gdialserver_main_thread,nullptr); + m_gdialserver_main_thread = 0; + } + if (m_gdialserver_request_handler_thread) + { + pthread_join(m_gdialserver_request_handler_thread,nullptr); + m_gdialserver_request_handler_thread = 0; + } + if (m_gdialserver_response_handler_thread) + { + pthread_join(m_gdialserver_response_handler_thread,nullptr); + m_gdialserver_response_handler_thread = 0; + } + + for (int i = 0; i < sizeof(m_servers)/sizeof(m_servers[0]); i++) + { + if (m_servers[i]) + { + soup_server_disconnect(m_servers[i]); + g_object_unref(m_servers[i]); + m_servers[i] = NULL; + } + } + + gdial_shield_term(); + gdial_ssdp_destroy(); + if (dial_rest_server) + { + g_object_unref(dial_rest_server); + dial_rest_server = NULL; + } + gdial_plat_application_service_notification(false,NULL); + gdial_plat_term(); + + if (m_main_loop) + { + g_main_loop_unref(m_main_loop); + m_main_loop = NULL; + } + + if (m_main_loop_context) + { + g_main_context_unref(m_main_loop_context); + m_main_loop_context = NULL; + } + GDIAL_LOGTRACE("Exiting ..."); + return true; +} + +void *gdialServiceImpl::mainThread(void *ctx) +{ + GDIAL_LOGTRACE("Entering ..."); + gdialServiceImpl *_instance = (gdialServiceImpl *)ctx; + g_main_context_push_thread_default(_instance->m_main_loop_context); + g_main_loop_run(_instance->m_main_loop); + _instance->m_gdialserver_main_thread = 0; + g_main_context_pop_thread_default(_instance->m_main_loop_context); + GDIAL_LOGTRACE("Exiting ..."); + pthread_exit(nullptr); +} + +void *gdialServiceImpl::requestHandlerThread(void *ctx) +{ + GDIAL_LOGTRACE("Entering ..."); + gdialServiceImpl *_instance = (gdialServiceImpl *)ctx; + RequestHandlerPayload reqHdlrPayload; + while(!_instance->m_RequestHandlerThreadExit) + { + reqHdlrPayload.appNameOrfriendlyname = ""; + reqHdlrPayload.appIdOractivation = ""; + reqHdlrPayload.state = ""; + reqHdlrPayload.error = ""; + reqHdlrPayload.data_param = nullptr; + reqHdlrPayload.event = INVALID_REQUEST; + { + // Wait for a message to be added to the queue + std::unique_lock lk(_instance->m_RequestHandlerEventMutex); + _instance->m_RequestHandlerCV.wait(lk, [instance = _instance]{return (instance->m_RequestHandlerThreadRun == true);}); + } + + if (_instance->m_RequestHandlerThreadExit == true) + { + GDIAL_LOGINFO(" threadSendRequest Exiting"); + _instance->m_RequestHandlerThreadRun = false; + break; + } + + if (_instance->m_RequestHandlerQueue.empty()) + { + _instance->m_RequestHandlerThreadRun = false; + continue; + } + + reqHdlrPayload = _instance->m_RequestHandlerQueue.front(); + _instance->m_RequestHandlerQueue.pop(); + + if ( nullptr != _instance->m_observer ) + { + GDIAL_LOGINFO("Request : Event:0x%x",reqHdlrPayload.event); + switch(reqHdlrPayload.event) + { + case APP_STATE_CHANGED: + { + std::string appName = reqHdlrPayload.appNameOrfriendlyname, + appId = reqHdlrPayload.appIdOractivation, + state = reqHdlrPayload.state, + error = reqHdlrPayload.error; + GDIAL_LOGINFO("APP_STATE_CHANGED : appName:%s appId:%s state:%s error:%s",appName.c_str(),appId.c_str(),state.c_str(),error.c_str()); + gdial_plat_application_state_changed(appName.c_str(),appId.c_str(),state.c_str(),error.c_str()); + } + break; + case ACTIVATION_CHANGED: + { + std::string activation = reqHdlrPayload.appIdOractivation, + friendlyName = reqHdlrPayload.appNameOrfriendlyname; + GDIAL_LOGINFO("ACTIVATION_CHANGED : actication:%s friendlyName:%s",activation.c_str(),friendlyName.c_str()); + gdial_plat_application_activation_changed(activation.c_str(),friendlyName.c_str()); + } + break; + case FRIENDLYNAME_CHANGED: + { + std::string friendlyName = reqHdlrPayload.appNameOrfriendlyname; + GDIAL_LOGINFO("FRIENDLYNAME_CHANGED : friendlyName:%s",friendlyName.c_str()); + gdial_plat_application_friendlyname_changed(friendlyName.c_str()); + } + break; + case REGISTER_APPLICATIONS: + { + GDIAL_LOGINFO("REGISTER_APPLICATIONS : data:%p",reqHdlrPayload.data_param); + gdial_plat_application_register_applications(reqHdlrPayload.data_param); + } + break; + case UPDATE_NW_STANDBY: + { + GDIAL_LOGINFO("UPDATE_NW_STANDBY : data:%u",reqHdlrPayload.user_param1); + gdial_plat_application_update_network_standby_mode((gboolean)reqHdlrPayload.user_param1); + } + break; + default: + { + + } + break; + } + } + } + _instance->m_gdialserver_request_handler_thread = 0; + GDIAL_LOGTRACE("Exiting ..."); + pthread_exit(nullptr); +} + +void *gdialServiceImpl::responseHandlerThread(void *ctx) +{ + gdialServiceImpl *_instance = (gdialServiceImpl *)ctx; + ResponseHandlerPayload response_data; + while(!_instance->m_ResponseHandlerThreadExit) + { + response_data.appName = ""; + response_data.parameterOrPayload = ""; + response_data.appIdOrQuery = ""; + response_data.AddDataUrl = ""; + response_data.event = APP_INVALID_STATE; + + { + // Wait for a message to be added to the queue + std::unique_lock lk(_instance->m_ResponseHandlerEventMutex); + _instance->m_ResponseHandlerCV.wait(lk, [instance = _instance]{return (instance->m_ResponseHandlerThreadRun == true);}); + } + + if (_instance->m_ResponseHandlerThreadExit == true) + { + GDIAL_LOGINFO(" threadSendResponse Exiting"); + _instance->m_ResponseHandlerThreadRun = false; + break; + } + + if (_instance->m_ResponseHandlerQueue.empty()) + { + _instance->m_ResponseHandlerThreadRun = false; + continue; + } + + response_data = _instance->m_ResponseHandlerQueue.front(); + _instance->m_ResponseHandlerQueue.pop(); + + if ( nullptr != _instance->m_observer ) + { + GDIAL_LOGINFO("Response : Event:0x%x",response_data.event); + switch(response_data.event) + { + case APP_LAUNCH_REQUEST_WITH_PARAMS: + { + std::string appName = response_data.appName, + payload = response_data.parameterOrPayload, + query = response_data.appIdOrQuery, + AddDataUrl = response_data.AddDataUrl; + GDIAL_LOGINFO("AppLaunchWithParam : appName:%s PayLoad:%s Query:%s AddUrl:%s", + appName.c_str(), + payload.c_str(), + query.c_str(), + AddDataUrl.c_str()); + _instance->m_observer->onApplicationLaunchRequestWithLaunchParam(appName,payload,query,AddDataUrl); + } + break; + case APP_LAUNCH_REQUEST: + { + std::string appName = response_data.appName, + parameter = response_data.parameterOrPayload; + GDIAL_LOGINFO("AppLaunch : appName:%s parameter:%s",appName.c_str(),parameter.c_str()); + _instance->m_observer->onApplicationLaunchRequest(appName,parameter); + } + break; + case APP_STOP_REQUEST: + { + std::string appName = response_data.appName, + appId = response_data.appIdOrQuery; + GDIAL_LOGINFO("AppStop : appName:%s appId:%s",appName.c_str(),appId.c_str()); + _instance->m_observer->onApplicationStopRequest(appName,appId); + } + break; + case APP_HIDE_REQUEST: + { + std::string appName = response_data.appName, + appId = response_data.appIdOrQuery; + GDIAL_LOGINFO("AppHide : appName:%s appId:%s",appName.c_str(),appId.c_str()); + _instance->m_observer->onApplicationHideRequest(appName,appId); + } + break; + case APP_STATE_REQUEST: + { + std::string appName = response_data.appName, + appId = response_data.appIdOrQuery; + GDIAL_LOGINFO("AppState : appName:%s appId:%s",appName.c_str(),appId.c_str()); + _instance->m_observer->onApplicationStateRequest(appName,appId); + } + break; + case APP_RESUME_REQUEST: + { + std::string appName = response_data.appName, + appId = response_data.appIdOrQuery; + GDIAL_LOGINFO("AppResume : appName:%s appId:%s",appName.c_str(),appId.c_str()); + _instance->m_observer->onApplicationResumeRequest(appName,appId); + } + break; + default: + { + + } + break; + } + } + } + _instance->m_gdialserver_response_handler_thread = 0; + _instance->m_observer->onStopped(); + pthread_exit(nullptr); +} + +gdialServiceImpl* gdialServiceImpl::getInstance(void) +{ + if (nullptr == m_gdialServiceImpl) + { + m_gdialServiceImpl = new gdialServiceImpl(); + } + return m_gdialServiceImpl; +} + +void gdialServiceImpl::destroyInstance() +{ + if (m_gdialServiceImpl) + { + m_gdialServiceImpl->stop_GDialServer(); + delete m_gdialServiceImpl; + m_gdialServiceImpl = nullptr; + } +} + +gdialService* gdialService::getInstance(GDialNotifier* observer, const std::vector& gdial_args,const std::string& actualprocessName ) +{ + GDIAL_LOGTRACE("Entering ..."); + + gdial_plat_util_logger_init(); + + if (nullptr == m_gdialService) + { + m_gdialService = new gdialService(); + } + + gdialServiceImpl* gdialImplInstance = gdialServiceImpl::getInstance(); + + if (nullptr != gdialImplInstance) + { + char name[256] = {0}; + std::string process_name = actualprocessName; + int input_argc = gdial_args.size(), + overall_argc = input_argc + 1;// store process name + char** argv = new char*[overall_argc]; + + if (process_name.empty()) + { + prctl(PR_GET_NAME, name, 0, 0, 0); + process_name = std::string(name); + + if (process_name.empty()) + { + process_name = "Unknown"; + } + } + + argv[0] = new char[process_name.size() + 1]; + GDIAL_LOGINFO("Process Name:[%s]",process_name.c_str()); + + for (int i = 0; i < input_argc; ++i) + { + argv[i+1] = new char[gdial_args[i].size() + 1]; + strncpy(argv[i+1], gdial_args[i].c_str(),(gdial_args[i].size() + 1)); + GDIAL_LOGINFO("Args:%d [%s]",i,gdial_args[i].c_str()); + } + GDIAL_LOGINFO("start_GDialServer with argc[%d]",overall_argc); + if ( 0 != gdialImplInstance->start_GDialServer(overall_argc,argv)) + { + GDIAL_LOGERROR("Failed to start GDial server"); + gdialServiceImpl::destroyInstance(); + delete m_gdialService; + m_gdialService = nullptr; + } + else + { + gdialImplInstance->setService(observer); + } + + // Free allocated memory after the thread starts + for (int i = 0; i < overall_argc; ++i) + { + delete[] argv[i]; + } + delete[] argv; + } + return m_gdialService; +} + +void gdialService::destroyInstance() +{ + if (nullptr != m_gdialService ) + { + gdialServiceImpl::destroyInstance(); + delete m_gdialService; + m_gdialService = nullptr; + } +} + +GDIAL_SERVICE_ERROR_CODES gdialService::ApplicationStateChanged(string applicationName, string appState, string applicationId, string error) +{ + gdialServiceImpl* gdialImplInstance = gdialServiceImpl::getInstance(); + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("appName[%s] appId[%s] state[%s] error[%s]", + applicationName.c_str(), + applicationId.c_str(), + appState.c_str(), + error.c_str()); + if ((nullptr != m_gdialService ) && (nullptr != gdialImplInstance)) + { + RequestHandlerPayload payload; + payload.event = APP_STATE_CHANGED; + + payload.appNameOrfriendlyname = applicationName; + payload.appIdOractivation = applicationId; + payload.state = appState; + payload.error = error; + gdialImplInstance->sendRequest(payload); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_SERVICE_ERROR_NONE; +} + +GDIAL_SERVICE_ERROR_CODES gdialService::ActivationChanged(string activation, string friendlyname) +{ + gdialServiceImpl* gdialImplInstance = gdialServiceImpl::getInstance(); + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("activation[%s] friendlyname[%s]",activation.c_str(),friendlyname.c_str()); + if ((nullptr != m_gdialService ) && (nullptr != gdialImplInstance)) + { + RequestHandlerPayload payload; + payload.event = ACTIVATION_CHANGED; + + payload.appNameOrfriendlyname = friendlyname; + payload.appIdOractivation = activation; + GDIAL_LOGINFO("ACTIVATION_CHANGED request sent"); + gdialImplInstance->sendRequest(payload); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_SERVICE_ERROR_NONE; +} + +GDIAL_SERVICE_ERROR_CODES gdialService::FriendlyNameChanged(string friendlyname) +{ + gdialServiceImpl* gdialImplInstance = gdialServiceImpl::getInstance(); + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("friendlyname[%s]",friendlyname.c_str()); + if ((nullptr != m_gdialService ) && (nullptr != gdialImplInstance)) + { + RequestHandlerPayload payload; + payload.event = FRIENDLYNAME_CHANGED; + + payload.appNameOrfriendlyname = friendlyname; + gdialImplInstance->sendRequest(payload); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_SERVICE_ERROR_NONE; +} + +std::string gdialService::getProtocolVersion() +{ + gdialServiceImpl* gdialImplInstance = gdialServiceImpl::getInstance(); + GDIAL_LOGTRACE("Entering ..."); + std::string protocolVersion; + if ((nullptr != m_gdialService ) && (nullptr != gdialImplInstance)) + { + protocolVersion = gdial_plat_application_get_protocol_version(); + } + GDIAL_LOGTRACE("Exiting ..."); + return protocolVersion; +} + +GDIAL_SERVICE_ERROR_CODES gdialService::RegisterApplications(RegisterAppEntryList* appConfigList) +{ + gdialServiceImpl* gdialImplInstance = gdialServiceImpl::getInstance(); + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("appConfigList[%p]",appConfigList); + if ((nullptr != m_gdialService ) && (nullptr != gdialImplInstance)) + { + RequestHandlerPayload payload; + payload.event = REGISTER_APPLICATIONS; + payload.data_param = appConfigList; + gdialImplInstance->sendRequest(payload); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_SERVICE_ERROR_NONE; +} + +void gdialService::setNetworkStandbyMode(bool nwStandbymode) +{ + gdialServiceImpl* gdialImplInstance = gdialServiceImpl::getInstance(); + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("nwStandbymode[%u]",nwStandbymode); + if ((nullptr != m_gdialService ) && (nullptr != gdialImplInstance)) + { + RequestHandlerPayload payload; + payload.event = UPDATE_NW_STANDBY; + payload.user_param1 = (bool)nwStandbymode; + gdialImplInstance->sendRequest(payload); + } + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::sendRequest( const RequestHandlerPayload& payload ) +{ + GDIAL_LOGTRACE("Entering ..."); + std::unique_lock lk(m_RequestHandlerEventMutex); + m_RequestHandlerQueue.push(payload); + m_RequestHandlerThreadRun = true; + m_RequestHandlerCV.notify_one(); + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::notifyResponse( const ResponseHandlerPayload& payload ) +{ + GDIAL_LOGTRACE("Entering ..."); + std::unique_lock lk(m_ResponseHandlerEventMutex); + m_ResponseHandlerQueue.push(payload); + m_ResponseHandlerThreadRun = true; + m_ResponseHandlerCV.notify_one(); + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::onApplicationLaunchRequestWithLaunchParam(string appName,string strPayLoad, string strQuery, string strAddDataUrl) +{ + ResponseHandlerPayload payload; + GDIAL_LOGTRACE("Entering ..."); + payload.event = APP_LAUNCH_REQUEST_WITH_PARAMS; + + payload.appName = appName; + payload.parameterOrPayload = strPayLoad; + payload.appIdOrQuery = strQuery; + payload.AddDataUrl = strAddDataUrl; + notifyResponse(payload); + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::onApplicationLaunchRequest(string appName, string parameter) +{ + ResponseHandlerPayload payload; + GDIAL_LOGTRACE("Entering ..."); + payload.event = APP_LAUNCH_REQUEST; + + payload.appName = appName; + payload.parameterOrPayload = parameter; + notifyResponse(payload); + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::onApplicationStopRequest(string appName, string appID) +{ + ResponseHandlerPayload payload; + GDIAL_LOGTRACE("Entering ..."); + payload.event = APP_STOP_REQUEST; + + payload.appName = appName; + payload.appIdOrQuery = appID; + notifyResponse(payload); + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::onApplicationHideRequest(string appName, string appID) +{ + ResponseHandlerPayload payload; + GDIAL_LOGTRACE("Entering ..."); + payload.event = APP_HIDE_REQUEST; + + payload.appName = appName; + payload.appIdOrQuery = appID; + notifyResponse(payload); + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::onApplicationResumeRequest(string appName, string appID) +{ + ResponseHandlerPayload payload; + GDIAL_LOGTRACE("Entering ..."); + payload.event = APP_RESUME_REQUEST; + + payload.appName = appName; + payload.appIdOrQuery = appID; + notifyResponse(payload); + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::onApplicationStateRequest(string appName, string appID) +{ + ResponseHandlerPayload payload; + GDIAL_LOGTRACE("Entering ..."); + payload.event = APP_STATE_REQUEST; + + payload.appName = appName; + payload.appIdOrQuery = appID; + notifyResponse(payload); + GDIAL_LOGTRACE("Exiting ..."); +} + +void gdialServiceImpl::onStopped() +{ + // +} + +void gdialServiceImpl::updatePowerState(string powerState) +{ + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("powerState : %s",powerState.c_str()); + if (m_observer) + { + m_observer->updatePowerState(powerState); + } + GDIAL_LOGTRACE("Exiting ..."); +} \ No newline at end of file diff --git a/server/include/gdial-plat-app.h b/server/include/gdial-plat-app.h index 3434315a..7594708c 100644 --- a/server/include/gdial-plat-app.h +++ b/server/include/gdial-plat-app.h @@ -42,6 +42,14 @@ GDialAppError gdial_plat_application_resume(const gchar *app_name, gint instance GDialAppError gdial_plat_application_stop(const gchar *app_name, gint instance_id); GDialAppError gdial_plat_application_state(const gchar *app_name, gint instance_id, GDialAppState *state); +GDialAppError gdial_plat_application_state_changed(const char *applicationName, const char *applicationId, const char *state, const char *error); +GDialAppError gdial_plat_application_activation_changed(const char *activation, const char *friendlyname); +GDialAppError gdial_plat_application_friendlyname_changed(const char *friendlyname); +const char* gdial_plat_application_get_protocol_version(); +GDialAppError gdial_plat_application_register_applications(void*); +void gdial_plat_application_update_network_standby_mode(gboolean nwstandbyMode); +GDialAppError gdial_plat_application_service_notification(gboolean isNotifyRequired, void* notifier); + void * gdial_plat_application_start_async(const gchar *app_name, const gchar *payload, const gchar *query, const gchar *additional_data_url, void *user_data); void * gdial_plat_application_state_async(const gchar *app_name, gint instance_id, void *user_data); void * gdial_plat_application_hide_async(const gchar *app_name, gint instance_id, void *user_data); diff --git a/server/include/gdial-plat-dev.h b/server/include/gdial-plat-dev.h index a1c76049..6034db17 100644 --- a/server/include/gdial-plat-dev.h +++ b/server/include/gdial-plat-dev.h @@ -31,11 +31,12 @@ const char * gdial_plat_dev_get_model(); bool gdial_plat_dev_set_power_state_on(); bool gdial_plat_dev_set_power_state_off(); bool gdial_plat_dev_toggle_power_state(); -bool gdial_plat_dev_get_nwstandby_mode(); -bool gdial_plat_dev_initialize(); -bool gdial_plat_dev_deinitialize(); +void gdial_plat_dev_nwstandby_mode_change(gboolean NetworkStandbyMode); + typedef void (*gdial_plat_dev_nwstandbymode_cb)(const bool ); void gdail_plat_dev_register_nwstandbymode_cb(gdial_plat_dev_nwstandbymode_cb cb); +typedef void (*gdial_plat_dev_powerstate_cb)(const char* ); +void gdail_plat_dev_register_powerstate_cb(gdial_plat_dev_powerstate_cb cb); #ifdef __cplusplus } diff --git a/server/include/gdialservice.h b/server/include/gdialservice.h new file mode 100644 index 00000000..44c88eb6 --- /dev/null +++ b/server/include/gdialservice.h @@ -0,0 +1,50 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _GDIAL_SERVICE_H_ +#define _GDIAL_SERVICE_H_ + +#include +#include +#include +#include +#include +#include "gdialservicecommon.h" + +using namespace std; + +class gdialService +{ +public: + static gdialService* getInstance(GDialNotifier* observer, const std::vector& gdial_args,const std::string& actualprocessName ); + static void destroyInstance(); + + GDIAL_SERVICE_ERROR_CODES ApplicationStateChanged(string applicationName, string appState, string applicationId, string error); + GDIAL_SERVICE_ERROR_CODES ActivationChanged(string activation, string friendlyname); + GDIAL_SERVICE_ERROR_CODES FriendlyNameChanged(string friendlyname); + string getProtocolVersion(void); + GDIAL_SERVICE_ERROR_CODES RegisterApplications(RegisterAppEntryList* appConfigList); + void setNetworkStandbyMode(bool nwStandbymode); + +private: + GDialNotifier* m_observer{nullptr}; + gdialService(){}; + virtual ~gdialService(){}; +}; +#endif /* gdialService_hpp */ \ No newline at end of file diff --git a/server/include/gdialservicecommon.h b/server/include/gdialservicecommon.h new file mode 100644 index 00000000..629796bf --- /dev/null +++ b/server/include/gdialservicecommon.h @@ -0,0 +1,84 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _GDIAL_SERVICE_COMMON_H_ +#define _GDIAL_SERVICE_COMMON_H_ + +#include +#include +#include +#include + +using namespace std; + +typedef enum gdialServiceErrorCodes +{ + GDIAL_SERVICE_ERROR_NONE, + GDIAL_SERVICE_ERROR_FAILED +} +GDIAL_SERVICE_ERROR_CODES; + +class RegisterAppEntry +{ +public: + std::string Names; + std::string prefixes; + std::string cors; + int allowStop; +}; + +class RegisterAppEntryList +{ +public: + void pushBack(RegisterAppEntry* appEntry) + { + appEntries.push_back(appEntry); + } + + const std::vector& getValues() const + { + return appEntries; + } + + ~RegisterAppEntryList() + { + for (RegisterAppEntry* appEntry : appEntries) + { + delete appEntry; + } + appEntries.clear(); + } + +private: + std::vector appEntries; +}; + +class GDialNotifier +{ +public: + virtual void onApplicationLaunchRequest(string appName, string parameter)=0; + virtual void onApplicationLaunchRequestWithLaunchParam (string appName,string strPayLoad, string strQuery, string strAddDataUrl)=0; + virtual void onApplicationStopRequest(string appName, string appID)=0; + virtual void onApplicationHideRequest(string appName, string appID)=0; + virtual void onApplicationResumeRequest(string appName, string appID)=0; + virtual void onApplicationStateRequest(string appName, string appID)=0; + virtual void onStopped(void)=0; + virtual void updatePowerState(string powerState)=0; +}; +#endif /* _GDIAL_SERVICE_COMMON_H_ */ \ No newline at end of file diff --git a/server/include/gdialserviceimpl.h b/server/include/gdialserviceimpl.h new file mode 100644 index 00000000..c64e6a2c --- /dev/null +++ b/server/include/gdialserviceimpl.h @@ -0,0 +1,128 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _GDIAL_SERVICE_IMPL_H_ +#define _GDIAL_SERVICE_IMPL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum _AppRequestEvents +{ + APP_STATE_CHANGED, + ACTIVATION_CHANGED, + FRIENDLYNAME_CHANGED, + REGISTER_APPLICATIONS, + UPDATE_NW_STANDBY, + INVALID_REQUEST +} +AppRequestEvents; + +typedef enum _AppResponseEvents +{ + APP_LAUNCH_REQUEST_WITH_PARAMS, + APP_LAUNCH_REQUEST, + APP_STOP_REQUEST, + APP_HIDE_REQUEST, + APP_STATE_REQUEST, + APP_RESUME_REQUEST, + APP_INVALID_STATE +} +AppResponseEvents; + +typedef struct _RequestHandlerPayload +{ + std::string appNameOrfriendlyname; + std::string appIdOractivation; + std::string state; + std::string error; + void* data_param; + bool user_param1; + AppRequestEvents event; +}RequestHandlerPayload; + +typedef struct _ResponseHandlerPayload +{ + std::string appName; + std::string parameterOrPayload; + std::string appIdOrQuery; + std::string AddDataUrl; + AppResponseEvents event; +}ResponseHandlerPayload; + +class gdialServiceImpl: public GDialNotifier +{ +public: + static gdialServiceImpl* getInstance(void); + static void destroyInstance(); + + int start_GDialServer(int argc, char *argv[]); + bool stop_GDialServer(); + void sendRequest( const RequestHandlerPayload& payload ); + void setService(GDialNotifier* service) + { + m_observer = service; + } + + virtual void onApplicationLaunchRequest(string appName, string parameter) override; + virtual void onApplicationLaunchRequestWithLaunchParam (string appName,string strPayLoad, string strQuery, string strAddDataUrl) override; + virtual void onApplicationStopRequest(string appName, string appID) override; + virtual void onApplicationHideRequest(string appName, string appID) override; + virtual void onApplicationResumeRequest(string appName, string appID) override; + virtual void onApplicationStateRequest(string appName, string appID) override; + virtual void onStopped() override; + virtual void updatePowerState(string powerState) override; + +private: + gdialServiceImpl(){}; + virtual ~gdialServiceImpl(){}; + + GDialNotifier *m_observer; + pthread_t m_gdialserver_main_thread{0}; + + static void *mainThread(void *ctx); + GMainLoop *m_main_loop{nullptr}; + GMainContext *m_main_loop_context{nullptr}; + + static void *requestHandlerThread(void *ctx); + pthread_t m_gdialserver_request_handler_thread{0}; + bool m_RequestHandlerThreadExit{0}; + bool m_RequestHandlerThreadRun{0}; + std::mutex m_RequestHandlerEventMutex; + std::queue m_RequestHandlerQueue; + std::condition_variable m_RequestHandlerCV; + + static void *responseHandlerThread(void *ctx); + pthread_t m_gdialserver_response_handler_thread{0}; + bool m_ResponseHandlerThreadExit{0}; + bool m_ResponseHandlerThreadRun{0}; + std::mutex m_ResponseHandlerEventMutex; + std::queue m_ResponseHandlerQueue; + std::condition_variable m_ResponseHandlerCV; + + void notifyResponse( const ResponseHandlerPayload& payload ); +}; +#endif /* gdialServiceImpl_hpp */ \ No newline at end of file diff --git a/server/include/gdialservicelogging.h b/server/include/gdialservicelogging.h new file mode 100644 index 00000000..1f8596c0 --- /dev/null +++ b/server/include/gdialservicelogging.h @@ -0,0 +1,76 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _GDIAL_SERVICE_LOGGING_H_ +#define _GDIAL_SERVICE_LOGGING_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define __FILENAME__ \ + (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : \ + (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)) + +typedef enum gdial_plat_util_LogLevel_enum +{ + FATAL_LEVEL = 0, + ERROR_LEVEL, + WARNING_LEVEL, + INFO_LEVEL, + VERBOSE_LEVEL, + TRACE_LEVEL +} +gdial_plat_util_LogLevel; + +#define __FILENAME__ \ + (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : \ + (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)) + +#define _LOG(LEVEL, FORMAT, ...) \ + gdial_plat_util_log(LEVEL, \ + __func__, __FILENAME__, __LINE__, syscall(__NR_gettid), \ + FORMAT, \ + ##__VA_ARGS__) + +void gdial_plat_util_logger_init(void); +void gdial_plat_util_set_loglevel(gdial_plat_util_LogLevel level); +void gdial_plat_util_log(gdial_plat_util_LogLevel level, + const char* func, + const char* file, + int line, + int threadID, + const char* format, ...); + +#define GDIAL_LOGTRACE(FMT, ...) _LOG(TRACE_LEVEL, FMT, ##__VA_ARGS__) +#define GDIAL_LOGVERBOSE(FMT, ...) _LOG(VERBOSE_LEVEL, FMT, ##__VA_ARGS__) +#define GDIAL_LOGINFO(FMT, ...) _LOG(INFO_LEVEL, FMT, ##__VA_ARGS__) +#define GDIAL_LOGWARNING(FMT, ...) _LOG(WARNING_LEVEL, FMT, ##__VA_ARGS__) +#define GDIAL_LOGERROR(FMT, ...) _LOG(ERROR_LEVEL, FMT, ##__VA_ARGS__) +#define GDIAL_LOGFATAL(FMT, ...) _LOG(FATAL_LEVEL, FMT, ##__VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif /* _GDIAL_SERVICE_COMMON_H_ */ \ No newline at end of file diff --git a/server/main.c b/server/main.c deleted file mode 100644 index f6cd6ff6..00000000 --- a/server/main.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * If not stated otherwise in this file or this component's Licenses.txt file the - * following copyright and licenses apply: - * - * Copyright 2019 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include - -#include "gdial-config.h" -#include "gdial-debug.h" -#include "gdial-options.h" -#include "gdial-shield.h" -#include "gdial-ssdp.h" -#include "gdial-rest.h" -#include "gdial-plat-util.h" -#include "gdial-plat-dev.h" -#include "gdial-plat-app.h" -#include "gdial_app_registry.h" -#include - -static const char *dial_specification_copyright = "Copyright (c) 2017 Netflix, Inc. All rights reserved."; - -#define MAX_UUID_SIZE 64 -#define UUID_FILE_PATH "/opt/.dial_uuid.txt" - -static GDialOptions options_; - -static GOptionEntry option_entries_[] = { - { - FRIENDLY_NAME_OPTION_LONG, - FRIENDLY_NAME_OPTION, - 0, G_OPTION_ARG_STRING, &options_.friendly_name, - FRIENDLY_NAME_DESCRIPTION, NULL - }, - { - MANUFACTURER_OPTION_LONG, - MANUFACTURER_OPTION, - 0, G_OPTION_ARG_STRING, &options_.manufacturer, - MANUFACTURER_DESCRIPTION, NULL - }, - { - MODELNAME_OPTION_LONG, - MODELNAME_OPTION, - 0, G_OPTION_ARG_STRING, &options_.model_name, - MODELNAME_DESCRIPTION, NULL - }, - { - UUID_OPTION_LONG, - UUID_OPTION, - 0, G_OPTION_ARG_STRING, &options_.uuid, - UUID_DESCRIPTION, NULL - }, - { - WAKE_OPTION_LONG, - WAKE_OPTION, - 0, G_OPTION_ARG_STRING, &options_.wake, - WAKE_DESCRIPTION, NULL - }, - { - IFNAME_OPTION_LONG, - IFNAME_OPTION, - 0, G_OPTION_ARG_STRING, &options_.iface_name, - IFNAME_DESCRIPTION, NULL - }, - { - APP_LIST_OPTION_LONG, - APP_LIST_OPTION, - 0, G_OPTION_ARG_STRING, &options_.app_list, - APP_LIST_DESCRIPTION, NULL - }, - { - FEATURE_FRIENDLYNAME_OPTION_LONG, - 0, - 0, G_OPTION_ARG_NONE, &options_.feature_friendlyname, - FEATURE_FRIENDLYNAME_DESCRIPTION, NULL - }, - { - FEATURE_WOLWAKE_OPTION_LONG, - 0, - 0, G_OPTION_ARG_NONE, &options_.feature_wolwake, - FEATURE_WOLWAKE_DESCRIPTION, NULL - }, - { NULL } -}; -static GMainLoop *loop_ = NULL; -static const gchar *iface_ipv4_address_ = NULL; - -static void signal_handler_rest_server_invalid_uri(GDialRestServer *dial_rest_server, const gchar *signal_message, gpointer user_data) { - g_return_if_fail(dial_rest_server && signal_message); - g_printerr("signal invalid-uri: [%s]\r\n", signal_message); -} - -static void signal_handler_rest_server_gmainloop_quit(GDialRestServer *dial_rest_server, const gchar *signal_message, gpointer user_data) { - g_return_if_fail(dial_rest_server && signal_message); - g_printerr("signal gmainloop-quit: [%s]\r\n", signal_message); - g_print("Exiting DIAL Protocol | %s \r\n", dial_specification_copyright); - g_main_loop_quit(loop_); -} -static GDialRestServer *dial_rest_server = NULL; - -static void server_activation_handler(gboolean status, const gchar *friendlyname) -{ - g_print("server_activation_handler status :%d \n",status); - gdial_ssdp_set_available(status,friendlyname); - if(dial_rest_server) - { - g_object_set(dial_rest_server,"enable" ,status, NULL); - } -} - -static void server_register_application(gpointer data) -{ - GList* g_app_list = (GList*) data; - g_print("server_register_application callback \n"); - if(g_app_list) { - g_print("server_register_application appList :%d\n", g_list_length (g_app_list)); - } - - /*Remove all existing registered Apps*/ - gdial_rest_server_unregister_all_apps(dial_rest_server); - while(g_app_list) { - gdial_rest_server_register_app_registry (dial_rest_server, (GDialAppRegistry *)g_app_list->data); - g_app_list = g_app_list->next; - } - - if (!options_.app_list) { - g_print(" No application is enabled from cmdline so ignore system app \r\n"); - } - else{ - size_t app_list_len = strlen(options_.app_list); - gchar *app_list_low = g_ascii_strdown(options_.app_list, app_list_len); - if (g_strstr_len(app_list_low, app_list_len , "system")) { - g_print("Register system app - enabled from cmdline\r\n"); - gdial_rest_server_register_app(dial_rest_server, "system", NULL, NULL, TRUE, TRUE, NULL); - } - else { - g_print("Dont register system app - not enabled from cmdline\r\n"); - } - } -} - -static void server_friendlyname_handler(const gchar * friendlyname) -{ - gdial_ssdp_set_friendlyname(friendlyname); -} - -static void signal_handler_rest_server_rest_enable(GDialRestServer *dial_rest_server, const gchar *signal_message, gpointer user_data) { - g_print(" signal_handler_rest_server_rest_enable received signal :%s \n ",signal_message ); - if(!strcmp(signal_message,"true")) - { - server_activation_handler(1, ""); - } - else - { - server_activation_handler(0, ""); - } -} - -static void gdial_http_server_throttle_callback(SoupServer *server, - SoupMessage *msg, const gchar *path, GHashTable *query, - SoupClientContext *client, gpointer user_data) -{ - g_print("gdial_http_server_throttle_callback \r\n"); - soup_message_headers_replace(msg->response_headers, "Connection", "close"); - soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); -} - -static void gdial_quit_thread(int signum) -{ - g_print("Exiting DIAL Server thread %d \r\n",signum); - server_activation_handler(0, ""); - usleep(50000); //Sleeping 50 ms to allow existing request to finish processing. - g_print(" calling g_main_loop_quit loop_: %p \r\n",loop_); - if(loop_)g_main_loop_quit(loop_); - -} - -int main(int argc, char *argv[]) { - - GError *error = NULL; - GOptionContext *option_context = g_option_context_new(NULL); - g_option_context_add_main_entries(option_context, option_entries_, NULL); - - if (!g_option_context_parse (option_context, &argc, &argv, &error)) { - g_print ("%s\r\n", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - if (!options_.iface_name) options_.iface_name = g_strdup(GDIAL_IFACE_NAME_DEFAULT); - - #define MAX_RETRY 3 - for(int i=1;i<=MAX_RETRY;i++) { - iface_ipv4_address_ = gdial_plat_util_get_iface_ipv4_addr(options_.iface_name); - if (!iface_ipv4_address_) { - g_warn_msg_if_fail(FALSE, "interface %s does not have IP\r\n", options_.iface_name); - if(i >= MAX_RETRY ) - return EXIT_FAILURE; - sleep(2); - } - else { - break; - } - } - gdial_plat_init(g_main_context_default()); - - gdail_plat_register_activation_cb(server_activation_handler); - gdail_plat_register_friendlyname_cb(server_friendlyname_handler); - gdail_plat_register_registerapps_cb (server_register_application); - - SoupServer * rest_http_server = soup_server_new(NULL, NULL); - SoupServer * ssdp_http_server = soup_server_new(NULL, NULL); - SoupServer * local_rest_http_server = soup_server_new(NULL, NULL); - soup_server_add_handler(rest_http_server, "/", gdial_http_server_throttle_callback, NULL, NULL); - soup_server_add_handler(ssdp_http_server, "/", gdial_http_server_throttle_callback, NULL, NULL); - - GSocketAddress *listen_address = g_inet_socket_address_new_from_string(iface_ipv4_address_, GDIAL_REST_HTTP_PORT); - gboolean success = soup_server_listen(rest_http_server, listen_address, 0, &error); - g_object_unref (listen_address); - if (!success) { - g_printerr("%s\r\n", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - else { - listen_address = g_inet_socket_address_new_from_string(iface_ipv4_address_, GDIAL_SSDP_HTTP_PORT); - success = soup_server_listen(ssdp_http_server, listen_address, 0, &error); - g_object_unref (listen_address); - if (!success) { - g_printerr("%s\r\n", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - else { - success = soup_server_listen_local(local_rest_http_server, GDIAL_REST_HTTP_PORT, SOUP_SERVER_LISTEN_IPV4_ONLY, &error); - if (!success) { - g_printerr("%s\r\n", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - } - } - gchar uuid_str[MAX_UUID_SIZE] = {0}; - char * static_apps_location = getenv("XDIAL_STATIC_APPS_LOCATION"); - if (static_apps_location != NULL && strlen(static_apps_location)) { - g_snprintf(uuid_str, MAX_UUID_SIZE, "%s", static_apps_location); - g_print("static uuid_str :%s\r\n", uuid_str); - } else { - FILE *fuuid = fopen(UUID_FILE_PATH, "r"); - if (fuuid == NULL) { - uuid_t random_uuid; - uuid_generate_random(random_uuid); - uuid_unparse(random_uuid, uuid_str); - g_print("generated uuid_str :%s\r\n", uuid_str); - fuuid = fopen(UUID_FILE_PATH, "w"); - if (fuuid != NULL) { - fprintf(fuuid, "%s", uuid_str); - fclose(fuuid); - } - } - else { - fgets(uuid_str, sizeof(uuid_str), fuuid); - printf("Persistent uuid_str: %s", uuid_str); - fclose(fuuid); - } - } - - dial_rest_server = gdial_rest_server_new(rest_http_server,local_rest_http_server,uuid_str); - if (!options_.app_list) { - g_print("no application is enabled from cmdline \r\n"); - } - else { - g_print("app_list to be enabled from command line %s\r\n", options_.app_list); - size_t app_list_len = strlen(options_.app_list); - gchar *app_list_low = g_ascii_strdown(options_.app_list, app_list_len); - if (g_strstr_len(app_list_low, app_list_len, "netflix")) { - g_print("netflix is enabled from cmdline\r\n"); - GList *allowed_origins = g_list_prepend(NULL, ".netflix.com"); - gdial_rest_server_register_app(dial_rest_server, "Netflix", NULL, NULL, TRUE, TRUE, allowed_origins); - g_list_free(allowed_origins); - } - else { - g_print("netflix is not enabled from cmdline\r\n"); - } - - if (g_strstr_len(app_list_low, app_list_len, "youtube")) { - g_print("youtube is enabled from cmdline\r\n"); - GList *allowed_origins = g_list_prepend(NULL, ".youtube.com"); - gdial_rest_server_register_app(dial_rest_server, "YouTube", NULL, NULL, TRUE, TRUE, allowed_origins); - g_list_free(allowed_origins); - } - else { - g_print("youtube is not enabled from cmdline\r\n"); - } - - if (g_strstr_len(app_list_low, app_list_len, "youtubetv")) { - g_print("youtubetv is enabled from cmdline\r\n"); - GList *allowed_origins = g_list_prepend(NULL, ".youtube.com"); - gdial_rest_server_register_app(dial_rest_server, "YouTubeTV", NULL, NULL, TRUE, TRUE, allowed_origins); - g_list_free(allowed_origins); - } - else { - g_print("youtubetv is not enabled from cmdline\r\n"); - } - - if (g_strstr_len(app_list_low, app_list_len, "youtubekids")) { - g_print("youtubekids is enabled from cmdline\r\n"); - GList *allowed_origins = g_list_prepend(NULL, ".youtube.com"); - gdial_rest_server_register_app(dial_rest_server, "YouTubeKids", NULL, NULL, TRUE, TRUE, allowed_origins); - g_list_free(allowed_origins); - } - else { - g_print("youtubekids is not enabled from cmdline\r\n"); - } - - if (g_strstr_len(app_list_low, app_list_len, "amazoninstantvideo")) { - g_print("AmazonInstantVideo is enabled from cmdline\r\n"); - GList *allowed_origins = g_list_prepend(NULL, ".amazonprime.com"); - gdial_rest_server_register_app(dial_rest_server, "AmazonInstantVideo", NULL, NULL, TRUE, TRUE, allowed_origins); - g_list_free(allowed_origins); - } - else { - g_print("AmazonInstantVideo is not enabled from cmdline\r\n"); - } - - if (g_strstr_len(app_list_low, app_list_len, "spotify")) { - g_print("spotify is enabled from cmdline\r\n"); - GList *app_prefixes= g_list_prepend(NULL, "com.spotify"); - GList *allowed_origins = g_list_prepend(NULL, ".spotify.com"); - gdial_rest_server_register_app(dial_rest_server, "com.spotify.Spotify.TV", app_prefixes, NULL, TRUE, TRUE, allowed_origins); - g_list_free(allowed_origins); - g_list_free(app_prefixes); - } - else { - g_print("spotify is not enabled from cmdline\r\n"); - } - - if (g_strstr_len(app_list_low, app_list_len, "pairing")) { - g_print("pairing is enabled from cmdline\r\n"); - GList *allowed_origins = g_list_prepend(NULL, ".comcast.com"); - gdial_rest_server_register_app(dial_rest_server, "Pairing", NULL, NULL, TRUE, TRUE, allowed_origins); - g_list_free(allowed_origins); - } - else { - g_print("pairing is not enabled from cmdline\r\n"); - } - - if (g_strstr_len(app_list_low, app_list_len, "system")) { - g_print("system is enabled from cmdline\r\n"); - gdial_rest_server_register_app(dial_rest_server, "system", NULL, NULL, TRUE, TRUE, NULL); - } - else { - g_print("system is not enabled from cmdline\r\n"); - } - - g_free(app_list_low); - } - - g_signal_connect(dial_rest_server, "invalid-uri", G_CALLBACK(signal_handler_rest_server_invalid_uri), NULL); - g_signal_connect(dial_rest_server, "gmainloop-quit", G_CALLBACK(signal_handler_rest_server_gmainloop_quit), NULL); - g_signal_connect(dial_rest_server, "rest-enable", G_CALLBACK(signal_handler_rest_server_rest_enable), NULL); - - gdial_ssdp_new(ssdp_http_server, &options_,uuid_str); - gdial_shield_init(); - gdial_shield_server(rest_http_server); - gdial_shield_server(ssdp_http_server); - - SoupServer * servers[] = {local_rest_http_server,rest_http_server, ssdp_http_server}; - for (int i = 0; i < sizeof(servers)/sizeof(servers[0]); i++) { - GSList *uris = soup_server_get_uris(servers[i]); - for (GSList *uri = uris; uri != NULL; uri = uri->next) { - char *uri_string = soup_uri_to_string(uri->data, FALSE); - g_print("Listening on %s\n", uri_string); - g_free(uri_string); - soup_uri_free(uri->data); - } - g_slist_free(uris); - } - - /* - * Use global context - */ - loop_ = g_main_loop_new (NULL, TRUE); - signal(SIGTERM,gdial_quit_thread); - g_main_loop_run (loop_); - - for (int i = 0; i < sizeof(servers)/sizeof(servers[0]); i++) { - soup_server_disconnect(servers[i]); - g_object_unref(servers[i]); - } - - gdial_shield_term(); - gdial_ssdp_destroy(); - g_object_unref(dial_rest_server); - gdial_plat_term(); - - g_main_loop_unref(loop_); - g_option_context_free(option_context); - return 0; -} diff --git a/server/plat/CMakeLists.txt b/server/plat/CMakeLists.txt index 07690d3d..04b004a5 100644 --- a/server/plat/CMakeLists.txt +++ b/server/plat/CMakeLists.txt @@ -46,8 +46,6 @@ include_directories( ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/plat ${CMAKE_CURRENT_SOURCE_DIR} - $ENV{PKG_CONFIG_SYSROOT_DIR}/usr/include/rdk/rtcast - $ENV{PKG_CONFIG_SYSROOT_DIR}/usr/include/pxcore $ENV{PKG_CONFIG_SYSROOT_DIR}/usr/include/WPEFramework $ENV{PKG_CONFIG_SYSROOT_DIR}/usr/include/WPEFramework/core/ $ENV{PKG_CONFIG_SYSROOT_DIR}/usr/include/WPEFramework/plugins/ @@ -61,9 +59,8 @@ set (GDIAL_PLAT_LIB_SOURCE_FILES ${PROJECT_SOURCE_DIR}/plat/gdial-plat-dev.c ${PROJECT_SOURCE_DIR}/plat/gdial-plat-util.c ${PROJECT_SOURCE_DIR}/plat/gdial_app_registry.c - ${PROJECT_SOURCE_DIR}/plat/rtdial.cpp - ${PROJECT_SOURCE_DIR}/plat/rtcache.cpp - ${PROJECT_SOURCE_DIR}/plat/rtabstractservice.cpp + ${PROJECT_SOURCE_DIR}/plat/gdial.cpp + ${PROJECT_SOURCE_DIR}/plat/gdialappcache.cpp ${PROJECT_SOURCE_DIR}/plat/Module.cpp ) @@ -72,4 +69,4 @@ if(PLATFORM) endif() add_library(gdial-plat SHARED ${GDIAL_PLAT_LIB_SOURCE_FILES}) -target_link_Libraries(gdial-plat PRIVATE ${GLIB_LIBRARIES} ${GOBJECT_LIBRARIES} -lpthread -lrtRemote -lrtCore -lWPEFrameworkCore -lWPEFrameworkTracing -lWPEFrameworkDefinitions -lWPEFrameworkProtocols -lWPEFrameworkPlugins -lWPEFrameworkSecurityUtil -lIARMBus) +target_link_Libraries(gdial-plat PRIVATE ${GLIB_LIBRARIES} ${GOBJECT_LIBRARIES} -lpthread -lWPEFrameworkCore -lWPEFrameworkTracing -lWPEFrameworkDefinitions -lWPEFrameworkProtocols -lWPEFrameworkPlugins -lWPEFrameworkSecurityUtil -lIARMBus) diff --git a/server/plat/Module.h b/server/plat/Module.h index 60b2e01c..3d3f7293 100644 --- a/server/plat/Module.h +++ b/server/plat/Module.h @@ -7,4 +7,4 @@ #undef EXTERNAL -#define EXTERNAL +#define EXTERNAL \ No newline at end of file diff --git a/server/plat/gdial-os-app.h b/server/plat/gdial-os-app.h index 7800d3f4..4a0d082c 100644 --- a/server/plat/gdial-os-app.h +++ b/server/plat/gdial-os-app.h @@ -33,6 +33,14 @@ int gdial_os_application_resume(const char *app_name, int instance_id); int gdial_os_application_stop(const char *app_name, int instance_id); int gdial_os_application_state(const char *app_name, int instance_id, GDialAppState *state); +int gdial_os_application_state_changed(const char *applicationName, const char *applicationId, const char *state, const char *error); +int gdial_os_application_activation_changed(const char *activation, const char *friendlyname); +int gdial_os_application_friendlyname_changed(const char *friendlyname); +const char* gdial_os_application_get_protocol_version(); +int gdial_os_application_register_applications(void*); +void gdial_os_application_update_network_standby_mode(gboolean nwstandbyMode); +int gdial_os_application_service_notification(gboolean isNotifyRequired, void* notifier); + #ifdef __cplusplus } #endif diff --git a/server/plat/gdial-plat-app.c b/server/plat/gdial-plat-app.c index fe18b210..929d9676 100644 --- a/server/plat/gdial-plat-app.c +++ b/server/plat/gdial-plat-app.c @@ -24,7 +24,8 @@ #include "gdial-config.h" #include "gdial-plat-app.h" #include "gdial-os-app.h" -#include "rtdial.hpp" +#include "gdial.hpp" +#include "gdialservicelogging.h" static void gdial_app_state_cb_default(gint instance_id, GDialAppState state, gpointer user_data); static GMainContext *g_main_context_ = NULL; @@ -58,7 +59,7 @@ typedef struct { static GHashTable *gdial_plat_app_async_contexts = NULL; static void gdial_app_state_cb_default(gint instance_id, GDialAppState state, gpointer user_data) { - g_print("instance [%d] state = [%d]\r\n", instance_id, state); + GDIAL_LOGINFO("instance [%d] state = [%d] data = [%p]", instance_id, state, user_data); } static gboolean GSourceFunc_application_start_async_cb(gpointer user_data) { @@ -96,9 +97,11 @@ static void GDestroyNotify_async_source_destory(gpointer data) { static void GDialPlatAppAsyncContext_destroy(gpointer data) { GDialPlatAppAsyncContext *app_async_context = (GDialPlatAppAsyncContext *)data; g_warn_if_fail(app_async_context->async_gsource == 0); - g_print("GDialPlatAppAsyncContext_destroy(%s)\r\n", app_async_context->type_str); + GDIAL_LOGINFO("GDialPlatAppAsyncContext_destroy(%s)", app_async_context->type_str); g_free(app_async_context->name); + app_async_context->name = NULL; g_free(app_async_context->type_str); + app_async_context->type_str = NULL; app_async_context->user_data = NULL; if (app_async_context->type == GDIAL_PLAT_APP_ASYNC_CONTEXT_TYPE_START) { GDialPlatAppStartContext *app_start_context = (GDialPlatAppStartContext *)app_async_context; @@ -133,29 +136,30 @@ static gboolean GSourceFunc_application_stop_async_cb(gpointer user_data) { void gdail_plat_register_activation_cb(gdial_plat_activation_cb cb) { g_activation_cb = cb; - rtdail_register_activation_cb((rtdial_activation_cb)cb); + gdial_register_activation_cb((gdial_activation_cb)cb); } void gdail_plat_register_friendlyname_cb(gdial_plat_friendlyname_cb cb) { g_friendlyname_cb = cb; - rtdail_register_friendlyname_cb(cb); + gdial_register_friendlyname_cb(cb); } void gdail_plat_register_registerapps_cb(gdial_plat_registerapps_cb cb) { g_registerapps_cb = cb; - rtdail_register_registerapps_cb(cb); + gdial_register_registerapps_cb(cb); } gint gdial_plat_init(GMainContext *main_context) { g_return_val_if_fail(main_context != NULL, GDIAL_APP_ERROR_INTERNAL); g_return_val_if_fail((g_main_context_ == NULL || g_main_context_ == main_context), GDIAL_APP_ERROR_INTERNAL); + g_main_context_ = g_main_context_ref(main_context); - if(!rtdial_init(g_main_context_)) { - g_print("rtdial_init failed !!!!!\n"); - return GDIAL_APP_ERROR_INTERNAL; + if(!gdial_init(main_context)) { + GDIAL_LOGERROR("gdial_init failed !!!!!"); + return GDIAL_APP_ERROR_INTERNAL; } if (gdial_plat_app_async_contexts == NULL) { @@ -235,7 +239,7 @@ void *gdial_plat_application_stop_async(const gchar *app_name, gint instance_id, } GDialAppError gdial_plat_application_state(const gchar *app_name, gint instance_id, GDialAppState *state) { - g_print("GDIAL : Inside gdial_plat_application_state\n"); + GDIAL_LOGINFO("GDIAL : Inside gdial_plat_application_state"); g_return_val_if_fail(app_name != NULL, GDIAL_APP_ERROR_BAD_REQUEST); g_return_val_if_fail(state != NULL, GDIAL_APP_ERROR_BAD_REQUEST); g_return_val_if_fail(instance_id != GDIAL_APP_INSTANCE_NONE, GDIAL_APP_ERROR_BAD_REQUEST); @@ -275,9 +279,65 @@ void gdial_plat_application_remove_async_source(void *async_source) { } void gdial_plat_term() { - rtdial_term(); - g_main_context_unref(g_main_context_); - g_warn_if_fail(g_hash_table_size(gdial_plat_app_async_contexts) == 0); - g_hash_table_unref(gdial_plat_app_async_contexts); + gdial_term(); + if (g_main_context_) + { + g_main_context_unref(g_main_context_); + g_main_context_ = NULL; + } + if (gdial_plat_app_async_contexts) + { + g_warn_if_fail(g_hash_table_size(gdial_plat_app_async_contexts) == 0); + g_hash_table_unref(gdial_plat_app_async_contexts); + gdial_plat_app_async_contexts = NULL; + } return; } + +GDialAppError gdial_plat_application_state_changed(const char *applicationName, const char *applicationId, const char *state, const char *error) +{ + g_return_val_if_fail(applicationName != NULL, GDIAL_APP_ERROR_BAD_REQUEST); + g_return_val_if_fail(applicationId != NULL, GDIAL_APP_ERROR_BAD_REQUEST); + g_return_val_if_fail(state != NULL, GDIAL_APP_ERROR_BAD_REQUEST); + g_return_val_if_fail(error != NULL, GDIAL_APP_ERROR_BAD_REQUEST); + + return gdial_os_application_state_changed(applicationName,applicationId,state,error); +} + +GDialAppError gdial_plat_application_activation_changed(const char *activation, const char *friendlyname) +{ + g_return_val_if_fail(activation != NULL, GDIAL_APP_ERROR_BAD_REQUEST); + g_return_val_if_fail(friendlyname != NULL, GDIAL_APP_ERROR_BAD_REQUEST); + + return gdial_os_application_activation_changed(activation,friendlyname); +} + +GDialAppError gdial_plat_application_friendlyname_changed(const char *friendlyname) +{ + g_return_val_if_fail(friendlyname != NULL, GDIAL_APP_ERROR_BAD_REQUEST); + + return gdial_os_application_friendlyname_changed(friendlyname); +} + +const char* gdial_plat_application_get_protocol_version(void) +{ + return gdial_os_application_get_protocol_version(); +} + +GDialAppError gdial_plat_application_register_applications(void* appList) +{ + g_return_val_if_fail(appList != NULL, GDIAL_APP_ERROR_BAD_REQUEST); + + return gdial_os_application_register_applications(appList); +} + +void gdial_plat_application_update_network_standby_mode(gboolean nwstandby) +{ + gdial_os_application_update_network_standby_mode(nwstandby); +} + +GDialAppError gdial_plat_application_service_notification(gboolean isNotifyRequired, void* notifier) +{ + g_return_val_if_fail((notifier != NULL)||(false == isNotifyRequired), GDIAL_APP_ERROR_BAD_REQUEST); + return gdial_os_application_service_notification(isNotifyRequired,notifier); +} diff --git a/server/plat/gdial-plat-dev.c b/server/plat/gdial-plat-dev.c index d9761ded..277a7cf7 100644 --- a/server/plat/gdial-plat-dev.c +++ b/server/plat/gdial-plat-dev.c @@ -19,16 +19,11 @@ #include #include "gdial-plat-dev.h" -#include "libIBus.h" -#include "pwrMgr.h" #include #include -IARM_Bus_PWRMgr_PowerState_t m_powerstate = IARM_BUS_PWRMGR_POWERSTATE_STANDBY; -static int m_sleeptime = 1; -static bool m_is_restart_req = false; - static gdial_plat_dev_nwstandbymode_cb g_nwstandbymode_cb = NULL; +static gdial_plat_dev_powerstate_cb g_powerstate_cb = NULL; const char * gdial_plat_dev_get_manufacturer() { return g_getenv("GDIAL_DEV_MANUFACTURER"); @@ -38,110 +33,31 @@ const char * gdial_plat_dev_get_model() { return g_getenv("GDIAL_DEV_MODEL"); } -void gdial_plat_dev_power_mode_change(const char *owner, IARM_EventId_t eventId, void *data, size_t len) -{ - if ((strcmp(owner, IARM_BUS_PWRMGR_NAME) == 0) && ( eventId == IARM_BUS_PWRMGR_EVENT_MODECHANGED )) { - IARM_Bus_PWRMgr_EventData_t *param = (IARM_Bus_PWRMgr_EventData_t *)data; - m_powerstate = param->data.state.newState; - if(m_powerstate == IARM_BUS_PWRMGR_POWERSTATE_ON) { - m_sleeptime = 1; - if (m_is_restart_req) { - //xdial restart to work in deepsleep wakeup - printf("systemctl restart xdial.service result: %d\n", system("systemctl restart xdial.service")); - m_is_restart_req = false; - } - } - else if(m_powerstate == IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP) { - m_sleeptime = 3; - //After DEEPSLEEP, restart xdial again for next transition. - m_is_restart_req = true; - } - printf("gdial_plat_dev_power_mode_change new power state: %d m_sleeptime:%d \n ",m_powerstate,m_sleeptime ); - } -} - -void gdial_plat_dev_nwstandby_mode_change(const char *owner, IARM_EventId_t eventId, void *data, size_t len) +void gdial_plat_dev_nwstandby_mode_change(gboolean NetworkStandbyMode) { - if ((strcmp(owner, IARM_BUS_PWRMGR_NAME) == 0) && ( eventId == IARM_BUS_PWRMGR_EVENT_NETWORK_STANDBYMODECHANGED )) { - IARM_Bus_PWRMgr_EventData_t *param = (IARM_Bus_PWRMgr_EventData_t *)data; - if(g_nwstandbymode_cb) g_nwstandbymode_cb(param->data.bNetworkStandbyMode); - printf("gdial_plat_dev_nwstandby_mode_change new nwstandby_mode :%d \n ",param->data.bNetworkStandbyMode); - } -} - -bool gdial_plat_dev_initialize() { - IARM_Bus_Init("xdialserver"); - IARM_Bus_Connect(); - IARM_Result_t res; - - IARM_Bus_RegisterEventHandler(IARM_BUS_PWRMGR_NAME,IARM_BUS_PWRMGR_EVENT_MODECHANGED, gdial_plat_dev_power_mode_change); - IARM_Bus_RegisterEventHandler(IARM_BUS_PWRMGR_NAME,IARM_BUS_PWRMGR_EVENT_NETWORK_STANDBYMODECHANGED, gdial_plat_dev_nwstandby_mode_change); - - IARM_Bus_PWRMgr_GetPowerState_Param_t param; - res = IARM_Bus_Call(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_API_GetPowerState, - (void *)¶m, sizeof(param)); - if (res == IARM_RESULT_SUCCESS) { - m_powerstate = param.curState; - } - - printf("gdial_plat_dev_initialize m_powerstate :%d \n",m_powerstate); - return true; -} - -bool gdial_plat_dev_deinitialize() { - IARM_Bus_Disconnect(); - IARM_Bus_Term(); - return true; + if(g_nwstandbymode_cb) g_nwstandbymode_cb(NetworkStandbyMode); + printf("gdial_plat_dev_nwstandby_mode_change new nwstandby_mode :%d",NetworkStandbyMode); } bool gdial_plat_dev_set_power_state_on() { - bool ret = true; - if(IARM_BUS_PWRMGR_POWERSTATE_ON != m_powerstate) { - printf("gdial_plat_dev_set_power_state_on set power state to ON m_sleeptime:%d\n",m_sleeptime); - IARM_Bus_PWRMgr_SetPowerState_Param_t param; - param.newState = IARM_BUS_PWRMGR_POWERSTATE_ON; - IARM_Result_t res = IARM_Bus_Call(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_API_SetPowerState, - (void *)¶m, sizeof(param)); - if(res != IARM_RESULT_SUCCESS) { - ret = false; - } - sleep(m_sleeptime); + if(g_powerstate_cb) { + g_powerstate_cb("ON"); } - return ret; + return true; } bool gdial_plat_dev_set_power_state_off() { - bool ret = true; - if(IARM_BUS_PWRMGR_POWERSTATE_ON == m_powerstate) { - printf("gdial_plat_dev_set_power_state_off set power state STANDBY \n"); - IARM_Bus_PWRMgr_SetPowerState_Param_t param; - param.newState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY; - IARM_Result_t res = IARM_Bus_Call(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_API_SetPowerState, - (void *)¶m, sizeof(param)); - if(res != IARM_RESULT_SUCCESS) { - ret = false; - } + if(g_powerstate_cb) { + g_powerstate_cb("STANDBY"); } - return ret; + return true; } bool gdial_plat_dev_toggle_power_state() { - bool ret = true; - IARM_Bus_PWRMgr_SetPowerState_Param_t param; - if(IARM_BUS_PWRMGR_POWERSTATE_ON != m_powerstate) { - param.newState = IARM_BUS_PWRMGR_POWERSTATE_ON; + if(g_powerstate_cb) { + g_powerstate_cb("TOGGLE"); } - else - { - param.newState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY; - } - printf("gdial_plat_dev_toggle_power_state new power state: %d \n", param.newState); - IARM_Result_t res = IARM_Bus_Call(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_API_SetPowerState, - (void *)¶m, sizeof(param)); - if(res != IARM_RESULT_SUCCESS) { - ret = false; - } - return ret; + return true; } void gdail_plat_dev_register_nwstandbymode_cb(gdial_plat_dev_nwstandbymode_cb cb) @@ -149,15 +65,7 @@ void gdail_plat_dev_register_nwstandbymode_cb(gdial_plat_dev_nwstandbymode_cb cb g_nwstandbymode_cb = cb; } -bool gdial_plat_dev_get_nwstandby_mode() { - bool nw_standby_mode = false; - IARM_Bus_PWRMgr_NetworkStandbyMode_Param_t param; - IARM_Result_t res = IARM_Bus_Call(IARM_BUS_PWRMGR_NAME, - IARM_BUS_PWRMGR_API_GetNetworkStandbyMode, (void *)¶m, - sizeof(param)); - if(res == IARM_RESULT_SUCCESS) { - nw_standby_mode = param.bStandbyMode; - } - printf("gdial_plat_dev_get_nwstandby_mode nwstandby_mode:%d \n",nw_standby_mode); - return nw_standby_mode; -} +void gdail_plat_dev_register_powerstate_cb(gdial_plat_dev_powerstate_cb cb) +{ + g_powerstate_cb = cb; +} \ No newline at end of file diff --git a/server/plat/gdial-plat-util.c b/server/plat/gdial-plat-util.c index 0046908d..a8c1400c 100644 --- a/server/plat/gdial-plat-util.c +++ b/server/plat/gdial-plat-util.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include "gdial-plat-util.h" +#include "gdialservicelogging.h" const char * gdial_plat_util_get_iface_ipv4_addr(const char *ifname) { const char *result = NULL; @@ -72,3 +74,58 @@ const char * gdial_plat_util_get_iface_mac_addr(const char *ifname) { return result; } + +static inline void sync_stdout() +{ + if (getenv("SYNC_STDOUT")) + setvbuf(stdout, NULL, _IOLBF, 0); +} + +static int gDefaultLogLevel = INFO_LEVEL; + +void gdial_plat_util_logger_init(void) +{ + const char *level = getenv("GDIAL_LIBRARY_DEFAULT_LOG_LEVEL"); + + sync_stdout(); + + if (level) + { + gDefaultLogLevel = (atoi(level)); + } +} + +void gdial_plat_util_set_loglevel(gdial_plat_util_LogLevel level) +{ + gDefaultLogLevel = level; +} + +void gdial_plat_util_log(gdial_plat_util_LogLevel level, + const char *func, + const char *file, + int line, + int threadID, + const char *format, ...) +{ + const char *levelMap[] = {"FATAL", "ERROR", "WARN", "INFO", "VERBOSE", "TRACE"}; + const short kFormatMessageSize = 4096; + char formatted[kFormatMessageSize]; + + if (((FATAL_LEVEL != level)&&(ERROR_LEVEL != level))&& + (gDefaultLogLevel < level)){ + return; + } + + va_list argptr; + va_start(argptr, format); + vsnprintf(formatted, kFormatMessageSize, format, argptr); + va_end(argptr); + fprintf(stderr, "[GDIAL][%d] %s [%s:%d] %s: %s \n", + (int)syscall(SYS_gettid), + levelMap[level], + basename(file), + line, + func, + formatted); + fflush(stderr); +} \ No newline at end of file diff --git a/server/plat/gdial.cpp b/server/plat/gdial.cpp new file mode 100644 index 00000000..b9c92266 --- /dev/null +++ b/server/plat/gdial.cpp @@ -0,0 +1,874 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +#include +#include +#include +#include +#include +#include + +#include "Module.h" +#include +#include +#include +#include +#include +#include +#include +#include "gdial-app.h" +#include "gdial-plat-dev.h" +#include "gdial-os-app.h" +#include "gdial-config.h" +#include "gdialappcache.hpp" +#include "gdial.hpp" +#include "gdial_app_registry.h" +#include "gdialservicelogging.h" + +static GMainContext *main_context_ = nullptr; +static int gdialInitCompleted = 0; +//cache +GDialAppStatusCache* AppCache = nullptr; +static gdial_activation_cb g_activation_cb = NULL; +static gdial_friendlyname_cb g_friendlyname_cb = NULL; +static gdial_registerapps_cb g_registerapps_cb = NULL; + +#define DIAL_MAX_NUM_OF_APPS (64) +#define DIAL_MAX_NUM_OF_APP_NAMES (64) +#define DIAL_MAX_NUM_OF_APP_PREFIXES (64) +#define DIAL_MAX_NUM_OF_APP_CORS (64) + +class GDialCastObject +{ +public: + GDialCastObject(){} + ~GDialCastObject() {} + + GDialErrorCode applicationStateChanged(const char *applicationName, const char *applicationId, const char *state, const char *error) + { + GDIAL_LOGTRACE("Entering ..."); + GDialErrorCode reterror = GDIAL_CAST_ERROR_INTERNAL; + AppInfo* AppObj = new AppInfo(applicationName,applicationId,state,error); + if ((nullptr != AppObj) && (nullptr != AppCache)) + { + GDIAL_LOGINFO("AppName : %s AppID : %s State : %s Error : %s", + AppObj->appName.c_str(), + AppObj->appId.c_str(), + AppObj->appState.c_str(), + AppObj->appError.c_str()); + if ( AppCacheError_OK == AppCache->UpdateAppStatusCache(AppObj)) + { + reterror = GDIAL_CAST_ERROR_NONE; + } + } + GDIAL_LOGTRACE("Exiting ..."); + return reterror; + } + + GDialErrorCode friendlyNameChanged(const char* friendlyname) + { + GDIAL_LOGTRACE("Entering ..."); + GDialErrorCode error = GDIAL_CAST_ERROR_INTERNAL; + if( g_friendlyname_cb && friendlyname ) + { + GDIAL_LOGINFO("GDialCastObject::friendlyNameChanged :%s ",friendlyname); + g_friendlyname_cb(friendlyname); + error = GDIAL_CAST_ERROR_NONE; + } + GDIAL_LOGTRACE("Exiting ..."); + return error; + } + + GDialErrorCode registerApplications(void* appList) + { + GDIAL_LOGTRACE("Entering ..."); + RegisterAppEntryList* appConfigList = static_cast(appList); + GList *gAppList = NULL; + int i = 0; + + for (RegisterAppEntry* appEntry : appConfigList->getValues()) + { + GList *gAppPrefxes = nullptr, + *allowed_origins = nullptr; + if (DIAL_MAX_NUM_OF_APPS<=i) + { + break; + } + GDIAL_LOGINFO("Application: %d ", i); + gAppPrefxes = g_list_prepend (gAppPrefxes, g_strdup(appEntry->prefixes.c_str())); + GDIAL_LOGINFO("%s, ", appEntry->prefixes.c_str()); + GDIAL_LOGINFO(""); + + allowed_origins = g_list_prepend (allowed_origins, g_strdup(appEntry->cors.c_str())); + GDIAL_LOGINFO("%s, ", appEntry->cors.c_str()); + GDIAL_LOGINFO(""); + + GHashTable *gProperties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + std::string appAllowStop = appEntry->allowStop ? "true" : "false"; + g_hash_table_insert(gProperties,g_strdup("allowStop"),g_strdup(appAllowStop.c_str())); + GDIAL_LOGINFO("allowStop: %s", appAllowStop.c_str()); + GDIAL_LOGINFO(""); + + GDialAppRegistry* app_registry = gdial_app_registry_new( g_strdup(appEntry->Names.c_str()), + gAppPrefxes, + gProperties, + TRUE, + TRUE, + allowed_origins); + gAppList = g_list_prepend (gAppList, app_registry); + GDIAL_LOGINFO("%s, ", appEntry->Names.c_str()); + GDIAL_LOGINFO(""); + ++i; + } + + //int appListSize = g_list_length (gAppList); + if( g_registerapps_cb ) { + GDIAL_LOGINFO("calling register_applications callback "); + g_registerapps_cb(gAppList); + } + /*Free the applist*/ + if (gAppList) { + g_list_free (gAppList); + gAppList = NULL; + } + GDIAL_LOGINFO("[%p] Freeing appConfigList",appConfigList); + delete appConfigList; + appConfigList = nullptr; + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_CAST_ERROR_NONE; + } + + const char* getProtocolVersion() + { + GDIAL_LOGINFO("GDIAL_PROTOCOL_VERSION_STR[%s]",GDIAL_PROTOCOL_VERSION_STR); + return GDIAL_PROTOCOL_VERSION_STR; + } + + GDialErrorCode activationChanged(std::string status, std::string friendlyName) + { + GDIAL_LOGTRACE("Entering ..."); + GDialErrorCode error = GDIAL_CAST_ERROR_INTERNAL; + GDIAL_LOGINFO("status: %s friendlyname: %s ",status.c_str(),friendlyName.c_str()); + if( g_activation_cb ) + { + if(!strcmp(status.c_str(), "true")) + { + g_activation_cb(1,friendlyName.c_str()); + } + else + { + g_activation_cb(0,friendlyName.c_str()); + } + GDIAL_LOGINFO("status: %s g_activation_cb :%p",status.c_str(), g_activation_cb); + error = GDIAL_CAST_ERROR_NONE; + } + GDIAL_LOGTRACE("Exiting ..."); + return error; + } + + void updateNetworkStandbyMode(gboolean nwstandbyMode) + { + GDIAL_LOGTRACE("Entering ..."); + gdial_plat_dev_nwstandby_mode_change(nwstandbyMode); + GDIAL_LOGTRACE("Exiting ..."); + } + + GDialErrorCode launchApplication(const char* appName, const char* args) + { + GDIAL_LOGTRACE("Entering ..."); + std::string applicationName = "", + parameter = ""; + if (nullptr!=appName) applicationName = appName; + if (nullptr!=args) parameter = args; + + GDIAL_LOGINFO("App[%s] param[%s] observer[%p]",applicationName.c_str(),parameter.c_str(),m_observer); + if (nullptr!=m_observer) + { + m_observer->onApplicationLaunchRequest(applicationName,parameter); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_CAST_ERROR_NONE; + } + + GDialErrorCode launchApplicationWithLaunchParams(const char *appName, const char *argPayload, const char *argQueryString, const char *argAdditionalDataUrl) + { + std::string applicationName = "", + payLoad = "", + queryString = "", + additionalDataUrl = ""; + GDIAL_LOGTRACE("Entering ..."); + + if (nullptr!=appName) applicationName = appName; + if (nullptr!=argPayload) payLoad = argPayload; + if (nullptr!=argQueryString) queryString = argQueryString; + if (nullptr!=argAdditionalDataUrl) additionalDataUrl = argAdditionalDataUrl; + + GDIAL_LOGINFO("App[%s] payload[%s] query_string[%s] additional_data_url[%s]observer[%p]", + applicationName.c_str(), + payLoad.c_str(), + queryString.c_str(), + additionalDataUrl.c_str(), + m_observer); + if (nullptr!=m_observer) + { + m_observer->onApplicationLaunchRequestWithLaunchParam( applicationName, + payLoad, + queryString, + additionalDataUrl ); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_CAST_ERROR_NONE; + } + + GDialErrorCode hideApplication(const char* appName, const char* appID) + { + GDIAL_LOGTRACE("Entering ..."); + std::string applicationName = "", + applicationId = ""; + if (nullptr!=appName) applicationName = appName; + if (nullptr!=appID) applicationId = appID; + + GDIAL_LOGINFO("App[%s]ID[%s]observer[%p]",applicationName.c_str(),applicationId.c_str(),m_observer); + if (nullptr!=m_observer) + { + m_observer->onApplicationHideRequest(applicationName,applicationId); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_CAST_ERROR_NONE; + } + + GDialErrorCode resumeApplication(const char* appName, const char* appID) + { + GDIAL_LOGTRACE("Entering ..."); + std::string applicationName = "", + applicationId = ""; + + if (nullptr!=appName) applicationName = appName; + if (nullptr!=appID) applicationId = appID; + + GDIAL_LOGINFO("App[%s]ID[%s]observer[%p]",applicationName.c_str(),applicationId.c_str(),m_observer); + if (nullptr!=m_observer) + { + m_observer->onApplicationResumeRequest(applicationName,applicationId); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_CAST_ERROR_NONE; + } + + GDialErrorCode stopApplication(const char* appName, const char* appID) + { + GDIAL_LOGTRACE("Entering ..."); + std::string applicationName = "", + applicationId = ""; + + if (nullptr!=appName) applicationName = appName; + if (nullptr!=appID) applicationId = appID; + + GDIAL_LOGINFO("App[%s]ID[%s]observer[%p]",applicationName.c_str(),applicationId.c_str(),m_observer); + if (nullptr!=m_observer) + { + m_observer->onApplicationStopRequest(applicationName,applicationId); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_CAST_ERROR_NONE; + } + + GDialErrorCode getApplicationState(const char* appName, const char* appID) + { + GDIAL_LOGTRACE("Entering ..."); + std::string applicationName = "", + applicationId = ""; + + if (nullptr!=appName) applicationName = appName; + if (nullptr!=appID) applicationId = appID; + + GDIAL_LOGINFO("App[%s]ID[%s]observer[%p]",applicationName.c_str(),applicationId.c_str(),m_observer); + if (nullptr!=m_observer) + { + m_observer->onApplicationStateRequest(applicationName,applicationId); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_CAST_ERROR_NONE; + } + + void setService(GDialNotifier* service) + { + m_observer = service; + } +private: + GDialNotifier *m_observer; +}; + +GDialCastObject* GDialObjHandle = nullptr; + +void gdial_register_activation_cb(gdial_activation_cb cb) +{ + g_activation_cb = cb; +} + +void gdial_register_friendlyname_cb(gdial_friendlyname_cb cb) +{ + g_friendlyname_cb = cb; +} + +void gdial_register_registerapps_cb(gdial_registerapps_cb cb) +{ + g_registerapps_cb = cb; +} + +bool gdial_init(GMainContext *context) +{ + bool returnValue = false; + + GDIAL_LOGTRACE("Entering ..."); + if(gdialInitCompleted) + { + GDIAL_LOGTRACE("Exiting ..."); + return true; + } + else + { + AppCache = new GDialAppStatusCache(); + if (nullptr == AppCache) + { + GDIAL_LOGERROR("GDialAppStatusCache Failed"); + } + else + { + GDialObjHandle = new GDialCastObject(); + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialCastObject Failed"); + delete AppCache; + AppCache = nullptr; + } + else + { + main_context_ = g_main_context_ref(context); + gdialInitCompleted = 1; + returnValue = true; + } + } + } + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; +} + +void gdial_term() +{ + GDIAL_LOGTRACE("Entering ..."); + if (GDialObjHandle) + { + delete GDialObjHandle; + GDialObjHandle = nullptr; + } + + if (main_context_) + { + g_main_context_unref(main_context_); + main_context_ = NULL; + } + + if (AppCache) + { + delete AppCache; + AppCache = nullptr; + } + gdialInitCompleted = 0; + GDIAL_LOGTRACE("Exiting ..."); +} + +/* + * The maximum DIAL payload accepted per the DIAL 1.6.1 specification. + */ +#define DIAL_MAX_PAYLOAD (4096) + +/* + * The maximum additionalDataUrl length + */ + +#define DIAL_MAX_ADDITIONALURL (1024) + +map parse_query(const char* query_string) { + if (!query_string) return {}; + char *unescaped = g_uri_unescape_string(query_string, nullptr); + // if unescaping failed due to invalid characters in the string, g_uri_unescape_segment returns null + // e.g. '%' character should be encoded as '%25'; we still fallback to undecoded string in such case + std::string query {unescaped ? unescaped : query_string}; + if (unescaped) { + g_free(unescaped); + unescaped = nullptr; + } + + map ret; + size_t begin = 0, end; + + while (begin < query.size()) { + end = query.find('&', begin); + if (end == string::npos) end = query.size(); + string next {query.substr(begin, end - begin)}; + size_t split = next.find('='); + if (split > 0 && split != string::npos) { + ret[next.substr(0, split)] = next.substr(split + 1,string::npos); + } + begin = end + 1; + } + return ret; +} + +int gdial_os_application_start(const char *app_name, const char *payload, const char *query_string, const char *additional_data_url, int *instance_id) { + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("App launch req: appName: %s query: [%s], payload: [%s], additionalDataUrl [%s] instance[%p]", + app_name, query_string, payload, additional_data_url,instance_id); + + if (strcmp(app_name,"system") == 0) { + auto parsed_query{parse_query(query_string)}; + if (parsed_query["action"] == "sleep") { + const char *system_key = getenv("SYSTEM_SLEEP_REQUEST_KEY"); + if (system_key && parsed_query["key"] != system_key) { + GDIAL_LOGINFO("system app request to change device to sleep mode, key comparison failed: user provided '%s'", parsed_query["key"].c_str()); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGINFO("system app request to change device to sleep mode"); + gdial_plat_dev_set_power_state_off(); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; + } + else if (parsed_query["action"] == "togglepower") { + const char *system_key = getenv("SYSTEM_SLEEP_REQUEST_KEY"); + if (system_key && parsed_query["key"] != system_key) { + GDIAL_LOGINFO("system app request to toggle the power state, key comparison failed: user provided '%s'", parsed_query["key"].c_str()); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGINFO("system app request to toggle the power state "); + gdial_plat_dev_toggle_power_state(); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; + } + } + gdial_plat_dev_set_power_state_on(); + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDialErrorCode ret = GDialObjHandle->launchApplicationWithLaunchParams(app_name, payload, query_string, additional_data_url); + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGERROR("GDialObjHandle.launchApplication failed!!! Error=%x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} + +using namespace WPEFramework; +JSONRPC::LinkType *netflixRemoteObject = NULL; +JSONRPC::LinkType *controllerRemoteObject = NULL; +#define MAX_LENGTH 1024 + +#ifdef NETFLIX_CALLSIGN_0 +const std::string nfx_callsign = "Netflix-0"; +#else +const std::string nfx_callsign = "Netflix"; +#endif + +std::string GetCurrentState() { + std::cout<<"GetCurrentState()"< pluginResponse; + Core::SystemInfo::SetEnvironment(_T("THUNDER_ACCESS"), (_T("127.0.0.1:9998"))); + unsigned char buffer[MAX_LENGTH] = {0}; + + //Obtaining controller object + if (NULL == controllerRemoteObject) { + int ret = GetSecurityToken(MAX_LENGTH,buffer); + if(ret<0) + { + controllerRemoteObject = new JSONRPC::LinkType(std::string()); + } else { + string sToken = (char*)buffer; + string query = "token=" + sToken; + GDIAL_LOGINFO("Security token = %s ",query.c_str()); + controllerRemoteObject = new JSONRPC::LinkType(std::string(), false, query); + } + } + std::string nfxstatus = "status@" + nfx_callsign; + if(controllerRemoteObject->Get(1000, _T(nfxstatus), pluginResponse) == Core::ERROR_NONE) + { + GDIAL_LOGINFO("Obtained netflix status = %s",nfxstatus.c_str()); + Core::JSON::ArrayType::Iterator index(pluginResponse.Elements()); + while (index.Next() == true) { + netflixState = index.Current().JSONState.Data(); + } //end of while loop + } //end of if case for querrying + GDIAL_LOGINFO("Netflix State = %s",netflixState.c_str()); + return netflixState; +} +void stop_netflix() +{ + JsonObject parameters; + JsonObject response; + parameters["callsign"] = nfx_callsign; + GDIAL_LOGTRACE("Entering ..."); + if (Core::ERROR_NONE == controllerRemoteObject->Invoke("deactivate", parameters, response)) { + std::cout << "Netflix is stoppped" << std::endl; + } else { + std::cout << "Netflix could not be deactivated" << std::endl; + } + GDIAL_LOGTRACE("Exiting ..."); +} + +int gdial_os_application_stop(const char *app_name, int instance_id) { + bool enable_stop = false; + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("AppName = %s appID = %s",app_name,std::to_string(instance_id).c_str()); + if((strcmp(app_name,"system") == 0)){ + GDIAL_LOGINFO("delete not supported for system app return GDIAL_APP_ERROR_BAD_REQUEST"); + return GDIAL_APP_ERROR_BAD_REQUEST; + } + std::string State = AppCache->SearchAppStatusInCache(app_name); + /* always to issue stop request to have a failsafe strategy */ + if (0 && State != "running") + { + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_BAD_REQUEST; + } + + std::ifstream netflixStopFile("/opt/enableXdialNetflixStop"); + if (netflixStopFile) + { + netflixStopFile.close(); + enable_stop = true; + } + + if ( strcmp(app_name,"Netflix") == 0 && enable_stop ) { + GDIAL_LOGINFO("NTS TESTING: force shutdown Netflix thunder plugin"); + stop_netflix(); + sleep(1); + } + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDialErrorCode ret = GDialObjHandle->stopApplication(app_name,std::to_string(instance_id).c_str()); + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.stopApplication failed!!! Error=%x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} + +int gdial_os_application_hide(const char *app_name, int instance_id) +{ + GDIAL_LOGTRACE("Entering ..."); + if((strcmp(app_name,"system") == 0)){ + GDIAL_LOGINFO("system app already in hidden state"); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; + } + #if 0 + GDIAL_LOGINFO("gdial_os_application_hide-->stop: appName = %s appID = %s",app_name,std::to_string(instance_id).c_str()); + std::string State = AppCache->SearchAppStatusInCache(app_name); + if (0 && State != "running") { + return GDIAL_APP_ERROR_BAD_REQUEST; + } + // Report Hide request not implemented for Youtube for ceritifcation requirement. + if(strncmp("YouTube", app_name, 7) != 0) { + GDialErrorCode ret = GDialObjHandle->stopApplication(app_name,std::to_string(instance_id).c_str()); + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.stopApplication failed!!! Error=%x",ret); + return GDIAL_APP_ERROR_INTERNAL; + } + return GDIAL_APP_ERROR_NONE; + } + return GDIAL_APP_ERROR_NONE; + #else + GDIAL_LOGINFO("gdial_os_application_hide: appName = %s appID = %s",app_name,std::to_string(instance_id).c_str()); + std::string State = AppCache->SearchAppStatusInCache(app_name); + if (State != "running") + { + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_BAD_REQUEST; + } + + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + + GDialErrorCode ret = GDialObjHandle->hideApplication(app_name,std::to_string(instance_id).c_str()); + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.hideApplication failed!!! Error=%x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; + #endif +} + +int gdial_os_application_resume(const char *app_name, int instance_id) { + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("appName = %s appID = %s",app_name,std::to_string(instance_id).c_str()); + + if((strcmp(app_name,"system") == 0)){ + GDIAL_LOGINFO("system app can not be resume"); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; + } + std::string State = AppCache->SearchAppStatusInCache(app_name); + if (State == "running") + { + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_BAD_REQUEST; + } + + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + + GDialErrorCode ret = GDialObjHandle->resumeApplication(app_name,std::to_string(instance_id).c_str()); + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.resumeApplication failed!!! Error=%x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} + +int gdial_os_application_state(const char *app_name, int instance_id, GDialAppState *state) { + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("App = %s Id = %d",app_name,instance_id); + if((strcmp(app_name,"system") == 0)){ + *state = GDIAL_APP_STATE_HIDE; + GDIAL_LOGINFO("getApplicationState: AppState = suspended "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; + } + std::string State = AppCache->SearchAppStatusInCache(app_name); + GDIAL_LOGINFO("getApplicationState: AppState = %s ",State.c_str()); + /* + * return cache, but also trigger a refresh + */ + if((strcmp(app_name,"system") != 0) &&( true || State == "NOT_FOUND")) { + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + + GDialErrorCode ret = GDialObjHandle->getApplicationState(app_name,NULL); + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.getApplicationState failed!!! Error: %x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + } + + if (State == "running") { + *state = GDIAL_APP_STATE_RUNNING; + } + else if (State == "suspended" || State == "hidden") { + *state = GDIAL_APP_STATE_HIDE; + } + else { + *state = GDIAL_APP_STATE_STOPPED; + } + + char* enable_stop = getenv("ENABLE_NETFLIX_STOP"); + if ( enable_stop != NULL ) { + if (strcmp(app_name,"Netflix") == 0 && strcmp(enable_stop,"true") == 0) { + std::string app_state = GetCurrentState(); + GDIAL_LOGINFO("Presence of Netflix thunder plugin state = %s to confirm state", app_state.c_str()); + if (app_state == "deactivated") { + *state = GDIAL_APP_STATE_STOPPED; + GDIAL_LOGINFO("app [%s] state converted to [%d]", app_name, *state); + } + else if (app_state == "suspended") + { + *state = GDIAL_APP_STATE_HIDE; + GDIAL_LOGINFO("app [%s] state converted to [%d]", app_name, *state); + } + else { + *state = GDIAL_APP_STATE_RUNNING; + } + } + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} + +int gdial_os_application_state_changed(const char *applicationName, const char *applicationId, const char *state, const char *error) +{ + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("appName: %s appId: [%s], state: [%s], error [%s]",applicationName, applicationId, state, error); + + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + + GDialErrorCode ret = GDialObjHandle->applicationStateChanged(applicationName,applicationId,state,error); + + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.applicationStateChanged failed!!! Error=%x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} + +int gdial_os_application_activation_changed(const char *activation, const char *friendlyname) +{ + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("activation: %s friendlyname: [%s]",activation, friendlyname); + + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + + GDialErrorCode ret = GDialObjHandle->activationChanged(activation,friendlyname); + + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.friendlyNameChanged failed!!! Error=%x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} + +int gdial_os_application_friendlyname_changed(const char *friendlyname) +{ + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("friendlyname: [%s]",friendlyname); + + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + + GDialErrorCode ret = GDialObjHandle->friendlyNameChanged(friendlyname); + + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.friendlyNameChanged failed!!! Error=%x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} + +const char* gdial_os_application_get_protocol_version(void) +{ + GDIAL_LOGTRACE("Entering ..."); + + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_PROTOCOL_VERSION_STR; + } + GDIAL_LOGTRACE("Exiting ..."); + return (GDialObjHandle->getProtocolVersion()); +} + +int gdial_os_application_register_applications(void* appList) +{ + GDIAL_LOGTRACE("Entering ..."); + + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + + GDialErrorCode ret = GDialObjHandle->registerApplications(appList); + + if (ret != GDIAL_CAST_ERROR_NONE) { + GDIAL_LOGINFO("GDialObjHandle.registerApplications failed!!! Error=%x",ret); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} + +void gdial_os_application_update_network_standby_mode(gboolean nwstandbymode) +{ + GDIAL_LOGTRACE("Entering ..."); + GDIAL_LOGINFO("nwstandbymode:%u",nwstandbymode); + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!! "); + } + else + { + GDialObjHandle->updateNetworkStandbyMode(nwstandbymode); + } + GDIAL_LOGTRACE("Exiting ..."); +} + +int gdial_os_application_service_notification(gboolean isNotifyRequired, void* notifier) +{ + GDIAL_LOGTRACE("Entering ..."); + if (nullptr == GDialObjHandle) + { + GDIAL_LOGERROR("GDialObjHandle NULL!!!"); + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_INTERNAL; + } + + GDIAL_LOGINFO("isNotifyRequired[%u]",isNotifyRequired); + if (isNotifyRequired) + { + GDialObjHandle->setService(static_cast(notifier)); + } + else + { + GDialObjHandle->setService(nullptr); + } + GDIAL_LOGTRACE("Exiting ..."); + return GDIAL_APP_ERROR_NONE; +} diff --git a/server/plat/rtdial.hpp b/server/plat/gdial.hpp similarity index 55% rename from server/plat/rtdial.hpp rename to server/plat/gdial.hpp index a3634719..2ade960b 100644 --- a/server/plat/rtdial.hpp +++ b/server/plat/gdial.hpp @@ -17,8 +17,8 @@ * limitations under the License. */ -#ifndef _RT_DIAL_H_ -#define _RT_DIAL_H_ +#ifndef _GDIAL_H_ +#define _GDIAL_H_ #include @@ -26,14 +26,28 @@ extern "C" { #endif -bool rtdial_init(GMainContext *context); -void rtdial_term(); -typedef void (*rtdial_activation_cb)(bool, const gchar *); -typedef void (*rtdial_friendlyname_cb)(const gchar *); -typedef void (*rtdial_registerapps_cb)(gpointer); -void rtdail_register_activation_cb(rtdial_activation_cb cb); -void rtdail_register_friendlyname_cb(rtdial_friendlyname_cb cb); -void rtdail_register_registerapps_cb(rtdial_registerapps_cb cb); +/* + ** Error strings + ** + */ +typedef enum _GDialErrorCode +{ + GDIAL_CAST_ERROR_NONE, + GDIAL_CAST_ERROR_FORBIDDEN, + GDIAL_CAST_ERROR_UNAVAILABLE, + GDIAL_CAST_ERROR_INVALID, + GDIAL_CAST_ERROR_INTERNAL +} +GDialErrorCode; + +bool gdial_init(GMainContext *context); +void gdial_term(); +typedef void (*gdial_activation_cb)(bool, const gchar *); +typedef void (*gdial_friendlyname_cb)(const gchar *); +typedef void (*gdial_registerapps_cb)(gpointer); +void gdial_register_activation_cb(gdial_activation_cb cb); +void gdial_register_friendlyname_cb(gdial_friendlyname_cb cb); +void gdial_register_registerapps_cb(gdial_registerapps_cb cb); #ifdef __cplusplus } diff --git a/server/plat/gdial_app_registry.c b/server/plat/gdial_app_registry.c index 9cf05f18..41a50553 100644 --- a/server/plat/gdial_app_registry.c +++ b/server/plat/gdial_app_registry.c @@ -20,14 +20,15 @@ */ #include - +#include "gdialservicelogging.h" #define GDIAL_STR_ENDS_WITH(s1, s2) ((s1 != NULL) && (s2 != NULL) && ((strlen(s2) == 0) || (g_str_has_suffix(s1, s2)))) void gdial_app_regstry_dispose (GDialAppRegistry *app_registry) { g_return_if_fail(app_registry != NULL); - printf ("freeing app name:%s\n", app_registry->name); + GDIAL_LOGINFO("freeing app name:%s", app_registry->name); g_free(app_registry->name); + app_registry->name = NULL; g_list_free_full(app_registry->allowed_origins, g_free); g_list_free_full(app_registry->app_prefixes, g_free); if (app_registry->properties) { @@ -82,7 +83,7 @@ GDialAppRegistry* gdial_app_registry_new (const gchar *app_name, const GList *ap app_registry->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_iter_init(&prop_iter, properties); while (g_hash_table_iter_next(&prop_iter, &key, &value)) { - g_print("inside register app properties key:%s value:%s\n",(gchar*)key, (gchar*)value); + GDIAL_LOGINFO("inside register app properties key:%s value:%s",(gchar*)key, (gchar*)value); g_hash_table_insert(app_registry->properties,g_strdup(key),g_strdup(value)); } } diff --git a/server/plat/gdialappcache.cpp b/server/plat/gdialappcache.cpp new file mode 100644 index 00000000..30caecbe --- /dev/null +++ b/server/plat/gdialappcache.cpp @@ -0,0 +1,115 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include "gdialappcache.hpp" + +std::string GDialAppStatusCache::Netflix_AppCacheId = "DialNetflix"; +std::string GDialAppStatusCache::Youtube_AppCacheId = "DialYoutube"; + +std::string GDialAppStatusCache :: getAppCacheId(const char* app_name) +{ + if (nullptr == app_name) + { + return std::string(""); + } + if(!strcmp(app_name,"Netflix")) + return GDialAppStatusCache::Netflix_AppCacheId; + else if(!strcmp(app_name,"YouTube")) + return GDialAppStatusCache::Youtube_AppCacheId; + else + { + GDIAL_LOGINFO("default case : App Name is id"); + return app_name; + } +} + +void GDialAppStatusCache :: setAppCacheId(std::string app_name,std::string id) +{ + GDIAL_LOGTRACE("Entering ..."); + if(!strcmp(app_name.c_str(),"Netflix")) + { + GDialAppStatusCache::Netflix_AppCacheId = id; + GDIAL_LOGINFO("App cache Id of Netflix updated to %s",GDialAppStatusCache::Netflix_AppCacheId.c_str()); + } + else if(!strcmp(app_name.c_str(),"YouTube")) + { + GDialAppStatusCache::Youtube_AppCacheId = id; + GDIAL_LOGINFO("App cache Id of Youtube updated to %s",GDialAppStatusCache::Youtube_AppCacheId.c_str()); + } + else + { + GDIAL_LOGINFO("Default App Name - id not cached "); + } + GDIAL_LOGTRACE("Exiting ..."); +} + +AppCacheErrorCodes GDialAppStatusCache::UpdateAppStatusCache(AppInfo* appEntry) +{ + GDIAL_LOGTRACE("Entering ..."); + AppCacheErrorCodes err; + GDIAL_LOGINFO("APPCache: AppName[%s] AppID[%s] AppState[%s] Error[%s]", + appEntry->appName.c_str(), + appEntry->appId.c_str(), + appEntry->appState.c_str(), + appEntry->appError.c_str()); + + std::string id = getAppCacheId(appEntry->appName.c_str()); + + if(doIdExist(id)) { + GDIAL_LOGINFO("erasing old data"); + err = ObjectCache->erase(id); + } + err = ObjectCache->insert(id,appEntry); + GDIAL_LOGTRACE("Exiting ..."); + return err; +} + +std::string GDialAppStatusCache::SearchAppStatusInCache(const char* app_name) +{ + GDIAL_LOGTRACE("Entering ..."); + std::string state = "NOT_FOUND"; + + std::string id = getAppCacheId(app_name); + if(doIdExist(id)) + { + AppInfo* appEntry = ObjectCache->findObject(id); + + state = appEntry->appState; + GDIAL_LOGINFO("APPCache: App Name[%s] AppID[%s] Error[%s]", + appEntry->appName.c_str(), + appEntry->appId.c_str(), + appEntry->appError.c_str()); + } + GDIAL_LOGINFO("App State = ",state.c_str()); + GDIAL_LOGTRACE("Exiting ..."); + return state; +} + +bool GDialAppStatusCache::doIdExist(std::string id) +{ + bool returnValue = false; + GDIAL_LOGTRACE("Entering [%p] ...",ObjectCache); + if(ObjectCache->touch(id) == AppCacheError_OK) + { + returnValue = true; + } + GDIAL_LOGINFO("IdExist [%s]",returnValue ? "true" : "false"); + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; +} diff --git a/server/plat/rtcache.hpp b/server/plat/gdialappcache.hpp similarity index 53% rename from server/plat/rtcache.hpp rename to server/plat/gdialappcache.hpp index c5c7ff98..900a3c8d 100644 --- a/server/plat/rtcache.hpp +++ b/server/plat/gdialappcache.hpp @@ -17,33 +17,46 @@ * limitations under the License. */ -#ifndef _RT_CACHE_H_ -#define _RT_CACHE_H_ +#ifndef _GDIAL_APPCACHE_H_ +#define _GDIAL_APPCACHE_H_ -#include "rtRemoteObjectCache.hpp" -#include "rtObject.h" -#include "rtRemote.h" +#include "gdialobjCacheHelper.hpp" #include #include #include #include #include +#include "gdialservicecommon.h" +#include "gdialservicelogging.h" using namespace std; -class rtAppStatusCache : public rtObject +class GDialAppStatusCache { public: - rtAppStatusCache(rtRemoteEnvironment* env) {ObjectCache = new rtRemoteObjectCache(env);}; - ~rtAppStatusCache() {delete(ObjectCache); }; - std::string getAppCacheId(const char *app_name); - void setAppCacheId(const char *app_name,std::string id); - rtError UpdateAppStatusCache(rtValue app_status); - std::string SearchAppStatusInCache(const char *app_name); + GDialAppStatusCache() { + ObjectCache = new GDialObjectCacheHelper(); + GDIAL_LOGINFO("ObjectCache[%p]",ObjectCache); + }; + ~GDialAppStatusCache() { + GDIAL_LOGINFO("ObjectCache[%p]",ObjectCache); + delete ObjectCache; + ObjectCache = nullptr; + }; + std::string getAppCacheId(const char* app_name); + void setAppCacheId(std::string app_name,std::string id); + AppCacheErrorCodes UpdateAppStatusCache(AppInfo* appEntry); + std::string SearchAppStatusInCache(const char* app_name); bool doIdExist(std::string id); + void setService(GDialNotifier* service) + { + m_observer = service; + } + private: - rtRemoteObjectCache* ObjectCache; + GDialObjectCacheHelper* ObjectCache; + GDialNotifier* m_observer; static std::string Netflix_AppCacheId; static std::string Youtube_AppCacheId; }; diff --git a/server/plat/gdialobjCacheHelper.hpp b/server/plat/gdialobjCacheHelper.hpp new file mode 100644 index 00000000..4bbbb368 --- /dev/null +++ b/server/plat/gdialobjCacheHelper.hpp @@ -0,0 +1,133 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef __GDIAL_OBJECT_CACHE_H__ +#define __GDIAL_OBJECT_CACHE_H__ + +#include +#include +#include +#include +#include +#include "gdialservicelogging.h" + +enum AppCacheErrorCodes { + AppCacheError_OK, + AppCacheError_NOT_FOUND, + AppCacheError_DUPLICATE_ENTRY, + AppCacheError_NULL_ENTRY +}; + +class AppInfo +{ + public: + std::string appName; + std::string appId; + std::string appState; + std::string appError; + + AppInfo(const std::string& name, const std::string& id, const std::string& state, const std::string& error) + : appName(name), + appId(id), + appState(state), + appError(error), + lastTouched(std::chrono::steady_clock::now()) {} + std::chrono::steady_clock::time_point lastTouched; +}; + +class GDialObjectCacheHelper +{ +public: + GDialObjectCacheHelper(){ } + ~GDialObjectCacheHelper() { + for (auto& entry : objects) { + if (entry.second) + { + delete entry.second; + entry.second = nullptr; + } + } + } + + AppInfo* findObject(const std::string& appName) const + { + GDIAL_LOGTRACE("Entering ..."); + auto it = objects.find(appName); + if (it != objects.end()) + { + GDIAL_LOGTRACE("Exiting ..."); + return it->second; + } + GDIAL_LOGTRACE("Exiting ..."); + return nullptr; + } + + AppCacheErrorCodes insert(std::string id, AppInfo* entry) + { + GDIAL_LOGTRACE("Entering ..."); + AppCacheErrorCodes returnValue = AppCacheError_NULL_ENTRY; + if (nullptr != entry) + { + auto result = objects.emplace(id, entry); + if (!result.second) + { + returnValue = AppCacheError_DUPLICATE_ENTRY; + } + else + { + returnValue = AppCacheError_OK; + } + } + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; + } + + AppCacheErrorCodes touch(const std::string& appname) + { + AppCacheErrorCodes returnValue = AppCacheError_NOT_FOUND; + GDIAL_LOGTRACE("Entering [%s]...",appname.c_str()); + auto it = objects.find(appname); + if (it != objects.end()) + { + GDIAL_LOGTRACE("Available [%s] [%p]",appname.c_str(),it->second); + it->second->lastTouched = std::chrono::steady_clock::now(); + returnValue = AppCacheError_OK; + } + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; + } + + AppCacheErrorCodes erase(const std::string& appname) + { + AppCacheErrorCodes returnValue = AppCacheError_NOT_FOUND; + GDIAL_LOGTRACE("Entering ..."); + auto it = objects.find(appname); + if (it != objects.end()) + { + delete it->second; + objects.erase(it); + returnValue = AppCacheError_OK; + } + GDIAL_LOGTRACE("Exiting ..."); + return returnValue; + } +private: + std::unordered_map objects; +}; +#endif diff --git a/server/plat/rtRemoteObjectCache.hpp b/server/plat/rtRemoteObjectCache.hpp deleted file mode 100644 index 2eac9c2c..00000000 --- a/server/plat/rtRemoteObjectCache.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * If not stated otherwise in this file or this component's Licenses.txt file the - * following copyright and licenses apply: - * - * Copyright 2019 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef __RT_OBJECT_CACHE_H__ -#define __RT_OBJECT_CACHE_H__ - -#include - -#include -#include -#include -#include - -class rtRemoteEnvironment; - -class rtRemoteObjectCache -{ -public: - rtRemoteObjectCache(rtRemoteEnvironment* env) - : m_env(env) - { } - - rtObjectRef findObject(std::string const& id); - rtFunctionRef findFunction(std::string const& id); - rtError insert(std::string const& id, rtObjectRef const& ref); - rtError insert(std::string const& id, rtFunctionRef const& ref); - rtError touch(std::string const& id, std::chrono::steady_clock::time_point now); - rtError erase(std::string const& id); - rtError markUnevictable(std::string const& id, bool state); - rtError removeUnused(); - rtError clear(); - -private: - rtRemoteEnvironment* m_env; -}; - -#endif diff --git a/server/plat/rtabstractservice.cpp b/server/plat/rtabstractservice.cpp deleted file mode 100644 index 591d0624..00000000 --- a/server/plat/rtabstractservice.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * If not stated otherwise in this file or this component's Licenses.txt file the - * following copyright and licenses apply: - * - * Copyright 2019 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -#include "rtabstractservice.hpp" -rtAbstractService::rtAbstractService(rtString serviceName) - : mServiceName(serviceName) - , mApiVersion(1), mEmit() -{ - mEmit = new rtEmit(); -} -rtAbstractService::~rtAbstractService() -{ -} -void rtAbstractService::setName(rtString n) -{ - mServiceName = n; -} -void rtAbstractService::setApiVersion(uint32_t v) -{ - mApiVersion = v; -} -rtError rtAbstractService::notify(const rtString& eventName, rtObjectRef e) -{ - mEmit.send(eventName, e); - return RT_OK; -} -rtError rtAbstractService::bye() -{ - printf("%s : Sending bye event!!!\n",mServiceName.cString()); - rtObjectRef e = new rtMapObject; - e.set("serviceName",mServiceName.cString()); - notify("bye", e); - return RT_OK; -} -#include -rtError rtAbstractService::name(rtString& v) const -{ - v = mServiceName; - return RT_OK; -} -rtError rtAbstractService::version(uint32_t& v) const -{ - v = mApiVersion; - return RT_OK; -} -rtError rtAbstractService::quirks(rtValue& v) const -{ - //rt services will override this method if they have any quirks - rtObjectRef e = new rtMapObject; - v = e; - return RT_OK; -} -rtError rtAbstractService::addListener(rtString eventName, const rtFunctionRef &f) -{ - return mEmit->addListener(eventName, f); -} -rtError rtAbstractService::delListener(rtString eventName, const rtFunctionRef &f) -{ - return mEmit->delListener(eventName, f); -} -rtError rtAbstractService::ping(const rtObjectRef ¶ms) -{ - printf("%s : ping!!!\n",mServiceName.cString()); - return RT_OK; -} -rtDefineObject(rtAbstractService, rtObject); -rtDefineProperty(rtAbstractService, name); -rtDefineProperty(rtAbstractService, version); -rtDefineProperty(rtAbstractService, quirks); -rtDefineMethod(rtAbstractService, addListener); -rtDefineMethod(rtAbstractService, delListener); -rtDefineMethod(rtAbstractService, ping); diff --git a/server/plat/rtabstractservice.hpp b/server/plat/rtabstractservice.hpp deleted file mode 100644 index 2cb74e15..00000000 --- a/server/plat/rtabstractservice.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * If not stated otherwise in this file or this component's Licenses.txt file the - * following copyright and licenses apply: - * - * Copyright 2019 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef _RT_ABSTRACT_SERVICE_H_ -#define _RT_ABSTRACT_SERVICE_H_ - -#include -#include - -class rtAbstractService : public rtObject -{ -public: - rtDeclareObject(rtAbstractService, rtObject); - rtReadOnlyProperty(name, name, rtString); - rtReadOnlyProperty(version, version, uint32_t); - rtReadOnlyProperty(quirks, quirks, rtValue); - rtMethod1ArgAndNoReturn("ping", ping, rtObjectRef); - rtMethod2ArgAndNoReturn("on", addListener, rtString, rtFunctionRef); - rtMethod2ArgAndNoReturn("delListener", delListener, rtString, rtFunctionRef); - rtError name(rtString& v) const; - rtError version(uint32_t& v) const; - rtError ping(const rtObjectRef& params); - rtError bye(); - virtual rtError quirks(rtValue& v) const; - virtual rtError addListener(rtString eventName, const rtFunctionRef &f); - virtual rtError delListener(rtString eventName, const rtFunctionRef &f); -protected: - rtAbstractService(rtString serviceName); - void setName(rtString n); - void setApiVersion(uint32_t v); - rtError notify(const rtString& eventName, rtObjectRef e); -public: - virtual ~rtAbstractService(); -private: - rtString mServiceName; - uint32_t mApiVersion; - rtEmitRef mEmit; -}; -#endif diff --git a/server/plat/rtcache.cpp b/server/plat/rtcache.cpp deleted file mode 100644 index 0f82f938..00000000 --- a/server/plat/rtcache.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * If not stated otherwise in this file or this component's Licenses.txt file the - * following copyright and licenses apply: - * - * Copyright 2019 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#include "rtcache.hpp" - -std::string rtAppStatusCache::Netflix_AppCacheId = "DialNetflix"; -std::string rtAppStatusCache::Youtube_AppCacheId = "DialYoutube"; - -std::string rtAppStatusCache :: getAppCacheId(const char *app_name) -{ - printf("RTCACHE : %s\n",__FUNCTION__); - - if(!strcmp(app_name,"Netflix")) - return rtAppStatusCache::Netflix_AppCacheId; - else if(!strcmp(app_name,"YouTube")) - return rtAppStatusCache::Youtube_AppCacheId; - else - { - printf("default case : App Name is id\n"); - return app_name; - } - -} - -void rtAppStatusCache :: setAppCacheId(const char *app_name,std::string id) -{ - printf("RTCACHE : %s\n",__FUNCTION__); - if(!strcmp(app_name,"Netflix")) - { - rtAppStatusCache::Netflix_AppCacheId = id; - printf("App cache Id of Netflix updated to %s\n",rtAppStatusCache::Netflix_AppCacheId.c_str()); - } - else if(!strcmp(app_name,"YouTube")) - { - rtAppStatusCache::Youtube_AppCacheId = id; - printf("App cache Id of Youtube updated to %s\n",rtAppStatusCache::Youtube_AppCacheId.c_str()); - } - else - { - printf("Default App Name - id not cached \n"); - } - -} - -rtError rtAppStatusCache::UpdateAppStatusCache(rtValue app_status) -{ - printf("RTCACHE : %s\n",__FUNCTION__); - - rtError err; - rtObjectRef temp = app_status.toObject(); - - std::string App_name {temp.get("applicationName").cString()}; - printf("RTCACHE : %s App Name = %s App ID = %s App State = %s Error = %s\n",__FUNCTION__,App_name.c_str(),temp.get("applicationId").cString(),temp.get("state").cString(),temp.get("error").cString()); - - std::string id = getAppCacheId(App_name.c_str()); - - if(doIdExist(id)) { - printf("erasing old data\n"); - err = ObjectCache->erase(id); - } - - err = ObjectCache->insert(id,temp); - return err; -} - -std::string rtAppStatusCache::SearchAppStatusInCache(const char *app_name) -{ - printf("RTCACHE : %s\n",__FUNCTION__); - - std::string id = getAppCacheId(app_name); - if(doIdExist(id)) - { - rtObjectRef state_param = ObjectCache->findObject(id); - - std::string state {state_param.get("state").cString()}; - printf("RTCACHE : %s App Name = %s App ID = %s Error = %s ",__FUNCTION__,state_param.get("applicationName").cString(),state_param.get("applicationId").cString(),state_param.get("error").cString()); - printf("App State = %s\n",state.c_str()); - return state; - } - - return "NOT_FOUND"; -} - -bool rtAppStatusCache::doIdExist(std::string id) -{ - printf("RTCACHE : %s : \n",__FUNCTION__); - auto now = std::chrono::steady_clock::now(); - - if(ObjectCache->touch(id,now)!= RT_OK) - { - printf("False\n"); - return false; - } - printf("True\n"); - return true; -} diff --git a/server/plat/rtcast.hpp b/server/plat/rtcast.hpp deleted file mode 100644 index 97e0bcd5..00000000 --- a/server/plat/rtcast.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * If not stated otherwise in this file or this component's Licenses.txt file the - * following copyright and licenses apply: - * - * Copyright 2019 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef _RT_CAST_H_ -#define _RT_CAST_H_ - -#include "rtabstractservice.hpp" -#include "rtRemote.h" -#include "rtObject.h" -#include "rtError.h" - -/* - * Error strings - */ -enum CastError { - CAST_ERROR_NONE, - CAST_ERROR_FORBIDDEN, - CAST_ERROR_UNAVAILABLE, - CAST_ERROR_INVALID, - CAST_ERROR_INTERNAL -}; - -struct rtCastError { - rtCastError(rtError errRt = RT_OK, CastError errCast = CAST_ERROR_NONE) : errRt(errRt),errCast(errCast){} - rtError errRt; - CastError errCast; -}; - -#define RTCAST_ERROR_NONE(v) ((v).errRt==RT_OK && (v).errCast==CAST_ERROR_NONE) -#define RTCAST_ERROR_RT(v) ((v).errRt) -#define RTCAST_ERROR_CAST(v) ((v).errCast) - - -class rtCastRemoteObject: public rtAbstractService -{ - rtDeclareObject(rtCastRemoteObject, rtAbstractService); - -public: - rtCastRemoteObject(rtString SERVICE_NAME) : rtAbstractService(SERVICE_NAME){} - ~rtCastRemoteObject() {} - - rtMethod1ArgAndNoReturn("onApplicationStateChanged", applicationStateChanged, rtObjectRef); - rtMethod1ArgAndNoReturn("onActivationChanged", activationChanged, rtObjectRef); - rtMethod1ArgAndNoReturn("onFriendlyNameChanged", friendlyNameChanged, rtObjectRef); - rtMethod1ArgAndNoReturn("onRegisterApplications", registerApplications, rtObjectRef); - rtMethodNoArgAndReturn("getProtocolVersion", getProtocolVersion, rtString); - virtual rtError applicationStateChanged(const rtObjectRef& params){ printf("applicationStateChanged rtCastRemoteObject");return RT_OK;} - virtual rtError activationChanged (const rtObjectRef& params){ printf("activationChanged rtCastRemoteObject");return RT_OK;} - virtual rtError friendlyNameChanged (const rtObjectRef& params){ printf("friendlyNameChanged rtCastRemoteObject");return RT_OK;} - virtual rtError registerApplications (const rtObjectRef& params){ printf("registerApplications rtCastRemoteObject");return RT_OK;} - virtual rtError getProtocolVersion(rtString& result){ printf("getProtocolVersion rtCastRemoteObject");return RT_OK;} - /* - * rtCast implementation should emit these events: - * onApplicationLaunchRequest - * onApplicationStopRequest - * onApplicationHideRequest - * onApplicationResumeRequest - * onApplicationStatusRequest - * For details please reference XCAST spec - */ -}; - -#endif diff --git a/server/plat/rtdial.cpp b/server/plat/rtdial.cpp deleted file mode 100644 index 6a275830..00000000 --- a/server/plat/rtdial.cpp +++ /dev/null @@ -1,698 +0,0 @@ -/* - * If not stated otherwise in this file or this component's Licenses.txt file the - * following copyright and licenses apply: - * - * Copyright 2019 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - - -#include -#include -#include -#include -#include - -#include "Module.h" -#include -#include -#include -#include -#include -#include -#include -#include "gdial-app.h" -#include "gdial-plat-dev.h" -#include "gdial-os-app.h" -#include "gdial-config.h" -#include "rtcast.hpp" -#include "rtcache.hpp" -#include "rtdial.hpp" -#include "gdial_app_registry.h" - -rtRemoteEnvironment* env; -static GSource *remoteSource = nullptr; -static GMainContext *main_context_ = nullptr; -static int INIT_COMPLETED = 0; -//cache -rtAppStatusCache* AppCache; -static rtdial_activation_cb g_activation_cb = NULL; -static rtdial_friendlyname_cb g_friendlyname_cb = NULL; -static rtdial_registerapps_cb g_registerapps_cb = NULL; - -#define DIAL_MAX_NUM_OF_APPS (64) -#define DIAL_MAX_NUM_OF_APP_NAMES (64) -#define DIAL_MAX_NUM_OF_APP_PREFIXES (64) -#define DIAL_MAX_NUM_OF_APP_CORS (64) - -class rtDialCastRemoteObject : public rtCastRemoteObject -{ - -public: - - rtDialCastRemoteObject(rtString SERVICE_NAME): rtCastRemoteObject(SERVICE_NAME) {printf("rtDialCastRemoteObject() const %s\n",SERVICE_NAME.cString());} - - ~rtDialCastRemoteObject() {} - - rtError applicationStateChanged(const rtObjectRef& params) { - printf("RTDIAL: rtDialCastRemoteObject::applicationStateChanged \n"); - rtObjectRef AppObj = new rtMapObject; - AppObj = params; - rtString app, id, state, error; - AppObj.get("applicationName",app); - AppObj.get("applicationId",id); - AppObj.get("state",state); - AppObj.get("error",error); - printf("applicationStateChanged AppName : %s AppID : %s State : %s Error : %s\n",app.cString(),id.cString(),state.cString(),error.cString()); - AppCache->UpdateAppStatusCache(rtValue(AppObj)); - return RT_OK; - } - - rtError friendlyNameChanged(const rtObjectRef& params) { - rtObjectRef AppObj = new rtMapObject; - AppObj = params; - rtString friendlyName; - AppObj.get("friendlyname",friendlyName); - printf("RTDIAL: rtDialCastRemoteObject::friendlyNameChanged :%s \n",friendlyName.cString()); - if( g_friendlyname_cb ) - { - g_friendlyname_cb(friendlyName.cString()); - } - return RT_OK; - } - - rtError registerApplications(const rtObjectRef& params) { - printf("RTDIAL : rtDialCastRemoteObject::registerApplications\n"); - rtString appFirstName; - - rtObjectRef AppObj = params; - GList *gAppList = NULL; - for(int i = 0 ; i< (DIAL_MAX_NUM_OF_APPS); i ++) { - rtObjectRef appInfo; - int err = AppObj.get(i,appInfo); - if(err == RT_OK) { - printf("Application: %d \n", i); - - rtObjectRef appPrefxes; - GList *gAppPrefxes = NULL; - err = appInfo.get("prefixes",appPrefxes); - if(err == RT_OK) { - for(int i = 0 ; i< (DIAL_MAX_NUM_OF_APP_PREFIXES); i ++) { - rtString appPrefx; - err = appPrefxes.get(i, appPrefx); - if(err == RT_OK) { - gAppPrefxes = g_list_prepend (gAppPrefxes, g_strdup(appPrefx.cString())); - printf("%s, ", appPrefx.cString()); - } - else { - break; - } - } - printf("\n"); - } - - rtObjectRef appCors; - GList *allowed_origins = NULL; - err = appInfo.get("cors", appCors); - if(err == RT_OK) { - for(int i = 0 ; i< (DIAL_MAX_NUM_OF_APP_CORS); i ++) { - rtString appCor; - err = appCors.get(i,appCor); - if(err == RT_OK) { - allowed_origins = g_list_prepend (allowed_origins, g_strdup(appCor.cString())); - printf("%s, ", appCor.cString()); - } - else { - break; - } - } - printf("\n"); - } - - rtObjectRef appProp; - GHashTable *gProperties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - err = appInfo.get("properties", appProp); - if (RT_OK == err) { - rtString appAllowStop; - err = appProp.get("allowStop", appAllowStop); - if (RT_OK == err) { - g_hash_table_insert(gProperties,g_strdup("allowStop"),g_strdup(appAllowStop.cString())); - printf("allowStop: %s", appAllowStop.cString()); - } - printf("\n"); - } - - rtObjectRef appNames; - err = appInfo.get("Names",appNames); - if(err == RT_OK) { - for(int i = 0 ; i< (DIAL_MAX_NUM_OF_APP_NAMES); i ++) { - rtString appName; - err = appNames.get(i,appName); - if(err == RT_OK) { - GDialAppRegistry* app_registry = gdial_app_registry_new ( - g_strdup(appName.cString()), - gAppPrefxes, - gProperties, - TRUE, - TRUE, - allowed_origins); - gAppList = g_list_prepend (gAppList, app_registry); - printf("%s, ", appName.cString()); - } - else { - break; - } - } - printf("\n"); - } - - } - } - - if( g_registerapps_cb ) { - printf("RTDIAL: rtDialCastRemoteObject:: calling register_applications callback \n"); - g_registerapps_cb(gAppList); - } - - /*Free the applist*/ - if (gAppList) { - g_list_free (gAppList); - gAppList = NULL; - } - return RT_OK; - } - - rtError getProtocolVersion(rtString& result) { - printf("RTDIAL : rtDialCastRemoteObject::getProtocolVersion \n"); - result = GDIAL_PROTOCOL_VERSION_STR; - return RT_OK; - } - - rtError activationChanged(const rtObjectRef& params) { - rtObjectRef AppObj = new rtMapObject; - AppObj = params; - rtString status; - rtString friendlyName; - AppObj.get("activation",status); - AppObj.get("friendlyname",friendlyName); - printf("RTDIAL: rtDialCastRemoteObject::activationChanged status: %s friendlyname: %s \n",status.cString(),friendlyName.cString()); - if( g_activation_cb ) - { - if(!strcmp(status.cString(), "true")) - { - g_activation_cb(1,friendlyName.cString()); - } - else - { - g_activation_cb(0,friendlyName.cString()); - } - printf("RTDIAL: rtDialCastRemoteObject:: status: %s g_activation_cb :%p \n",status.cString(), g_activation_cb); - } - return RT_OK; - } - - rtCastError launchApplication(const char* appName, const char* args) { - printf("RTDIAL: rtDialCastRemoteObject::launchApplication App:%s args:%s\n",appName,args); - rtObjectRef AppObj = new rtMapObject; - AppObj.set("applicationName",appName); - AppObj.set("parameters",args); - AppObj.set("isUrl","true"); - - rtCastError error(RT_OK,CAST_ERROR_NONE); - RTCAST_ERROR_RT(error) = notify("onApplicationLaunchRequest",AppObj); - return error; - } - - rtCastError launchApplicationWithLaunchParams(const char *appName, const char *argPayload, const char *argQueryString, const char *argAdditionalDataUrl) { - printf("RTDIAL: rtDialCastRemoteObject::launchApplicationWithLaunchParams App:%s payload:%s query_string:%s additional_data_url: %s\n", - appName, argPayload, argQueryString, argAdditionalDataUrl); - rtObjectRef AppObj = new rtMapObject; - AppObj.set("applicationName",appName); - AppObj.set("payload",argPayload); - AppObj.set("query",argQueryString); - AppObj.set("addDataUrl",argAdditionalDataUrl); - AppObj.set("isUrl","false"); - - rtCastError error(RT_OK,CAST_ERROR_NONE); - RTCAST_ERROR_RT(error) = notify("onApplicationLaunchRequest",AppObj); - return error; - } - - rtCastError hideApplication(const char* appName, const char* appID) { - printf("RTDIAL: rtDialCastRemoteObject::hideApplication App:%s ID:%s\n",appName,appID); - rtObjectRef AppObj = new rtMapObject; - AppObj.set("applicationName",appName); - if(appID != NULL) - AppObj.set("applicationId",appID); - - rtCastError error(RT_OK,CAST_ERROR_NONE); - RTCAST_ERROR_RT(error) = notify("onApplicationHideRequest",AppObj); - return error; - } - - rtCastError resumeApplication(const char* appName, const char* appID) { - printf("RTDIAL: rtDialCastRemoteObject::resumeApplication App:%s ID:%s\n",appName,appID); - rtObjectRef AppObj = new rtMapObject; - AppObj.set("applicationName",appName); - if(appID != NULL) - AppObj.set("applicationId",appID); - - rtCastError error(RT_OK,CAST_ERROR_NONE); - RTCAST_ERROR_RT(error) = notify("onApplicationResumeRequest",AppObj); - return error; - } - - rtCastError stopApplication(const char* appName, const char* appID) { - printf("RTDIAL: rtDialCastRemoteObject::stopApplication App:%s ID:%s\n",appName,appID); - rtObjectRef AppObj = new rtMapObject; - AppObj.set("applicationName",appName); - if(appID != NULL) - AppObj.set("applicationId",appID); - - rtCastError error(RT_OK,CAST_ERROR_NONE); - RTCAST_ERROR_RT(error) = notify("onApplicationStopRequest",AppObj); - return error; - } - - rtCastError getApplicationState(const char* appName, const char* appID) { - printf("RTDIAL: rtDialCastRemoteObject::getApplicationState App:%s ID:%s\n",appName,appID); - rtObjectRef AppObj = new rtMapObject; - AppObj.set("applicationName",appName); - if(appID != NULL) - AppObj.set("applicationId",appID); - - rtCastError error(RT_OK,CAST_ERROR_NONE); - RTCAST_ERROR_RT(error) = notify("onApplicationStateRequest",AppObj); - return error; - } - - -private: - -}; - -rtDefineObject(rtCastRemoteObject, rtAbstractService); -rtDefineMethod(rtCastRemoteObject, applicationStateChanged); -rtDefineMethod(rtCastRemoteObject, activationChanged); -rtDefineMethod(rtCastRemoteObject, friendlyNameChanged); -rtDefineMethod(rtCastRemoteObject, registerApplications); -rtDefineMethod(rtCastRemoteObject, getProtocolVersion); - -rtDialCastRemoteObject* DialObj; - -static gboolean pumpRemoteObjectQueue(gpointer data) -{ -// printf("### %s : %s : %d ### \n",__FILE__,__func__,__LINE__); - rtError err; - GSource *source = (GSource *)data; - do { - g_source_set_ready_time(source, -1); - err = rtRemoteProcessSingleItem(); - } while (err == RT_OK); - if (err != RT_OK && err != RT_ERROR_QUEUE_EMPTY) { -// printf("RTDIAL: rtRemoteProcessSingleItem() returned %s", rtStrError(err)); - return G_SOURCE_CONTINUE; - } - return G_SOURCE_CONTINUE; -} - -static GSource *attachRtRemoteSource() -{ -// printf("### %s : %s : %d ###\n",__FILE__,__func__,__LINE__); - static GSourceFuncs g_sourceFuncs = - { - nullptr, // prepare - nullptr, // check - [](GSource *source, GSourceFunc callback, gpointer data) -> gboolean // dispatch - { - if (g_source_get_ready_time(source) != -1) { - g_source_set_ready_time(source, -1); - return callback(data); - } - return G_SOURCE_CONTINUE; - }, - nullptr, // finalize - nullptr, // closure_callback - nullptr, // closure_marshall - }; - GSource *source = g_source_new(&g_sourceFuncs, sizeof(GSource)); - g_source_set_name(source, "RT Remote Event dispatcher"); - g_source_set_can_recurse(source, TRUE); - g_source_set_callback(source, pumpRemoteObjectQueue, source, nullptr); - g_source_set_priority(source, G_PRIORITY_HIGH); - - rtError e = rtRemoteRegisterQueueReadyHandler(env, [](void *data) -> void { - GSource *source = (GSource *)data; - g_source_set_ready_time(source, 0); - }, source); - - if (e != RT_OK) - { - printf("RTDIAL: Failed to register queue handler: %d", e); - g_source_destroy(source); - return nullptr; - } - g_source_attach(source, main_context_); - return source; -} - -void rtdail_register_activation_cb(rtdial_activation_cb cb) -{ - g_activation_cb = cb; -} - -void rtdail_register_friendlyname_cb(rtdial_friendlyname_cb cb) -{ - g_friendlyname_cb = cb; -} - -void rtdail_register_registerapps_cb(rtdial_registerapps_cb cb) -{ - g_registerapps_cb = cb; -} - -bool rtdial_init(GMainContext *context) { - if(INIT_COMPLETED) - return true; - rtError err; - const char* objName; - - gdial_plat_dev_initialize(); - env = rtEnvironmentGetGlobal(); - err = rtRemoteInit(env); - -//cache - AppCache = new rtAppStatusCache(env); - - printf("RTDIAL: %s\n",__func__); - - if (err != RT_OK){ - printf("RTDIAL: rtRemoteinit Failed\n"); - return false; - } - - main_context_ = g_main_context_ref(context); - remoteSource = attachRtRemoteSource(); - - if (!remoteSource) - printf("RTDIAL: Failed to attach rt remote source"); - - objName = getenv("PX_WAYLAND_CLIENT_REMOTE_OBJECT_NAME"); - if(!objName) objName = "com.comcast.xdialcast"; - - DialObj = new rtDialCastRemoteObject("com.comcast.xdialcast"); - err = rtRemoteRegisterObject(env, objName, DialObj); - if (err != RT_OK){ - printf("RTDIAL: rtRemoteRegisterObject for %s failed! error:%s !\n", objName, rtStrError(err)); - return false; - } - - INIT_COMPLETED =1; - return true; -} - -void rtdial_term() { - printf("RTDIAL: %s \n",__FUNCTION__); - - gdial_plat_dev_deinitialize(); - g_main_context_unref(main_context_); - g_source_unref(remoteSource); - - DialObj->bye(); - delete (AppCache); - rtError e = rtRemoteShutdown(); - if (e != RT_OK) - { - printf("RTDIAL: rtRemoteShutdown failed: %s \n", rtStrError(e)); - } - //delete(DialObj); -} - -/* - * The maximum DIAL payload accepted per the DIAL 1.6.1 specification. - */ -#define DIAL_MAX_PAYLOAD (4096) - -/* - * The maximum additionalDataUrl length - */ - -#define DIAL_MAX_ADDITIONALURL (1024) - -map parse_query(const char* query_string) { - if (!query_string) return {}; - char *unescaped = g_uri_unescape_string(query_string, nullptr); - // if unescaping failed due to invalid characters in the string, g_uri_unescape_segment returns null - // e.g. '%' character should be encoded as '%25'; we still fallback to undecoded string in such case - std::string query {unescaped ? unescaped : query_string}; - if (unescaped) { - g_free(unescaped); - unescaped = nullptr; - } - - map ret; - size_t begin = 0, end; - - while (begin < query.size()) { - end = query.find('&', begin); - if (end == string::npos) end = query.size(); - string next {query.substr(begin, end - begin)}; - size_t split = next.find('='); - if (split > 0 && split != string::npos) { - ret[next.substr(0, split)] = next.substr(split + 1,string::npos); - } - begin = end + 1; - } - return ret; -} - -int gdial_os_application_start(const char *app_name, const char *payload, const char *query_string, const char *additional_data_url, int *instance_id) { - printf("RTDIAL gdial_os_application_start : Application launch request: appName: %s query: [%s], payload: [%s], additionalDataUrl [%s]\n", - app_name, query_string, payload, additional_data_url); - - if (strcmp(app_name,"system") == 0) { - auto parsed_query{parse_query(query_string)}; - if (parsed_query["action"] == "sleep") { - const char *system_key = getenv("SYSTEM_SLEEP_REQUEST_KEY"); - if (system_key && parsed_query["key"] != system_key) { - printf("RTDIAL: system app request to change device to sleep mode, key comparison failed: user provided '%s'\n", parsed_query["key"].c_str()); - return GDIAL_APP_ERROR_INTERNAL; - } - printf("RTDIAL: system app request to change device to sleep mode\n"); - gdial_plat_dev_set_power_state_off(); - return GDIAL_APP_ERROR_NONE; - } - else if (parsed_query["action"] == "togglepower") { - const char *system_key = getenv("SYSTEM_SLEEP_REQUEST_KEY"); - if (system_key && parsed_query["key"] != system_key) { - printf("RTDIAL: system app request to toggle the power state, key comparison failed: user provided '%s'\n", parsed_query["key"].c_str()); - return GDIAL_APP_ERROR_INTERNAL; - } - printf("RTDIAL: system app request to toggle the power state \n"); - gdial_plat_dev_toggle_power_state(); - return GDIAL_APP_ERROR_NONE; - } - } - gdial_plat_dev_set_power_state_on(); - rtCastError ret = DialObj->launchApplicationWithLaunchParams(app_name, payload, query_string, additional_data_url); - if (RTCAST_ERROR_RT(ret) != RT_OK) { - printf("RTDIAL: DialObj.launchApplication failed!!! Error=%s\n",rtStrError(RTCAST_ERROR_RT(ret))); - return GDIAL_APP_ERROR_INTERNAL; - } - return GDIAL_APP_ERROR_NONE; -} - -using namespace WPEFramework; -JSONRPC::LinkType *netflixRemoteObject = NULL; -JSONRPC::LinkType *controllerRemoteObject = NULL; -#define MAX_LENGTH 1024 - -#ifdef NETFLIX_CALLSIGN_0 -const std::string nfx_callsign = "Netflix-0"; -#else -const std::string nfx_callsign = "Netflix"; -#endif - -std::string GetCurrentState() { - std::cout<<"GetCurrentState()"< pluginResponse; - Core::SystemInfo::SetEnvironment(_T("THUNDER_ACCESS"), (_T("127.0.0.1:9998"))); - unsigned char buffer[MAX_LENGTH] = {0}; - - //Obtaining controller object - if (NULL == controllerRemoteObject) { - int ret = GetSecurityToken(MAX_LENGTH,buffer); - if(ret<0) - { - controllerRemoteObject = new JSONRPC::LinkType(std::string()); - } else { - string sToken = (char*)buffer; - string query = "token=" + sToken; - printf("Security token = %s \n",query.c_str()); - controllerRemoteObject = new JSONRPC::LinkType(std::string(), false, query); - } - } - std::string nfxstatus = "status@" + nfx_callsign; - if(controllerRemoteObject->Get(1000, _T(nfxstatus), pluginResponse) == Core::ERROR_NONE) - { - printf("Obtained netflix status = %s\n",nfxstatus.c_str()); - Core::JSON::ArrayType::Iterator index(pluginResponse.Elements()); - while (index.Next() == true) { - netflixState = index.Current().JSONState.Data(); - } //end of while loop - } //end of if case for querrying - printf("Netflix State = %s\n",netflixState.c_str()); - return netflixState; -} -void stop_netflix() -{ - JsonObject parameters; - JsonObject response; - parameters["callsign"] = nfx_callsign; - if (Core::ERROR_NONE == controllerRemoteObject->Invoke("deactivate", parameters, response)) { - std::cout << "Netflix is stoppped" << std::endl; - } else { - std::cout << "Netflix could not be deactivated" << std::endl; - } -} - -int gdial_os_application_stop(const char *app_name, int instance_id) { - printf("RTDIAL gdial_os_application_stop: appName = %s appID = %s\n",app_name,std::to_string(instance_id).c_str()); - if((strcmp(app_name,"system") == 0)){ - printf("RTDIAL delete not supported for system app return GDIAL_APP_ERROR_BAD_REQUEST\n"); - return GDIAL_APP_ERROR_BAD_REQUEST; - } - std::string State = AppCache->SearchAppStatusInCache(app_name); - /* always to issue stop request to have a failsafe strategy */ - if (0 && State != "running") - return GDIAL_APP_ERROR_BAD_REQUEST; - - char* enable_stop = getenv("ENABLE_NETFLIX_STOP"); - if ( enable_stop != NULL ) { - if ( strcmp(app_name,"Netflix") == 0 && strcmp(enable_stop,"true") == 0) { - printf("NTS TESTING: force shutdown Netflix thunder plugin\n"); - stop_netflix(); - sleep(1); - } - } - rtCastError ret = DialObj->stopApplication(app_name,std::to_string(instance_id).c_str()); - if (RTCAST_ERROR_RT(ret) != RT_OK) { - printf("RTDIAL: DialObj.stopApplication failed!!! Error=%s\n",rtStrError(RTCAST_ERROR_RT(ret))); - return GDIAL_APP_ERROR_INTERNAL; - } - return GDIAL_APP_ERROR_NONE; -} - -int gdial_os_application_hide(const char *app_name, int instance_id) { - if((strcmp(app_name,"system") == 0)){ - printf("RTDIAL system app already in hidden state\n"); - return GDIAL_APP_ERROR_NONE; - } - #if 0 - printf("RTDIAL gdial_os_application_hide-->stop: appName = %s appID = %s\n",app_name,std::to_string(instance_id).c_str()); - std::string State = AppCache->SearchAppStatusInCache(app_name); - if (0 && State != "running") { - return GDIAL_APP_ERROR_BAD_REQUEST; - } - rtCastError ret = DialObj->stopApplication(app_name,std::to_string(instance_id).c_str()); - if (RTCAST_ERROR_RT(ret) != RT_OK) { - printf("RTDIAL: DialObj.stopApplication failed!!! Error=%s\n",rtStrError(RTCAST_ERROR_RT(ret))); - return GDIAL_APP_ERROR_INTERNAL; - } - return GDIAL_APP_ERROR_NONE; - #else - printf("RTDIAL gdial_os_application_hide: appName = %s appID = %s\n",app_name,std::to_string(instance_id).c_str()); - std::string State = AppCache->SearchAppStatusInCache(app_name); - if (State != "running") - return GDIAL_APP_ERROR_BAD_REQUEST; - rtCastError ret = DialObj->hideApplication(app_name,std::to_string(instance_id).c_str()); - if (RTCAST_ERROR_RT(ret) != RT_OK) { - printf("RTDIAL: DialObj.hideApplication failed!!! Error=%s\n",rtStrError(RTCAST_ERROR_RT(ret))); - return GDIAL_APP_ERROR_INTERNAL; - } - return GDIAL_APP_ERROR_NONE; - #endif -} - -int gdial_os_application_resume(const char *app_name, int instance_id) { - printf("RTDIAL gdial_os_application_resume: appName = %s appID = %s\n",app_name,std::to_string(instance_id).c_str()); - - if((strcmp(app_name,"system") == 0)){ - printf("RTDIAL system app can not be resume\n"); - return GDIAL_APP_ERROR_NONE; - } - std::string State = AppCache->SearchAppStatusInCache(app_name); - if (State == "running") - return GDIAL_APP_ERROR_BAD_REQUEST; - rtCastError ret = DialObj->resumeApplication(app_name,std::to_string(instance_id).c_str()); - if (RTCAST_ERROR_RT(ret) != RT_OK) { - printf("RTDIAL: DialObj.resumeApplication failed!!! Error=%s\n",rtStrError(RTCAST_ERROR_RT(ret))); - return GDIAL_APP_ERROR_INTERNAL; - } - return GDIAL_APP_ERROR_NONE; -} - -int gdial_os_application_state(const char *app_name, int instance_id, GDialAppState *state) { - printf("RTDIAL gdial_os_application_state: App = %s \n",app_name); - if((strcmp(app_name,"system") == 0)){ - *state = GDIAL_APP_STATE_HIDE; - printf("RTDIAL getApplicationState: AppState = suspended \n"); - return GDIAL_APP_ERROR_NONE; - } - std::string State = AppCache->SearchAppStatusInCache(app_name); - printf("RTDIAL getApplicationState: AppState = %s \n",State.c_str()); - /* - * return cache, but also trigger a refresh - */ - if((strcmp(app_name,"system") != 0) &&( true || State == "NOT_FOUND")) { - rtCastError ret = DialObj->getApplicationState(app_name,NULL); - if (RTCAST_ERROR_RT(ret) != RT_OK) { - printf("RTDIAL: DialObj.getApplicationState failed!!! Error: %s\n",rtStrError(RTCAST_ERROR_RT(ret))); - return GDIAL_APP_ERROR_INTERNAL; - } - } - - if (State == "running") { - *state = GDIAL_APP_STATE_RUNNING; - } - else if (State == "suspended" || State == "hidden") { - *state = GDIAL_APP_STATE_HIDE; - } - else { - *state = GDIAL_APP_STATE_STOPPED; - } - - char* enable_stop = getenv("ENABLE_NETFLIX_STOP"); - if ( enable_stop != NULL ) { - if (strcmp(app_name,"Netflix") == 0 && strcmp(enable_stop,"true") == 0) { - std::string app_state = GetCurrentState(); - printf("RTDIAL: Presence of Netflix thunder plugin state = %s to confirm state\r\n", app_state.c_str()); - if (app_state == "deactivated") { - *state = GDIAL_APP_STATE_STOPPED; - printf("RTDIAL: app [%s] state converted to [%d]\r\n", app_name, *state); - } - else if (app_state == "suspended" || app_state == "hidden") - { - *state = GDIAL_APP_STATE_HIDE; - printf("RTDIAL: app [%s] state converted to [%d]\r\n", app_name, *state); - } - else { - *state = GDIAL_APP_STATE_RUNNING; - } - } - } - - return GDIAL_APP_ERROR_NONE; -}