Changeset 2408

Show
Ignore:
Timestamp:
08/05/07 21:54:03 (1 year ago)
Author:
dgollub
Message:

Initial port of irmc-sync to 0.30 API - to 100% untested.

TODO:
- implemenet discover function
- lock connect/disconnect to connect only once to the mobile
- handle todo object type/database correctly (check IrMC spec...)
- build bfb noinst shared lib and link against irmc-sync against it for
cable support.... (low priority?)


Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/irmc-sync/src/irmc_obex.c

    r1453 r2408  
    7272  case OBEX_EV_REQDONE: 
    7373    userdata->busy = 0; 
    74     if(mode == OBEX_CLIENT) { 
     74    //if(mode == OBEX_CLIENT) { 
     75    // FIXME: fix obex header 
     76    if (mode == 0) { 
    7577      client_done(handle, object, obex_cmd, obex_rsp); 
    7678    } else  { 
     
    316318  tcsetattr(userdata->fd, TCSANOW, &newtio); 
    317319 
     320#if HAVE_COBEX   
    318321  if (userdata->cabletype == IRMC_CABLE_SIEMENS) 
    319322    return(cobex_connect(handle, ud)); 
     323#endif   
    320324  if (userdata->cabletype != IRMC_CABLE_ERICSSON) 
    321325    goto err; 
     
    455459obex_t* irmc_obex_client(irmc_config *config) { 
    456460  obex_ctrans_t bttrans; 
     461#if HAVE_COBEX   
    457462  obex_ctrans_t cabletrans = { obex_cable_connect, cobex_disconnect, 
    458463                               NULL, cobex_write,  
    459464                               cobex_handleinput, 0 }; 
     465#endif   
     466 
    460467#if HAVE_IRDA 
    461468  obex_ctrans_t irdatrans = { obex_irda_connect, obex_irda_disconnect, 
     
    482489  irdatrans.customdata = userdata; 
    483490#endif 
     491 
     492#if HAVE_COBEX   
    484493  cabletrans.customdata = userdata; 
     494#endif   
     495 
    485496#endif 
    486497#if OBEX_USERDATA 
     
    489500  irdatrans.userdata = userdata; 
    490501#endif 
     502   
     503#if HAVE_COBEX   
    491504  cabletrans.userdata = userdata; 
     505#endif   
     506 
    492507#endif 
    493508  memcpy(&userdata->btu, &config->btunit, sizeof(struct bt_unit)); 
     
    524539    break; 
    525540  case MEDIUM_CABLE: 
     541#if HAVE_COBEX     
    526542    if (!(handle = OBEX_Init(OBEX_TRANS_CUST, obex_event, 0))) 
    527543      return(0); 
    528544    OBEX_RegisterCTransport(handle, &cabletrans); 
     545#endif     
    529546    break; 
    530547  } 
     
    666683    }  
    667684  } else { 
    668     osync_error_free(&error); 
     685    osync_error_unref(&error); 
    669686  } 
    670687  return(NULL); 
  • plugins/irmc-sync/src/irmc_sync.c

    r1693 r2408  
    2323 
    2424#include <opensync/opensync.h> 
    25 #include <stdlib.h> 
    26 #include <string.h> 
     25#include <opensync/opensync-format.h> 
     26#include <opensync/opensync-plugin.h> 
     27#include <opensync/opensync-context.h> 
     28#include <opensync/opensync-data.h> 
     29#include <opensync/opensync-helper.h> 
     30#include <opensync/opensync-group.h> 
     31#include <opensync/opensync-version.h> 
     32 
    2733#include <assert.h> 
    2834 
     
    5561} data_type_information; 
    5662 
    57 gboolean get_generic_changeinfo(OSyncContext *ctx, data_type_information *info, OSyncError **error); 
    58 void create_calendar_changeinfo(int sync_type, OSyncContext *ctx, char *data, char *luid, int type); 
    59 void create_addressbook_changeinfo(int sync_type, OSyncContext *ctx, char *data, char *luid, int type); 
    60 void create_notebook_changeinfo(int sync_type, OSyncContext *ctx, char *data, char *luid, int type); 
    61  
    6263void safe_strcat(char *s1, const char *s2, int len) 
    6364{ 
     
    117118    sn = irmc_obex_get_serial(config->obexhandle); 
    118119  } else { 
    119     osync_error_free(&error); 
     120    osync_error_unref(&error); 
    120121    error = NULL; 
    121122  } 
     
    123124  irmc_obex_disconnect(config->obexhandle, &error); 
    124125  if (error) 
    125     osync_error_free(&error); 
     126    osync_error_unref(&error); 
    126127 
    127128  irmc_obex_cleanup(config->obexhandle); 
     
    137138    irmc_obex_disconnect(config->obexhandle, &error); 
    138139    if (error) 
    139       osync_error_free(&error); 
     140      osync_error_unref(&error); 
    140141 
    141142    irmc_obex_cleanup(config->obexhandle); 
     
    231232 * Load the synchronization anchors. 
    232233 */ 
    233 void load_sync_anchors( OSyncMember *member, irmc_config *config ) 
    234 
    235   osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, member, config);                      
    236   char *anchor = osync_anchor_retrieve(member, "event"); 
     234void load_sync_anchors( irmc_environment *env ) 
     235
     236  osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env); 
     237 
     238  irmc_config *config = &(env->config); 
     239 
     240  char *anchor = osync_anchor_retrieve(env->anchor_path, "event"); 
    237241  if (!anchor) { 
    238242    config->calendar_changecounter = 0; 
     
    247251  g_free( anchor ); 
    248252 
    249   anchor = osync_anchor_retrieve(member, "contact"); 
     253  anchor = osync_anchor_retrieve(env->anchor_path, "contact"); 
    250254  if (!anchor) { 
    251255    config->addressbook_changecounter = 0; 
     
    259263  g_free( anchor ); 
    260264 
    261   anchor = osync_anchor_retrieve(member, "note"); 
     265  anchor = osync_anchor_retrieve(env->anchor_path, "note"); 
    262266  if (!anchor) { 
    263267    config->notebook_changecounter = 0; 
     
    272276  g_free( anchor ); 
    273277 
    274   anchor = osync_anchor_retrieve(member, "general"); 
     278  anchor = osync_anchor_retrieve(env->anchor_path, "general"); 
    275279  if (!anchor) { 
    276280    config->serial_number = NULL; 
     
    289293 * Save synchronization anchors. 
    290294 */ 
    291 void save_sync_anchors( OSyncMember *member, const irmc_config *config ) 
    292 
    293   osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, member, config);                      
     295void save_sync_anchors( const irmc_environment *env ) 
     296
     297  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, env); 
     298 
    294299  char anchor[ 1024 ]; 
    295  
     300  const irmc_config *config = &(env->config); 
     301 
     302  /* TODO: check if sink is active  
    296303  if (osync_member_objtype_enabled(member, "event")) { 
    297304        if (config->calendar_changecounter >= 0 && strcmp(config->calendar_dbid, "FFFFFF")) { 
    298305                snprintf( anchor, sizeof( anchor ), "%d:%s", config->calendar_changecounter, config->calendar_dbid ); 
    299                 osync_anchor_update( member, "event", anchor ); 
     306                osync_anchor_update( env->anchor_path, "event", anchor ); 
    300307        } else { 
    301308                osync_trace(TRACE_INTERNAL, "ERROR: Invalid values for event anchor detected."); 
     
    308315        if (config->addressbook_changecounter >= 0 && strcmp(config->addressbook_dbid, "FFFFFF")) { 
    309316                snprintf( anchor, sizeof( anchor ), "%d:%s", config->addressbook_changecounter, config->addressbook_dbid ); 
    310                 osync_anchor_update( member, "contact", anchor ); 
     317                osync_anchor_update( env->anchor_path, "contact", anchor ); 
    311318        } else { 
    312319                osync_trace(TRACE_INTERNAL, "ERROR: Invalid values for contact anchor detected."); 
     
    319326        if (config->notebook_changecounter >= 0 && strcmp(config->notebook_dbid, "FFFFFF")) { 
    320327                snprintf( anchor, sizeof( anchor ), "%d:%s", config->notebook_changecounter, config->notebook_dbid ); 
    321                 osync_anchor_update( member, "note", anchor ); 
     328                osync_anchor_update( env->anchor_path, "note", anchor ); 
    322329        } else { 
    323330                osync_trace(TRACE_INTERNAL, "ERROR: Invalid values for note anchor detected."); 
     
    326333        osync_trace(TRACE_INTERNAL, "WARNING: Synchronization of notes was disabled."); 
    327334  } 
     335  */ 
    328336    
    329337  snprintf( anchor, sizeof( anchor ), "%s", config->serial_number ); 
    330   osync_anchor_update( member, "general", anchor ); 
     338  osync_anchor_update( env->anchor_path, "general", anchor ); 
    331339  osync_trace(TRACE_EXIT, "%s", __func__); 
    332340} 
    333341 
     342// TODO: drop me 
     343#if 0 
    334344/** 
    335345 * Tests whether a connection to a device with the given configuration can 
     
    347357  // parse the configuration 
    348358  if (!parse_settings(&config, configuration, strlen(configuration), &error)) { 
    349     osync_error_free(&error); 
     359    osync_error_unref(&error); 
    350360    *result = 0; 
    351361    osync_trace(TRACE_EXIT, "%s: %p", __func__, result); 
     
    357367  // connect to the device 
    358368  if (!irmc_obex_connect(config.obexhandle, config.donttellsync ? NULL : "IRMC-SYNC", &error)) { 
    359     osync_error_free(&error); 
     369    osync_error_unref(&error); 
    360370    if (!irmc_obex_disconnect(config.obexhandle, &error)) 
    361       osync_error_free(&error); 
     371      osync_error_unref(&error); 
    362372 
    363373    *result = 0; 
     
    371381  // retrieve the 'telecom/devinfo.txt' file, which is available on all IrMC capable devices 
    372382  if (!irmc_obex_get(config.obexhandle, "telecom/devinfo.txt", data, &size, &error)) { 
    373     osync_error_free(&error); 
     383    osync_error_unref(&error); 
    374384    if (!irmc_obex_disconnect(config.obexhandle, &error)) 
    375       osync_error_free(&error); 
     385      osync_error_unref(&error); 
    376386    irmc_obex_cleanup(config.obexhandle); 
    377387 
     
    384394  // succeeded to connect and fetch data 
    385395  if (!irmc_obex_disconnect(config.obexhandle, &error)) 
    386     osync_error_free(&error); 
     396    osync_error_unref(&error); 
    387397  irmc_obex_cleanup(config.obexhandle); 
    388398 
     
    391401  return result; 
    392402} 
    393  
    394 /** 
    395  * Checks whether a slowsync is necessary. 
    396  * 
    397  * That's the case if one of the following conditions matches: 
    398  *   - the device has an unknown serial number 
    399  *   - the database id differs from our saved one 
    400  *   - the changelog contains a '*' in the last line 
    401  */ 
    402 gboolean detect_slowsync(int changecounter, char *object, char **dbid, char **serial_number, 
    403                          gboolean *slowsync, obex_t obexhandle, OSyncError **error) 
    404 
    405   osync_trace(TRACE_ENTRY, "%s(%d, %s, %s, %s, %p, %p)", __func__, changecounter, object, *dbid, *serial_number, obexhandle, error); 
    406  
    407   char *data; 
    408   char *datap; 
    409   int len = DATABUFSIZE; 
    410   char serial[256]; 
    411   char did[256] = ""; 
    412   char *filename; 
    413   int ret; 
    414  
    415   data = g_malloc(DATABUFSIZE); 
    416   datap = data; 
    417  
    418   filename = g_strdup_printf("telecom/%s/luid/%d.log", object, changecounter); 
    419  
    420   memset(data, 0, DATABUFSIZE); 
    421   len = DATABUFSIZE - 1; 
    422   if (!irmc_obex_get(obexhandle, filename, data, &len, error)) { 
    423     g_free(filename); 
    424     g_free(data); 
    425     osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); 
    426     return FALSE; 
    427   } 
    428  
    429   g_free(filename); 
    430   data[len] = '\0'; 
    431  
    432   ret = sscanf(datap, "SN:%256s\r\n", serial); 
    433  if (ret > 0) { 
    434     if (!*serial_number || strcmp(*serial_number, serial)) { 
    435       if (*serial_number) 
    436         g_free(*serial_number); 
    437       *serial_number = g_strdup(serial); 
    438       *slowsync = TRUE; 
    439     } 
    440   } 
    441   datap = strstr(datap, "\r\n"); 
    442   if (!datap) { 
    443     g_free(data); 
    444     osync_trace(TRACE_EXIT, "%s: TRUE", __func__); 
    445     return TRUE; 
    446   } 
    447  
    448   datap+=2; 
    449   sscanf(datap, "DID:%256s\r\n", did); 
    450   if (!*dbid || strcmp(*dbid, did)) { 
    451     // This is a new database 
    452     if (*dbid) 
    453       g_free(*dbid); 
    454     *dbid = g_strdup(did); 
    455     *slowsync = TRUE; 
    456   } 
    457   datap = strstr(datap, "\r\n"); 
    458   if (!datap) { 
    459     g_free(data); 
    460     osync_trace(TRACE_EXIT, "%s: TRUE", __func__); 
    461     return TRUE; 
    462   } 
    463   datap+=2; 
    464   //sscanf(datap, "Total-Records:%d\r\n", &foo); 
    465   datap = strstr(datap, "\r\n"); 
    466   if (!datap) { 
    467     g_free(data); 
    468     osync_trace(TRACE_EXIT, "%s: TRUE", __func__); 
    469     return TRUE; 
    470   } 
    471   datap+=2; 
    472   //sscanf(datap, "Maximum-Records:%d\r\n", &foo); 
    473   datap = strstr(datap, "\r\n"); 
    474  
    475   if ( strstr(datap, "*") != NULL ) { 
    476     *slowsync = TRUE; 
    477   } 
    478  
    479   g_free(data); 
    480  
    481   osync_trace(TRACE_EXIT, "%s: TRUE", __func__); 
    482   return TRUE; 
    483 
    484  
    485  
    486 /** 
    487  * Initialize the connection. 
    488  */ 
    489 static void *irmcInitialize(OSyncMember *member, OSyncError **error) 
    490 
    491   osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, member, error);                       
    492   char *configdata; 
    493   int configsize; 
    494  
    495   // create new environment, where all connection information are stored in 
    496   irmc_environment *env = malloc(sizeof(irmc_environment)); 
    497   assert(env != NULL); 
    498   memset(env, 0, sizeof(irmc_environment)); 
    499  
    500   // retrieve the config data for this member 
    501   if (!osync_member_get_config(member, &configdata, &configsize, error)) { 
    502     osync_error_update(error, "Unable to get config data: %s", osync_error_print(error)); 
    503     free(env); 
    504     osync_trace(TRACE_EXIT, "%s: NULL", __func__); 
    505     return NULL; 
    506   } 
    507  
    508   // parse the config data of this member 
    509   if (!parse_settings( &(env->config), configdata, configsize, error)) { 
    510     osync_error_update(error, "Unable to parse config data: %s", osync_error_print(error)); 
    511     free(env); 
    512     osync_trace(TRACE_EXIT, "%s: NULL", __func__); 
    513     return NULL; 
    514   } 
    515  
    516   free(configdata); 
    517   env->member = member; 
    518  
    519   // return the environment 
    520   osync_trace(TRACE_EXIT, "%s: %p", __func__, env); 
    521   return (void *)env; 
    522 
    523  
    524 /** 
    525  * Establishes connection to the device. 
    526  */ 
    527 static void irmcConnect(OSyncContext *ctx) 
    528 
    529   osync_trace(TRACE_ENTRY, "%s(%p)", __func__, ctx);                     
    530   irmc_environment *env = (irmc_environment *)osync_context_get_plugin_data(ctx); 
    531   irmc_config *config = &(env->config); 
    532  
    533   config->obexhandle = irmc_obex_client(config); 
    534  
    535   // connect to the device 
     403#endif 
     404 
     405/** 
     406 * Creates the calendar specific changeinfo for slow- and fastsync 
     407 */ 
     408void create_calendar_changeinfo(int sync_type, OSyncContext *ctx, char *data, char *luid, int type) 
     409
     410  osync_trace(TRACE_ENTRY, "%s(%i, %p, %p, %s, %i)", __func__, sync_type, ctx, data, luid, type); 
     411  osync_trace(TRACE_SENSITIVE, "Content of data:\n%s", data); 
     412 
    536413  OSyncError *error = NULL; 
    537   if (!irmc_obex_connect(config->obexhandle, config->donttellsync ? NULL : "IRMC-SYNC", &error)) { 
    538     irmc_disconnect(config); 
    539     osync_context_report_osyncerror(ctx, &error); 
    540     osync_trace(TRACE_EXIT, "%s: %s", __func__, osync_error_print(&error)); 
    541     return; 
    542   } 
    543  
    544   // load the synchronization anchors 
    545   load_sync_anchors(env->member, config); 
    546  
    547   // check whether a slowsync is necessary 
    548  
    549   gboolean slowsync = FALSE;   
    550414   
    551   if (osync_member_objtype_enabled(env->member, "event")) {  
    552     slowsync = FALSE; 
    553     if ( !detect_slowsync( config->calendar_changecounter, "cal", &(config->calendar_dbid), 
    554                            &(config->serial_number), &slowsync, config->obexhandle, &error ) ) 
    555     { 
    556       irmc_disconnect(config); 
    557       osync_context_report_osyncerror(ctx, &error); 
    558       osync_trace(TRACE_EXIT, "%s: %s", __func__, osync_error_print(&error)); 
    559       return; 
     415  if (sync_type == SLOW_SYNC) { 
     416    char *event_start = data, *todo_start; 
     417    char *event_end = NULL; 
     418    char *event = NULL; 
     419    int objtype; 
     420 
     421 
     422    do { 
     423      char *start = event_start; 
     424      objtype = SYNC_OBJECT_TYPE_CALENDAR; 
     425      event_start = strstr(start, "BEGIN:VEVENT"); 
     426      todo_start = strstr(start, "BEGIN:VTODO"); 
     427      if (!event_start || (todo_start && (todo_start < event_start))) { 
     428        event_start = todo_start; 
     429        objtype = SYNC_OBJECT_TYPE_TODO; 
     430      } 
     431      if (objtype == SYNC_OBJECT_TYPE_CALENDAR) 
     432        if ((event_end = strstr(start, "END:VEVENT"))) 
     433          event_end += strlen("END:VEVENT"); 
     434 
     435      if (objtype == SYNC_OBJECT_TYPE_TODO) 
     436        if ((event_end = strstr(start, "END:VTODO"))) 
     437          event_end += strlen("END:VTODO"); 
     438 
     439      if (event_start && event_end) { 
     440        int pos = 0; 
     441        int event_size = event_end - event_start + 256; 
     442        event = g_malloc(event_size); 
     443        memset(event, 0, event_size); 
     444 
     445        sprintf(event, "BEGIN:VCALENDAR\r\nVERSION:1.0\r\n"); 
     446        pos = strlen(event); 
     447        memcpy(event+pos,event_start,event_end-event_start); 
     448        sprintf(event+(pos+event_end-event_start), "\r\nEND:VCALENDAR\r\n"); 
     449 
     450        OSyncChange *change = osync_change_new(&error); 
     451        g_assert(change); 
     452 
     453 
     454        if (objtype == SYNC_OBJECT_TYPE_CALENDAR) { 
     455          //osync_change_set_objformat_string(change, "vevent10"); 
     456        } else if (objtype == SYNC_OBJECT_TYPE_TODO) { 
     457          //osync_change_set_objformat_string(change, "vtodo10"); 
     458        } 
     459 
     460        event_start = strstr(event, "X-IRMC-LUID:"); 
     461        if (event_start) { 
     462          char luid[256]; 
     463          if (sscanf(event_start, "X-IRMC-LUID:%256s", luid)) { 
     464            osync_change_set_uid(change, g_strdup(luid)); 
     465          } 
     466        } 
     467        event_size = strlen(event); 
     468 
     469        // TODO set data 
     470        OSyncData *data = NULL; 
     471        // OSyncData *data = osync_data_new(event, event_size, objformatXXX, &error); 
     472 
     473        osync_change_set_data(change, data); 
     474        osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_ADDED); 
     475        osync_context_report_change(ctx, change); 
     476      } 
     477 
     478      event_start = event_end; 
     479    } while(event_start); 
     480 
     481  } else { 
     482    OSyncChange *change = osync_change_new(&error); 
     483    g_assert(change); 
     484 
     485    //osync_change_set_objformat_string(change, "plain"); 
     486    osync_change_set_uid(change, g_strdup(luid)); 
     487 
     488    int event_size = strlen(data); 
     489    if (event_size > 0) { 
     490      event_size = strlen(data); 
    560491    } else { 
    561       osync_member_set_slow_sync(env->member, "event", slowsync); 
    562     } 
    563   } 
     492      data = NULL; 
     493      event_size = 0; 
     494    } 
     495 
     496    /* H stands for hard delete. D stands for delete. */ 
     497    if (type == 'H' || type == 'D') 
     498      osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED); 
     499    else if (type == 'M' || event_size == 0) { 
     500      // TODO set data 
     501      OSyncData *data = NULL; 
     502      // OSyncData *data = osync_data_new(event, event_size, objformatXXX, &error); 
     503 
     504      osync_change_set_data(change, data); 
     505      osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_MODIFIED); 
     506    } 
     507 
     508    osync_context_report_change(ctx, change); 
     509  } 
     510  osync_trace(TRACE_EXIT, "%s", __func__); 
     511
     512 
     513/** 
     514 * Creates the addressbook specific changeinfo for slow- and fastsync 
     515 */ 
     516void create_addressbook_changeinfo(int sync_type, OSyncContext *ctx, char *data, char *luid, int type) 
     517
     518  osync_trace(TRACE_ENTRY, "%s(%i, %p, %p, %s, %i)", __func__, sync_type, ctx, data, luid, type);                        
     519  osync_trace(TRACE_SENSITIVE, "Content of data:\n%s", data); 
     520 
     521  OSyncError *error = NULL; 
    564522   
    565   if (osync_member_objtype_enabled(env->member, "contact")) {  
    566     slowsync = FALSE; 
    567     if ( !detect_slowsync( config->addressbook_changecounter, "pb", &(config->addressbook_dbid), 
    568                            &(config->serial_number), &slowsync, config->obexhandle, &error ) ) 
    569     { 
    570       irmc_disconnect(config); 
    571       osync_context_report_osyncerror(ctx, &error); 
    572       osync_trace(TRACE_EXIT, "%s: %s", __func__, osync_error_print(&error)); 
    573       return; 
     523  if (sync_type == SLOW_SYNC) { 
     524    char *vcard_start = data; 
     525    char *vcard_end = NULL; 
     526    char *vcard = NULL; 
     527 
     528    do { 
     529      char *start = vcard_start; 
     530      vcard_start = strstr(start, "BEGIN:VCARD"); 
     531      if ((vcard_end = strstr(start, "END:VCARD"))) 
     532        vcard_end += strlen("END:VCARD"); 
     533 
     534      if (vcard_start && vcard_end) { 
     535        int vcard_size = vcard_end - vcard_start+1; 
     536        vcard = g_malloc(vcard_size); 
     537        memcpy(vcard, vcard_start, vcard_end - vcard_start); 
     538        vcard[vcard_end - vcard_start] = 0; 
     539 
     540        OSyncChange *change = osync_change_new(&error); 
     541        g_assert(change); 
     542 
     543        //osync_change_set_objformat_string(change, "vcard21"); 
     544 
     545        vcard_start = strstr(vcard, "X-IRMC-LUID:"); 
     546        if (vcard_start) { 
     547          char luid[256]; 
     548          if (sscanf(vcard_start, "X-IRMC-LUID:%256s", luid)) { 
     549            osync_change_set_uid(change, g_strdup(luid)); 
     550          } 
     551        } 
     552        vcard_size = strlen(vcard); 
     553        // TODO set data 
     554        OSyncData *data = NULL; 
     555        // OSyncData *data = osync_data_new(vcard, vcard_size, objformatXXX, &error); 
     556 
     557        osync_change_set_data(change, data); 
     558 
     559        osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_ADDED); 
     560        osync_context_report_change(ctx, change); 
     561      } 
     562 
     563      vcard_start = vcard_end; 
     564    } while(vcard_start); 
     565  } else { 
     566    OSyncChange *change = osync_change_new(&error); 
     567    g_assert(change); 
     568 
     569    //osync_change_set_objformat_string(change, "vcard21"); 
     570    osync_change_set_uid(change, g_strdup(luid)); 
     571 
     572    int vcard_size = strlen(data); 
     573    if (vcard_size > 0) { 
     574      vcard_size = strlen(data); 
    574575    } else { 
    575       osync_member_set_slow_sync(env->member, "contact", slowsync); 
    576     } 
    577   } 
     576      vcard_size = 0; 
     577    } 
     578 
     579    /* H stands for hard delete. D stands for delete. */ 
     580    if (type == 'H' || type == 'D') 
     581      osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED); 
     582    else if (type == 'M' || vcard_size == 0) { 
     583      osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_MODIFIED); 
     584      // TODO set data 
     585      OSyncData *data = NULL; 
     586      // OSyncData *data = osync_data_new(vcard, vcard_size, objformatXXX, &error); 
     587 
     588      osync_change_set_data(change, data); 
     589 
     590    } 
     591 
     592    osync_context_report_change(ctx, change); 
     593  } 
     594  osync_trace(TRACE_EXIT, "%s", __func__); 
     595
     596 
     597/** 
     598 * Creates the notebook specific changeinfo for slow- and fastsync 
     599 */ 
     600void create_notebook_changeinfo(int sync_type, OSyncContext *ctx, char *data, char *luid, int type) 
     601
     602  osync_trace(TRACE_ENTRY, "%s(%i, %p, %p, %s, %i)", __func__, sync_type, ctx, data, luid, type);                        
     603  osync_trace(TRACE_SENSITIVE, "Content of data:\n%s", data); 
    578604   
    579   if (osync_member_objtype_enabled(env->member, "note")) {  
    580     slowsync = FALSE; 
    581     if ( !detect_slowsync( config->notebook_changecounter, "nt", &(config->notebook_dbid), 
    582                            &(config->serial_number), &slowsync, config->obexhandle, &error ) ) 
    583     { 
    584       irmc_disconnect(config); 
    585       osync_context_report_osyncerror(ctx, &error); 
    586       osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error)); 
    587       return; 
     605  OSyncError *error = NULL; 
     606 
     607  if (sync_type == SLOW_SYNC) { 
     608    char *vnote_start = data; 
     609    char *vnote_end = NULL; 
     610    char *vnote = NULL; 
     611 
     612    do { 
     613      char *start = vnote_start; 
     614      vnote_start = strstr(start, "BEGIN:VNOTE"); 
     615      if ((vnote_end = strstr(start, "END:VNOTE"))) 
     616        vnote_end += strlen("END:VNOTE"); 
     617 
     618      if (vnote_start && vnote_end) { 
     619        int vnote_size = vnote_end - vnote_start+1; 
     620        vnote = g_malloc(vnote_size); 
     621        memcpy(vnote, vnote_start, vnote_end - vnote_start); 
     622        vnote[vnote_end - vnote_start] = 0; 
     623 
     624        OSyncChange *change = osync_change_new(&error); 
     625        g_assert(change); 
     626 
     627        //osync_change_set_objformat_string(change, "vnote11"); 
     628 
     629        vnote_start = strstr(vnote, "X-IRMC-LUID:"); 
     630        if (vnote_start) { 
     631          char luid[256]; 
     632          if (sscanf(vnote_start, "X-IRMC-LUID:%256s", luid)) { 
     633            osync_change_set_uid(change, g_strdup(luid)); 
     634          } 
     635        } 
     636 
     637        vnote_size = strlen(vnote); 
     638        // TODO set data 
     639        OSyncData *data = NULL; 
     640        // OSyncData *data = osync_data_new(vnote, vnote_size, objformatXXX, &error); 
     641 
     642        osync_change_set_data(change, data); 
     643 
     644 
     645        osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_ADDED); 
     646        osync_context_report_change(ctx, change); 
     647      } 
     648 
     649      vnote_start = vnote_end; 
     650    } while(vnote_start); 
     651  } else { 
     652    OSyncChange *change = osync_change_new(&error); 
     653    g_assert(change); 
     654 
     655    //osync_change_set_objformat_string(change, "vnote11"); 
     656    osync_change_set_uid(change, g_strdup(luid)); 
     657 
     658    int vnote_size = strlen(data); 
     659    if (vnote_size > 0) { 
     660      vnote_size = strlen(data); 
    588661    } else { 
    589       osync_member_set_slow_sync(env->member, "note", slowsync); 
    590     } 
    591   } 
    592  
    593   osync_context_report_success(ctx); 
    594 
    595  
    596 /** 
    597  * Requests all changeinfo from the device. 
    598  * 
    599  * This method calls get_generic_changeinfo() with 
    600  * a different info structure for every object type 
    601  * (calendar, addressbook, notebook). 
    602  */ 
    603 static void irmcGetChangeinfo(OSyncContext *ctx) 
    604 
    605   osync_trace(TRACE_ENTRY, "%s(%p)", __func__, ctx); 
    606   OSyncError *error = 0; 
    607  
    608   irmc_environment *env = (irmc_environment *)osync_context_get_plugin_data(ctx); 
    609   irmc_config *config = &(env->config); 
    610  
    611   data_type_information info; 
    612  
    613   memset(&info, 0, sizeof(info)); 
    614   strcpy(info.name, "calendar"); 
    615   strcpy(info.identifier, "event"); 
    616   strcpy(info.path_identifier, "cal"); 
    617   strcpy(info.path_extension, "vcs"); 
    618   info.change_counter = &(config->calendar_changecounter); 
    619  
    620   if (osync_member_objtype_enabled(env->member, "event")) { 
    621     if (!get_generic_changeinfo(ctx, &info, &error)) 
    622       goto error; 
    623   } 
    624  
    625   memset(&info, 0, sizeof(info)); 
    626   strcpy(info.name, "addressbook"); 
    627   strcpy(info.identifier, "contact"); 
    628   strcpy(info.path_identifier, "pb"); 
    629   strcpy(info.path_extension, "vcf"); 
    630   info.change_counter = &(config->addressbook_changecounter); 
    631  
    632   if (osync_member_objtype_enabled(env->member, "contact")) { 
    633     if (!get_generic_changeinfo(ctx, &info, &error)) 
    634       goto error; 
    635   } 
    636  
    637   memset(&info, 0, sizeof(info)); 
    638   strcpy(info.name, "notebook"); 
    639   strcpy(info.identifier, "note"); 
    640   strcpy(info.path_identifier, "nt"); 
    641   strcpy(info.path_extension, "vnt"); 
    642   info.change_counter = &(config->notebook_changecounter); 
    643  
    644   if (osync_member_objtype_enabled(env->member, "note")) { 
    645     if (!get_generic_changeinfo(ctx, &info, &error)) 
    646       goto error; 
    647   } 
    648  
    649   osync_context_report_success(ctx); 
     662      data = NULL; 
     663      vnote_size = 0; 
     664    } 
     665 
     666    /* H stands for hard delete. D stands for delete. */ 
     667    if (type == 'H' || type == 'D') 
     668      osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED); 
     669    else if (type == 'M' || vnote_size == 0) { 
     670      osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_MODIFIED); 
     671      // TODO set data 
     672      OSyncData *data = NULL; 
     673      // OSyncData *data = osync_data_new(vnote, vnote_size, objformatXXX, &error); 
     674 
     675      osync_change_set_data(change, data); 
     676    } 
     677 
     678    osync_context_report_change(ctx, change); 
     679  } 
    650680  osync_trace(TRACE_EXIT, "%s", __func__); 
    651   return; 
    652  
    653 error: 
    654   osync_context_report_osyncerror(ctx, &error); 
    655   osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error)); 
    656681} 
    657682 
     
    664689 *   - create_notebook_changeinfo() 
    665690 */ 
    666 gboolean get_generic_changeinfo(OSyncContext *ctx, data_type_information *info, OSyncError **error) 
    667 { 
    668   osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, ctx, error); 
     691gboolean get_generic_changeinfo(irmc_environment *env, OSyncObjTypeSink *sink, OSyncContext *ctx, data_type_information *info, OSyncError **error) 
     692{ 
     693  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, env, sink, ctx, info, error); 
    669694 
    670695  char *buffer; 
     
    677702  int dummy; 
    678703 
    679   irmc_environment *env = (irmc_environment *)osync_context_get_plugin_data(ctx); 
    680704  irmc_config *config = &(env->config); 
    681705 
     
    686710 
    687711  // check whether we have to do a slowsync 
    688   if (osync_member_get_slow_sync(env->member, info->identifier) == TRUE) { 
     712  if (osync_objtype_sink_get_slowsync(sink) == TRUE) { 
    689713    osync_trace(TRACE_INTERNAL, "slowsync %s\n", info->name ); 
    690714    buffer_length = DATABUFSIZE; 
     
    741765      // continue anyway; Siemens models will fail this get if document is empty 
    742766      g_free(filename); 
    743       osync_error_free(error); 
     767      osync_error_unref(error); 
    744768      *error = 0; 
    745769      buffer_length = 0; 
     
    875899} 
    876900 
    877 /** 
    878  * Creates the calendar specific changeinfo for slow- and fastsync 
    879  */ 
    880 void create_calendar_changeinfo(int sync_type, OSyncContext *ctx, char *data, char *luid, int type) 
    881 
    882   osync_trace(TRACE_ENTRY, "%s(%i, %p, %p, %s, %i)", __func__, sync_type, ctx, data, luid, type); 
    883   osync_trace(TRACE_SENSITIVE, "Content of data:\n%s", data); 
     901 
     902 
     903 
     904 
     905/** 
     906 * Checks whether a slowsync is necessary. 
     907 * 
     908 * That's the case if one of the following conditions matches: 
     909 *   - the device has an unknown serial number 
     910 *   - the database id differs from our saved one 
     911 *   - the changelog contains a '*' in the last line 
     912 */ 
     913gboolean detect_slowsync(int changecounter, char *object, char **dbid, char **serial_number, 
     914                         gboolean *slowsync, obex_t obexhandle, OSyncError **error) 
     915
     916  osync_trace(TRACE_ENTRY, "%s(%d, %s, %s, %s, %p, %p)", __func__, changecounter, object, *dbid, *serial_number, obexhandle, error); 
     917 
     918  char *data; 
     919  char *datap; 
     920  int len = DATABUFSIZE; 
     921  char serial[256]; 
     922  char did[256] = ""; 
     923  char *filename; 
     924  int ret; 
     925 
     926  data = g_malloc(DATABUFSIZE); 
     927  datap = data; 
     928 
     929  filename = g_strdup_printf("telecom/%s/luid/%d.log", object, changecounter); 
     930 
     931  memset(data, 0, DATABUFSIZE); 
     932  len = DATABUFSIZE - 1; 
     933  if (!irmc_obex_get(obexhandle, filename, data, &len, error)) { 
     934    g_free(filename); 
     935    g_free(data); 
     936    osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); 
     937    return FALSE; 
     938  } 
     939 
     940  g_free(filename); 
     941  data[len] = '\0'; 
     942 
     943  ret = sscanf(datap, "SN:%256s\r\n", serial); 
     944 if (ret > 0) { 
     945    if (!*serial_number || strcmp(*serial_number, serial)) { 
     946      if (*serial_number) 
     947        g_free(*serial_number); 
     948      *serial_number = g_strdup(serial); 
     949      *slowsync = TRUE; 
     950    } 
     951  } 
     952  datap = strstr(datap, "\r\n"); 
     953  if (!datap) { 
     954    g_free(data); 
     955    osync_trace(TRACE_EXIT, "%s: TRUE", __func__); 
     956    return TRUE; 
     957  } 
     958 
     959  datap+=2; 
     960  sscanf(datap, "DID:%256s\r\n", did); 
     961  if (!*dbid || strcmp(*dbid, did)) { 
     962    // This is a new database 
     963    if (*dbid) 
     964      g_free(*dbid); 
     965    *dbid = g_strdup(did); 
     966    *slowsync = TRUE; 
     967  } 
     968  datap = strstr(datap, "\r\n"); 
     969  if (!datap) { 
     970    g_free(data); 
     971    osync_trace(TRACE_EXIT, "%s: TRUE", __func__); 
     972    return TRUE; 
     973  } 
     974  datap+=2; 
     975  //sscanf(datap, "Total-Records:%d\r\n", &foo); 
     976  datap = strstr(datap, "\r\n"); 
     977  if (!datap) { 
     978    g_free(data); 
     979    osync_trace(TRACE_EXIT, "%s: TRUE", __func__); 
     980    return TRUE; 
     981  } 
     982  datap+=2; 
     983  //sscanf(datap, "Maximum-Records:%d\r\n", &foo); 
     984  datap = strstr(datap, "\r\n"); 
     985 
     986  if ( strstr(datap, "*") != NULL ) { 
     987    *slowsync = TRUE; 
     988  } 
     989 
     990  g_free(data); 
     991 
     992  osync_trace(TRACE_EXIT, "%s: TRUE", __func__); 
     993  return TRUE; 
     994
     995 
     996/** 
     997 * Establishes connection to the device. 
     998 */ 
     999static void irmcConnect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) 
     1000
     1001  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, ctx);                     
     1002  irmc_environment *env = (irmc_environment *)data; 
     1003  irmc_config *config = &(env->config); 
     1004 
     1005  config->obexhandle = irmc_obex_client(config); 
     1006 
     1007  // connect to the device 
     1008  OSyncError *error = NULL; 
     1009  if (!irmc_obex_connect(config->obexhandle, config->donttellsync ? NULL : "IRMC-SYNC", &error)) { 
     1010    irmc_disconnect(config); 
     1011    osync_context_report_osyncerror(ctx, error); 
     1012    osync_trace(TRACE_EXIT, "%s: %s", __func__, osync_error_print(&error)); 
     1013    return; 
     1014  } 
     1015 
     1016  // load the synchronization anchors 
     1017  load_sync_anchors(env); 
     1018 
     1019  // check whether a slowsync is necessary 
     1020 
     1021 
     1022/* TODO: port sink engine stuff.. 
     1023  gboolean slowsync = FALSE;   
    8841024   
    885   irmc_environment *env = (irmc_environment *)osync_context_get_plugin_data(ctx); 
    886  
    887   if (sync_type == SLOW_SYNC) { 
    888     char *event_start = data, *todo_start; 
    889     char *event_end = NULL; 
    890     char *event = NULL; 
    891     int objtype; 
    892  
    893  
    894     do { 
    895       char *start = event_start; 
    896       objtype = SYNC_OBJECT_TYPE_CALENDAR; 
    897       event_start = strstr(start, "BEGIN:VEVENT"); 
    898       todo_start = strstr(start, "BEGIN:VTODO"); 
    899       if (!event_start || (todo_start && (todo_start < event_start))) { 
    900         event_start = todo_start; 
    901         objtype = SYNC_OBJECT_TYPE_TODO; 
    902       } 
    903       if (objtype == SYNC_OBJECT_TYPE_CALENDAR) 
    904         if ((event_end = strstr(start, "END:VEVENT"))) 
    905           event_end += strlen("END:VEVENT"); 
    906  
    907       if (objtype == SYNC_OBJECT_TYPE_TODO) 
    908         if ((event_end = strstr(start, "END:VTODO"))) 
    909           event_end += strlen("END:VTODO"); 
    910  
    911       if (event_start && event_end) { 
    912         int pos = 0; 
    913         int event_size = event_end - event_start + 256; 
    914         event = g_malloc(event_size); 
    915         memset(event, 0, event_size); 
    916  
    917         sprintf(event, "BEGIN:VCALENDAR\r\nVERSION:1.0\r\n"); 
    918         pos = strlen(event); 
    919         memcpy(event+pos,event_start,event_end-event_start); 
    920         sprintf(event+(pos+event_end-event_start), "\r\nEND:VCALENDAR\r\n"); 
    921  
    922         OSyncChange *change = osync_change_new(); 
    923         osync_change_set_member(change, env->member); 
    924         g_assert(change); 
    925  
    926         if (objtype == SYNC_OBJECT_TYPE_CALENDAR) 
    927           osync_change_set_objformat_string(change, "vevent10"); 
    928         else if (objtype == SYNC_OBJECT_TYPE_TODO) 
    929           osync_change_set_objformat_string(change, "vtodo10"); 
    930  
    931         event_start = strstr(event, "X-IRMC-LUID:"); 
    932         if (event_start) { 
    933           char luid[256]; 
    934           if (sscanf(event_start, "X-IRMC-LUID:%256s", luid)) { 
    935             osync_change_set_uid(change, g_strdup(luid)); 
    936           } 
    937         } 
    938         event_size = strlen(event); 
    939         osync_change_set_data(change, event, event_size, TRUE); 
    940         osync_change_set_changetype(change, CHANGE_ADDED); 
    941         osync_context_report_change(ctx, change); 
    942       } 
    943  
    944       event_start = event_end; 
    945     } while(event_start); 
    946  
    947   } else { 
    948     OSyncChange *change = osync_change_new(); 
    949     osync_change_set_member(change, env->member); 
    950     g_assert(change); 
    951  
    952     osync_change_set_objformat_string(change, "plain"); 
    953     osync_change_set_uid(change, g_strdup(luid)); 
    954  
    955     int event_size = strlen(data); 
    956     if (event_size > 0) { 
    957       event_size = strlen(data); 
     1025  if (osync_member_objtype_enabled(env->member, "event")) {  
     1026    slowsync = FALSE; 
     1027    if ( !detect_slowsync( config->calendar_changecounter, "cal", &(config->calendar_dbid), 
     1028                           &(config->serial_number), &slowsync, config->obexhandle, &error ) ) 
     1029    { 
     1030      irmc_disconnect(config); 
     1031      osync_context_report_osyncerror(ctx, &error); 
     1032      osync_trace(TRACE_EXIT, "%s: %s", __func__, osync_error_print(&error)); 
     1033      return; 
    9581034    } else { 
    959       data = NULL; 
    960       event_size = 0; 
    961     } 
    962  
    963     /* H stands for hard delete. D stands for delete. */ 
    964     if (type == 'H' || type == 'D') 
    965       osync_change_set_changetype(change, CHANGE_DELETED); 
    966     else if (type == 'M' || event_size == 0) { 
    967       osync_change_set_data(change, data, event_size, TRUE); 
    968       osync_change_set_changetype(change, CHANGE_MODIFIED); 
    969     } 
    970  
    971     osync_context_report_change(ctx, change); 
    972   } 
     1035      osync_member_set_slow_sync(env->member, "event", slowsync); 
     1036    } 
     1037  } 
     1038   
     1039  if (osync_member_objtype_enabled(env->member, "contact")) {  
     1040    slowsync = FALSE; 
     1041    if ( !detect_slowsync( config->addressbook_changecounter, "pb", &(config->addressbook_dbid), 
     1042                           &(config->serial_number), &slowsync, config->obexhandle, &error ) ) 
     1043    { 
     1044      irmc_disconnect(config); 
     1045      osync_context_report_osyncerror(ctx, &error); 
     1046      osync_trace(TRACE_EXIT, "%s: %s", __func__, osync_error_print(&error)); 
     1047      return; 
     1048    } else { 
     1049      osync_member_set_slow_sync(env->member, "contact", slowsync); 
     1050    } 
     1051  } 
     1052   
     1053  if (osync_member_objtype_enabled(env->member, "note")) {  
     1054    slowsync = FALSE; 
     1055    if ( !detect_slowsync( config->notebook_changecounter, "nt", &(config->notebook_dbid), 
     1056                           &(config->serial_number), &slowsync, config->obexhandle, &error ) ) 
     1057    { 
     1058      irmc_disconnect(config); 
     1059      osync_context_report_osyncerror(ctx, &error); 
     1060      osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error)); 
     1061      return; 
     1062    } else { 
     1063      osync_member_set_slow_sync(env->member, "note", slowsync); 
     1064    } 
     1065  } 
     1066*/ 
     1067 
     1068  osync_context_report_success(ctx); 
     1069
     1070 
     1071/** 
     1072 * This method is called to disconnect from the device. 
     1073 */ 
     1074static void irmcDisconnect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) 
     1075
     1076  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); 
     1077 
     1078  irmc_environment *env = (irmc_environment *)data; 
     1079 
     1080  // TODO: handle disconnect of several sink engines.. 
     1081  // disconnect from the device 
     1082  irmc_disconnect(&(env->config)); 
     1083 
     1084  osync_context_report_success(ctx); 
     1085 
    9731086  osync_trace(TRACE_EXIT, "%s", __func__); 
    9741087} 
    9751088 
    9761089/** 
    977  * Creates the addressbook specific changeinfo for slow- and fastsync 
    978  */ 
    979 void create_addressbook_changeinfo(int sync_type, OSyncContext *ctx, char *data, char *luid, int type) 
    980 
    981   osync_trace(TRACE_ENTRY, "%s(%i, %p, %p, %s, %i)", __func__, sync_type, ctx, data, luid, type);                        
    982   osync_trace(TRACE_SENSITIVE, "Content of data:\n%s", data); 
    983    
    984   irmc_environment *env = (irmc_environment *)osync_context_get_plugin_data(ctx); 
    985  
    986   if (sync_type == SLOW_SYNC) { 
    987     char *vcard_start = data; 
    988     char *vcard_end = NULL; 
    989     char *vcard = NULL; 
    990  
    991     do { 
    992       char *start = vcard_start; 
    993       vcard_start = strstr(start, "BEGIN:VCARD"); 
    994       if ((vcard_end = strstr(start, "END:VCARD"))) 
    995         vcard_end += strlen("END:VCARD"); 
    996  
    997       if (vcard_start && vcard_end) { 
    998         int vcard_size = vcard_end - vcard_start+1; 
    999         vcard = g_malloc(vcard_size); 
    1000         memcpy(vcard, vcard_start, vcard_end - vcard_start); 
    1001         vcard[vcard_end - vcard_start] = 0; 
    1002  
    1003         OSyncChange *change = osync_change_new(); 
    1004         osync_change_set_member(change, env->member); 
    1005&nb