Changeset 2972

Show
Ignore:
Timestamp:
12/17/07 15:59:28 (10 months ago)
Author:
prahal
Message:

Create an updated version of 0.34 (which build with changes to the build system

  • hopefully ) as svn is broken.

Plus some fixes for http-server.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • tags/plugins-0.35/syncml/CMakeLists.txt

    r2970 r2972  
    44 
    55SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules" ) 
    6 SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_INSTALL_PREFIX}/share/opensync-1.0/cmake/modules/") 
    7  
    8 INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) 
    96 
    107# find requirements 
    11 SET ( LIBSYNCML_MIN_VERSION "0.4.6" ) 
     8SET ( LIBSYNCML_MIN_VERSION "0.4.5" ) 
    129 
    1310FIND_PACKAGE( OpenSync REQUIRED ) 
    1411FIND_PACKAGE( GLIB2 REQUIRED ) 
    1512FIND_PACKAGE( LibXml2 REQUIRED ) 
    16 # TODO - check whether LibSyncml supports obex and/or http 
    1713FIND_PACKAGE( LibSyncMl REQUIRED ) 
    1814 
    1915INCLUDE( OpenSyncInternal ) 
    20  
    21 # Defaults 
    22 SET( ENABLE_OBEX TRUE CACHE BOOL "OBEX Transport" ) 
    23 SET( ENABLE_HTTP TRUE CACHE BOOL "HTTP Transport" ) 
    24  
    25 CONFIGURE_FILE("config.h.cmake" "config.h") 
    2616 
    2717ADD_SUBDIRECTORY( src ) 
  • tags/plugins-0.35/syncml/src/CMakeLists.txt

    r2942 r2972  
    11LINK_DIRECTORIES( ${OPENSYNC_LIBRARY_DIRS} ${GLIB2_LIBRARY_DIRS} ${LIBXML2_LIBRARY_DIRS} ${LIBSYNCML_LIBRARY_DIRS}) 
    2 INCLUDE_DIRECTORIES(${OPENSYNC_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIRS} ${LIBSYNCML_INCLUDE_DIRS}
     2INCLUDE_DIRECTORIES( ${OPENSYNC_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIRS} ${LIBSYNCML_INCLUDE_DIRS}
    33 
    4 SET(SOURCE_FILES syncml_plugin.c syncml_common.c syncml_devinf.c syncml_callbacks.c
     4OPENSYNC_PLUGIN_ADD( syncml-plugin syncml_plugin.c
    55 
    6 IF (ENABLE_OBEX) 
    7         SET(SOURCE_FILES ${SOURCE_FILES} syncml_obex_client.c) 
    8 ENDIF (ENABLE_OBEX) 
     6TARGET_LINK_LIBRARIES( syncml-plugin ${OPENSYNC_LIBRARIES} ${LIBSYNCML_LIBRARIES} ${GLIB2_LIBRARIES} ${LIBXML2_LIBRARIES} ) 
    97 
    10 IF (ENABLE_HTTP) 
    11         SET(SOURCE_FILES ${SOURCE_FILES} syncml_http_client.c syncml_http_server.c) 
    12 ENDIF (ENABLE_HTTP) 
     8###### INSTALL ###################  
     9OPENSYNC_PLUGIN_INSTALL( syncml-plugin )  
    1310 
    14 OPENSYNC_PLUGIN_ADD(syncml-plugin ${SOURCE_FILES}) 
     11OPENSYNC_PLUGIN_CONFIG( syncml-obex-client ) 
     12OPENSYNC_PLUGIN_CONFIG( syncml-http-server ) 
    1513 
    16 TARGET_LINK_LIBRARIES(syncml-plugin ${OPENSYNC_LIBRARIES} ${LIBSYNCML_LIBRARIES} ${GLIB2_LIBRARIES} ${LIBXML2_LIBRARIES}) 
    17  
    18 ###### INSTALL ################### 
    19 OPENSYNC_PLUGIN_INSTALL(syncml-plugin) 
    20  
    21 IF (ENABLE_OBEX) 
    22         OPENSYNC_PLUGIN_CONFIG(syncml-obex-client) 
    23 ENDIF (ENABLE_OBEX) 
    24  
    25 IF (ENABLE_HTTP) 
    26         OPENSYNC_PLUGIN_CONFIG(syncml-http-server) 
    27         OPENSYNC_PLUGIN_CONFIG(syncml-http-client) 
    28 ENDIF (ENABLE_HTTP) 
  • tags/plugins-0.35/syncml/src/syncml-http-server

    r2960 r2972  
    3131     <name>Contacts</name> 
    3232     <objtype>contact</objtype> 
    33      <objformat>vcard21</objformat> 
    3433  </database> 
    3534   
     
    3837     <name>Calendar</name> 
    3938     <objtype>event</objtype> 
    40      <objformat>vevent20</objformat> 
    4139  </database> 
    4240 
     41   
    4342  <!-- Note database --> 
    4443  <database> 
    4544     <name>Notes</name> 
    4645     <objtype>note</objtype> 
    47      <objformat>vnote10</objformat> 
    4846  </database> 
    4947 
  • tags/plugins-0.35/syncml/src/syncml-obex-client

    r2960 r2972  
    11<?xml version="1.0"?> 
    22<config> 
    3   <!-- sets the connection type to use. --> 
    4   <!-- please note that actually OBEX over network is not supported --> 
    5   <!-- 1 means obex over serial cable --> 
    6   <!-- 2 means obex over bluetooth    --> 
    7   <!-- 3 means obex over IRDA         --> 
    8   <!-- 4 means obex over network      --> 
    9   <!-- 5 means obex over usb          --> 
    10   <type>2</type> 
    11    
    12   <!-- (Only for bluetooth) The bluetooth address if the bluetooth mode is selected. 
    13        `hciconfig scan` to search bluetooth devices.  --> 
     3  <!-- (Only for bluetooth) The bluetooth address if the bluetooth mode is selected --> 
    144  <bluetooth_address></bluetooth_address> 
    155   
    16   <!-- (Only for bluetooth) The bluetooth channel to use. 
    17        `sdptool browse $MAC` to search for the correct channel --> 
     6  <!-- (Only for bluetooth) The bluetooth channel to use. `sdptool browse $MAC` to search for the correct channel --> 
    187  <bluetooth_channel></bluetooth_channel> 
    198   
     
    3524  <!-- the password for the username --> 
    3625  <password></password> 
    37   
     26   
     27  <!-- sets the connection type to use. 5 means obex over usb, 2 means obex over bluetooth --> 
     28  <type>2</type> 
     29   
    3830  <!-- If wbxml is enabled, defines wether the wbxml should use string tables --> 
    3931  <usestringtable>0</usestringtable> 
  • tags/plugins-0.35/syncml/src/syncml_plugin.c

    <
    r2919 r2972  
    1919 */ 
    2020 
    21 #include "config.h" 
    22  
    23 #include "syncml_common.h" 
    24  
    25 #ifdef ENABLE_HTTP 
    26 #  include "syncml_http_client.h" 
    27 #  include "syncml_http_server.h" 
    28 #endif 
    29  
    30 #ifdef ENABLE_OBEX 
    31 #  include "syncml_obex_client.h" 
    32 #endif 
     21#include "syncml_plugin.h" 
     22 
     23static void syncml_free_database(SmlDatabase *database) 
     24
     25        if (database->url) 
     26                g_free(database->url); 
     27 
     28        if (database->objtype) 
     29                g_free(database->objtype); 
     30 
     31        if (database->objformat_name) 
     32                g_free(database->objformat_name); 
     33 
     34        if (database->sink) 
     35                osync_objtype_sink_unref(database->sink); 
     36 
     37        g_free(database); 
     38
     39 
     40static SmlChangeType _get_changetype(OSyncChange *change) 
     41
     42        switch (osync_change_get_changetype(change)) { 
     43                case OSYNC_CHANGE_TYPE_ADDED: 
     44                        return SML_CHANGE_ADD; 
     45                case OSYNC_CHANGE_TYPE_MODIFIED: 
     46                        return SML_CHANGE_REPLACE; 
     47                case OSYNC_CHANGE_TYPE_DELETED: 
     48                        return SML_CHANGE_DELETE; 
     49                default: 
     50                        ; 
     51        } 
     52        return SML_CHANGE_UNKNOWN; 
     53
     54 
     55static const char *_objtype_to_contenttype(const char *objtype) 
     56
     57        if (!strcmp(objtype, "contact")) { 
     58                return SML_ELEMENT_TEXT_VCARD; 
     59        } 
     60        if (!strcmp(objtype, "event")) { 
     61                return SML_ELEMENT_TEXT_VCAL; 
     62        } 
     63        if (!strcmp(objtype, "todo")) { 
     64                return SML_ELEMENT_TEXT_VCAL; 
     65        } 
     66        if (!strcmp(objtype, "note")) { 
     67                return SML_ELEMENT_TEXT_PLAIN; 
     68        } 
     69        if (!strcmp(objtype, "data")) { 
     70                return SML_ELEMENT_TEXT_PLAIN; 
     71        } 
     72        return NULL; 
     73
     74 
     75static const char *_format_to_contenttype(OSyncChange *change) 
     76
     77        return _objtype_to_contenttype(osync_change_get_objtype(change)); 
     78
     79 
     80static osync_bool syncml_config_parse_database(SmlPluginEnv *env, xmlNode *cur, OSyncError **error) 
     81
     82        osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, env, cur, error); 
     83 
     84        SmlDatabase *database = osync_try_malloc0(sizeof(SmlDatabase), error); 
     85        if (!database) 
     86                goto error; 
     87 
     88        database->env = env; 
     89 
     90        while (cur != NULL) { 
     91                char *str = (char*)xmlNodeGetContent(cur); 
     92                if (str) { 
     93                        if (!xmlStrcmp(cur->name, (const xmlChar *)"name")) { 
     94                                database->url = g_strdup(str); 
     95                        } else if (!xmlStrcmp(cur->name, (const xmlChar *)"objtype")) { 
     96                                database->objtype = g_strdup(str); 
     97                        } else if (!xmlStrcmp(cur->name, (const xmlChar *)"objformat")) { 
     98                                database->objformat_name = g_strdup(str);; 
     99                        } 
     100 
     101                        xmlFree(str); 
     102                } 
     103                cur = cur->next; 
     104        } 
     105 
     106        if (!database->url) { 
     107                osync_error_set(error, OSYNC_ERROR_GENERIC, "Database name not set"); 
     108                goto error_free_database; 
     109        } 
     110 
     111        if (!database->objtype) { 
     112                osync_error_set(error, OSYNC_ERROR_GENERIC, "\"objtype\" of a database not set"); 
     113                goto error_free_database; 
     114        } 
     115 
     116        if (!database->objformat_name) { 
     117                osync_error_set(error, OSYNC_ERROR_GENERIC, "Object Fomrat \"%s\" of a database not set", database->objformat_name); 
     118                goto error_free_database; 
     119        } 
     120 
     121        env->databases = g_list_append(env->databases, database); 
     122 
     123        osync_trace(TRACE_EXIT, "%s", __func__); 
     124        return TRUE; 
     125 
     126error_free_database: 
     127        syncml_free_database(database); 
     128error: 
     129        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); 
     130        return FALSE; 
     131
     132 
     133static const char *_contenttype_to_format(const char *contenttype) 
     134
     135        if (!strcmp(contenttype, SML_ELEMENT_TEXT_VCARD)) { 
     136                return "contact"; 
     137        } 
     138        if (!strcmp(contenttype, SML_ELEMENT_TEXT_VCAL)) { 
     139                return "event"; 
     140        } 
     141        if (!strcmp(contenttype, SML_ELEMENT_TEXT_PLAIN)) { 
     142                return "note"; 
     143        } 
     144        return NULL; 
     145
     146 
     147static OSyncChangeType _to_osync_changetype(SmlChangeType type) 
     148
     149        switch (type) { 
     150                case SML_CHANGE_ADD: 
     151                        return OSYNC_CHANGE_TYPE_ADDED; 
     152                case SML_CHANGE_REPLACE: 
     153                        return OSYNC_CHANGE_TYPE_MODIFIED; 
     154                case SML_CHANGE_DELETE: 
     155                        return OSYNC_CHANGE_TYPE_DELETED; 
     156                default: 
     157                        ;        
     158        } 
     159        return OSYNC_CHANGE_TYPE_UNKNOWN; 
     160
     161 
     162static void _ds_event(SmlDsSession *dsession, SmlDsEvent event, void *userdata) 
     163
     164        osync_trace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, dsession, event, userdata); 
     165 
     166        SmlDatabase *database = (SmlDatabase *)userdata; 
     167 
     168        osync_trace(TRACE_INTERNAL, "database: %s", database->objtype); 
     169        switch (event) { 
     170                case SML_DS_EVENT_GOTCHANGES: 
     171                        database->gotChanges = TRUE; 
     172                        if (database->gotChanges && database->finalChanges) { 
     173                                osync_trace(TRACE_INTERNAL,"getChangesCtx report success at _recv_change"); 
     174                                osync_context_report_success(database->getChangesCtx); 
     175                                database->getChangesCtx = NULL; 
     176                        } 
     177                        break; 
     178                case SML_DS_EVENT_COMMITEDCHANGES:       
     179                        break; 
     180        } 
     181 
     182        osync_trace(TRACE_EXIT, "%s", __func__); 
     183
     184 
     185static SmlBool _recv_change(SmlDsSession *dsession, SmlChangeType type, const char *uid, char *data, unsigned int size, const char *contenttype, void *userdata, SmlError **smlerror) 
     186
     187        osync_trace(TRACE_ENTRY, "%s(%p, %i, %s, %p, %i, %s, %p, %p)", __func__, dsession, type, uid, data, size, contenttype, userdata, smlerror); 
     188        SmlDatabase *database = (SmlDatabase *)userdata; 
     189        OSyncError *error = NULL; 
     190        g_assert(database->getChangesCtx); 
     191 
     192        if (!type) { 
     193                osync_context_report_success(database->getChangesCtx); 
     194                osync_trace(TRACE_EXIT, "%s", __func__); 
     195                return TRUE; 
     196        } 
     197 
     198        OSyncChange *change = osync_change_new(&error); 
     199        if (!change) { 
     200                osync_error_set(&error, OSYNC_ERROR_GENERIC, "No change created: %s", osync_error_print(&error)); 
     201                goto error; 
     202        } 
     203         
     204//              osync_change_set_member(change, env->member); 
     205 
     206        osync_change_set_uid(change, uid); 
     207        if (contenttype != NULL) { 
     208                /* We specify the objformat plain for vcard and vcal 
     209                 * since we cannot be really sure what the device sends 
     210                 * us, without looking at the devinf. Since we dont use 
     211                 * the devinf yet, we let the opensync detector decide 
     212                 * what format the item is. 
     213                 *  
     214                 * For text/plain (notes) we specify the memo format,  
     215                 * so that it does not get detected */ 
     216 
     217                /* 
     218                if (!strcmp(contenttype, SML_ELEMENT_TEXT_VCARD)) 
     219                        objformat = g_strdup("plain"); 
     220                else if (!strcmp(contenttype, SML_ELEMENT_TEXT_VCAL)) 
     221                        objformat = g_strdup("plain"); 
     222                else if (!strcmp(contenttype, SML_ELEMENT_TEXT_PLAIN)) 
     223                        objformat = g_strdup("memo"); 
     224                        */ 
     225 
     226        } 
     227 
     228        /* XXX Workaround for mobiles which only handle localtime! TODO: make use of UTC field in DevCap and handle it is OpenSync framework! */ 
     229        /* 
     230        if (!strcmp(contenttype, SML_ELEMENT_TEXT_VCAL) && env->onlyLocaltime && type != SML_CHANGE_DELETE) { 
     231                char *_data = osync_time_vcal2utc(data); 
     232                g_free(data); 
     233                data = _data; 
     234                size = strlen(data); 
     235        } 
     236        */ 
     237 
     238        OSyncData *odata = osync_data_new(data, size+1, database->objformat, &error); 
     239        if (!odata) { 
     240                osync_change_unref(change); 
     241                goto error; 
     242        } 
     243 
     244 
     245//              if (_to_osync_changetype(type) == OSYNC_CHANGE_TYPE_DELETED) 
     246        if(contenttype) 
     247                osync_data_set_objtype(odata, _contenttype_to_format(contenttype)); 
     248        else 
     249                osync_data_set_objtype(odata, database->objtype); 
     250 
     251 
     252        osync_change_set_data(change, odata); 
     253        osync_change_set_changetype(change, _to_osync_changetype(type)); 
     254 
     255        osync_data_unref(odata); 
     256 
     257        osync_context_report_change(database->getChangesCtx, change); 
     258 
     259        osync_change_unref(change); 
     260 
     261        osync_trace(TRACE_EXIT, "%s", __func__); 
     262        return TRUE; 
     263 
     264error: 
     265//      osync_context_report_osyncwarning(ctx, error); 
     266        osync_error_unref(&error); 
     267 
     268        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error)); 
     269        return FALSE; 
     270
     271 
     272static void _recv_change_reply(SmlDsSession *dsession, SmlStatus *status, const char *newuid, void *userdata) 
     273
     274        osync_trace(TRACE_ENTRY, "%s(%p, %p, %s, %p)", __func__, dsession, status, newuid, userdata); 
     275        struct commitContext *ctx = userdata; 
     276        OSyncContext *context = ctx->context; 
     277         
     278        if (smlStatusGetClass(status) != SML_ERRORCLASS_SUCCESS) { 
     279                osync_context_report_error(context, OSYNC_ERROR_GENERIC, "Unable to commit change. Error %i", smlStatusGetCode(status)); 
     280        } else { 
     281                if (newuid) 
     282                        osync_change_set_uid(ctx->change, newuid); 
     283                g_free(ctx); 
     284                 
     285                osync_context_report_success(context); 
     286        } 
     287         
     288        osync_trace(TRACE_EXIT, "%s", __func__); 
     289
     290 
     291static void _recv_sync_reply(SmlSession *session, SmlStatus *status, void *userdata) 
     292
     293        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, session, status, userdata); 
     294         
     295        printf("Received an reply to our sync\n"); 
     296         
     297        osync_trace(TRACE_EXIT, "%s", __func__); 
     298
     299 
     300static void _recv_sync(SmlDsSession *dsession, unsigned int numchanges, void *userdata) 
     301
     302        osync_trace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, dsession, numchanges, userdata); 
     303        SmlDatabase *database = (SmlDatabase *)userdata; 
     304         
     305        osync_trace(TRACE_INTERNAL,"Going to receive %i changes - objtype: %s", numchanges, database->objtype); 
     306        printf("Going to receive %i changes\n", numchanges); 
     307 
     308        osync_trace(TRACE_EXIT, "%s", __func__); 
     309
     310 
     311static void _recv_alert_reply(SmlSession *session, SmlStatus *status, void *userdata) 
     312
     313        osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata); 
     314         
     315        SmlDatabase *database = (SmlDatabase*) userdata; 
     316 
     317        osync_trace(TRACE_INTERNAL, "Received an reply to our Alert - %s\n", database->objtype); 
     318         
     319 
     320        osync_trace(TRACE_EXIT, "%s", __func__); 
     321
     322 
     323static SmlBool _recv_alert(SmlDsSession *dsession, SmlAlertType type, const char *last, const char *next, void *userdata) 
     324
     325        osync_trace(TRACE_ENTRY, "%s(%p, %i, %s, %s, %p)", __func__, dsession, type, last, next, userdata); 
     326        SmlDatabase *database = (SmlDatabase*) userdata; 
     327        SmlPluginEnv *env = database->env; 
     328        SmlBool ret = TRUE; 
     329         
     330        char *key = g_strdup_printf("remoteanchor%s", smlDsSessionGetLocation(dsession)); 
     331 
     332        if ((!last || !osync_anchor_compare(env->anchor_path, key, last)) && type == SML_ALERT_TWO_WAY) 
     333                ret = FALSE; 
     334         
     335        osync_bool ans = osync_objtype_sink_get_slowsync(database->sink); 
     336        if (ans) 
     337                ret = FALSE; 
     338         
     339        if (!ret || type != SML_ALERT_TWO_WAY) 
     340                osync_objtype_sink_set_slowsync(database->sink, TRUE); 
     341         
     342        osync_anchor_update(env->anchor_path, key, next); 
     343        g_free(key); 
     344         
     345        if (!ret) { 
     346                smlDsSessionSendAlert(dsession, SML_ALERT_SLOW_SYNC, last, next, _recv_alert_reply, database, NULL); 
     347        } else { 
     348                smlDsSessionSendAlert(dsession, SML_ALERT_TWO_WAY, last, next, _recv_alert_reply, database, NULL); 
     349        } 
     350         
     351        smlDevInfAgentGetDevInf(env->agent); 
     352         
     353        osync_trace(TRACE_EXIT, "%s: %i", __func__, ret); 
     354        return ret; 
     355
     356 
     357static void _ds_alert(SmlDsSession *dsession, void *userdata) 
     358
     359        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, dsession, userdata); 
     360 
     361        SmlDatabase *database = (SmlDatabase *)userdata; 
     362 
     363        database->session = dsession; 
     364        smlDsSessionRef(dsession); 
     365 
     366        osync_trace(TRACE_EXIT, "%s", __func__); 
     367
     368 
     369static void _manager_event(SmlManager *manager, SmlManagerEventType type, SmlSession *session, SmlError *error, void *userdata) 
     370
     371        osync_trace(TRACE_ENTRY, "%s(%p, %i, %p, %p, %p)", __func__, manager, type, session, error, userdata); 
     372        SmlPluginEnv *env = userdata; 
     373        GList *o = NULL; 
     374 
     375        switch (type) { 
     376                case SML_MANAGER_SESSION_FLUSH: 
     377                case SML_MANAGER_CONNECT_DONE: 
     378                        env->gotDisconnect = FALSE; 
     379                        break; 
     380                case SML_MANAGER_DISCONNECT_DONE: 
     381                        osync_trace(TRACE_INTERNAL, "connection with device has ended"); 
     382                        env->gotDisconnect = TRUE; 
     383                         
     384                        o = env->databases; 
     385                        for (; o; o = o->next) { 
     386                                SmlDatabase *database = o->data; 
     387 
     388                                if (database->disconnectCtx) { 
     389                                        osync_context_report_success(database->disconnectCtx); 
     390                                        database->disconnectCtx = NULL; 
     391                                } 
     392                        } 
     393 
     394                        break; 
     395                case SML_MANAGER_TRANSPORT_ERROR: 
     396                        osync_trace(TRACE_INTERNAL, "There was an error in the transport: %s", smlErrorPrint(&error)); 
     397                        if (!env->gotDisconnect) { 
     398                                if (env->tryDisconnect == FALSE) { 
     399                                        env->tryDisconnect = TRUE; 
     400                                        smlTransportDisconnect(env->tsp, NULL, NULL); 
     401                                        while (!env->gotDisconnect) { 
     402                                                smlManagerDispatch(manager); 
     403                                        } 
     404                                } else { 
     405                                        env->gotDisconnect = TRUE; 
     406                                        osync_trace(TRACE_EXIT_ERROR, "%s: error while disconnecting: %s", __func__, smlErrorPrint(&error)); 
     407                                        return; 
     408                                } 
     409                        } 
     410                        goto error; 
     411                        break; 
     412                case SML_MANAGER_SESSION_NEW: 
     413                        osync_trace(TRACE_INTERNAL, "Just received a new session with ID %s\n", smlSessionGetSessionID(session)); 
     414                        smlSessionUseStringTable(session, env->useStringtable); 
     415                        smlSessionUseOnlyReplace(session, env->onlyReplace); 
     416                         
     417                        if (env->recvLimit) 
     418                                smlSessionSetReceivingLimit(session, env->recvLimit); 
     419                                 
     420                        if (env->maxObjSize) 
     421                                smlSessionSetReceivingMaxObjSize(session, env->maxObjSize); 
     422                         
     423                        env->session = session; 
     424                        smlSessionRef(session); 
     425                        break; 
     426                case SML_MANAGER_SESSION_FINAL: 
     427                        osync_trace(TRACE_INTERNAL, "Session %s reported final\n", smlSessionGetSessionID(session)); 
     428                        env->gotFinal = TRUE; 
     429 
     430                        if (env->connectCtx) { 
     431                                osync_context_report_success(env->connectCtx); 
     432                                env->connectCtx = NULL; 
     433                        } 
     434 
     435                        o = env->databases; 
     436                        for (; o; o = o->next) { 
     437                                SmlDatabase *database = o->data; 
     438 
     439                                osync_trace(TRACE_INTERNAL, "gotChanges: %i getChangesCtx: %p objtype: %s", 
     440                                        database->gotChanges, database->getChangesCtx, database->objtype); 
     441 
     442                                if (database->getChangesCtx) { 
     443                                        database->finalChanges = TRUE; 
     444                                        if (database->gotChanges && database->finalChanges) { 
     445                                                osync_trace(TRACE_INTERNAL,"getChangesCtx report success at final"); 
     446                                                osync_context_report_success(database->getChangesCtx); 
     447                                                database->getChangesCtx = NULL; 
     448                                        } 
     449 
     450                                } 
     451 
     452 
     453                                if (database->commitCtx) { 
     454                                        osync_context_report_success(database->commitCtx); 
     455                                        database->commitCtx = NULL; 
     456                                } 
     457                         
     458 
     459                        } 
     460                        break; 
     461                case SML_MANAGER_SESSION_END: 
     462                        osync_trace(TRACE_INTERNAL, "Session %s has ended\n", smlSessionGetSessionID(session)); 
     463                        if (!smlTransportDisconnect(env->tsp, NULL, &error)) 
     464                                goto error; 
     465                        break; 
     466                case SML_MANAGER_SESSION_ERROR: 
     467                        osync_trace(TRACE_INTERNAL, "There was an error in the session %s: %s", smlSessionGetSessionID(session), smlErrorPrint(&error)); 
     468                        goto error; 
     469                        break; 
     470                case SML_MANAGER_SESSION_WARNING: 
     471                        printf("WARNING: %s\n", smlErrorPrint(&error)); 
     472                        break; 
     473        } 
     474         
     475        osync_trace(TRACE_EXIT, "%s", __func__); 
     476        return; 
     477         
     478error:; 
     479        OSyncError *oserror = NULL; 
     480        osync_error_set(&oserror, OSYNC_ERROR_GENERIC, smlErrorPrint(&error)); 
     481         
     482        if (env->connectCtx) { 
     483                osync_context_report_osyncerror(env->connectCtx, oserror); 
     484                env->connectCtx = NULL; 
     485        } 
     486 
     487         
     488        o = env->databases; 
     489        for (; o; o = o->next) { 
     490                SmlDatabase *database = o->data; 
     491 
     492                 
     493                if (database->getChangesCtx) { 
     494                        osync_context_report_osyncerror(database->getChangesCtx, oserror); 
     495                        database->getChangesCtx = NULL; 
     496                } 
     497 
     498                if (database->commitCtx) { 
     499                        osync_context_report_osyncerror(database->commitCtx, oserror); 
     500                        database->commitCtx = NULL; 
     501                } 
     502 
     503                if (database->disconnectCtx) { 
     504                        osync_context_report_osyncerror(database->disconnectCtx, oserror); 
     505                        database->disconnectCtx = NULL; 
     506                } 
     507 
     508                 
     509        } 
     510 
     511        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&oserror)); 
     512
     513 
     514static gboolean _sessions_prepare(GSource *source, gint *timeout_) 
     515
     516        *timeout_ = 50; 
     517        return FALSE; 
     518
     519 
     520static gboolean _sessions_check(GSource *source) 
     521
     522        SmlPluginEnv *env = *((SmlPluginEnv **)(source + 1)); 
     523 
     524        GList *o = env->databases; 
     525        for (; o; o = o->next) { 
     526                SmlDatabase *database = o->data; 
     527                if (database->session && smlDsSessionCheck(database->session)) 
     528                        return TRUE; 
     529        } 
     530                 
     531        if (smlManagerCheck(env->manager)) 
     532                return TRUE; 
     533                 
     534        return FALSE; 
     535
     536 
     537static gboolean _sessions_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) 
     538
     539        SmlPluginEnv *env = user_data; 
     540         
     541        GList *o = env->databases; 
     542        for (; o; o = o->next) { 
     543                SmlDatabase *database = o->data; 
     544                if (database->session) 
     545                        smlDsSessionDispatch(database->session); 
     546        } 
     547 
     548        smlManagerDispatch(env->manager); 
     549        return TRUE; 
     550
     551 
     552static void _verify_user(SmlAuthenticator *auth, const char *username, const char *password, void *userdata, SmlErrorType *reply) 
     553
     554        osync_trace(TRACE_ENTRY, "%s(%p, %s, %s, %p, %p)", __func__, auth, username, password, userdata, reply); 
     555        SmlPluginEnv *env = userdata; 
     556         
     557        osync_trace(TRACE_SENSITIVE, "configured is %s, %s", env->username, env->password); 
     558        if (env->username && (!env->password || !username || !password || strcmp(env->username, username) || strcmp(env->password, password))) { 
     559                *reply = SML_ERROR_AUTH_REJECTED; 
     560        } else { 
     561                *reply = SML_AUTH_ACCEPTED; 
     562        } 
     563        osync_trace(TRACE_EXIT, "%s: %i", __func__, *reply); 
     564
     565 
     566static void connect_http_server(void *data, OSyncPluginInfo *info, OSyncContext *ctx) 
     567
     568        osync_trace(TRACE_ENTRY, "%s(%p)", __func__, ctx); 
     569        SmlPluginEnv *env = (SmlPluginEnv *)data; 
     570 
     571        env->tryDisconnect = FALSE; 
     572 
     573        /* For the obex client, we will store the context at this point since 
     574         * we can only answer it as soon as the device returned an answer to our san */ 
     575        env->connectCtx = ctx; 
     576 
     577        /* This ref counting is needed to avoid a segfault. TODO: review if this is really needed.  
     578         * To reproduce the segfault - just remove the osync_context_ref() call in the next line. */ 
     579        osync_context_ref(env->connectCtx); 
     580   
     581        /* For the http server we can report success right away since we know 
     582         * that we already received an alert (otherwise we could not have triggered 
     583         * the synchronization) */ 
     584        GList *o = env->databases; 
     585        for (; o; o = o->next) { 
     586                SmlDatabase *database = o->data; 
     587 
     588                if (database->session) 
     589                        smlDsSessionGetAlert(database->session, _recv_alert, database); 
     590        } 
     591         
     592        /* If we already received the final, we just report success. otherwise 
     593         * we let the final report success */ 
     594        if (env->gotFinal) 
     595                osync_context_report_success(ctx); 
     596        else 
     597                env->connectCtx = ctx; 
     598 
     599        osync_trace(TRACE_EXIT, "%s", __func__); 
     600        return; 
     601
     602 
     603static void connect_obex_client(void *data, OSyncPluginInfo *info, OSyncContext *ctx) 
     604
     605        osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); 
     606 
     607        SmlPluginEnv *env = (SmlPluginEnv *)data; 
     608 
     609        SmlError *error = NULL; 
     610        OSyncError *oserror = NULL; 
     611 
     612        if (env->isConnected) { 
     613                osync_context_report_success(ctx); 
     614                osync_trace(TRACE_EXIT, "%s", __func__); 
     615                return; 
     616        } 
     617 
     618        env->tryDisconnect = FALSE; 
     619 
     620        /* For the obex client, we will store the context at this point since 
     621         * we can only answer it as soon as the device returned an answer to our san */ 
     622        env->connectCtx = ctx; 
     623 
     624        /* This ref counting is needed to avoid a segfault. TODO: review if this is really needed. 
     625           To reproduce the segfault - just remove the osync_context_ref() call in the next line. */  
     626        osync_context_ref(env->connectCtx); 
     627         
     628        if (!smlTransportConnect(env->tsp, &error)) 
     629                goto error; 
     630        else 
     631                env->isConnected = TRUE; 
     632 
     633        if (!smlNotificationSend(env->san, env->tsp, &error)) 
     634                goto error_free_san; 
     635 
     636        smlNotificationFree(env->san); 
     637        env->san = NULL; 
     638 
     639        osync_trace(TRACE_EXIT, "%s", __func__); 
     640        return; 
     641         
     642error_free_san: 
     643        smlNotificationFree(env->san); 
     644        env->san = NULL; 
     645error: 
     646        osync_error_set(&oserror, OSYNC_ERROR_GENERIC, "%s", smlErrorPrint(&error)); 
     647        smlErrorDeref(&error); 
     648        osync_context_report_osyncerror(ctx, oserror); 
     649        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&oserror)); 
     650
     651 
     652static void get_changeinfo(void *data, OSyncPluginInfo *info, OSyncContext *ctx) 
     653
     654        osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); 
     655        SmlPluginEnv *env = (SmlPluginEnv *)data; 
     656 
     657        OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); 
     658        SmlDatabase *database = osync_objtype_sink_get_userdata(sink); 
     659 
     660        database->getChangesCtx = ctx; 
     661        osync_context_ref(database->getChangesCtx); 
     662 
     663        SmlError *error = NULL; 
     664        OSyncError *oserror = NULL; 
     665         
     666        if (smlTransportGetType(env->tsp) == SML_TRANSPORT_OBEX_CLIENT) { 
     667                smlDsSessionGetAlert(database->session, _recv_alert, database); 
     668        } 
     669         
     670        smlDsSessionGetEvent(database->session, _ds_event, database); 
     671        smlDsSessionGetSync(database->session, _recv_sync, database); 
     672        smlDsSessionGetChanges(database->session, _recv_change, database); 
     673 
     674        // avoid flushing to early 
     675        env->num++; 
     676 
     677        if (env->num >= g_list_length(env->databases)) { 
     678                env->num = 0; 
     679                if (!smlSessionFlush(env->session, TRUE, &error)) 
     680                        goto error; 
     681        } 
     682 
     683        osync_trace(TRACE_EXIT, "%s", __func__); 
     684        return; 
     685         
     686error: 
     687        osync_error_set(&oserror, OSYNC_ERROR_GENERIC, "%s", smlErrorPrint(&error)); 
     688        smlErrorDeref(&error); 
     689        osync_context_report_osyncerror(ctx, oserror); 
     690        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&oserror)); 
     691
     692 
     693static void sync_done(void *data, OSyncPluginInfo *info, OSyncContext *ctx) 
     694
     695        osync_context_report_success(ctx); 
     696
     697 
     698static void disconnect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) 
     699
     700        osync_trace(TRACE_ENTRY, "%s(%p)", __func__, ctx); 
     701        SmlPluginEnv *env = (SmlPluginEnv *)data; 
     702 
     703        OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); 
     704        SmlDatabase *database = osync_objtype_sink_get_userdata(sink); 
     705 
     706        OSyncError *oserror = NULL; 
     707        SmlError *error = NULL; 
     708         
     709        env->gotFinal = FALSE; 
     710         
     711        if (!smlSessionEnd(env->session, &error)) 
     712                goto error; 
     713         
     714        if (env->gotDisconnect) { 
     715                osync_context_report_success(ctx); 
     716        } else { 
     717                database->disconnectCtx = ctx; 
     718                osync_context_ref(database->disconnectCtx); 
     719        } 
     720 
     721 
     722        osync_trace(TRACE_EXIT, "%s", __func__); 
     723        return; 
     724         
     725error: 
     726        osync_error_set(&oserror, OSYNC_ERROR_GENERIC, "%s", smlErrorPrint(&error)); 
     727        smlErrorDeref(&error); 
     728        osync_context_report_osyncerror(ctx, oserror); 
     729        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&oserror)); 
     730
     731 
     732static void finalize(void *data) 
     733
     734        osync_trace(TRACE_ENTRY, "%s(%p)", __func__, data); 
     735        SmlPluginEnv *env = (SmlPluginEnv *)data; 
     736         
     737        /* Stop the manager */ 
     738        if (env->manager) 
     739                smlManagerStop(env->manager); 
     740         
     741        if (env->tsp) 
     742                smlTransportFinalize(env->tsp, NULL); 
     743         
     744        if (env->tsp) 
     745                smlTransportFree(env->tsp); 
     746 
     747        if (env->san) 
     748                smlNotificationFree(env->san); 
     749 
     750        if (env->identifier) 
     751                g_free(env->identifier); 
     752 
     753        if (env->username) 
     754                g_free(env->username); 
     755 
     756        if (env->password) 
     757                g_free(env->password); 
     758 
     759        if (env->bluetoothAddress) 
     760                g_free(env->bluetoothAddress); 
     761 
     762        if (env->url) 
     763                g_free(env->url); 
     764 
     765        if (env->anchor_path) 
     766                g_free(env->anchor_path); 
     767 
     768        if (env->source) { 
     769                g_source_destroy(env->source); 
     770                g_source_unref(env->source); 
     771                g_free(env->source_functions); 
     772        } 
     773 
     774        while (env->databases) { 
     775                SmlDatabase *db = env->databases->data; 
     776                syncml_free_database(db); 
     777 
     778                env->databases = g_list_remove(env->databases, db); 
     779        } 
     780         
     781        g_free(env); 
     782 
     783        osync_trace(TRACE_EXIT, "%s", __func__); 
     784
     785 
     786static void batch_commit(void *data, OSyncPluginInfo *info, OSyncContext *ctx, OSyncContext **contexts, OSyncChange **changes) 
     787
     788        osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, ctx, contexts, changes); 
     789        SmlPluginEnv *env = (SmlPluginEnv *)data; 
     790 
     791        OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); 
     792        SmlDatabase *database = osync_objtype_sink_get_userdata(sink); 
     793 
     794        SmlError *error = NULL; 
     795        OSyncError *oserror = NULL; 
     796        int i = 0; 
     797        int num = 0; 
     798         
     799        database->commitCtx = ctx; 
     800        osync_context_ref(database->commitCtx); 
     801         
     802        for (i = 0; changes[i]; i++) { 
     803                /* 
     804                if (!strcmp(_format_to_contenttype(changes[i]), SML_ELEMENT_TEXT_VCARD)) 
     805                        numContact++; 
     806                else if (!strcmp(_format_to_contenttype(changes[i]), SML_ELEMENT_TEXT_VCAL)) 
     807                        numCalendar++; 
     808                else if (!strcmp(_format_to_contenttype(changes[i]), SML_ELEMENT_TEXT_PLAIN)) 
     809                        numNote++; 
     810                */       
     811                num++; 
     812        } 
     813         
     814        if (!smlDsSessionSendSync(database->session, num, _recv_sync_reply, NULL, &error)) 
     815                goto error; 
     816 
     817        for (i = 0; changes[i]; i++) { 
     818                OSyncChange *change = changes[i]; 
     819                OSyncContext *context = contexts[i]; 
     820                 
     821                osync_trace(TRACE_INTERNAL, "Uid: \"%s\", Format: \"%s\", Changetype: \"%i\"", osync_change_get_uid(change), osync_change_get_objtype(change), osync_change_get_changetype(change)); 
     822                 
     823                struct commitContext *tracer = osync_try_malloc0(sizeof(struct commitContext), &oserror); 
     824                if (!tracer) 
     825                        goto oserror; 
     826                 
     827                tracer->change = change; 
     828                tracer->context = context; 
     829 
     830                OSyncData *data = osync_change_get_data(change); 
     831                char *buf = NULL; 
     832                unsigned int size = 0; 
     833                osync_data_get_data(data, &buf, &size); 
     834         
     835                osync_trace(TRACE_INTERNAL, "Committing entry \"%s\": \"%s\"", osync_change_get_uid(change), buf); 
     836