/*************************************************************************** * Copyright (C) 2006 by Daniel Gollub * * Copyright (C) 2011 by Quentin Denis * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "gnokii_sync.h" #include "gnokii_comm.h" #include "gnokii_config.h" #include "gnokii_calendar.h" #include "gnokii_contact.h" static void free_gnokiienv(gnokii_env *env) { osync_trace(TRACE_ENTRY, "%s()", __func__); while (env->sinkenvs) { gnokii_sinkenv *sinkenv = (gnokii_sinkenv *) env->sinkenvs->data; osync_free(sinkenv); env->sinkenvs = osync_list_remove(env->sinkenvs, sinkenv); } if (env->state) osync_free(env->state); osync_free(env); osync_trace(TRACE_EXIT, "%s", __func__); return; } static void connect(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata) { osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, userdata, info, ctx); OSyncError *error = NULL; gnokii_env *env = (gnokii_env *) userdata; //TODO: OSyncSinkStateDB *state_db = osync_objtype_sink_get_state_db(sink); //TODO: implement osync_sink_state_equal? see file-sync // connect to cellphone if (!gnokii_comm_connect(env->state)) { osync_error_set(&error, OSYNC_ERROR_GENERIC, "Connection failed"); goto error; } osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); return; error: osync_context_report_osyncerror(ctx, error); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error)); osync_error_unref(&error); } static void sync_done(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata) { osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, userdata, info, ctx); //OSyncError *error = NULL; //gnokii_env *env = (gnokii_env *) data; //FIXME: remove? OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); //FIXME: remove? gnokii_sinkenv *sinkenv = osync_objtype_sink_get_userdata(sink); //TODO: implement OSyncSinkStateDB *state_db stuff? // answer the call osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); return; /*unused error: osync_context_report_osyncerror(ctx, error); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error)); osync_error_unref(&error); */ } static void disconnect(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata) { osync_trace(TRACE_ENTRY, "%s(%p)", __func__, ctx); //OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); gnokii_env *env = (gnokii_env *) userdata; // disconnect the connection with phone if (!gnokii_comm_disconnect(env->state)) { osync_context_report_error(ctx, OSYNC_ERROR_GENERIC, "disconnect failed"); return; } // answer the call osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void finalize(void *data) { osync_trace(TRACE_ENTRY, "%s(%p)", __func__, data); gnokii_env *env = (gnokii_env *)data; // free everything free_gnokiienv(env); osync_trace(TRACE_EXIT, "%s", __func__); } /* Here we actually tell opensync which sinks are available. */ static osync_bool discover(OSyncPluginInfo *info, void *userdata, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, userdata, info, error); // Set available sinks, for now just enable all. OSyncList *s, *sinks = osync_plugin_info_get_objtype_sinks(info); for (s = sinks; s; s = s->next) { OSyncObjTypeSink *sink = (OSyncObjTypeSink *) s->data; osync_objtype_sink_set_available(sink, TRUE); } OSyncVersion *version = osync_version_new(error); osync_version_set_plugin(version, "gnokii-sync"); //osync_version_set_modelversion(version, "version"); //osync_version_set_firmwareversion(version, "firmwareversion"); //osync_version_set_softwareversion(version, "softwareversion"); //osync_version_set_hardwareversion(version, "hardwareversion"); osync_plugin_info_set_version(info, version); osync_version_unref(version); osync_trace(TRACE_EXIT, "%s", __func__); return TRUE; } static void *initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, plugin, info, error); gnokii_env *env = NULL; OSyncPluginConfig *config = NULL; OSyncObjTypeSink *event_sink = NULL; OSyncObjTypeSink *contact_sink = NULL; OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); struct gn_statemachine *state_machine; state_machine = osync_try_malloc0(sizeof(struct gn_statemachine), error); if (!state_machine) goto error; config = osync_plugin_info_get_config(info); if (!config) { osync_error_set(error, OSYNC_ERROR_MISCONFIGURATION, "No Plugin configuration"); goto error; } env = osync_try_malloc0(sizeof(gnokii_env), error); if (!env) goto error; /* set gnokii state_machine for sinkenv */ env->state = state_machine; if (!gnokii_config_parse(env, config, error)) goto error; /* main sink (objtype neutral) handles only connect and disconnect! */ OSyncObjTypeSink *mainsink = osync_objtype_main_sink_new(error); if (!mainsink) goto error; osync_objtype_sink_set_connect_func(mainsink, connect); osync_objtype_sink_set_disconnect_func(mainsink, disconnect); osync_objtype_sink_set_userdata(mainsink, env); osync_plugin_info_set_main_sink(info, mainsink); /* end of main sink */ contact_sink = osync_plugin_info_find_objtype(info, "contact"); if (contact_sink) { osync_objtype_sink_set_get_changes_func(contact_sink, gnokii_contact_get_changes); osync_objtype_sink_set_commit_func(contact_sink, gnokii_contact_commit_change); osync_objtype_sink_set_sync_done_func(contact_sink, sync_done); /* Request an hashtable from the framework. */ osync_objtype_sink_enable_hashtable(contact_sink, TRUE); gnokii_sinkenv *contact_sinkenv = osync_try_malloc0(sizeof(gnokii_sinkenv), error); if (!contact_sinkenv) goto error; contact_sinkenv->objformat = osync_format_env_find_objformat(formatenv, "gnokii-contact"); contact_sinkenv->env = env; /* Set userdata */ osync_objtype_sink_set_userdata(contact_sink, contact_sinkenv); env->sinkenvs = osync_list_append(env->sinkenvs, contact_sinkenv); } else { osync_trace(TRACE_INTERNAL, "Contact sink is disable by configuration."); } /* end of contact sink */ /* init the event sink */ event_sink = osync_plugin_info_find_objtype(info, "event"); if (!event_sink) goto error; event_sink = osync_plugin_info_find_objtype(info, "event"); if (event_sink) { osync_objtype_sink_set_get_changes_func(event_sink, gnokii_calendar_get_changes); osync_objtype_sink_set_commit_func(event_sink, gnokii_calendar_commit_change); osync_objtype_sink_set_sync_done_func(event_sink, sync_done); /* Request an hashtable from the framework. */ osync_objtype_sink_enable_hashtable(event_sink, TRUE); gnokii_sinkenv *event_sinkenv = osync_try_malloc0(sizeof(gnokii_sinkenv), error); if (!event_sinkenv) goto error; event_sinkenv->objformat = osync_format_env_find_objformat(formatenv, "gnokii-event"); event_sinkenv->env = env; /* Set userdata */ osync_objtype_sink_set_userdata(contact_sink, event_sinkenv); env->sinkenvs = osync_list_append(env->sinkenvs, event_sinkenv); } else { osync_trace(TRACE_INTERNAL, "Event sink is disable by configuration."); } /* end of event sink */ osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; error: if (env) free_gnokiienv(env); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } osync_bool get_sync_info(OSyncPluginEnv *env, OSyncError **error) { OSyncPlugin *plugin = osync_plugin_new(error); if (!plugin) goto error; //Tell opensync something about your plugin osync_plugin_set_name(plugin, "gnokii-sync"); osync_plugin_set_longname(plugin, "Nokia (gnokii) Mobile Device"); osync_plugin_set_description(plugin, "Synchronize with Nokia cellphones (FBUS)"); //Now set the function we made earlier osync_plugin_set_initialize(plugin, initialize); osync_plugin_set_finalize(plugin, finalize); osync_plugin_set_discover(plugin, discover); osync_plugin_env_register_plugin(env, plugin, error); osync_plugin_unref(plugin); return TRUE; error: osync_trace(TRACE_ERROR, "Unable to register: %s", osync_error_print(error)); osync_error_unref(error); return FALSE; } int get_version(void) { return 1; }