| 1 | \chapter{Synchronization Plugins} |
|---|
| 2 | Synchronization Plugins are modules which provides access to a certain device, |
|---|
| 3 | application or protocol. All of those plugins provide independent of the |
|---|
| 4 | synchronized content/format or connection type, the same functions: |
|---|
| 5 | \begin{itemize} |
|---|
| 6 | \item initialize. This function parse the plugin configuration and initializes |
|---|
| 7 | the plugin. If the plugin acts as server, it also initializes this one and |
|---|
| 8 | listen for incoming connections. |
|---|
| 9 | \item finalize. This function releases all gained memory by the plugin and stops |
|---|
| 10 | the listening server if present. |
|---|
| 11 | \item discover. This function is intended to get called initially to gain |
|---|
| 12 | information about the target application, device or system. In detail it detects |
|---|
| 13 | all supported formats and individual capabilities of this format, if possible. |
|---|
| 14 | And basic information about the target application/device like version, vendor, |
|---|
| 15 | product, etc. ... |
|---|
| 16 | %\item usable. This function is intended to check if the target |
|---|
| 17 | %application/device is usable. |
|---|
| 18 | \end{itemize} |
|---|
| 19 | |
|---|
| 20 | \begin{figure} |
|---|
| 21 | \centering |
|---|
| 22 | \includegraphics[bb=0 0 661 960, scale=0.60]{simple-sync-sequence} |
|---|
| 23 | % simple-sync-sequence.png: 661x960 pixel, 72dpi, 23.32x33.87 cm, bb=0 0 661 960 |
|---|
| 24 | \caption{Plugin Synchronization Sequence} |
|---|
| 25 | \label{fig:SimpleSyncSequence} |
|---|
| 26 | \end{figure} |
|---|
| 27 | |
|---|
| 28 | Those function are called "Generic Functions" and MUST be implemented by |
|---|
| 29 | plugin. |
|---|
| 30 | |
|---|
| 31 | \section{Generic Functions} |
|---|
| 32 | The Generic Functions are the only functions, which got called synchronously by |
|---|
| 33 | the OpenSync Framework. |
|---|
| 34 | \subsection{Initialization} |
|---|
| 35 | \subsection{Finalize} |
|---|
| 36 | \subsection{Discover} |
|---|
| 37 | %\subsection{Usable} |
|---|
| 38 | \section{Sink Functions} |
|---|
| 39 | All ">Sink Functions"< are called asynchronously, not like the "Generic |
|---|
| 40 | Functions", and have to reply with OSyncContext functions if the task was |
|---|
| 41 | executed or not. It's very important that the ">Sink Functions"< reply the |
|---|
| 42 | request by the OpenSync Framework with the OSyncContext functions. Even on |
|---|
| 43 | error condition the Sink Function have to reply with a special OSyncContext |
|---|
| 44 | error function. Otherwise the OpenSync Framework until the timeout for this |
|---|
| 45 | function call is reached, which may take sometime for some usually time |
|---|
| 46 | consuming functions\\ |
|---|
| 47 | The Main Sink, which is Object Type neutral, doesn't have any required Sink |
|---|
| 48 | Functions. For the Object Type Sink are the implementation of some Sink |
|---|
| 49 | Functions required: |
|---|
| 50 | |
|---|
| 51 | \begin{center} |
|---|
| 52 | % use packages: array |
|---|
| 53 | \begin{tabular}{ll} |
|---|
| 54 | \textbf{Function} & \textbf{Implementation} \\ |
|---|
| 55 | Connect & O \\ |
|---|
| 56 | Get Changes & M \\ |
|---|
| 57 | Commit / Batch Commit & M (only Commit \textbf{or} Batch Commit) \\ |
|---|
| 58 | Committed All & O (only available in combination with Commit)\\ |
|---|
| 59 | Synchronization Done & O \\ |
|---|
| 60 | Disconnect & O |
|---|
| 61 | \end{tabular} |
|---|
| 62 | \end{center} |
|---|
| 63 | |
|---|
| 64 | The Plugin don't have to register a Main Sink if there is no need for Object |
|---|
| 65 | Type neutral tasks. |
|---|
| 66 | \subsection{Connect} |
|---|
| 67 | The Connect function is available for all Object Type Sinks and could be used to |
|---|
| 68 | establish Object Type specific connection. If the connection establishment is an |
|---|
| 69 | Object Type neutral task (e.g. Bluetooth, USB, ...) and needded to be done only |
|---|
| 70 | once, only the Main Sink should be used. This avoids problems with shared access |
|---|
| 71 | to an interface, since a connect function would be called for each Object Type |
|---|
| 72 | for the same interface.\\ |
|---|
| 73 | This function MUST only establish a connection to the device or resource. After |
|---|
| 74 | the connection got established successful the plugin MUST reply the context with |
|---|
| 75 | \verb|osync_context_reply_success()|. On error the plugin replies a |
|---|
| 76 | human-readable |
|---|
| 77 | (aka. userfriendly) error message with \verb|osync_context_reply_error()|. |
|---|
| 78 | \subsection{Get Changes} |
|---|
| 79 | The Get Changes function get called by the OpenSync Framework to request changes |
|---|
| 80 | since last synchronization or all entries of the Object Type specific resource. |
|---|
| 81 | Later one MUST be done when a Slow Sync got requested by the OpenSync |
|---|
| 82 | Synchronization framework. If a Slow Sync got requested for this Sink MUST be |
|---|
| 83 | checked with \verb|osync_objtype_sink_get_slowsync()|. On a Slow Sync the |
|---|
| 84 | Changetype (for all changes) is \verb|OSYNC_CHANGE_TYPE_ADDED|. On a regular |
|---|
| 85 | (fast sync) synchronization it's up to the Get Changes function to determine |
|---|
| 86 | the Changetype. Every change have to be reported with |
|---|
| 87 | \verb|osync_context_report_change()|. On a error the Sink Function have to |
|---|
| 88 | reply the context with \verb|osync_context_report_error()| and stop/leave this |
|---|
| 89 | function ASAP. If the protocol, application or device isn't able to report |
|---|
| 90 | changed entries since last sync, the OpenSync Helper Hashtable should be used |
|---|
| 91 | to determine the Changetype of the entry. |
|---|
| 92 | \subsection{Commit} |
|---|
| 93 | This function get called with a single OSyncChange object, which MUST be |
|---|
| 94 | committed to the application or device. If the commit failed the context MUST be |
|---|
| 95 | replied with \verb|osync_context_report_error()|. On success the context get |
|---|
| 96 | replied with \verb|osync_context_success()|. If Hashtable is already involved in |
|---|
| 97 | the Get Changes functions, then the Commit function has to update the entries |
|---|
| 98 | for the Hashtable for entries which get committed. |
|---|
| 99 | \subsection{Batch Commit} |
|---|
| 100 | The batch commit function is intended for protocols, device or application which |
|---|
| 101 | only allow batch committing (sending all changes at once). This function get |
|---|
| 102 | called with an array of changes which have of be committed all at once. |
|---|
| 103 | \subsection{Committed All} |
|---|
| 104 | This function got called after all entries got committed, even if error appeared |
|---|
| 105 | while committing. This function get not called if Batch Commit function is |
|---|
| 106 | registered for this Sink. |
|---|
| 107 | \subsection{Synchronization Done} |
|---|
| 108 | This function got called only after a successful synchronization. |
|---|
| 109 | When using Hashtable \verb|osync_hashtable_save()| should get called, to |
|---|
| 110 | do persistent store of the Hashtable. |
|---|
| 111 | \subsection{Disconnect} |
|---|
| 112 | This function MUST only handle the disconnect of the sink. Don't do further |
|---|
| 113 | cleanup here, the finalize function is intended for releasing memory and |
|---|
| 114 | cleanup. The disconnect function might never get called when even the connect |
|---|
| 115 | function failed. |
|---|
| 116 | \section{Properties} |
|---|
| 117 | Each Synchronization Plugin has properties which get set within the |
|---|
| 118 | \verb|get_sync_info()| function. The properties are: |
|---|
| 119 | |
|---|
| 120 | \begin{itemize} |
|---|
| 121 | \item Name, short name of the plugin should be less then 15 characters. This |
|---|
| 122 | name isn't visible to the user, at least not for rich OpenSync Frontends. |
|---|
| 123 | \item Longname, is the name of the plugin which is visible to the user in |
|---|
| 124 | rich OpenSync frontends. Should not be longer then 50 characters. |
|---|
| 125 | \item Description, about the Plugin visible to the end user in OpenSync |
|---|
| 126 | Frontends, and should additionally help to choose the right plugin. |
|---|
| 127 | \item Configuration Type, defines if the plugins needs any configuration or if |
|---|
| 128 | the configuration is optional or simply not needed. |
|---|
| 129 | \item Process Type, defines how the plugin get started: threaded, forked or by |
|---|
| 130 | an external process. |
|---|
| 131 | \item Timeouts, for initialization, finalization and timeout can be configured |
|---|
| 132 | for the plugin needs. |
|---|
| 133 | \end{itemize} |
|---|
| 134 | |
|---|
| 135 | \subsection{Name} |
|---|
| 136 | The name of the plugin get defined like all plugin properties in |
|---|
| 137 | \verb|get_sync_info()| function with calling \verb|osync_plugin_set_name()|. |
|---|
| 138 | This name got used mostly for internal configuration and isn't visible to the |
|---|
| 139 | user (at least not for rich OpenSync Frontend user). The name should be less |
|---|
| 140 | then 15 characters and should one word (no spaces). Example: ">palm-sync"< |
|---|
| 141 | \subsection{Longname} |
|---|
| 142 | The Longname of the plugin is the only name visible for regular user to choose |
|---|
| 143 | the correct plugin from a list of available plugins. Use the description field |
|---|
| 144 | to describe the plugin in more detail. Don't include the term ">Plugin"> in the |
|---|
| 145 | Longname. Example: ">Palm Device"< |
|---|
| 146 | \subsection{Description} |
|---|
| 147 | The description should additionaltly help the user to choose the correct plugin |
|---|
| 148 | if there are several plugins with similar names. Bad example: ">Plugin to sync |
|---|
| 149 | your pda. Version 0.23. http://foo.edu/hacking/opensync"<. The term ">Plugin"< |
|---|
| 150 | might confuse regular user, avoid it. If your plugin supports several different |
|---|
| 151 | devices don't list all known to work models, this might confuses people as well. |
|---|
| 152 | Again, don't list models! If your plugin is based on a synchronization |
|---|
| 153 | implementation mention the name of protocol. No version numbers, no URLs and |
|---|
| 154 | most user won't care about the authors name or E-Mail address. |
|---|
| 155 | \subsection{Plugin Timeouts} |
|---|
| 156 | The default plugin timeout should basically fit the need for all plugins. If |
|---|
| 157 | your plugin is known to be very slow you can change the timeout for this plugin |
|---|
| 158 | with following functions: |
|---|
| 159 | \begin{itemize} |
|---|
| 160 | \item \verb|osync_plugin_set_initliaze_timeout()| |
|---|
| 161 | \item \verb|osync_plugin_set_finalize_timeout()| |
|---|
| 162 | \item \verb|osync_plugin_set_discover_timeout()| |
|---|
| 163 | %\item \verb|osync_plugin_set_useable_timeout()| |
|---|
| 164 | \end{itemize} |
|---|
| 165 | The timeout unit is in seconds. It's possible to overwrite custom plugin timeout |
|---|
| 166 | with setting individual timeouts in the member configuration (syncmember.conf). |
|---|
| 167 | \subsection{Configuration Types} |
|---|
| 168 | If the plugin doesn't need any configuration by the user the plugin should the |
|---|
| 169 | configuration type to \verb|OSYNC_PLUGIN_NO_CONFIGURATION| with the |
|---|
| 170 | \verb|osync_plugin_set_config_type()| function. If the plugin don't need by |
|---|
| 171 | default a configuration but could be is additionally configurable the |
|---|
| 172 | configuration type should be set to \verb|OSYNC_PLUGIN_OPTIONAL_CONFIGURATION|. |
|---|
| 173 | If the plugin can't perform without any configuration the type should be set |
|---|
| 174 | to\\ \verb|OSYNC_PLUGIN_NEEDS_CONFIGURATION| (set by default). |
|---|
| 175 | \subsection{Process Types} |
|---|
| 176 | The Process Type declares how a plugin get started. By default the plugin get |
|---|
| 177 | started by the OpenSync Framework within a thread ( |
|---|
| 178 | \verb|OSYNC_START_TYPE_THREAD|). If the Plugin is known to conflict with the |
|---|
| 179 | process mainloop of the OpenSync Framework, it's possible to run the plugin in |
|---|
| 180 | a separated process by forking it. The forking is done by the OpenSync |
|---|
| 181 | Framework when the start type got set to \verb|OSYNC_START_TYPE_PROCESS|. If the |
|---|
| 182 | plugin has to access a not public interface to get access to the data resources |
|---|
| 183 | of an application it's possible to integrate the plugin within this application. |
|---|
| 184 | So the plugin is running all the time this application is running and can |
|---|
| 185 | communicate with the OpenSync Framework when the Process Type got set to |
|---|
| 186 | \verb|OSYNC_START_TYPE_EXTERNAL|. The Process Type can be changed with the |
|---|
| 187 | \verb|osync_plugin_set_start_type()| function. |
|---|
| 188 | \section{Configuration} |
|---|