summaryrefslogtreecommitdiff
path: root/sat-event-downloader/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sat-event-downloader/main.c')
-rwxr-xr-xsat-event-downloader/main.c639
1 files changed, 639 insertions, 0 deletions
diff --git a/sat-event-downloader/main.c b/sat-event-downloader/main.c
new file mode 100755
index 0000000..eaad47d
--- /dev/null
+++ b/sat-event-downloader/main.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.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://floralicense.org/license/
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <vconf.h>
+#include <dlog.h>
+#include <ITapiSat.h>
+#include <TapiUtility.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#include "utils.h"
+#include "event-list.h"
+
+#define INPUT_NODE_DEV_FILE_PATH "/dev/event"
+#define DBUS_SERVICE_SAT_EVT_DW "org.tizen.sat-event-downloader"
+#define PATH_LENGTH_MAX 20
+#define SAT_LANGAGUE_MAX 15
+#define USER_EVENT_MAX 10
+
+struct event_info{
+ guint source;
+ int fd;
+};
+
+typedef struct {
+ gpointer dbus_connection;
+ GMainLoop *mainloop;
+ gchar *path;
+ guint signal_id;
+ struct event_info info[USER_EVENT_MAX];
+} SatEvtDownloader_t;
+
+struct language {
+ const char *code;
+ int ival; /* for Convert from code to integer */
+};
+
+
+static struct language langs[SAT_LANGAGUE_MAX] = {
+ {"en_GB.UTF-8", SETTING_LANG_ENGLISH,},
+ {"en_US.UTF-8", SETTING_LANG_ENGLISH,},
+ {"de_DE.UTF-8", SETTING_LANG_GERMAN,},
+ {"es_ES.UTF-8", SETTING_LANG_SPAINISH,},
+ {"pt_PT.UTF-8", SETTING_LANG_PORTUGUESE,},
+ {"it_IT.UTF-8", SETTING_LANG_ITALIAN,},
+ {"fr_FR.UTF-8", SETTING_LANG_FRENCH,},
+ {"tr_TR.UTF-8", SETTING_LANG_TURKISH,},
+ {"ko_KR.UTF-8", SETTING_LANG_KOREA,},
+ {"zh_CN.UTF-8", SETTING_LANG_CHINA,},
+ {"zh_HK.UTF-8", SETTING_LANG_CANTONESE,},
+ {"zh_TW.UTF-8", SETTING_LANG_TAIWAN,},
+ {"ja_JP.UTF-8", SETTING_LANG_JAPAN,},
+ {"ru_RU.UTF-8", SETTING_LANG_RUSSIAN,},
+ {"el_GR.UTF-8", SETTING_LANG_GREEK,}
+};
+
+static SatEvtDownloader_t *sat_info;
+
+static int _get_language_int(const char *lang_code)
+{
+ int i;
+ int ret = -1;
+ char *str1, *str2;
+
+ dbg("convert lang_code (%s) to integer.\n", lang_code);
+
+ str1 = g_strjoinv(NULL, g_strsplit_set(lang_code, "_.-", -1));
+
+ for(i = 0; i<SAT_LANGAGUE_MAX; i++) {
+ str2 = g_strjoinv(NULL, g_strsplit_set(langs[i].code, "_.-", -1));
+ if(strcasecmp(str1, str2) == 0) {
+ ret = langs[i].ival;
+ dbg("success to convert!! (%d), str1(%s), str2(%s)", ret, str1, str2);
+ }
+ }
+ return ret;
+}
+
+static GVariant* _sat_gen_event_download_data(const TelSatEventDownloadReqInfo_t *pEventData)
+{
+ GVariant *result = NULL;
+
+ switch(pEventData->eventDownloadType)
+ {
+ case TAPI_EVENT_SAT_DW_TYPE_USER_ACTIVITY:{
+ gboolean user_activity = TRUE;
+ dbg("user activity (%d) ", user_activity);
+ result = g_variant_new("(b)", user_activity);
+ } break;
+ case TAPI_EVENT_SAT_DW_TYPE_IDLE_SCREEN_AVAILABLE:{
+ gboolean idle_screen = pEventData->u.bIdleScreenAvailable;
+ dbg("idle screen available (%d)", idle_screen);
+
+ result = g_variant_new("(b)", idle_screen);
+ } break;
+ case TAPI_EVENT_SAT_DW_TYPE_LANGUAGE_SELECTION:{
+ gint selected_language;
+ dbg("selected language (%d)", pEventData->u.languageSelectionEventReqInfo.language);
+
+ selected_language = pEventData->u.languageSelectionEventReqInfo.language;
+ result = g_variant_new("(i)", selected_language);
+ } break;
+ case TAPI_EVENT_SAT_DW_TYPE_BROWSER_TERMINATION:
+ case TAPI_EVENT_SAT_DW_TYPE_DATA_AVAILABLE:
+ case TAPI_EVENT_SAT_DW_TYPE_CHANNEL_STATUS:
+ default :
+ dbg("not support download event (%d)", pEventData->eventDownloadType);
+ break;
+ }
+
+ return result;
+}
+
+
+static int _sat_request_download_event(const TelSatEventDownloadReqInfo_t *pEventData)
+{
+ GVariant *rst = NULL;
+ GVariant *download_data = NULL;
+ GVariant *inparam = NULL;
+ GError *error = NULL;
+ gint event_download_type, src_dev, dest_dev;
+ gint res = 0, env_resp = 0;
+
+ dbg("Func Entrance ");
+
+ if (!sat_info || !sat_info->dbus_connection || !pEventData){
+ dbg("invalid parameter");
+ return TAPI_API_INVALID_INPUT;
+ }
+
+ event_download_type = pEventData->eventDownloadType;
+ src_dev = TAPI_SAT_DEVICE_ID_ME;
+ dest_dev = TAPI_SAT_DEVICE_ID_SIM;
+ download_data = _sat_gen_event_download_data(pEventData);
+ dbg("event type(%d)", event_download_type);
+ inparam = g_variant_new("(iiiv)", event_download_type, src_dev, dest_dev, download_data);
+
+ rst = g_dbus_connection_call_sync(sat_info->dbus_connection, DBUS_TELEPHONY_SERVICE,
+ sat_info->path, DBUS_TELEPHONY_SAT_INTERFACE, "DownloadEvent", inparam, NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+ g_variant_unref(inparam);
+
+ if (!rst) {
+ dbg( "error to send ui display status(%s)", error->message);
+ g_error_free(error);
+ return -1;
+ }
+
+ g_variant_get(rst, "(ii)", &res, &env_resp);
+ dbg("result (%d)", res);
+
+dbg("envelope response (%d)", env_resp);
+
+ return res;
+}
+
+static guint sat_register_gio_watch(int fd, void *callback, char *event_key)
+{
+ GIOChannel *channel = NULL;
+ guint source;
+
+ if (!callback) {
+ dbg("callback is null !!");
+ return FALSE;
+ }
+
+ channel = g_io_channel_unix_new(fd);
+ source = g_io_add_watch(channel, G_IO_IN, (GIOFunc) callback, event_key);
+
+ return source;
+}
+
+static void sat_allocate_watch_source(int index, const char * path, void *callback, char *event_key)
+{
+ int fd;
+ guint source;
+
+ ret_if(NULL == sat_info);
+
+ fd = open(path , O_RDONLY);
+
+ if (fd < 0 ) {
+ dbg("fail to open file (%s)", path);
+ return;
+ }
+ source = sat_register_gio_watch(fd, callback, event_key);
+ sat_info->info[index].source = source;
+ sat_info->info[index].fd = fd;
+ dbg("allocate index[%d], path[%s], source[%d], fd[%d]", index, path, source, fd);
+}
+
+static void sat_release_watch_source(void)
+{
+ int index;
+
+ ret_if(NULL == sat_info);
+
+ for(index=0; index<USER_EVENT_MAX; index++) {
+ dbg("remove source[%d] = %d, fd[%d] ", index,
+ sat_info->info[index].source, sat_info->info[index].fd);
+ g_source_remove(sat_info->info[index].source);
+ sat_info->info[index].source = 0;
+ if(sat_info->info[index].fd != -1) {
+ close(sat_info->info[index].fd);
+ sat_info->info[index].fd = -1;
+ }
+ }
+}
+
+static gboolean on_recv_key_event(GIOChannel *channel, GIOCondition condition, gpointer data)
+{
+ TelSatEventDownloadReqInfo_t event_dw_request;
+ char *event_key = (char *)data;
+ struct input_event *input;
+ int ret;
+ int n, fd;
+ char buf[1024];
+
+ fd = g_io_channel_unix_get_fd(channel);
+
+ n = read(fd, buf, sizeof(struct input_event));
+ if(n<0){
+ dbg("fail to read");
+ return TRUE;
+ }
+
+ input = (struct input_event *)buf;
+ dbg("key type (0x%x), code (%hd), fd(%d)", input->type, input->code, fd);
+
+ if(input->type != EV_KEY && input->type != EV_ABS) {
+ dbg("unwanted event !!!");
+ return FALSE;
+ }
+
+ event_dw_request.eventDownloadType = TAPI_EVENT_SAT_DW_TYPE_USER_ACTIVITY;
+ ret = _sat_request_download_event(&event_dw_request);
+ retvm_if(ret<0, TRUE, "_sat_request_downlod_event failed");
+
+ /* If we got here, that means evelope command
+ * for user activity has been sent to CP,
+ * so remove all watch sources for event nodes and
+ * remove user activity event from the event list.
+ */
+ sat_release_watch_source();
+ event_list_remove(event_key);
+
+ if(event_list_count() == 0)
+ g_main_loop_quit(sat_info->mainloop);
+
+ g_io_channel_unref(channel);
+ channel = NULL;
+
+ return FALSE;
+}
+
+static void user_activity(char * event_key)
+{
+ int index;
+
+ dbg("Enter: event_key (%s)", event_key);
+
+ for(index=0;index<USER_EVENT_MAX;index++) {
+ char path[PATH_LENGTH_MAX] = {0};
+ (void) sprintf(path, "%s%d", INPUT_NODE_DEV_FILE_PATH, index);
+ sat_allocate_watch_source(index, (const char *)path, on_recv_key_event, event_key);
+ }
+}
+
+static void idle_screen_available(char *event_key)
+{
+ TelSatEventDownloadReqInfo_t event_dw_request;
+ int screen_top;
+ int ret;
+
+ if(vconf_get_int(event_key, &screen_top)<0)
+ ret_if("vconf_get_int(VCONFKEY_IDLE_SCREEN_TOP) failed");
+
+ dbg("idle screen top status (%d)", screen_top);
+
+ if(screen_top == 1)
+ {
+ event_dw_request.eventDownloadType = TAPI_EVENT_SAT_DW_TYPE_IDLE_SCREEN_AVAILABLE;
+ event_dw_request.u.bIdleScreenAvailable = TRUE;
+
+ ret = _sat_request_download_event(&event_dw_request);
+ retm_if(ret<0, "_sat_request_downlod_event failed");
+
+ event_list_remove(event_key);
+ }
+}
+
+static void language_selection()
+{
+ TelSatEventDownloadReqInfo_t event_dw_request;
+ TelSatLanguageType_t sat_lang = TAPI_SAT_LP_LANG_UNSPECIFIED;
+ int language = 0;
+ char *lang_code = NULL;
+ int ret = 0;
+
+ lang_code = vconf_get_str(VCONFKEY_LANGSET);
+ language = _get_language_int((const char*)lang_code);
+ if(language == -1)
+ ret_if("vconf_get_str(VCONFKEY_LANGSET) failed");
+
+ switch(language){
+ case SETTING_LANG_ENGLISH:
+ sat_lang = TAPI_SAT_LP_ENGLISH;
+ break;
+ case SETTING_LANG_GERMAN:
+ sat_lang = TAPI_SAT_LP_GERMAN;
+ break;
+ case SETTING_LANG_DUTCH:
+ sat_lang = TAPI_SAT_LP_DUTCH;
+ break;
+ case SETTING_LANG_SPAINISH:
+ sat_lang = TAPI_SAT_LP_SPANISH;
+ break;
+ case SETTING_LANG_PORTUGUESE:
+ sat_lang = TAPI_SAT_LP_PORTUGUESE;
+ break;
+ case SETTING_LANG_GREEK:
+ sat_lang = TAPI_SAT_LP_GREEK;
+ break;
+ case SETTING_LANG_ITALIAN:
+ sat_lang = TAPI_SAT_LP_ITALIAN;
+ break;
+ case SETTING_LANG_FRENCH:
+ sat_lang = TAPI_SAT_LP_FRENCH;
+ break;
+ case SETTING_LANG_TURKISH:
+ sat_lang = TAPI_SAT_LP_TURKISH;
+ break;
+ default:
+ sat_lang = TAPI_SAT_LP_LANG_UNSPECIFIED;
+ break;
+ }
+ dbg("lang_code = %s, language[%d], [0x%x]", lang_code, language, sat_lang);
+
+ event_dw_request.eventDownloadType = TAPI_EVENT_SAT_DW_TYPE_LANGUAGE_SELECTION;
+ event_dw_request.u.languageSelectionEventReqInfo.language = sat_lang;
+ ret = _sat_request_download_event(&event_dw_request);
+ retm_if(ret<0, "_sat_request_downlod_event failed");
+}
+
+static void sat_event_download_cb(keynode_t *node, void *data)
+{
+ ret_if(NULL == data);
+ char *event_key = data;
+
+ dbg("Enter: event_key (%s)", event_key);
+
+ if(strcmp(event_key, VCONFKEY_IDLE_SCREEN_TOP) == 0)
+ idle_screen_available(event_key);
+ else if(strcmp(event_key, VCONFKEY_LANGSET) == 0)
+ language_selection();
+
+ if(event_list_count() == 0)
+ g_main_loop_quit(sat_info->mainloop);
+}
+
+static void sat_process_setup_event_list(GVariant* setup_event_list_info)
+{
+ GVariant *evt_list = NULL;
+ gint event_count = 0;
+ int is_idle_on_top = 0;
+ int ret = 0;
+
+ if(!setup_event_list_info){
+ dbg("setup_event_list_info is NULL.");
+ return;
+ }
+
+ g_variant_get(setup_event_list_info, "(i@v)", &event_count, &evt_list);
+
+ dbg("event count (%d)", event_count);
+
+ if(event_count == 0) {
+ dbg("event count is zero indicating remove entire list of events in ME.");
+ event_list_clear();
+ goto EXIT;
+ }
+
+ if (evt_list) {
+ guchar data;
+ GVariantIter *iter = NULL;
+ GVariant *inner_gv = NULL;
+
+ inner_gv = g_variant_get_variant(evt_list);
+ dbg("event list exist type_format(%s)", g_variant_get_type_string(inner_gv));
+
+ g_variant_get(inner_gv, "ai", &iter);
+ while (g_variant_iter_loop(iter, "i", &data)) {
+ dbg("event(%d)", data);
+
+ if (data == TAPI_EVENT_SAT_DW_TYPE_USER_ACTIVITY) {
+ EventData *event_data = calloc(1, sizeof(EventData));
+ char * event_key = strdup("key/dummy/user_activity");
+
+ event_data->event_cb = sat_event_download_cb;
+ event_data->event_key = event_key;
+
+ ret = event_list_add(event_data);
+ if(ret<0)
+ {
+ dbg("fail to add list.");
+ free(event_data->event_key);
+ free(event_data);
+ }
+ user_activity(event_key);
+ }
+ else if (data == TAPI_EVENT_SAT_DW_TYPE_IDLE_SCREEN_AVAILABLE) {
+ EventData *event_data = calloc(1, sizeof(EventData));
+ char * event_key = strdup(VCONFKEY_IDLE_SCREEN_TOP);
+
+ event_data->event_cb = sat_event_download_cb;
+ event_data->event_key = event_key;
+
+ ret = event_list_add(event_data);
+ if(ret<0)
+ {
+ dbg("fail to add list.");
+ free(event_data->event_key);
+ free(event_data);
+ }
+
+ /* Check here current status of idle screen */
+ if(vconf_get_int(event_key, &is_idle_on_top) < 0)
+ dbg("vconf_get_int(%s) failed", event_key);
+
+ dbg("idle screen top status (%d)", is_idle_on_top);
+
+ if(is_idle_on_top == 1) {
+ dbg("send evelope command immediately.");
+ idle_screen_available(event_key);
+ }
+ free(event_key);
+ }
+ else if (data == TAPI_EVENT_SAT_DW_TYPE_LANGUAGE_SELECTION) {
+ EventData *event_data = calloc(1, sizeof(EventData));
+ event_data->event_cb = sat_event_download_cb;
+ event_data->event_key = strdup(VCONFKEY_LANGSET);
+
+ ret = event_list_add(event_data);
+ if(ret<0)
+ {
+ dbg("fail to add list.");
+ free(event_data->event_key);
+ free(event_data);
+ }
+ }
+ }
+ //while end
+ g_variant_iter_free(iter);
+ g_variant_unref(inner_gv);
+ }
+
+ event_count = event_list_count();
+ dbg("event_list_count: %d", event_count);
+
+EXIT:
+ if(event_count == 0)
+ g_main_loop_quit(sat_info->mainloop);
+
+ return;
+}
+
+static void on_sat_signal_handler(GDBusConnection *connection, const gchar *sender_name,
+ const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
+ GVariant *parameters, gpointer user_data)
+{
+
+ if (!g_strcmp0(interface_name, DBUS_TELEPHONY_SAT_INTERFACE)) {
+ dbg("on_sat_signal_handler: signal_name = %s", signal_name);
+ //This can be implemented using hash table as well, but as the number is too small opted for if else
+ if (!g_strcmp0(signal_name, "SetupEventList")) {
+ sat_process_setup_event_list(parameters);
+ }
+ return;
+ }
+
+ dbg("on_sat_signal_handler: Invalid Command");
+ return;
+}
+
+static void sat_register_event(const char* noti_id)
+{
+ gchar** dbus_noti = NULL;
+
+ dbus_noti = g_strsplit((const char*) noti_id, ":", 2);
+ if (!dbus_noti) {
+ dbg("invalid noti_id");
+ return;
+ }
+
+ dbg("dbus signal interface(%s) signal(%s) path(%s)", dbus_noti[0], dbus_noti[1], sat_info->path);
+
+ sat_info->signal_id = g_dbus_connection_signal_subscribe(sat_info->dbus_connection,
+ DBUS_TELEPHONY_SERVICE, /* Sender */
+ dbus_noti[0], /* Interface */
+ dbus_noti[1], /* Member */
+ sat_info->path, /* Object path */
+ NULL, /* arg0 */
+ G_DBUS_SIGNAL_FLAGS_NONE, on_sat_signal_handler, NULL, NULL );
+
+ dbg("subscribe from signal ID (%d)", sat_info->signal_id);
+
+ g_strfreev(dbus_noti);
+
+ return;
+}
+
+static int sat_dbus_register()
+{
+ gint id = 0;
+
+ dbg("Enter");
+
+ id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
+ DBUS_SERVICE_SAT_EVT_DW,
+ G_BUS_NAME_OWNER_FLAGS_REPLACE,
+ NULL,
+ NULL, NULL,
+ NULL,
+ NULL);
+
+ dbg("register dbus name id(%d)", id);
+
+ return 0;
+}
+
+static gboolean sat_event_downloader_init(void)
+{
+ GError *error = NULL;
+ char **modem_list = NULL;
+
+ retv_if(NULL == sat_info, FALSE);
+
+ modem_list = tel_get_cp_name_list();
+ if(modem_list == NULL){
+ dbg("getting modem list failed, Exiting App");
+ return FALSE;
+ }
+
+ dbg("cp name(%s)", modem_list[0]);
+
+ sat_info->path = g_strdup_printf("%s/%s", DBUS_TELEPHONY_DEFAULT_PATH, modem_list[0]);
+ sat_info->dbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (!sat_info->dbus_connection) {
+ dbg("sat_event_downloader_init: Error in creating dbus_connection %s", error->message);
+ g_error_free(error);
+ return FALSE;
+ }
+
+ //register SETUP "EVENT LIST" event
+ sat_register_event(TAPI_NOTI_SAT_SETUP_EVENT_LIST);
+
+ return TRUE;
+}
+
+static void sat_event_downloader_exit(void)
+{
+ ret_if(NULL == sat_info);
+ /* Unsubscribe All the signals from dbus..*/
+ dbg("unsubsribe from signal ID (%d) ", sat_info->signal_id);
+ g_dbus_connection_signal_unsubscribe(sat_info->dbus_connection, sat_info->signal_id);
+ g_object_unref((gpointer) sat_info->dbus_connection);
+
+ g_main_loop_quit(sat_info->mainloop);
+ sat_release_watch_source();
+ g_free(sat_info->path);
+ g_free(sat_info);
+
+ return;
+}
+
+int main(int argc, char *argv[])
+{
+ dbg(" Enter ");
+
+ g_type_init();
+
+ sat_dbus_register();
+
+
+ sat_info = g_new0(SatEvtDownloader_t, 1);
+
+ if (sat_info == NULL ) {
+ dbg("Main: Memory Allocation for sat_info failed");
+ return EXIT_FAILURE;
+ }
+
+ dbg("calling g_main_loop");
+ sat_info->mainloop = g_main_loop_new(NULL, FALSE);
+ if (!sat_info->mainloop) {
+ dbg("fail to create g_mail_loop for sat_info");
+ g_free(sat_info);
+ return EXIT_FAILURE;
+ }
+
+ if (!sat_event_downloader_init()) {
+ dbg("Init failed !!");
+ sat_event_downloader_exit();
+ return EXIT_FAILURE;
+ }
+
+ g_main_loop_run(sat_info->mainloop);
+
+ event_list_clear();
+ sat_event_downloader_exit();
+
+ dbg("Exit");
+ exit(1);
+ return EXIT_SUCCESS;
+}
+