| 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 | */ |
|---|
| | 408 | void 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 | |
|---|
| 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); |
|---|
| 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 | */ |
|---|
| | 516 | void 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; |
|---|
| 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); |
|---|
| 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 | */ |
|---|
| | 600 | void 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); |
|---|
| 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); |
|---|
| 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 | } |
|---|
| 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 | */ |
|---|
| | 913 | gboolean 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 | */ |
|---|
| | 999 | static 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; |
|---|
| 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; |
|---|
| 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 | */ |
|---|
| | 1074 | static 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 | |
|---|
| 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 |
|---|