[os-libsynthesis] avoiding disk writes during sync without changes

2014-08-29 Thread Patrick Ohly
Hello!

For IVI, I am working on cloud syncing. When syncing against a WebDAV
server, SyncEvolution runs a two-way sync with binfile client on the
WebDAV side and a server with admin data handled by SyncEvolution on the
other side.

One goal for IVI is to minimize or better, avoid disk writes, because
flash storage must last as long as possible.

The most common case is that nothing changed on either side. In this
case, libsynthesis unnecessarily updates nonce (even if not used; I've
already patched that (1)), sync anchors (again, I have a patch for this:
skip writing of admin data after detecting the special case (2)) and the
change log in the binfile client.

This last write happens in TBinfileImplDS::changeLogPreflight(). The
changes are minor, just a few bytes change. I suspect that these are the
time stamps and modcount embedded in the log.

Would it be possible to check in changeLogPreflight() how significant
the changes are? If there were no item changes, what would be the effect
of not updating the header?

There are two cases where that can happen with the attached patch:
- the processes crashes
- SyncEvolution skips the session shutdown, see (2).

(1) For local sync, requestedauthnone/requestedauth and
requiredauthnone/requiredauth are used. Patch attached. Okay?

(2) This happens in SyncEvolution: the SaveAdminData implementation
detects that nothing happened during the sync, then returns an error to
libsynthesis and tells the SyncEvolution event loop to stop the sync
without sending the final reply message to the client. The server side
then finishes the sync successfully while the client side simply aborts
without doing its own session shutdown. This also eliminates
SaveAdminData on the binfile client side.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.


From 4683fceb72cef0e7301b735a23b1f40323da52ba Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Fri, 29 Aug 2014 10:35:47 +0200
Subject: [PATCH 1/2] syncsession: avoid unnecessary nonce update

When the configure auth type needs no nonce, don't generate one
and return NULL immediately, like newChallenge() would do.

That avoids unnecessary disk writes for storing the new nonce, which
is important for local syncs in IVI. It also avoids debug output about
a challenge that would not get sent.
---
 src/sysync/syncsession.cpp | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/sysync/syncsession.cpp b/src/sysync/syncsession.cpp
index 54c119c..f7c7a11 100644
--- a/src/sysync/syncsession.cpp
+++ b/src/sysync/syncsession.cpp
@@ -4061,15 +4061,22 @@ bool TSyncSession::processSyncOpItem(
 // generate challenge for session
 SmlChalPtr_t TSyncSession::newSessionChallenge(void)
 {
+  sysync::TAuthTypes auth = requestedAuthType();
+
+  // Avoid misleading debug output (there is no challenge)
+  // and more importantly, creating a new nonce that is not
+  // going to be used. That causes unnecessary disk writes.
+  if (auth == sysync::auth_none) return NULL;
+
   string nonce;
   getNextNonce(fRemoteURI.c_str(),nonce);
   PDEBUGPRINTFX(DBG_PROTO,(
 Challenge for next auth: AuthType=%s, Nonce='%s', binary %sallowed,
-authTypeSyncMLNames[requestedAuthType()],
+authTypeSyncMLNames[auth],
 nonce.c_str(),
 getEncoding()==SML_WBXML ?  : NOT 
   ));
-  return newChallenge(requestedAuthType(),nonce,getEncoding()==SML_WBXML);
+  return newChallenge(auth,nonce,getEncoding()==SML_WBXML);
 } // TSyncSession::newSessionChallenge
 
 
-- 
2.1.0.rc1

From 115cef8a0ec1823b58808bbb9820f7cb82c2a313 Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Fri, 29 Aug 2014 10:39:17 +0200
Subject: [PATCH 2/2] binfileclient: avoid disk writes in changeLogPreflight()

During a normal sync where nothing changed, only the header gets
updated. This change is not critical and thus does not have to be
flushed to disk unless also some entries get added or updated.

The advantage is that when SyncEvolution detects a sync where nothing
changed on either side and skips the client's session shutdown, the
.bfi is left unchanged, which reduces flash wearout.

To detect item changes, a brute-force byte comparison is used. This
requires less changes to the code and is less error-prone than adding
modified=true to all places where existingentries gets modified.
---
 src/sysync/binfileimplds.cpp | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/src/sysync/binfileimplds.cpp b/src/sysync/binfileimplds.cpp
index 314ccc7..947fa0c 100755
--- a/src/sysync/binfileimplds.cpp
+++ b/src/sysync/binfileimplds.cpp
@@ -741,9 +741,9 @@ localstatus TBinfileImplDS::changeLogPreflight(bool aValidChangelog)
 lsd.c_str()
   ));
   #endif
-  // - save header

Re: [os-libsynthesis] comparison of PHOTO data

2014-07-14 Thread Patrick Ohly
On Mon, 2014-07-14 at 18:15 +0200, Lukas Zeller wrote:
 Hello Patrick,
 
 On 11 Jul 2014, at 15:27, Patrick Ohly patrick.o...@intel.com wrote:
 
  I'm currently investigating why a comparison of two PHOTO fields of
  different length returns field equal. PHOTO is defined as:
  
   field name=PHOTO type=string compare=conflict 
  merge=fillempty/
 
 My first question would be why PHOTO was defined string here, not blob?

I changed that in this commit:

commit 6d3b1cf64b09cf1603b813137d14d529a31dda8b
Author: Patrick Ohly patrick.o...@intel.com
Date:   Fri Jul 5 09:45:15 2013 +0200

EDS: update PHOTO+GEO during slow sync, avoid rewriting PHOTO file

If PHOTO and/or GEO were the only modified properties during a slow
sync, the updated item was not written into local storage because
they were marked as compare=never = not relevant.

For PHOTO this was intentional in the sample config, with the
rationale that local storages often don't store the data exactly as
requested. When that happens, comparing the data would lead to
unnecessary writes. But EDS and probably all other local SyncEvolution
storages (KDE, file) store the photo exactly as requested, so not
considering changes had the undesirable effect of not always writing
new photo data.

For GEO, ignoring it was accidental.

A special merge script handles EDS file:// photo URIs. When the
loosing item has the data in a file and the winning item has binary
data, the data in the file may still be up-to-date, so before allowing
MERGEFIELDS() to overwrite the file reference with binary data and
thus forcing EDS to write a new file, check the content. If it
matches, use the file reference in both items.

Unfortunately I did not write down why I changed the type, instead of
merely changing the compare setting.

Does it matter at all?

 IMHO The real bug is that TBlobField does not override compareWith.
 TBlobField's compareWith could ignore aCaseInsensitive and use memcmp,
 for the case of actually comparing two blobs, and fall back to
 TStringField for comparison with other types.
 
  We have std::string as value and therefore can store null bytes as part
  of the data, but the actual comparison falls back to C-string
  operations, which only work for null bytes at the end.
 
 There's to much C strings throughout the entire project, so for text,
 C string semantics are assumed pretty much everywhere.
 
 TBlobField however makes use of the true binary byte string capability of 
 std::string exactly this way.

That's also true for TStringField, except that it occasionally falls
back to plain C operations, which is only correct for real strings.

  I think the strcmp() needs to be replaced with something that also looks
  at the rest of the string if no difference is found. Agreed?
 
 A fully std::string compatible comparison would be nicer here, and fix the 
 problem.

Here's the patch that I ended up using:

commit 9278e054e9a9a2aa8c73aed98cb42bf1f9bfd0fe
Author: Patrick Ohly patrick.o...@intel.com
Date:   Mon Jul 14 05:00:54 2014 -0700

string fields: full compare

String fields also get used for arbitrary binary data, like
photos. In that case we need to compare the entire std::string,
not just the part before any embedded null byte.

This gets done using std::string::compare. Case-insensitive
comparison still uses C strucmp() and thus should never be used
for non-string data.

diff --git a/src/sysync/itemfield.cpp b/src/sysync/itemfield.cpp
index e6f7d71..64867e0 100644
--- a/src/sysync/itemfield.cpp
+++ b/src/sysync/itemfield.cpp
@@ -801,7 +801,7 @@ bool TStringField::merge(TItemField aItemField, const char 
aSep)
 // Note: Both fields must be assigned. NO TEST IS DONE HERE!
 sInt16 TStringField::compareWith(TItemField aItemField, bool aCaseInsensitive)
 {
-  sInt16 result;
+  int result;
   PULLFROMPROXY;
   if (aItemField.isBasedOn(fty_string)) {
 TStringField *sfP = static_castTStringField *(aItemField);
@@ -812,7 +812,7 @@ sInt16 TStringField::compareWith(TItemField aItemField, 
bool aCaseInsensitive)
 if (aCaseInsensitive)
   result=strucmp(fString.c_str(),sfP-fString.c_str());
 else
-  result=strcmp(fString.c_str(),sfP-fString.c_str());
+  result=fString.compare(sfP-fString);
   }
   else {
 // convert other field to string
@@ -821,7 +821,7 @@ sInt16 TStringField::compareWith(TItemField aItemField, 
bool aCaseInsensitive)
 if (aCaseInsensitive)
   result=strucmp(fString.c_str(),s.c_str());
 else
-  result=strcmp(fString.c_str(),s.c_str());
+  result=fString.compare(s);
   }
   return result 0 ? 1 : (result0 ? -1 : 0);
 } // TStringField::compareWith


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak

[os-libsynthesis] comparison of PHOTO data

2014-07-11 Thread Patrick Ohly
Hello!

I'm currently investigating why a comparison of two PHOTO fields of
different length returns field equal. PHOTO is defined as:

  field name=PHOTO type=string compare=conflict merge=fillempty/

I think the specific situation is that the two values contain a null
byte somewhere in the middle, and the part before that is equal.

I think the following code does the comparison, doesn't it?

sInt16 TStringField::compareWith(TItemField aItemField, bool aCaseInsensitive)
{
  sInt16 result;
  PULLFROMPROXY;
  if (aItemField.isBasedOn(fty_string)) {
TStringField *sfP = static_castTStringField *(aItemField);
#ifdef STREAMFIELD_SUPPORT
sfP-pullFromProxy(); // make sure we have all chars
#endif
// direct compare possible, return strcmp
if (aCaseInsensitive)
  result=strucmp(fString.c_str(),sfP-fString.c_str());
else
  result=strcmp(fString.c_str(),sfP-fString.c_str());
  }
...

We have std::string as value and therefore can store null bytes as part
of the data, but the actual comparison falls back to C-string
operations, which only work for null bytes at the end.

I think the strcmp() needs to be replaced with something that also looks
at the rest of the string if no difference is found. Agreed?

Or do we need a real binary type? Using string type for PHOTO also has
the risk that during a merge operation, the two values will get
concatenated (thus breaking the images) unless some custom merge script
resolves the conflict differently first.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] How to run syncevolution at bare minimum processing.

2014-05-19 Thread Patrick Ohly
On Mon, 2014-05-19 at 18:46 +0530, anuj chauhan wrote:

 I have a quad-core machine with 8gb ram and these processes are
 consuming about 90-94% of the cpu usage.I want to tune syncevolution
 so that it could run on bare minimum processing.For this i have done
 following modification :
 1.  Commented out the code which gets the Server DevInf. I
 suspect, this will reduce load on Server and client as well.
 
 2.  Removed the file synccompare. During these concurrent runs,
 top command showed high CPU usage for Perl just after syncevolution
 completed its exercise. By removing this file, this reduced the client
 load and processing.

Instead it would have been better to use printChanges=0. This disables
the invocation of synccompare.

 3.  Reduced the log level to 0. Number of IO went down along with
 the disk usage.

You can decrease it further by also using dumpData=0.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] mixing properties with and without group tag (was: Re: suppressempty + arrays)

2014-05-14 Thread Patrick Ohly
On Wed, 2014-05-14 at 17:44 +0200, Lukas Zeller wrote:
 Hello Patrick,
 
 On 12.05.2014, at 18:25, Patrick Ohly patrick.o...@intel.com wrote:
 
  [...] 
  and a property which has a group tag must not reuse any of these
  unassigned group tag values.
  
  Actually, a property which has a group *field* - it doesn't matter
  whether the current property has a group tag value. This check was
  missing. Attached a patch adding it, in a brute-force manner. Does that
  look right?
 
 Yes, it looks right to me. I guess you've found out in the meantime if it 
 also *works* right :-)

Yes, it works for me. But it's good that you had a look at it anyway,
because my vCard profile certainly isn't representative.

I'll include this and the other patches (including the removal of
backslash escaping in parameters!) in the master branch of libsynthesis
on freedesktop.org once it passed all my tests. There's also a memory
leak fix for SWAP().

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] mixing properties with and without group tag (was: Re: suppressempty + arrays)

2014-05-12 Thread Patrick Ohly
On Mon, 2014-05-12 at 12:55 +0200, Patrick Ohly wrote:
 The X-ABRELATEDNAMES properties were not generated. The labels should be
 redundant, but some peers get confused. Google preserves them as
 stand-alone X-ABLabel without tag. DAViCal preserves them with tag,
 which then happened to confuse SyncEvolution's conversion code (separate
 issue).

This second issue actually is in the groupfield support of libsynthesis:

[2014-05-12 15:02:45.501] Parsing: 
  * [2014-05-12 15:02:45.501] 
BEGIN:VCARD
VERSION:3.0
PRODID:-//Synthesis AG//NONSGML SyncML Engine V3.4.0.47//EN
REV:20140512T150240Z
UID:syuid974165.212266710163478
N:Doe;John;;;
FN:John Doe
X-EVOLUTION-FILE-AS:Doe\, John
TITLE:tester
TEL;TYPE=WORK,VOICE:business 1
X-MOZILLA-HTML:FALSE
item3.X-ABLabel:Spouse
item2.X-ABLabel:Manager
item1.X-ABLabel:Assistant
END:VCARD
  * [2014-05-12 15:02:45.501] Successfully parsed: 
  * [2014-05-12 15:02:45.501] Item
LocalID='syuid974165.212266710163478.vcf', RemoteID='',
operation=wants-add, size: [maxlocal,maxremote,actual]
  * [2014-05-12 15:02:45.501] 
-  0 :integer SYNCLVL [   0, n/a, 0] : unassigned
-  1 :  timestamp REV [   0,   0, 0] : 2014-05-12T15:02:40Z 
(TZ: UTC)
-  2 : string UID [   0, n/a,27] : 
syuid974165.212266710163478
-  3 : string GROUP_TAG   [   0, n/a, 0] : array with 3 elements
 -- element0 : item3
 -- element1 : item2
 -- element2 : item1
-  4 : string N_LAST  [   0,   0, 3] : Doe
-  5 : string N_FIRST [   0,   0, 4] : John
...
- 23 :  telephone TEL [   0,   0, 0] : array with 1 elements
 -- element0 : business 1
- 24 :integer TEL_FLAGS   [   0,   0, 0] : array with 1 elements
 -- element0 : 10
- 25 :integer TEL_SLOT[   0,   0, 0] : array with 0 elements
...
- 83 : string LABEL   [   0,   0, 0] : array with 3 elements
 -- element0 : Spouse
 -- element1 : Manager
 -- element2 : Assistant
- 84 : string XPROPS  [   0,   0, 0] : array with 0 elements

This field list makes it look like TEL business 1 at index #0 had the
same group tag as LABEL Spouse, thus adding a label to a TEL which had
no label.

I think the code which deals with group tags must use the same logic
that I introduced for sharedfield: a property which has a group field
array, but no group tag, must set an unassigned value in the group field
array, and a property which has a group tag must not reuse any of these
unassigned group tag values.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] mixing properties with and without group tag (was: Re: suppressempty + arrays)

2014-05-12 Thread Patrick Ohly
On Mon, 2014-05-12 at 17:29 +0200, Patrick Ohly wrote:
 I think the code which deals with group tags must use the same logic
 that I introduced for sharedfield: a property which has a group field
 array, but no group tag, must set an unassigned value in the group field
 array,

That was already done:
  if (aPropP-groupFieldID!=FID_NOT_SUPPORTED) {
TItemField *g_fldP =  
aItem.getArrayFieldAdjusted(aPropP-groupFieldID+baseoffset,repoffset,false);
if (g_fldP)
  g_fldP-setAsString(aGroupName,aGroupNameLen); // store the group name 
(aGroupName might be NULL, that's ok)
  }

  and a property which has a group tag must not reuse any of these
 unassigned group tag values.

Actually, a property which has a group *field* - it doesn't matter
whether the current property has a group tag value. This check was
missing. Attached a patch adding it, in a brute-force manner. Does that
look right?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.


From f0396958e9311db0bcf44a1810ee89afc99b Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Mon, 12 May 2014 09:03:56 -0700
Subject: [PATCH] mimedir parser: avoid reusing group tag

When two properties (TEL and X-ABLabel in this example) share the same group
field, then storing the property where a group tag was used for the first time
must not reuse unassigned group field entries.

There was some logic for that already (see someGroups), but it failed to
handle this case. This approach here uses brute-force instead of trying to me
smart: the reuse check in the nmaxrep for loop will fail repeatedly at the
beginning until reaching the end of the group field array.
---
 src/sysync/mimedirprofile.cpp |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp
index 418c5d0..e618f80 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -4168,8 +4168,11 @@ bool TMimeDirProfileHandler::parseProperty(
   TItemField *e_fldP = NULL;
   if (e_basefldP)
 e_fldP=e_basefldP-getArrayField(e_rep,true); // get leaf field, if it exists
-  if (!e_basefldP || (e_fldP  e_fldP-isAssigned())) {
-// base field of one of the main fields does not exist or leaf field is already assigned
+  if (!e_basefldP || (e_fldP  e_fldP-isAssigned()) ||
+  (aPropP-groupFieldID!=FID_NOT_SUPPORTED  !valuelist 
+   aItem.getArrayFieldAdjusted(aPropP-groupFieldID+baseoffset,e_rep,true))) {
+// base field of one of the main fields does not exist or leaf field is already assigned,
+// or the group field entry is already in use (doesn't matter whether it is empty)
 // - skip that repetition
 dostore = false;
 break;
-- 
1.7.10.4

___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] parameter value escaping (was: Re: vCard group tags)

2014-05-06 Thread Patrick Ohly
On Mon, 2014-05-05 at 14:42 +0200, Patrick Ohly wrote:
 On Fri, 2014-05-02 at 11:59 +0200, Lukas Zeller wrote:
  On 02.05.2014, at 10:38, Patrick Ohly patrick.o...@intel.com wrote:
   I noticed another problem with the use X-ABLabel parameter approach:
   storing complex strings (spaces, quotation marks) in a parameter value
   is harder.
  
  That's probably why Apple chose the X-ABLabel property approach. An
  unparseable parameter could ruin the real data, a unknown property is
  less dangerous.
  
   The EDS vCard parser gets it wrong and fails to parse:
   
   X-ABRELATEDNAMES;X-ABLabel=domestic partner:domestic partner
   
   That is valid according to http://tools.ietf.org/html/rfc2425#page-5
   because the space is a SAFE-CHAR and thus may appear in a ptext, but the
   EDS parser does not expect the space. To work around this, we could
   voluntarily quote the string even though it is not required. 
   
   Now, the conceptual problem with X-ABLabel parameter is that a quoted
   string cannot contain double quotes. It is probably rare that a user
   enters double quotes as part of a label, but it cannot be ruled out
   either. Line breaks are also only allowed in property values and not
   parameter values.
 
 I've looked into TMimeDirProfileHandler::generateValue() some more to
 understand under which circumstances libsynthesis uses quoted strings
 (with double quotes at start and end) as parameter value. At first
 glance it doesn't seem to do that at all. Instead special values are
 escaped with backslash.
 
 item29.X-ABLabel:custom-label5\nUmlaut-ä\nSemicolon\;
 -
 X-ABRELATEDNAMES;X-ABLabel=custom-label5\nUmlaut-ä\nSemicolon\;:custom 
 relationship
 
 Where is it specified that the backslash escape mechanism can be used in
 parameter values?
 
 http://tools.ietf.org/html/rfc2425#page-5 says:
 
 
param= param-name = param-value *(, param-value)
 
param-name   = x-name / iana-token
 
param-value  = ptext / quoted-string
 
ptext  = *SAFE-CHAR
 
SAFE-CHAR= WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-ASCII
   ; Any character except CTLs, DQUOTE, ;, :, ,
 
 My reading of that is that special characters must not appear in a ptext
 at all, not even when escaped with backslash. One has to use a quoted
 string, which (unfortunately) cannot hold all characters either.
 
 IMHO libsynthesis is currently producing broken vCards. I consider
 changing the code so that it uses quoted strings if it detects unsafe
 characters in the value and filters out invalid ones. unsafe would be
 more conservative than in the RFC itself and also include spaces, to
 work around the EDS parser bug.

Attached is a patch which makes the libsynthesis parser and generator
behave according to my current understanding of the RFCs. The risk of
course is that there are cases where backslashes are used in parameter
values and the peer (unpatched libsynthesis, other implementations)
expect that backslash escaping is used.

The Evolution Data Server parser does not use backslash escaping for
parameters. To exchange values containing backslashes, the patch is
needed.

This becomes relevant in the context of the X-ABLabel parameter. My hope
is that all other parameters are simple enough that the ambiguity never
arises.

Or do we need an on/off switch for backslash escaping depending on the
peer?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.


From 8a7356c1518aca405eb29ddf12a2d1052375da68 Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Tue, 6 May 2014 12:13:19 +0200
Subject: [PATCH 2/2] MIME parser + encoder: no backslash quoting in parameter
 values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

RFC 2425 (MIME DIR) and RFC 6350 (vCard) do not describe backslash
escaping for special characters in parameter values. Only the more
limited quoted-string (double quotes at start and end, no line breaks,
no double quotes inside value) is specified.

The following two examples both contain a literal backslash:

URL;X-ABLabel=Custom-label6 Backslash \:http://custom.com
X-ABRELATEDNAMES;X-ABLabel=custom-label5 Umlaut ä Semicolon ; Backslash \ end of label:custom relationship

This commit limits backslash escaping to parsing and generating
property values. Backslashs in parameters are stored literally during
parsing. A quoted string parameter value is used for every value that
is more complex than alphanumeric plus underscore and hyphen.

In particular spaces (while allowed in unquoted values) are only
generated as part of quoted strings because the Evolution Data Server
parser had problems with them (fixed in EDS 3.10).
---
 src/sysync/mimedirprofile.cpp |   60 -
 1 file changed, 42

[os-libsynthesis] folding parameter values (was: Re: vCard group tags)

2014-05-06 Thread Patrick Ohly
On Mon, 2014-05-05 at 14:42 +0200, Patrick Ohly wrote:
 On Fri, 2014-05-02 at 11:59 +0200, Lukas Zeller wrote:
  On 02.05.2014, at 10:38, Patrick Ohly patrick.o...@intel.com wrote:
   I noticed another problem with the use X-ABLabel parameter approach:
   storing complex strings (spaces, quotation marks) in a parameter value
   is harder.
  
  That's probably why Apple chose the X-ABLabel property approach. An
  unparseable parameter could ruin the real data, a unknown property is
  less dangerous.
  
   The EDS vCard parser gets it wrong and fails to parse:
   
   X-ABRELATEDNAMES;X-ABLabel=domestic partner:domestic partner
   
   That is valid according to http://tools.ietf.org/html/rfc2425#page-5
   because the space is a SAFE-CHAR and thus may appear in a ptext, but the
   EDS parser does not expect the space. To work around this, we could
   voluntarily quote the string even though it is not required. 
   
   Now, the conceptual problem with X-ABLabel parameter is that a quoted
   string cannot contain double quotes. It is probably rare that a user
   enters double quotes as part of a label, but it cannot be ruled out
   either. Line breaks are also only allowed in property values and not
   parameter values.
 
 I've looked into TMimeDirProfileHandler::generateValue() some more to
 understand under which circumstances libsynthesis uses quoted strings
 (with double quotes at start and end) as parameter value. At first
 glance it doesn't seem to do that at all. Instead special values are
 escaped with backslash.
 
 item29.X-ABLabel:custom-label5\nUmlaut-ä\nSemicolon\;
 -
 X-ABRELATEDNAMES;X-ABLabel=custom-label5\nUmlaut-ä\nSemicolon\;:custom 
 relationship
 
 Where is it specified that the backslash escape mechanism can be used in
 parameter values?
 
 http://tools.ietf.org/html/rfc2425#page-5 says:
 
 
param= param-name = param-value *(, param-value)
 
param-name   = x-name / iana-token
 
param-value  = ptext / quoted-string
 
ptext  = *SAFE-CHAR
 
SAFE-CHAR= WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-ASCII
   ; Any character except CTLs, DQUOTE, ;, :, ,
 
 My reading of that is that special characters must not appear in a ptext
 at all, not even when escaped with backslash. One has to use a quoted
 string, which (unfortunately) cannot hold all characters either.

Furthermore, folding is not described for parameter values, is it?

X-ABRELATEDNAMES;X-ABLabel=custom-label5 Umlaut ä Semicolon ; Backslash \ 
 newline  tab \t end of label:custom relationship

This is what libsynthesis produces for a long parameter value. The \t
was part of the original value. With the revised parser/generator it
just gets passed through.

I think the generator should be changed to not fold a line unless the
property value has started.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] folding parameter values (was: Re: vCard group tags)

2014-05-06 Thread Patrick Ohly
On Tue, 2014-05-06 at 13:29 +0200, Patrick Ohly wrote:
 On Mon, 2014-05-05 at 14:42 +0200, Patrick Ohly wrote:
  On Fri, 2014-05-02 at 11:59 +0200, Lukas Zeller wrote:
   On 02.05.2014, at 10:38, Patrick Ohly patrick.o...@intel.com wrote:
I noticed another problem with the use X-ABLabel parameter approach:
storing complex strings (spaces, quotation marks) in a parameter value
is harder.
   
   That's probably why Apple chose the X-ABLabel property approach. An
   unparseable parameter could ruin the real data, a unknown property is
   less dangerous.
   
The EDS vCard parser gets it wrong and fails to parse:

X-ABRELATEDNAMES;X-ABLabel=domestic partner:domestic partner

That is valid according to http://tools.ietf.org/html/rfc2425#page-5
because the space is a SAFE-CHAR and thus may appear in a ptext, but the
EDS parser does not expect the space. To work around this, we could
voluntarily quote the string even though it is not required. 

Now, the conceptual problem with X-ABLabel parameter is that a quoted
string cannot contain double quotes. It is probably rare that a user
enters double quotes as part of a label, but it cannot be ruled out
either. Line breaks are also only allowed in property values and not
parameter values.
  
  I've looked into TMimeDirProfileHandler::generateValue() some more to
  understand under which circumstances libsynthesis uses quoted strings
  (with double quotes at start and end) as parameter value. At first
  glance it doesn't seem to do that at all. Instead special values are
  escaped with backslash.
  
  item29.X-ABLabel:custom-label5\nUmlaut-ä\nSemicolon\;
  -
  X-ABRELATEDNAMES;X-ABLabel=custom-label5\nUmlaut-ä\nSemicolon\;:custom 
  relationship
  
  Where is it specified that the backslash escape mechanism can be used in
  parameter values?
  
  http://tools.ietf.org/html/rfc2425#page-5 says:
  
  
 param= param-name = param-value *(, param-value)
  
 param-name   = x-name / iana-token
  
 param-value  = ptext / quoted-string
  
 ptext  = *SAFE-CHAR
  
 SAFE-CHAR= WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-ASCII
; Any character except CTLs, DQUOTE, ;, :, ,
  
  My reading of that is that special characters must not appear in a ptext
  at all, not even when escaped with backslash. One has to use a quoted
  string, which (unfortunately) cannot hold all characters either.
 
 Furthermore, folding is not described for parameter values, is it?
 
 X-ABRELATEDNAMES;X-ABLabel=custom-label5 Umlaut ä Semicolon ; Backslash \ 
  newline  tab \t end of label:custom relationship
 
 This is what libsynthesis produces for a long parameter value. The \t
 was part of the original value. With the revised parser/generator it
 just gets passed through.
 
 I think the generator should be changed to not fold a line unless the
 property value has started.

I'm not sure about that anymore. The EDS parser/generator has no
problems with folding inside parameters.

Attached is a patch which does what I had in mind, but we can probably
ignore it unless folding inside parameters really turns out to be wrong
and/or cause problems.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.


diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp
index 83acbca..929ef5c 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -2101,6 +2101,7 @@ static void finalizeProperty(
   const char *proptext,
   string aString,
   TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility)
+  size_t foldStartingAt, // First byte offset where folding is allowed.
   bool aDoNotFold, // set to prevent folding
   bool aDoSoftBreak // set to insert QP-softbreaks when \r is encountered, otherwise do a full hard break (which essentially inserts a space for mimo_old)
 )
@@ -2112,6 +2113,7 @@ static void finalizeProperty(
   ssize_t foldLoc = -1; // possible break location - linear white space or explicit break indicator
   bool explf;
   cAppCharP firstunwritten=proptext; // none written yet
+  const char *start = proptext;
   while (proptext  (c=*proptext)!=0) {
 // remember position of last lwsp (space or TAB)
 if (aMimeMode==mimo_old  (c==' ' || c==0x09))
@@ -2142,8 +2144,8 @@ static void finalizeProperty(
 llen++;
 // explicit linefeed flag
 explf=(c=='\n' || c=='\r');
-if (aDoNotFold) {
-  // prohibit folding for ugly devices like V3i
+if (aDoNotFold || (proptext  (proptext - start)  foldStartingAt)) {
+  // prohibit folding for ugly devices like V3i or in the middle of the parameters
   if (explf) {
 // append what we have until here
 n--; // explicit \n or \r is ignored

Re: [os-libsynthesis] vCard group tags

2014-05-05 Thread Patrick Ohly
On Fri, 2014-05-02 at 11:59 +0200, Lukas Zeller wrote:
 On 02.05.2014, at 10:38, Patrick Ohly patrick.o...@intel.com wrote:
  I noticed another problem with the use X-ABLabel parameter approach:
  storing complex strings (spaces, quotation marks) in a parameter value
  is harder.
 
 That's probably why Apple chose the X-ABLabel property approach. An
 unparseable parameter could ruin the real data, a unknown property is
 less dangerous.
 
  The EDS vCard parser gets it wrong and fails to parse:
  
  X-ABRELATEDNAMES;X-ABLabel=domestic partner:domestic partner
  
  That is valid according to http://tools.ietf.org/html/rfc2425#page-5
  because the space is a SAFE-CHAR and thus may appear in a ptext, but the
  EDS parser does not expect the space. To work around this, we could
  voluntarily quote the string even though it is not required. 
  
  Now, the conceptual problem with X-ABLabel parameter is that a quoted
  string cannot contain double quotes. It is probably rare that a user
  enters double quotes as part of a label, but it cannot be ruled out
  either. Line breaks are also only allowed in property values and not
  parameter values.

I've looked into TMimeDirProfileHandler::generateValue() some more to
understand under which circumstances libsynthesis uses quoted strings
(with double quotes at start and end) as parameter value. At first
glance it doesn't seem to do that at all. Instead special values are
escaped with backslash.

item29.X-ABLabel:custom-label5\nUmlaut-ä\nSemicolon\;
-
X-ABRELATEDNAMES;X-ABLabel=custom-label5\nUmlaut-ä\nSemicolon\;:custom 
relationship

Where is it specified that the backslash escape mechanism can be used in
parameter values?

http://tools.ietf.org/html/rfc2425#page-5 says:


   param= param-name = param-value *(, param-value)

   param-name   = x-name / iana-token

   param-value  = ptext / quoted-string

   ptext  = *SAFE-CHAR

   SAFE-CHAR= WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-ASCII
  ; Any character except CTLs, DQUOTE, ;, :, ,

My reading of that is that special characters must not appear in a ptext
at all, not even when escaped with backslash. One has to use a quoted
string, which (unfortunately) cannot hold all characters either.

IMHO libsynthesis is currently producing broken vCards. I consider
changing the code so that it uses quoted strings if it detects unsafe
characters in the value and filters out invalid ones. unsafe would be
more conservative than in the RFC itself and also include spaces, to
work around the EDS parser bug.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] vCard group tags

2014-05-02 Thread Patrick Ohly
On Fri, 2014-05-02 at 11:59 +0200, Lukas Zeller wrote:
 Hello Patrick,
 
 On 02.05.2014, at 10:38, Patrick Ohly patrick.o...@intel.com wrote:
 
  What do you mean by independent properties?
  
  For example, ADR and TEL are independent in the sense that their values
  are stored in different field arrays. Sharing the LABEL field for the
  new parameter creates a dependency (or risk of collision) that did not
  exist before.
 
 But how can this work at all? The index in the field arrays is what
 relates the components (e.g. TEL, TEL_FLAGS and LABEL) to each other.
 
 This would mean all of the field arrays would need to have rows for
 the *sum* of all the TEL+ADR+EMAIL+URL+xxx, with most rows empty, to
 be able to share a single LABEL array.
 
 Now I see why you want to check the availability of LABEL row even if 
 assigned via a property parameter.
 
 Hmmm - indeed this might work, at the expense of a lot of empty
 elements in the actual property field arrays.

Exactly, that's what I need and get with the patch.

I suspect that a groupfield would cause less empty elements if (and only
if) no groups are used, because then values from different properties
can use the same UNASSIGNED entry in the group field. But I haven't
checked whether that's really how it works; it is not very relevant with
Google because Google uses many group tags, even if the label is just
Other.

If different properties end up sharing the same UNASSIGNED group tag,
then adding labels is harder in scripts (must move entries before
setting the tag), but that's not necessary at the moment.

  I'm just not sure right now if the generator part of MimeProfile is
 prepared for properly skipping entirely empty rows to avoid generating
 empty property lines in the vCard output. But that would be fixable as
 well.

That part already works.

  That's because the code which checks where to store the ADR value does
  not check whether the LABEL at the position is available.
  
  There's another problem:
  
  TEL:123456789
  ADR;X-ABLabel=labelAdr:xxx
  
  A simplistic check LABEL[0] empty will accept position #0 for ADR. But
  doing so will add the labelAdr also to the TEL, which was previously
  created at position #0.
  
  That means that the check has to be LABEL[0] does not exist.
 
 Yes. Fortunately, TItemField differentiates between empty and unassigned; the 
 check needs to be for the latter.

Unassigned is not good enough. If the LABEL array gets extended at the
end (for example, because the third ADR had a X-ABLabel parameter), then
I have unassigned entries at the beginning of the array which must not
be used, because there are already other properties associated with
them.

Here's the patch:

diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp
index 5b0ecc7..3699ad0 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -4154,6 +4154,35 @@ bool TMimeDirProfileHandler::parseProperty(
   else
 dostore = true; // at least one field exists, we might 
store
 }
+// - check if fields used for parameters are empty
+const TParameterDefinition *paramP = aPropP-parameterDefs;
+while (paramP) {
+  if (mimeModeMatch(paramP-modeDependency)
+#ifndef NO_REMOTE_RULES
+   (!paramP-ruleDependency || 
isActiveRule(paramP-ruleDependency))
+#endif
+  ) {
+if (paramP-convdef.fieldid==FID_NOT_SUPPORTED)
+  continue; // no field, no need to check it
+sInt16 e_fid = paramP-convdef.fieldid /* +baseoffset */;
+sInt16 e_rep = repoffset;
+aItem.adjustFidAndIndex(e_fid,e_rep);
+// - get base field
+TItemField *e_basefldP = aItem.getField(e_fid);
+TItemField *e_fldP = NULL;
+if (e_basefldP)
+  e_fldP=e_basefldP-getArrayField(e_rep,true); // get 
leaf field, if it exists
+if (!e_basefldP || e_fldP) {
+  // base field of one of the main fields does not exist 
or leaf field is already in use
+  // (unassigned is not good enough, otherwise we might 
end up adding information
+  // to some other, previously parsed property using the 
same array field)
+  // - skip that repetition
+  dostore=false;
+  break;
+}
+  }
+  paramP=paramP-next;
+}
 // check if we can test more repetitions
 if (!dostore) {
   if (aRepArray[repid]+1maxrep || maxrep==REP_ARRAY) {


  I'm undecided now how to proceed. Simplify X-ABLabel property values so
  that they can be stored as parameter? Use the more complex X-ABLabel
  property and grouping

Re: [os-libsynthesis] vCard group tags

2014-04-30 Thread Patrick Ohly
On Tue, 2014-04-29 at 18:00 +0200, Lukas Zeller wrote:
 Hi Patrick,
 
 you are faster in understanding the details than I could look them
 up :-)

Live and learn. Or use the source, Luke ;-)

However, it helps to spell out observations and thoughts occasionally,
so let me continue with a related problem.

I decided that a separate X-ABLabel for every TEL, ADR, X-ABDate,
X-ABRELATEDNAMES, etc. is too verbose and too different from
traditional usage of vCard. Recipients of such a vCard must be able to
understand and support groups, which is not guaranteed. For example, the
Evolution vCard parser supports groups, but the higher level of
abstraction does not (or not easily).

I also don't see what advantage X-ABLabel as property has over X-ABLabel
as parameter. I understand that a property could itself have parameters
or complex values, but that's not the case here. A simple string might
just as well be attached as parameter.

So that's what I am trying to do:
 1. Parse with groups: X-ABLabel property enabled.
 2. Throw away group tags.
 3. Generate with parameter: X-ABLabel parameter enabled.

This direction works. What fails is reading such a generated vCard,
because different properties store their X-ABLabel parameter in the same
LABEL field array, overwriting each others' values.

The logic for choosing a position must now also (or instead?!) check
whether the LABEL position is unused when adding a new ADR. In other
words, when parsing an ADR, look at LABEL to determine the position. I
thought I could achieve that with:


property name=X-ABLabel suppressempty=yes groupfield=GROUP_TAG 
rule=HAVE-ABLABEL-PROPERTY
  value field=LABEL repeat=array increment=1 minshow=0/
  position field=LABEL repeat=array increment=1 minshow=1/
/property

property name=ADR values=7 groupfield=GROUP_TAG
  value index=0 field=ADR_POBOX/
  value index=1 field=ADR_ADDTL/
  value index=2 field=ADR_STREET/
  value index=3 field=ADR_CITY/
  value index=4 field=ADR_REG/
  value index=5 field=ADR_ZIP/
  value index=6 field=ADR_COUNTRY/
  position field=LABEL repeat=array increment=1 minshow=1/
  parameter name=TYPE default=yes positional=no show=yes
value field=ADR_STREET_FLAGS conversion=multimix combine=,
  enum name=HOME value=B0/
  enum name=WORK value=B1/
  enum mode=ignore   value=B2/ !-- OTHER --

  !-- enum mode=prefix name=X-CustomLabel- value=1.L/ --
  !-- enum mode=prefix name=X-Synthesis-Ref value=2.L/ --
/value
  /parameter
  parameter name=X-ABLabel rule=HAVE-ABLABEL-PARAMETER
value field=LABEL/
  /parameter
/property

However, when parsing a vCard with HAVE-ABLABEL-PARAMETER unset and
HAVE-ABLABEL-PROPERTY set,
sysync::TMimeDirProfileHandler::parseProperty() goes into an endless
loop involving sysync::TMultiFieldItem::adjustFidAndIndex() directly on
the first ADR:

ADR;TYPE=HOME:PO;neighborhood;home address\n;City;State;ZIP;Country

It's permanently increasing repoffset.

I've not looked further, but I suspect that this is because of using
LABEL twice, once indirectly via the group field and once via the
position field.

I'll try applying different property elements, even if that means more
duplication in the profile.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] vCard group tags

2014-04-30 Thread Patrick Ohly
 : 1
 -- element1 : 2
- 75 : string ADR_STREET_LABEL [ n/a,   0, 0] : unassigned
- 76 :integer ADR_STREET_ID   [ n/a,   0, 0] : unassigned
- 77 :  multiline ADR_POBOX   [   0,   0, 0] : array with 3 elements
 -- element0 : PO
 -- element1 : unassigned
 -- element2 : unassigned
- 78 :  multiline ADR_CITY[   0,   0, 0] : array with 3 elements
 -- element0 : City
 -- element1 : unassigned
 -- element2 : unassigned
- 79 :  multiline ADR_REG [   0,   0, 0] : array with 3 elements
 -- element0 : State
 -- element1 : unassigned
 -- element2 : unassigned
- 80 :  multiline ADR_ZIP [   0,   0, 0] : array with 3 elements
 -- element0 : ZIP
 -- element1 : unassigned
 -- element2 : unassigned
- 81 :  multiline ADR_COUNTRY [   0,   0, 0] : array with 3 elements
 -- element0 : Country
 -- element1 : unassigned
 -- element2 : unassigned
- 82 :  multiline NOTE[   0,   0,15] : A test contact.
- 83 : string PHOTO   [   0,   0,   516] : �PNG

- 84 : string PHOTO_TYPE  [   0,   0, 0] : empty
- 85 : string PHOTO_VALUE [   0,   0, 0] : empty
- 86 : string GEO_LAT [   0,   0, 0] : empty
- 87 : string GEO_LONG[   0,   0, 0] : empty
- 88 : string CRYPTOENCRYPTPREF [   0,   0, 0] : empty
- 89 : string CRYPTOPROTOPREF [   0,   0, 0] : array with 0 elements
- 90 : string CRYPTOSIGNPREF  [   0,   0, 0] : empty
- 91 : string OPENPGPFP   [   0,   0, 0] : empty
- 92 : string XPROPS  [   0,   0, 0] : array with 2 elements
 -- element0 : 
X-PHONETIC-FIRST-NAME:John
 -- element1 : 
X-PHONETIC-LAST-NAME:Doe

Do I need to modify the source code to ensure that parameters do not
exist yet?

Similar to for (sInt16 e=0; eaPropP-numValues; e++) { the code would
also need to iterate over aPropP-parameterDefs.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] vCard group tags

2014-04-29 Thread Patrick Ohly
On Wed, 2014-04-16 at 17:34 +0200, Lukas Zeller wrote:
 Hello Patrick,
 
 On 11.04.2014, at 12:18, Patrick Ohly patrick.o...@intel.com wrote:
 
  Google CardDAV and iOS/OS X use group tags to represent custom labels in
  vCards. Attached is an example. Note that the Google vCard format used
  by CardDAV is not the same as the one used by Gmail's export feature.
  The example is from CardDAV.
  
  I am trying to understand how I can support that using libsynthesis.
  
  The doc mentions:
  
  groupfield
  [...]
  Is there an example using this feature?
 
 I implemented that feature back at Synthesis in 2010 for Beat's
 Android client, and what is shown in the docs (the TITLE/ORG case) is
 in fact taken from that client's config.
 
  Is the following field list and profile correct?
  
  Field list:
  
   field name=TITLE array=yes type=string/
   field name=ORG_NAME array=yes type=string/
   field name=ORG_DIVISION array=yes type=string/
   field name=ORG_OFFICE tarray=yes ype=string/
   field name=ORG_TEAM array=yes type=string/
   field name=ROLE array=yes  type=string/
   field name=GROUP-TAG-TITLE-ORG array=yes type=string/
  
  Profile:
  
 property name=TITLE grouptag=GROUP-TAG-TITLE-ORG
   value field=TITLE/
 /property
 property name=ORG values=4 grouptag=GROUP-TAG-TITLE-ORG
   value index=0 field=ORG_NAME/
   value index=1 field=ORG_DIVISION/
   value index=2 field=ORG_OFFICE/
   value index=3 field=ORG_TEAM/
 /property
  
  
  My understanding is that parsing the example from the documentation will 
  lead to:
  ORG = [ myOwnCompany, myEmployer ]
  TITLE = [ boss, employee ]
  GROUP-TAG-TITLE-ORG = [ A, B ]
 
 Yes, that's excactly what is supposed to happen.

Unfortunately I am not getting the group-tag field populated. I'm
attaching my field list and profile.

When parsing, I get:

[2014-04-28 19:31:37.575] Parsing: 
  * [2014-04-28 19:31:37.575] 
BEGIN:VCARD
VERSION:3.0
N:Doe;John;1;Mr.;Sr.
FN:Mr. John 1 Doe Sr.
NICKNAME:Johnny
TITLE:tester
ORG:at company
REV:2014-04-28T17:31:23Z
UID:6a5bd79f8b1cdd58
BDAY;VALUE=DATE:1970-12-30
ADR;TYPE=HOME:PO;neighborhood;home address\n;City;State;ZIP;Country
ADR;TYPE=WORK:;;work address
ADR;TYPE=OTHER:;;custom address
TEL;TYPE=WORK:business 1
TEL;TYPE=CELL:mobile
TEL;TYPE=HOME:home
TEL:main
TEL;TYPE=FAX,WORK:work fax
TEL;TYPE=FAX,HOME:home fax
item13.TEL:google voice
TEL;TYPE=PAGER:pager
item14.TEL:custom
EMAIL;TYPE=HOME,PREF:john@home.com
EMAIL;TYPE=WORK:d...@work.com
item1.EMAIL:j...@custom.com
NOTE:A test contact.
PHOTO;ENCODING=B:iVBORw0KGgoNSUhEUgAAACQXCAYAAABj7u2bBmJLR0QA/w
 D/AP+gvaeTCXBIWXMAAAsTAAALEwEAmpwYB3RJTUUH1gEICjgdiWkBOQAAAB10RVh0Q
 29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAABaElEQVRIx+3Wu0tcURAG8F98gRKT
 YGORRqwksJV/QOqFFIFgKgsRYbHV1larDQQCKQxpUscyhUmXJuCSNpYWPsAU6wPxHW6aWbgsu+v
 e3RUs7geHc+fON3O+M4c5HHLkyHG/eISkg5heIGmUr++hVWigyY6THlejbWSt0Bv8QBXX2MF7jK
 U4IyjjJ45xg31sYKZuw7Xv9Gh6vvXO9QbBtbGNJ8Ert+AlTURkFjQX9g5e4ykGUcBm+FaDexx2M
 UQOYhIL2Lpj09oV9CvsQgPuePj+hP037BL6M6yRSdDZHWVOcBHcEv7FvyN8xxqmeynovA1Baf4U
 VvANhyn/Uq8E/Q57ssNufhvx1QZrDHfS9p9i3sQsnscdNowXWEQlOBXMYyI4j3EavqFUzpOYl4O
 TqUJ9+NzmkbXyb6Ryfumm7Wso4it2cYXL6K6PeBmcV8E5iEvxPDjv8CyVaxQfsIfbqGIlf17k6B
 b/Ae0cnahfg6KuAElFTkSuQmCC
item4.IMPP;X-SERVICE-TYPE=GoogleTalk:xmpp:google%20talk
item5.IMPP;X-SERVICE-TYPE=AIM:aim:aim
item6.IMPP;X-SERVICE-TYPE=Yahoo:ymsgr:yahoo
item7.IMPP;X-SERVICE-TYPE=Skype:skype:skype
item8.IMPP;X-SERVICE-TYPE=QQ:x-apple:QQ
item9.IMPP;X-SERVICE-TYPE=MSN:msnim:MSN
item10.IMPP;X-SERVICE-TYPE=ICQ:aim:ICQ
item11.IMPP;X-SERVICE-TYPE=Jabber:xmpp:Jabber
item12.IMPP;X-SERVICE-TYPE=Chat-label:x-apple:custom%20chat
X-EVOLUTION-FILE-AS:Doe\, John
X-MOZILLA-HTML:FALSE
X-ABLABEL:custom-label
X-PHONETIC-FIRST-NAME:John
X-PHONETIC-LAST-NAME:Doe
item1.X-ABLabel:custom-label
item2.X-ABDATE:1971-01-01
item2.X-ABLabel:Anniversary
item3.X-ABDATE:2000-02-01
item3.X-ABLabel:custom-label
item4.X-ABLabel:Other
item5.X-ABLabel:Other
item6.X-ABLabel:Other
item7.X-ABLabel:Other
item8.X-ABLabel:Other
item9.X-ABLabel:Other
item10.X-ABLabel:Other
item11.X-ABLabel:Other
item12.X-ABLabel:Other
item13.X-ABLabel:Google Voice
item14.X-ABLabel:custom-label
item15.X-ABRELATEDNAMES:spouse
item15.X-ABLabel:Spouse
item16.X-ABRELATEDNAMES:child
item16.X-ABLabel:Child
item17.X-ABRELATEDNAMES:mother
item17.X-ABLabel:Mother
item18.X-ABRELATEDNAMES:father
item18.X-ABLabel:Father
item19.X-ABRELATEDNAMES:parent
item19.X-ABLabel:Parent
item20.X-ABRELATEDNAMES:brother
item20.X-ABLabel:Brother
item21.X-ABRELATEDNAMES:sister
item21.X-ABLabel:Sister
item22.X-ABRELATEDNAMES:friend
item22.X-ABLabel:Friend
item23.X-ABRELATEDNAMES:relative
item23.X-ABLabel:relative
item24.X-ABRELATEDNAMES:manager
item24.X-ABLabel:Manager
item25.X-ABRELATEDNAMES:assistant
item25.X-ABLabel:Assistant
item26.X-ABRELATEDNAMES:referred-by
item26.X-ABLabel:referred by
item27.X-ABRELATEDNAMES:partner
item27.X

Re: [os-libsynthesis] vCard group tags

2014-04-29 Thread Patrick Ohly
 : Country
 -- element1 : unassigned
 -- element2 : unassigned
- 82 :  multiline NOTE[   0,   0,15] : A test contact.
- 83 : string PHOTO   [   0,   0,   516] : �PNG

- 84 : string PHOTO_TYPE  [   0,   0, 0] : empty
- 85 : string PHOTO_VALUE [   0,   0, 0] : empty
- 86 : string GEO_LAT [   0,   0, 0] : empty
- 87 : string GEO_LONG[   0,   0, 0] : empty
- 88 : string CRYPTOENCRYPTPREF [   0,   0, 0] : empty
- 89 : string CRYPTOPROTOPREF [   0,   0, 0] : array with 0 elements
- 90 : string CRYPTOSIGNPREF  [   0,   0, 0] : empty
- 91 : string OPENPGPFP   [   0,   0, 0] : empty
- 92 : string XPROPS  [   0,   0, 0] : array with 2 elements
 -- element0 : 
X-PHONETIC-FIRST-NAME:John
 -- element1 : 
X-PHONETIC-LAST-NAME:Doe


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




00vcard-fieldlist.xml
Description: XML document


01vcard-profile.xml
Description: XML document
___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] vCard group tags

2014-04-29 Thread Patrick Ohly
On Tue, 2014-04-29 at 09:50 +0200, Patrick Ohly wrote:
 On Mon, 2014-04-28 at 23:18 +0200, Lukas Zeller wrote:
  Hi Patrick,
  
   Unfortunately I am not getting the group-tag field populated. I'm
   attaching my field list and profile.
  
  small oversight on my and your part :-)
  
  The attribute to be added to property is called groupfield, not 
  grouptag...
 
 I fixed that (see attached profile + field list). It fills the GROUP_TAG
 array now, but the LABEL array only has one entry, apparently the last
 one. The array positions also don't match:
 
 item34.URL:http\://custom.com
 item34.X-ABLabel:Custom-label
 
 -  3 : string GROUP_TAG   [   0, n/a, 0] : array with 19
 elements
  -- element0 : item34
 -  4 : string LABEL   [   0,   0, 0] : array with 1 elements
  -- element0 : Custom-label
 - 34 : string WEB [   0,   0, 0] : array with 19 
 elements
  -- element0 : unassigned
 ...
  -- element   18 : http://custom.com;

I've stepped through TMimeDirProfileHandler::parseProperty() when
parsing a simpler example:

BEGIN:VCARD
VERSION:3.0
N:Doe;John;1;Mr.;Sr.
FN:Mr. John 1 Doe Sr.
UID:6f354d698b7ccd22
item1.URL:http\://company.com
item1.X-ABLabel:Work
item2.URL:http\://custom.com
item2.X-ABLabel:Custom-label
END:VCARD

When parsing item1.X-ABLabel:Work,
TMimeDirProfileHandler::parseProperty() immediately skips over the
parameter parsing because there is none and fieldoffsetfound was set to
true in
fieldoffsetfound = (aPropP-nameExts==NULL); // no first pass needed at all 
w/o nameExts, just use offs=0

It then has repoffset == 0 when storing the group tag:

  // parameters are all processed by now, decision made to store data (if 
!dostore, routine exits above)
  // - store the group tag value if we have one
  if (aPropP-groupFieldID!=FID_NOT_SUPPORTED) {
TItemField *g_fldP =  
aItem.getArrayFieldAdjusted(aPropP-groupFieldID+baseoffset,repoffset,false);
if (g_fldP)
  g_fldP-setAsString(aGroupName,aGroupNameLen); // store the group name 
(aGroupName might be NULL, that's ok)
  }

This happens to be correct (accidentally) for item1.X-ABLabel:Work.

When repeating this for item2.X-ABLabel, the setAsString() above
overwrites item1 with item2 at offset 0, leading to:

-  3 : string GROUP_TAG   [   0, n/a, 0] : array with 2
elements
 -- element0 : item2
 -- element1 : item2

The second element here came from item2.URL.

The group tag matching is buried in the parameter parsing loop. Skipping
it via the (aPropP-nameExts==NULL) is incorrect if the property has a
group name.

I'm not sure what the correct way of executing that code in this
particular case is. The following patch does not work:

diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp
index 5b0ecc7..16a5aac 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -3835,7 +3835,7 @@ bool TMimeDirProfileHandler::parseProperty(
   encoding = enc_none; // no encoding by default
   charset = aMimeMode==mimo_standard ? chs_utf8 : fDefaultInCharset; // always 
UTF8 for real MIME-DIR (same as enclosing SyncML doc), for mimo_old depends on 
inputcharset remote rule option (normally UTF-8)
   nameextmap = 0; // no name extensions detected so far
-  fieldoffsetfound = (aPropP-nameExts==NULL); // no first pass needed at all 
w/o nameExts, just use offs=0
+  fieldoffsetfound = (aPropP-nameExts==NULL)  !aGroupNameLen; // no first 
pass needed at all w/o nameExts, just use offs=0, except when we have to match 
a group name
   valuelist = aPropP-valuelist; // cache flag
   // prepare storage as unprocessed value
   if (aPropP-unprocessed) {

It loops twice, but still never reaches the group name matching because
that is inside a while (propnameextP) loop that never gets entered.

Should that code be copied out for the simpler case of a property with
no aPropP-nameExts?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] vCard group tags

2014-04-29 Thread Patrick Ohly
On Tue, 2014-04-29 at 17:18 +0200, Patrick Ohly wrote:
 On Tue, 2014-04-29 at 09:50 +0200, Patrick Ohly wrote:
  On Mon, 2014-04-28 at 23:18 +0200, Lukas Zeller wrote:
   Hi Patrick,
   
Unfortunately I am not getting the group-tag field populated. I'm
attaching my field list and profile.
   
   small oversight on my and your part :-)
   
   The attribute to be added to property is called groupfield, not 
   grouptag...
  
  I fixed that (see attached profile + field list). It fills the GROUP_TAG
  array now, but the LABEL array only has one entry, apparently the last
  one. The array positions also don't match:
  
  item34.URL:http\://custom.com
  item34.X-ABLabel:Custom-label
  
  -  3 : string GROUP_TAG   [   0, n/a, 0] : array with 19
  elements
   -- element0 : item34
  -  4 : string LABEL   [   0,   0, 0] : array with 1 
  elements
   -- element0 : Custom-label
  - 34 : string WEB [   0,   0, 0] : array with 19 
  elements
   -- element0 : unassigned
  ...
   -- element   18 : http://custom.com;
 
 I've stepped through TMimeDirProfileHandler::parseProperty() when
 parsing a simpler example:
 
 BEGIN:VCARD
 VERSION:3.0
 N:Doe;John;1;Mr.;Sr.
 FN:Mr. John 1 Doe Sr.
 UID:6f354d698b7ccd22
 item1.URL:http\://company.com
 item1.X-ABLabel:Work
 item2.URL:http\://custom.com
 item2.X-ABLabel:Custom-label
 END:VCARD
 
 When parsing item1.X-ABLabel:Work,
 TMimeDirProfileHandler::parseProperty() immediately skips over the
 parameter parsing because there is none and fieldoffsetfound was set to
 true in
 fieldoffsetfound = (aPropP-nameExts==NULL); // no first pass needed at 
 all w/o nameExts, just use offs=0
 
 It then has repoffset == 0 when storing the group tag:
 
   // parameters are all processed by now, decision made to store data (if 
 !dostore, routine exits above)
   // - store the group tag value if we have one
   if (aPropP-groupFieldID!=FID_NOT_SUPPORTED) {
 TItemField *g_fldP =  
 aItem.getArrayFieldAdjusted(aPropP-groupFieldID+baseoffset,repoffset,false);
 if (g_fldP)
   g_fldP-setAsString(aGroupName,aGroupNameLen); // store the group name 
 (aGroupName might be NULL, that's ok)
   }
 
 This happens to be correct (accidentally) for item1.X-ABLabel:Work.

Looking further at aPropP-nameExts it seems that this what relates to
position in the profile config. I did not have that for my X-ABLabel.
Adding it seems to fix the problem. So it seems that groupfield can
only be used reliably with a property which has a position, correct?

property name=X-ABLabel suppressempty=yes groupfield=GROUP_TAG
  value field=LABEL repeat=array increment=1 minshow=0/
  position field=LABEL repeat=array increment=1 minshow=1/
/property

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] SyncML Server Performance using Syncevolution

2014-04-29 Thread Patrick Ohly
On Tue, 2014-04-29 at 23:22 +0530, Sachin Gupta wrote:
 one more thing. everytime i invoke syncevolution, it has to load all
 the xmls, build up its data structures, and all the other stuff.
 Can i implement threads in it and run it as a daemon. This will i can
 save time from doing all this.
 
 From within, can i then implement threads and launch multiple sync operations?

Multithreading is not going to work. You should be able to run a sync
repeatedly in the same process, but reusing the XML loading will require
putting the loop fairly deeply into the SyncEvolution stack (see
SyncContext.cpp).

I'm still not sure why you want to do this when you can simply use more
client machines. It might safe you some time for setting up a cluster if
(and only if!) you can manage to run all clients from the same machine,
but I have my doubts whether that will be possible.

-- 
Best Regards

Patrick Ohly
Senior Software Engineer

Intel GmbH
Open Source Technology Center   
Usenerstr. 5a   Phone: +49-228-2493652
53129 Bonn
Germany


___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] Duplication of data during a merge scenario

2014-04-28 Thread Patrick Ohly
On Mon, 2014-04-28 at 18:23 +0530, Rajesh Kumar Pawar wrote:
 I've been trying to work on a merging  scenario using syncevolution as
 a client.

 The steps that I followed in this scenario are as follows
 
 1.   Created a contact with TEL;CELL:12456399
 
 2.   Perform slow sync with server
 
 3.   Modify the field in client vCard as TEL;CELL:12456300
 
 4.   Wait for 5min to ensure sufficient difference between the
 modification time stamps.
 
 5.   Modified the field as TEL;CELL:12456391 on server. 
 
 6.   Perform a two-way sync.

In this scenario, the server decides how to handle the conflict. What
SyncML implementation are you using as server? You only mention that you
use SyncEvolution as client.

If the server is not SyncEvolution or libsynthesis based, then you need
to talk to the server implementer; there's not much that SyncEvolution
or libsynthesis can do.

At least not when sticking to a standard SyncML sync. There was an idea
a while back to do a SyncML sync in two phases: in the first phase
pretend that the client has no changes, and just retrieve changes from
the server. This way conflict resolution can be done in the client. Then
in the second phase, send the client changes (including merge results)
back to the server, hoping that no further changes had been made there
in the meantime. This never got implemented, though.

In SyncEvolution there is a similar (but not quite the same) data loss
issue when adding an address on one side and a telephone number on the
other side. I'm currently looking at that.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] SyncML Server Performance using Syncevolution

2014-04-26 Thread Patrick Ohly
On Sat, 2014-04-26 at 23:42 +0530, Sachin Gupta wrote:
 On Fri, Apr 25, 2014 at 3:29 PM, Patrick Ohly patrick.o...@intel.com wrote:
  On Fri, 2014-04-25 at 15:03 +0530, Sachin Gupta wrote:
   Can you suggest how i can test SyncML Server performance and have 2500
   users/syncevolutions connecting simultaneously?
 
  There's no ready-made solution. You'll have to write your own scripts
  for configuring SyncEvolution and running the desired benchmark.
 
  Note that each context in SyncEvolution gets its own device ID. So if
  you want to simulate n different devices, use:
 
  syncevolution --configure ... client-1@client-1
  ...
  syncevolution --configure ... client-n@client-n
 
 I figured so. So wrote scripts which will launch syncevo each with
 unique device ids and seperate user accounts.
 But the concern is managing these number of syncs through a time
 period. Exploring if JMETER can help me out in this.\
 Also being a process, it would not be possible to launch so many
 processes in parallel.
 Memory and CPU would be issues, right? Would need very high end
 systems for this?

I have not measured this. Try it and you'll see. My expection is that
you will need multiple client machines, though.

 Would it be possible doing this launching processes or shall i look
 into creating threads within the Syncevolution launching and
 controlling sessions from there?

I would just use multiple client machines. Much simpler and scales
perfectly.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] mapping between individual X- extensions and grouped extensions

2014-04-26 Thread Patrick Ohly
On Sat, 2014-04-26 at 12:30 +0200, Lukas Zeller wrote:
 The afterread/beforewrite script could do such a conversion as well,
 however for normalizing data these are executed too late on the server
 side for normalized data to be used in slow sync matching, so it'll be
 more complicated to correctly match and merge records.

What do you mean with that? The afterread script gets called after
reading and before using the field list, right? So whatever
transformation is necessary (for example, X-JABBER - IMPP) can be done
in time before the engine processes the IMPP field.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] SyncML Server Performance using Syncevolution

2014-04-25 Thread Patrick Ohly
On Fri, 2014-04-25 at 15:03 +0530, Sachin Gupta wrote:
 Hi Lukas/Patrick,
 
 
 I have to run some test cases using syncevolution as client to test a
 SyncML server performance. Expectation is to put load of around 2500
 users syncing concurrently for an hour.

That's a bit vague. What kind of changes are supposed to be synced
during that hour? The load will depend a lot on that. At the low end you
just have 2500 users connecting repeatedly without data changing on
client or server. The high end is open-ended; lots of items and slow
syncs will be more expensive than few items and incremental changes.

 Can you suggest how i can test SyncML Server performance and have 2500
 users/syncevolutions connecting simultaneously?

There's no ready-made solution. You'll have to write your own scripts
for configuring SyncEvolution and running the desired benchmark.

Note that each context in SyncEvolution gets its own device ID. So if
you want to simulate n different devices, use:

syncevolution --configure ... client-1@client-1
...
syncevolution --configure ... client-n@client-n

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] mapping between individual X- extensions and grouped extensions

2014-04-25 Thread Patrick Ohly
Hello!

I am trying to figure out how I can translate between Evolution/SyncML
vCard format and CardDAV (in particular, Google Contacts).

Google Contacts seems to follow the format as used by Apple, which is
not surprising considering that Apple iOS and OS X are probably the main
clients using CardDAV.

The key difference is that CardDAV uses IMPP (rfc 4770) for all kinds of
chat protocols, whereas Evolution and several SyncML implementations use
one kind of X- extension per protocol (X-AIM, X-JABBER, ...).

Evolution:
X-JABBER;TYPE=HOME;X-EVOLUTION-UI-SLOT=2:JABBER DOE

Google CardDAV:
item5.IMPP;X-SERVICE-TYPE=GoogleTalk:xmpp:google%20talk
item5.X-ABLabel:Other

Note that X-SERVICE-TYPE=GoogleTalk is the provider of the service.
xmpp: is part of the URL value and defines the chat protocol used by
the service; the rest of the value uses URL encoding of special
characters (a space in this case). The label is just that, a label
chosen by the user.

Evolution doesn't have support for custom labels, so there is nothing
exactly corresponding to X-ABLabel yet. TYPE comes close.

Same for some dates (X-EVOLUTION-ANNIVERSARY vs. X-ABDate):

Evolution:
X-EVOLUTION-ANNIVERSARY:2006-01-09

Google CardDAV:
item3.X-ABDATE:1971-01-01
item3.X-ABLabel:Anniversary
item4.X-ABDATE:2000-02-01
item4.X-ABLabel:custom-label

The exception is BDAY, which is used by both sides.

Finally, the same difference exists for related persons:

Evolution:
X-EVOLUTION-SPOUSE:Joan Doe

Google CardDAV:
item16.X-ABRELATEDNAMES:spouse
item16.X-ABLabel:Spouse

At the moment, SyncEvolution uses separate fields for AIM (AIM_HANDLE,
an array) and spouse (a single value). I'm leaning towards changing that
into a more generic field list where there is one array for IMPP, one
array for DATE, and one array for related NAMES. I think that can be
mapped fairly directly to the vCard format used by Google CardDAV. For
example:

  field name=IMPP array=yes type=string compare=conflict/ !-- 
includes protocol: xmpp:google%20talk --
  field name=IMPP_SERVICE array=yes type=string compare=conflict/ 
!-- GoogleTalk --
  field name=IMPP_LABEL array=yes type=string compare=conflict/ 
!-- Other --
  field name=GROUP-TAG-IMPP array=yes type=string 
compare=conflict/ !-- group tag connecting IMPP_LABEL = X-ABLabel with IMPP 
and IMPP_SERVICE --

The bigger problem will be on the Evolution side. I don't see how I can
teach libsynthesis that a IMPP entry whose protocol (encoded as part of
the value!) is xmpp maps to X-JABBER.

Should I keep the traditional JABBER_HANDLE array and move entries back
and forth between it and the IMPP array? This could be done with
incoming/outgoing resp. afterread/beforewrite scripts.

Then the traditional profile will only use the JABBER_HANDLE, as before,
whereas the new profile only uses IMPP.

For SyncEvolution-SyncEvolution syncing the new profile should be used
because it will be more complete. Perhaps I can achieve that by offering
multiple datatypes and then letting the sync engines negotiate the most
suitable one.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] UID + CardDAV

2014-04-16 Thread Patrick Ohly
On Fri, 2014-04-11 at 16:52 +0200, Patrick Ohly wrote:
[property name=UID rule=HAVE-VCARD-UID shows up in CtCap]
 Could it be a bug that the disable property shows up in the CtCap?
 
 Darn, probably a circular dependency again: we have to be ready to send
 CtCap before we know the peer, so the rule mechanism (which depends on
 knowing the peer) can't be used to influence the CtCap. Right?

A closer look at the CtCap seems to confirm that. For example,
SyncEvolution knows that KDE uses X-KADDRESSBOOK-X-Profession instead of
ROLE, so it has:

!-- X-KADDRESSBOOK-X-Profession property for KDE, ROLE for everyone 
else --
property name=ROLE rule=KDE/
property name=ROLE rule=other
  value field=ROLE/
/property
property name=X-KADDRESSBOOK-X-Profession suppressempty=yes 
show=no rule=KDE
  value field=ROLE/
/property

This is a somewhat convoluted way of saying that vCard ROLE is not
active for KDE (no value specied) and that X-KADDRESSBOOK-X-Profession
is to be used instead.

In the CtCap, both properties show up:

PropertyPropNameROLE/PropNameMaxOccur1/MaxOccur/Property
PropertyPropNameX-KADDRESSBOOK-X-Profession/PropNameMaxOccur1/MaxOccur/Property

This means that I can't put properties that are never meant to be sent
over SyncML into the profile used for syncing. I need to maintain a
separate profile with UID enabled that gets used for 
MAKETEXTWITHPROFILE/PARSETEXTWITHPROFILE.

I wonder whether it makes sense to have X-KADDRESSBOOK-X-Profession
appear in the CtCap. Probably not, because SyncEvolution will not use it
during syncing, only during storing in the datastore. I probably need to
change the way how SyncEvolution adapts the main profile for specific
storages: instead of setting rules in MAKETEXTWITHPROFILE or
PARSETEXTWITHPROFILE, it needs to do its own custom pre-processing to
turn the main profile into a KDE profile or an EDS profile.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] vCard group tags

2014-04-16 Thread Patrick Ohly
Hello!

Google CardDAV and iOS/OS X use group tags to represent custom labels in
vCards. Attached is an example. Note that the Google vCard format used
by CardDAV is not the same as the one used by Gmail's export feature.
The example is from CardDAV.

I am trying to understand how I can support that using libsynthesis.

The doc mentions:

groupfield

New in 3.4: This optional attribute can be used to specify a string 
field (usually
a array or a repeating field) which represents the vCard or vCalendar 
group tag (a prefix to
the property name, separated by a dot). The group tag can be used to 
link properties together
which can occur multiple times. For example, some vCards might contain 
more than one
ORG and TITLE. Now each title belongs to a particular organisation, so 
the group tag is
used to represent that:

A.ORG:myOwnCompany
B.ORG:myEmployer

B.TITLE:employee
A.TITLE:boss

The groupfield mechanism makes sure that TITLE and ORG repetitions will 
be stored in the
same repetition index (array position if ORG and TITLE are mapped to 
arrays) according to
their group tag, even if occuring out of order in the incoming vCard.

Is there an example using this feature?

Is the following field list and profile correct?

Field list:

  field name=TITLE array=yes type=string/
  field name=ORG_NAME array=yes type=string/
  field name=ORG_DIVISION array=yes type=string/
  field name=ORG_OFFICE tarray=yes ype=string/
  field name=ORG_TEAM array=yes type=string/
  field name=ROLE array=yes  type=string/
  field name=GROUP-TAG-TITLE-ORG array=yes type=string/

Profile:

property name=TITLE grouptag=GROUP-TAG-TITLE-ORG
  value field=TITLE/
/property
property name=ORG values=4 grouptag=GROUP-TAG-TITLE-ORG
  value index=0 field=ORG_NAME/
  value index=1 field=ORG_DIVISION/
  value index=2 field=ORG_OFFICE/
  value index=3 field=ORG_TEAM/
/property


My understanding is that parsing the example from the documentation will lead 
to:
ORG = [ myOwnCompany, myEmployer ]
TITLE = [ boss, employee ]
GROUP-TAG-TITLE-ORG = [ A, B ]

The challenge will be to convert between
item6.IMPP;X-SERVICE-TYPE=AIM:aim:aim
item6.X-ABLabel:Other
and
X-AIM:aim

Custom labels will also be fun, if that's what Evolution decides to
use (currently it is unsupported).

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.


BEGIN:VCARD
VERSION:3.0
N:Doe;John;1;Mr.;Sr.
FN:Mr. John 1 Doe Sr.
NICKNAME:Johnny
TITLE:tester
ORG:at company
REV:2014-04-11T08:43:42Z
UID:6f354d698b7ccd22
BDAY;VALUE=DATE:1970-12-30
ADR;TYPE=HOME:PO;neighborhood;home address\n;City;State;ZIP;Country
ADR;TYPE=WORK:;;work address
item1.ADR:;;custom address
TEL;TYPE=WORK:business 1
TEL;TYPE=CELL:mobile
TEL;TYPE=HOME:home
TEL:main
TEL;TYPE=FAX,WORK:work fax
TEL;TYPE=FAX,HOME:home fax
item14.TEL:google voice
TEL;TYPE=PAGER:pager
item15.TEL:custom
EMAIL;TYPE=HOME,PREF:john@home.com
EMAIL;TYPE=WORK:d...@work.com
item2.EMAIL:j...@custom.com
NOTE:A test contact.
PHOTO;ENCODING=B:/9j/4AAQSkZJRgABAQAAAQABAAD/4QDSRXhpZgAASUkqAAgCADEBAg
 AHJgAAAGmHBAABLgBQaWNhc2EAAAIAAJAHAAQwMjIwhpIHAH0AAABMA
 AAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
 ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
 gICAgICAgICAgICAgICAgICAgAP/bAIQAAwICCAgICAgICAgICAgICAgICAgICAgICAgICAgIBw
 gIBwcHBwcHBwcHBwcHCgcHBwgJCQkHBwwMCggMBwgJCAEDBAQGBQYKBgYKDQwMDA0MDAwMDAgIC
 AgIDAgIDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI/8AAEQgCgAKAAwEiAAIR
 AQMRAf/EAB0AAAICAwEBAQIDBAUBBgcACAn/xABFEAACAQMDAwIEBAQEBAMHBQE
 AAQIDBBEFITEGEkFRYQcTInEIMoGRFEKhsSNSwfAVYtHhM3LxFhgkQ0SCkgk0U2PSF//EABsBAA
 IDAQEBAAACAQMEBQYH/8QAKxEBAQACAQQDAAICAQQDAAECEQMEEiExBRNBI
 lEyYRQjQoGxUpGh/9oADAMBAAIRAxEAPwD5IyEjOAkj1rmMIZFHkgoocMoykZSCigKzBDFEwojH
 EEUAaPYMpExErMUGonohJDDbyPSQUUZcQGwxQ1I9BBpAXYcBJBJBKIDbBlIJRM9oxWIoOKMxiMh
 EAxFBRRlRDjEDb09FDInoxCSDRbRQPJYCiYk/ATwJXnPJ6nAFQwZVX6sDWoo0tsHp1CJ/E/U0Rq
 txnZC2T2skXtlVzBnu/CyI0uf0uOdyJe3vY8N7Ln7Fdz0jVWDnwZUe2e7xng1266uoucYKaxjd5
 Nc1L4kU4N9zz2vZ+wt5sf03ZXSatfH3FT1KK5a/7nGKvxpeW8ZXCNX6h+JlSrtH6UZ8+q456XTp
 9u+aj1nSpLum1+5RT+Mdo0/D+5843GqVpbym5L38EaKT3Zhz62z0unTvoH//ALPa5xLj1JVP42W
 8WllYfufOPYm8I9s+FuimdfyG+h9SaD8VqEqm81hm+2+vUJ7xqxa+58QUrlLjZr3LGy6krQbcak
 kvuaMevv6S8D7dtLiEt4tE7HufGmkfE+6pbxm2l4Z0rRPxEvEfnRx9tzbxdbjldVVl076CUMLKe
 56Fxl5xn1OSW/x1t6jSb7Y+pc1/iDSh2zp1FKL533Nc6nCqvprplX8ufPgfaSTjnG65OZ6L8VaN
 RuDlzsmb1ouqR7eUWTmwpbx1bSiNoLBFp105LcbVvI96SaLcbFdx0mxQyKFjEWUWsNBRR7AcYi7

Re: [os-libsynthesis] Photo Data getting truncated

2014-04-09 Thread Patrick Ohly
On Wed, 2014-04-09 at 19:13 +0530, anuj chauhan wrote:
 Hi Patrick,
 
 
 I am trying to syncronize image data with funambol server but while
 sending the data to server syncevolution is truncating the image data
 to somewhere
 200-300 bytes.The actual image data was 2423 bytes.
 
 
 Below is snippet of what  am trying to send(length of image data is
 2423 bytes) :
 
 
 BEGIN:VCARD
 N:lastname3;firstname3;Kumar;Mr;Phd
 EMAIL;WORK;INTERNET:wo...@hotmail.com
 EMAIL;HOME;INTERNET:ho...@hotmail.com
 URL:http://www.care1.com
 ADR;HOME:;;Caprio;Demalio;Romania;RD3258;USA
 ADR;WORK:;;Caprio;Demalio;Romania;RD3258;USA
 PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxMTEhQUExQWFRQXGBUUFxUUFxQUFRUUFBQXFhUVFBQYHCggGBwlHBQUITEhJSkrLi4uFx8zODMsNygtLisBCgoKDg0OGhAQGywkHxwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLP/AABEIALcBEwMBIgACEQEDEQH/xAAcAAABB...remainder
  of B encoded binary data...
 END:VCARD

There is no VERSION:3.0 in this example. Are you sure that the engine is
parsing it as vCard 3.0?

Have you checked that base64 decoding worked as expected? Look at the
field list dump at loglevel=4.

If all of that worked, can you attach the full test data?


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] How to synchronise image with server

2014-04-07 Thread Patrick Ohly
On Mon, 2014-04-07 at 18:00 +0530, Anuj wrote:
 Hi Patrick,
 Thanks for replying ,
 I have a doubt on where to define value =uri
 In mime profile or somewhere else.please specify.

Please follow http://www.ietf.org/rfc/rfc2426.txt for formatting your
PHOTO data.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] How to synchronise image with server

2014-04-04 Thread Patrick Ohly
On Fri, 2014-04-04 at 05:28 -0500, anuj chauhan wrote:
 Hi Patrick,
 
 
 I created a photo field as mentioned
 on https://tools.ietf.org/html/rfc6350#page-30.Below is sample for
 that
 
 
 PHOTO:file:///home/droot/evol_store1/photos/Blue hills.jpg.
 
 
 
 but when i tracked the outgoing log I found that syncevolution has
 converted the string file:///home/droot/evol_store1/photos/Blue
 hills.jpg. into base64 format and sent the url for syncronization,

A full log at loglevel=4 would be useful in cases like this.

However, after looking at 04vcard-photo-inlining.xml I have a hunch: you
don't specify VALUE=uri explicitly, and the script checks for that.

That follows http://www.ietf.org/rfc/rfc2426.txt which says The default
is binary value. You used vCard 4.0, which is not used or supported by
SyncEvolution. vCard 4.0 has a different definition of the PHOTO
property (value is always a URI and inline data is represented as a
special URI).

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] How to synchronise image with server

2014-04-02 Thread Patrick Ohly
On Wed, 2014-04-02 at 13:32 +0530, Anuj wrote:
 Hi ,
 I want to synchronise image with server but have no clue of its 
 representation in 
 vCard.Do I need to put URL of image in vCard photo field or entire
 image data need to be put in vCard.kindly guide me on this issue 
 I am using file based backend for syncevolution.

You can either base64 encode the photo data as specified by
https://tools.ietf.org/html/rfc6350#page-30 or you can use a file URL.
SyncEvolution then will read the file data and inline it before sending
to the server.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] How to build a installation package for syncevoltion client for ubuntu

2014-03-05 Thread Patrick Ohly
On Tue, 2014-03-04 at 16:33 +0530, anuj chauhan wrote:
 w.r.t previous mail, i want to ask that how do i build a .deb package
 from the source compiled locally?
 
 I can see that there are options to make or make install, but could
 not find any command to build a .deb package.
 
 
 normally there are options to build a package using buildpkg command,
 but i could not find the same here.

It is not normal for autotool's based projects to have make targets for
packaging in distro-specific formats like .rpm or .deb. This is
something that distros add when taking upstream source from a git repo
or source tar balls.

In the case of SyncEvolution, there is a make deb target. It's meant
to be used as part of the nightly testing and depends on CheckInstall
being installed. Your mileage may vary.

You are probably better off learning how to build a .deb package and
doing that the normal way - see Debian HOWTOs.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.




___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] how to configure libsynthesis syncronizing a group of contactcs.

2014-01-27 Thread Patrick Ohly
On Mon, 2014-01-27 at 07:16 -0600, anuj chauhan wrote:

 I want to synchronize a group of contacts .Is there any group-filed
 tag in libsynthesis
 
 for contacts.or any subsection in xml configuraton for
 group-synchronization.I am completly blank on how to achieve this
 through synthesis.

Defining a group of contacts is not standardized in vCard. If you want
to synchronize it, you probably have at least one system where groups of
contacts are supported. Which system is that and how does it exchange a
group?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] PHOTO + compare=never

2013-07-10 Thread Patrick Ohly
On Fri, 2013-07-05 at 14:05 +0200, Lukas Zeller wrote:
 On 05.07.2013, at 11:58, Patrick Ohly patrick.o...@intel.com wrote:
 
  [...]
  I broke MERGEFIELDS() when introducing that mode, see attached patch. It
  is now still not backward-compatible. Is there a way to have a builtin
  function with an optional parameter?
 
 There is, see the OPTVAL() in the param definitions, for example param_find 
 in scriptcontext.cpp.
 In the function implementation, you can test for isAssigned() to see if the 
 parameter was specified
 in the call or not.

I've implemented that now in the patch that'll appear in the FDO master
git branch soon.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] temporary local ID + FinalizeLocalID

2013-07-05 Thread Patrick Ohly
On Wed, 2013-06-26 at 16:10 +0200, Patrick Ohly wrote:
 On Mon, 2013-06-10 at 12:35 +0200, Lukas Zeller wrote:
  On 10.06.2013, at 11:57, Patrick Ohly patrick.o...@intel.com wrote:
   I'll probably try something else: if commands were delayed in a
   message which is marked Final, then force execution of the commands at
   the end of processing that message and issue their Status commands, just
   as syncing normally would.
  
  Sounds like a good compromise to me.
 
 I've implemented that. I've run this through a full test against
 different peers, without problems. Or rather, there were problems
 earlier, which shows that the tests covered relevant corner cases ;-)
 These problems have been addressed.

After adding more tests, I found one more problem: the combination of
Moredata and queuing preceding items failed. Patch attached. I intend
to squash it into the preserve status order patch before including FDO
master branch.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.

From 1f01b69ee1aa597924f90c48a299db254a0cd5d9 Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Mon, 1 Jul 2013 08:52:47 +0200
Subject: [PATCH 1/4] merge: ordered status

Add/Replace commands which contain incomplete items are special: they
must trigger a Status 213 response in the same message, which cannot
be done without processing the previously queued commands first.

We could try to queue the incomplete command without processing it at
all, but that would change the response in a way that might be
unexpected by the peer (although legal). Better play it safe and
finish all queued commands, then process the command.
---
 src/sysync/synccommand.cpp |   18 ++
 src/sysync/synccommand.h   |4 
 src/sysync/syncsession.cpp |7 +++
 3 files changed, 29 insertions(+)

diff --git a/src/sysync/synccommand.cpp b/src/sysync/synccommand.cpp
index ef363d1..3b27d63 100755
--- a/src/sysync/synccommand.cpp
+++ b/src/sysync/synccommand.cpp
@@ -2289,6 +2289,24 @@ missingeoc:
 } // TSyncOpCommand::AddNextChunk
 
 
+// SyncOp commands can execute out of order except when they
+// contain chunked items, because then we would have to issue
+// a 213 Status immediately, which would violate the ordering
+// of Status replies.
+bool TSyncOpCommand::canExecuteOutOfOrder()
+{
+  SmlItemListPtr_t *itemnodePP=(fSyncOpElementP-itemList);
+  while (*itemnodePP) {
+SmlItemListPtr_t thisitemnode = *itemnodePP;
+if (thisitemnode-item 
+thisitemnode-item-flags  SmlMoreData_f) {
+  return false;
+}
+itemnodePP = (thisitemnode-next);
+  }
+  return true;
+}
+
 // execute command (perform real actions, generate status)
 // returns true if command has executed and can be deleted
 bool TSyncOpCommand::execute(void)
diff --git a/src/sysync/synccommand.h b/src/sysync/synccommand.h
index bc5869c..c070905 100755
--- a/src/sysync/synccommand.h
+++ b/src/sysync/synccommand.h
@@ -90,6 +90,9 @@ public:
   #endif
   // - analyze command (but do not yet execute)
   virtual bool analyze(TPackageStates aPackageState) { fPackageState=aPackageState; return true; }; // returns false if command is bad and cannot be executed
+  // - execute() can be called even if there are other already queued commands.
+  //   True by default, exceptions must be defined explicitly.
+  virtual bool canExecuteOutOfOrder() { return true; }
   // - execute command (perform real actions, generate status)
   virtual bool execute(void); // returns true if command could execute, false if it must be queued for later finishing (next message)
   // - get number of bytes that will be still available in the workspace after
@@ -413,6 +416,7 @@ public:
   virtual ~TSyncOpCommand();
   virtual bool isSyncOp() { return true; };
   virtual bool analyze(TPackageStates aPackageState);
+  virtual bool canExecuteOutOfOrder();
   virtual bool execute(void);
   #ifndef USE_SML_EVALUATION
   // - get (approximated) message size required for sending it
diff --git a/src/sysync/syncsession.cpp b/src/sysync/syncsession.cpp
index 870342a..a394bed 100644
--- a/src/sysync/syncsession.cpp
+++ b/src/sysync/syncsession.cpp
@@ -2549,6 +2549,13 @@ Ret_t TSyncSession::process(TSmlCommand *aSyncCommandP)
 delayExecUntilNextRequest(aSyncCommandP);
   }
   else {
+if (fDelayedExecutionCommands.size()0 
+!aSyncCommandP-canExecuteOutOfOrder()) {
+  PDEBUGPRINTFX(DBG_SESSION,(%s: command cannot be executed with other commands already delayed - flush queue,aSyncCommandP-getName()));
+  fCmdIncoming = NULL;
+  tryDelayedExecutionCommands();
+}
+
 // command is ok, execute it
 fCmdIncomingState=aSyncCommandP-getPackageState

[os-libsynthesis] PHOTO + compare=never

2013-07-04 Thread Patrick Ohly
Hello!

I just noticed one aspect of the example configs that I wasn't aware of:
syncclient_sample_config.xml:  field name=PHOTO type=blob 
compare=never merge=fillempty/

What I see in a slow is that if all fields are equal except for the
photo, the modified photo is not stored because merging considers it not
relevant (compare=never = eqm_none).

According to the doc:
never: field is not compared at all. This is for fields that do not 
contain user data, such
as REV in vCard. It would not make sense to compare these fields, as 
they are not rele-
vant for finding out if two objects have the same data or not.


What was the rationale for using that mode for PHOTO? Is it for storages
which store photo data after re-encoding it? With such a storage, the
comparison would yield a false field is different, causing unnecessary
writes. But with a storage that stores the data as-is, comparing it is
better (IMHO), because modified data actually gets stored. The downside
is that comparisons become more expensive.

Speaking of comparisons,  with EDS this is slightly tricky. Inlined data
gets replaced with a file reference, so what the comparison really needs
to do is not comparing
file:///tmp/testing/temp-testpim/data/evolution/addressbook/pim-manager-testsync-testcontacts-foo/photos/pas_id_51D53D180001_photo-file1.image%252Fjpeg
 against the binary data in the incoming item, but rather the content of that 
file.

I probably need to write a comparescript for that, right? In that case
compare=never may be the right thing to do again, but I am not sure.
Won't it lead to the situation again where MERGEFIELDS() incorrectly not
marks an item as changed even though it was?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] PHOTO + compare=never

2013-07-04 Thread Patrick Ohly
On Thu, 2013-07-04 at 13:01 +0300, Patrick Ohly wrote:
 Hello!
 
 I just noticed one aspect of the example configs that I wasn't aware of:
 syncclient_sample_config.xml:  field name=PHOTO type=blob 
 compare=never merge=fillempty/
 
 What I see in a slow is that if all fields are equal except for the
 photo, the modified photo is not stored because merging considers it not
 relevant (compare=never = eqm_none).
 
 According to the doc:
 never: field is not compared at all. This is for fields that do not 
 contain user data, such
 as REV in vCard. It would not make sense to compare these fields, 
 as they are not rele-
 vant for finding out if two objects have the same data or not.
 
 
 What was the rationale for using that mode for PHOTO? Is it for storages
 which store photo data after re-encoding it? With such a storage, the
 comparison would yield a false field is different, causing unnecessary
 writes. But with a storage that stores the data as-is, comparing it is
 better (IMHO), because modified data actually gets stored. The downside
 is that comparisons become more expensive.

When using compare=conflict fot PHOTO, I get

[2013-07-04 14:35:45.739] Winning and loosing Field 'PHOTO' not equal: 'BLOB 
size=0'  'BLOB size=0'
[2013-07-04 14:35:45.739] - updated fields such that both have same value 
'BLOB size=0'

and PHOTO == EMPTY in a script also does not work. Shouldn't a blob
comparison compare the content (= byte string) and treat a blob of size
0 as empty?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] redundant DB updates - script for processing incoming items from SyncML peer?

2013-06-11 Thread Patrick Ohly
Hello!

When storing contacts in Evolution Data Server, SyncEvolution applies a
beforewritescript which massages the contact such that it meets
Evolution conventions. For example, the VOICE flag must be set for TEL,
because otherwise Evolution ignores the number.

This leads to the following situation:
  * Contact with TEL;TYPE=WORK:1234 is received.
  * It gets processed and before writing, the flag is set =
TEL;TYPE=WORK,VOICE:1234
  * The next sync is a slow sync, so the incoming item (absolutely
unmodified!) gets compared against the one from the datastore.
  * Because the datastores' and the incoming items TEL flags are
different, the engine concludes that the DB item must be merged
and updated in the DB.
  * Because the same beforewritescript is again applied after the
merge, the exact same item gets sent as update to the DB,
without changing anything.

This leads to one unnecessary database operation, which is undesirable
when slow syncs are frequent and the storage resides on flash storage.
This is the case for syncing with PBAP in IVI.

IMHO the adapt item to what is expected by data store step should be
applied to the incoming item *before* processing it, in other words, in
the incomingscript. If processing then doesn't break the item again,
the script does not need to run again before writing.

But the SySync_config_reference.pdf explicitly warns against that:
Note that this is not the place to implement database specific
conversions, because this is better done in the beforewritescript and
afterread-script in the datastore section.

Is that because normally, datatypes are shared between different data
stores?

I could avoid that by defining datatypes such that they only get used in
exactly one data store. The putting data store specific transformations
into the datatype's incomingscript would be okay, wouldn't it?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] temporary local ID + FinalizeLocalID

2013-06-10 Thread Patrick Ohly
On Mon, 2013-06-10 at 12:35 +0200, Lukas Zeller wrote:
 On 10.06.2013, at 11:57, Patrick Ohly patrick.o...@intel.com wrote:
  I'll probably try something else: if commands were delayed in a
  message which is marked Final, then force execution of the commands at
  the end of processing that message and issue their Status commands, just
  as syncing normally would.
 
 Sounds like a good compromise to me.

It seems to be working, too :-)

  The effect will be that commands only get delayed across messages if
  there will be more of them coming in anyway. The hope is that this will
  avoid or at least minimize state change issues.
  
  Note that the problem that I am running into also exists in the
  unmodified code: I expect similar issues when the server delays
  processing because of timing.
 
 Probably not, because the server can only delay processing at the very
 beginning of the sync, while it loads the sync set in the background.
 So far, this was the only (but well tested with very long lasting sync
 set loads) case of delaying command execution. Delaying execution
 after sync has actually started is a new case.

Ah, I see. I had skipped over the
fLocalSyncDatastoreP-engIsStarted(false) check in the relevant code:

TSyncSession::processSyncOpItem()
...
  // check if we can process it now
  // Note: request time limit is active in server only.
  if (!fLocalSyncDatastoreP-engIsStarted(false) || RemainingRequestTime()0) {
aQueueForLater=true; // re-execute later...
return true; // ...but otherwise ok
  }

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] temporary local ID + FinalizeLocalID

2013-06-07 Thread Patrick Ohly
On Mon, 2013-06-03 at 22:17 +0200, Lukas Zeller wrote:
  How about yet another approach: the store is allowed to return a new
  error code, LOCERR_AGAIN, for add/update/delete operations. The engine
  then remembers all operations with that return code and calls them again
  (with the exact same parameters and without freeing resources!) at a
  suitable time, for example the end of the current message. In the second
  call, the store must execute or finish the operation.
  
  The engine must not call an operation on an item for which it has
  already something pending. If that happens, it has to complete the first
  operation first. That way the store can keep a list of pending
  operations with the ItemID as key.
 
 Sounds like a good solution indeed. I like it better than
 late-handling return codes especially because it avoids any risk of
 breaking existing datastores (and possible unsafe assumptions in their
 implementations), because for those nothing would change outside *and*
 inside the engine.
 
 It's also somewhat similar to the finalisationscript mechanism,
 which also keeps items (or parts of them) in memory for using them
 again at the end of the session, usually to resolve cross references
 (parent/child tasks for example). Maybe some of the mechanisms can be
 re-used for LOCERR_AGAIN. 

I found a different mechanism: TSyncSession::processSyncOpItem() can
decide to delay execution of the command by setting a flag. Currently
this is done when processing the message already took too long.

I have changed the command and item processing call chain and my backend
so that it can kick of the operation and continue when the chain is
invoked again. For that, I am setting the aQueueForLater=true to use the
existing queuing mechanism for SyncML commands.

Now I found one problem with that: after the first of several Add or
Update commands got queued, all following commands are also queued. What
I'd like to see instead is that they all get processed.

Then in the level above the engine, right before sending the response, I
would gather all pending operations and combine them into a batched,
asynchronous add or update operation. The batching is expected to be
much more efficient with EDS. It also allows overlapping local
processing in the PIM storage with network IO. But right now, I always
only get one item to be batched because everything else is still in the
queue for later processing.

Is the command received after other commands needed to be delayed -
must be delayed, too something which is imposed by SyncML?

I tried to think of situations where the engine needs to enforce
completion of the pending operation before triggering another one, but
couldn't think of such a situation. My expectation is that either the
backend will properly serialize the item changes or the item changes are
independent (update foo, delete bar).

But what could happen is that update foo gets started, does not
complete, and then delete bar gets processed right away. That would
re-order the status messages such that the status for the later command
gets sent first. That's because my backend currently can only do
insert/update asynchronously, but not deletes.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] temporary local ID + FinalizeLocalID

2013-06-03 Thread Patrick Ohly
Hello!

I'm trying to batch local database adds together to increase performance
in SyncEvolution (https://bugs.freedesktop.org/show_bug.cgi?id=52669 and
https://bugs.freedesktop.org/show_bug.cgi?id=64838#c5).

My hope was that I can postpone the actual modification and return a
temporary local ID. Then later or in parallel, combine multiple items
together in a batch add. Finally, the temporary ID was meant to be
replaced by the final one in FinalizeLocalID.

But I hit the first snag pretty early: FinalizeLocalID() doesn't seem to
get called on the server side where I need this feature primarily (for
PBAP, CalDAV, ActiveSync the server side is the one with the local
database).

dsFinalizeLocalID, the wrapper around the store's FinalizeLocalID, gets
called in three functions:
(gdb) b sysync::TBinfileImplDS::changeLogPostflight
Breakpoint 2 at 0x106f956: file 
/home/pohly/syncevolution/libsynthesis/src/sysync/binfileimplds.cpp, line 462.
(gdb) b sysync::TBinfileImplDS::SaveAdminData
Breakpoint 3 at 0x10739fd: file 
/home/pohly/syncevolution/libsynthesis/src/sysync/binfileimplds.cpp, line 2389.
(gdb) b sysync::TLocalEngineDS::engGenerateMapItems
Breakpoint 4 at 0x109c79c: file 
/home/pohly/syncevolution/libsynthesis/src/sysync/localengineds.cpp, line 6635.

None of these get called on the server side during a
refresh-from-client, slow or normal two-way sync. That makes sense, map
items are only relevant on the client, and the server is not using the
binfile class.

But shouldn't the server also call FinalizeLocalID somewhere? Where
would be the right place for it?

Regarding FinalizeLocalID() in the client, I see some conceptual issues
with it, at least for what I am trying to achieve. My main concern is
about error handling.

FinalizeLocalID() can return an error code, but dsFinalizeLocalID does
not check for errors. It merely checks for ID modified. So in case of
an error, the local store itself has to remember that writing failed and
do something.

What that something could be is not clear. It could return an error in
EndDataWrite(), in which case I would expect the engine to enforce a
slow sync in the next sync session. I can't think of other, realistic
options right now.

I think a better solution would be to delay handling the result of a
database write until the entire SyncML message has been processed. Then
give the store a chance to finalize the ID of each item that was touched
as part of that SyncML message. The store can use that opportunity to
flush the pending operations and return error codes for each item, just
as it would normally do in the synchronous write operations. Then the
engine continues with the same error handling that it already does.

The advantage, besides better error handling, is that the store has a
natural place to flush pending operations. Without the intermediate
FinalizeLocalID() calls a new max pending operations setting
independent of the SyncML message size would be needed.

Comments?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] Sync mode extensions must be optional

2013-03-10 Thread Patrick Ohly
On Thu, 2012-10-11 at 12:27 +0200, Lukas Zeller wrote:
 Hi Patrick,
 
 I found that some servers don't like the sync mode extensions in the
 devInf you introduced for SyncEvolution a while ago (crash syncs with
 misleading errors as apparently their wbxml decoders fail or
 something).
 
 As I see no way to automatically control this, I added a session level
 config flag syncmodeextensions that must be set explicitly to enable
 the extensions. The default is off, to make sure current libsynthesis
 (master branch) users will no see any difference in behaviour once
 they update. For SyncEvolution, you need to add this flag to your
 config.

For SyncEvolution 1.3.99.3, I've extended the SyncEvolution
SyncMLVersion setting to control whether the extensions are enabled.
They are enabled by default because I don't expect many users to use
affected servers, whereas more user will want it on for use with
SyncEvolution as server.

I had already done this a while ago, but then noticed a problem during
release testing which caused me to back out the changes again because I
didn't have time to investigate.

It turned out that I didn't enable the feature on the server side.
Strictly speaking, that shouldn't be necessary, because the server will
only add the extensions when the client already sent his, so there
should not be any problem. But it makes sense to have this configurable,
just in case.

The master branch of libsynthesis on freedesktop.org is now based on the
latest gitorious master branch. Lukas, it contains two patches which you
might want to include:


commit 9b0c01cf2fff6701bdb026518048fc4b06a7072e
Author: Patrick Ohly patrick.o...@intel.com
Date:   Thu Feb 21 00:51:53 2013 -0800

caching mode: fix memory leak

When deleting unmatched local sync items, the TSyncItem instance was
leaked after removing it from fItems.


commit 99159e0991664f8c8319e634598ea6c9bd73fcc2
Author: Patrick Ohly patrick.o...@intel.com
Date:   Mon Sep 10 09:15:20 2012 +0200

autotools: bumped minor version

Bumped minor version so that SyncEvolution can ensure that the version
it is compiled against really fixes the VJOURNAL-plain text
conversion problem.

BTW, did you tag 3.4.0.47? There is a comment about the version, but not
the tag itself.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] one-way sync + sync tokens not updated

2012-08-21 Thread Patrick Ohly
Hello!

SyncEvolution's ActiveSync backend is the first one which uses the
string tokens in StartDataRead() and EndDataWrite(). The backend always
runs inside a binfile-based SyncML client.

In one particular test I am using a one-way-from-server sync,
initiated by the client, and noticed a problem: the new token created by
the backend in EndDataWrite() was not passed to the StartDataRead() in
the next sync.

The backend cannot handle that, because the tokens come directly from
ActiveSync, which only allows reusing old tokens in a few limited cases.
In this case, the server rejected the obsolete token, causing an
unexpected slow sync.

Full log is here:
http://syncev.meego.com/2012-08-16-17-03_all/testing-amd64/14-exchange/Client_Sync_eds_contact_testOneWayFromLocal.send.client.B/syncevolution-log.html

It has no debug output explaining the problem. I tracked it down to
this:

// save end of session state
localstatus TCustomImplDS::implSaveEndOfSession(bool aUpdateAnchors)
{
  localstatus sta=LOCERR_OK;
  PDEBUGBLOCKCOLL(SaveEndOfSession);
  // update TCustomImplDS dsSavedAdmin variables (other levels have already 
updated their variables
  if (aUpdateAnchors) {
if (!fRefreshOnly || fSlowSync) {
...
  // also update opaque reference string possibly needed in DS API 
implementations
  fPreviousToRemoteSyncIdentifier = fCurrentSyncIdentifier;
=PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,(updating sync token 
(fPreviousToRemoteSyncIdentifier) from %s to current sync token 
%s,fPreviousToRemoteSyncIdentifier.c_str(),fCurrentSyncIdentifier.c_str()));
} else {
=PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,(keeping old sync token 
(fPreviousToRemoteSyncIdentifier) %s instead of updating to current sync token 
%s,fPreviousToRemoteSyncIdentifier.c_str(),fCurrentSyncIdentifier.c_str()));
}

I added that debug output. It confirms that the keeping old sync token
branch is taken.

What is the rationale here? Is the goal perhaps that if the client
switches back to a two-way sync, all changes since the last two-way sync
get sent, despite the intermediate one-way sync?

Those changes include the changes made on behalf of the server during
the one-way-from-server sync. Is that filtered out?

My test is probably broken. IMHO one-way sync only makes sense into a
storage which never changes on the receiving side. In the ActiveSync
case, that cannot be guaranteed, so I might as well just skip the test.

OTOH, a user might decide to use an ActiveSync server as remote backup,
in which case one-way syncing makes sense again. Would it be acceptable
to always take the updating sync token branch above?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] PBAP: one-way sync modes

2012-08-21 Thread Patrick Ohly
Hello!

For the PBAP caching mechanism in SyncEvolution I'd like to use the
Synthesis engine. I think that makes sense because the engine does a few
things which would have to be done manually otherwise (translate between
formats, finding pairs). The improvements below would also make sense in
other use cases.

At the moment the engine (or rather, SyncML) lacks a few things which I
need to change. I'm focusing on one-way-from-client syncing because the
server has a bit more control over what it does and because it matches
the SyncEvolution use case.

In SyncML, incremental one-way syncs fall back to a two-way slow sync
after a failure. If the server has an item which the client no longer
has, then the item will be recreated on the client, despite the
intention to only transfer data in one direction. Right?

This is undesirable in general (IMHO), and an absolute no-no for PBAP as
the client, because it cannot write the changes.

As a first step I would disable sending changes to the client if the
client asked for a one-way-from-client sync. The server's datastore can
already be marked read-only (readonly config option, SETREADONLY());
something similar for the peer's datastore would make sense. Then I
could leave the default behavior as it is and use a script function to
trigger the desired behavior.

Actually, there is SETREFRESHONLY(). According to the docs, it is meant
to be used for turning a two-way sync requested by the client into a
refresh-from-remote. I need to check whether I can use that or still
need to add/modify something.

Suppose a slow sync was done in that modified refresh-only mode. Any
item that the server has which are not on the client need to be removed
if the server's storage is meant to mirror the client.

At the moment, the engine cannot know whether it is meant to mirror the
data and thus it will leave the extra items on the server unchanged. I
intend to add a mirror config option similar to readonly. If
set, the engine will not only avoid sending changes to the client, it
will also remove those extra local items.

Finally, during a slow sync where a match was found, extra properties in
the server's copy of an item must be removed to avoid keeping stale
data. This can already be done by configuring the merging of items
accordingly (instead of preserving as much data as possible, ensure that
the client's item is always considered the winning one and that its
version completely overwrites the server's).


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] [SyncEvolution] Recurrences with Nth weekday of the month

2012-06-22 Thread Patrick Ohly
On Thu, 2012-06-21 at 10:51 +1000, Mathew McBride wrote:
 Hi,
 
 I'm testing SyncEvolution against my Funambol connector (GroupDAV) at 
 the moment. I've been testing some recurrence combinations and it seems 
 recurrences of type 'N' weekday of the month (i.e second tuesday of the 
 month) aren't supported?
[...]
 The original Evolution event has this:
 RRULE:BYDAY=TU;BYSETPOS=2;COUNT=2;FREQ=MONTHLY;WKST=SU
 
 The environment is Ubuntu 12.04 with the provided Evolution and 
 SyncEvolution versions (1.2.2).
 
 Are these type of recurrences supported with Evolution?

In Evolution, yes, in libsynthesis, no. I can reproduce the problem and
noticed that the code (src/sysync/rrules.cpp, RRULE2toInternal()) bails
out because it doesn't recognize the BYSETPOS keyword.

Lukas, was that a conscious decision, perhaps because it cannot be
supported in combination with vCalendar 1.0, or just an oversight? What
would it take to support that?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] Funambol and large SyncML messages?

2012-06-18 Thread Patrick Ohly
On Mon, 2012-06-18 at 09:30 +0200, Lukas Zeller wrote:
 occasionally, I get error reports from libsynthesis (iOS client) users
 which experience SyncML Error 511 (server error) with
 Funambol/OneMediaHub servers. Analyzing these, it always boils down to
 a big (99kBytes) client message that the server apparently cannot
 handle. As the server does not send a MaxMsgSize, libsynthesis makes
 the message as big as fits into it's local buffer which is 100k by
 default.
 
 My question - did you experience this large message size problem with
 Funambol as well? Or are you using a smaller message size than the
 default in SyncEvolution anyway?

The default message size is 15 bytes. I vaguely remember such issues
for myFunambol, but chalked it up to server isn't reliable instead of
investigating.

Testing against OneMedia has not been successful at all, as in most
tests don't run. First there was the issue with slow syncs causing the
server to report the 411 try again later error, then it started
throwing XML parser errors for a (as far as I can tell so far) correct
DevInf.

 I'm just wondering if reducing the message size could reliably fix
 that Error 511 problem - and if so how small the message size should
 be.

I don't know. I guess you could try asking Funambol (their mailing list
is now on SourceForge), but be prepared to be told to install a Funambol
client and emulate its behavior (that was the response that I got for
the DevInf issue).

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] [PATCH] Improve readability of SyncML TK error messages

2012-06-08 Thread Patrick Ohly
On Thu, 2012-06-07 at 12:31 +0200, Lukas Zeller wrote:
 Hi Andris,
 
 thanks for the patch. However, the SMLERRPRINTFX() macro, like all
 debug output macros across the entire library, is supposed to output a
 linefeed by itself. It also actually does so in my builds of
 libsynthesis, so if the LFs are missing in your output, it must be
 something along the path from SMLERRPRINTFX() to the actual output
 function.
 
 I think the problem is in the CONSOLEINFO_LIBC shortcut output mode
 Patrick added this February (13ff1e4149 (logging + Linux: enable
 console output)), where CONSOLEPRINTF() is mapped to
 fprintf(stderr,...) without adding a LF. In my (iOS) build this new
 mode is not used, but output ends in a plain puts(), which does add
 the LF.

Indeed. I wasn't aware of that convention when adding the code.

 diff --git a/src/sysync/sysync_debug.h b/src/sysync/sysync_debug.h
 index 61d4cdd..68dce5e 100755
 --- a/src/sysync/sysync_debug.h
 +++ b/src/sysync/sysync_debug.h
 @@ -110,7 +110,7 @@ TDebugLogger *getDbgLogger(void);
// Because a lot of libs log to stderr, include a unique prefix.
// Assumes that all printf format strings are plain strings.
#define CONSOLEPUTS(m) CONSOLE_PRINTF_VARARGS(%s, (m))
 -#define CONSOLE_PRINTF_VARARGS(_m, _args...) fprintf(stderr, SYSYNC  _m, 
 ##_args)
 +#define CONSOLE_PRINTF_VARARGS(_m, _args...) fprintf(stderr, SYSYNC  _m 
 \n, ##_args)
#define CONSOLEPRINTF(m) CONSOLE_PRINTF_VARARGS m
  # else // CONSOLEINFO_LIBC
#define CONSOLEPUTS(m) ConsolePuts(m)

I've added that to my repo and also refined the CONSOLEINFO_LIBC code a
bit: instead of always using stdio, it lets the app override the actual
function.

I'm adding that because I get quite a bit of error output from the
SyncML TK which seems to be harmless. Some of reporting inside
libsynthesis duplicates my own reporting. So I'd rather disable console
printing dynamically and only enable it when the log level in
SyncEvolution is sufficiently high.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] scripts + datastore

2012-05-02 Thread Patrick Ohly
On Fri, 2012-04-27 at 16:27 +0200, Lukas Zeller wrote:
 On Apr 25, 2012, at 15:11 , Patrick Ohly wrote:
  But in practice that pointer is always NULL. I wasn't sure anyway
  whether I would get the pointer to the local or remote datastore.
 
 from fDsP you'd get the pointer to the local datastore (TLocalEngineDS *).
 
 So to reach the remote datastore from a given TMultiFieldItem (which
 you certainly have at comparescript), I'd rather use
 
   yourMultiFieldItem-getRemoteItemType-getRelatedDatastore()
 
 to get to the datastore that has defined that item's remote type.

Thanks, that worked.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] scripts + datastore

2012-04-25 Thread Patrick Ohly
Hello!

I am trying to solve one issue in SyncEvolution: when trying to find
pairs, it needs to know on a per-datastore basis whether both remote and
local storage have truly unique UID/RECURRENCE-ID that can be relied
upon (iCalendar 2.0 semantic).

So far, I am using a compare script for that, but it has to make
assumptions about the peer. To overcome that I added code that allows
clients to add SyncCap entries to the CTCap (similar to the can restart
flag). This information is stored at the receiving end in the
TSyncDataStore base class by the TRemoteDataStore while parsing the
SyncCap (again, very similar to fCanRestart).

But now my problem is: how can the compare script access that
information?

It runs inside the datatype context. Does that mean that all
datastores sharing the same type also share the same context and that
the initscript for the type is only invoked once?

The script functions in multifielditemtype.cpp (like SYNCOP()) looked
promising. It's possible to get a pointer to some kind of datastore:

TSyncDataStore *related = static_castTMultiFieldItemType 
*(aFuncContextP-getCallerContext())-getRelatedDatastore();

But in practice that pointer is always NULL. I wasn't sure anyway
whether I would get the pointer to the local or remote datastore.

Any hints?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] Sync server with oracle database

2012-04-24 Thread Patrick Ohly
On Mon, 2012-04-23 at 22:23 +0200, Lukas Zeller wrote:
 To make a server out of libsynthesis, what needs to be done outside
 libsynthesis is the connection to the HTTP transport, and session
 handling (SyncML session objects must be kept around between HTTP
 requests until the entire session completes or is aborted).
 
 The opensource SyncEvolution project has done this, however
 SyncEvolution has quite some complexity of its own so I don't know how
 easy it would be to use the HTTP transport code from SyncEvolution.

It would be pretty hard. The HTTP server in SyncEvolution is written in
Python using the Twisted framework and depends on the D-Bus API provided
by the SyncEvolution core, so one also inherits all the rest of
SyncEvolution (own configuration system, backends, etc.).

For writing one's own server, the Synthesis SDK and server will be
easier.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] 409 item merged in client + multiple sync cycles in a single session

2012-03-09 Thread Patrick Ohly
On Tue, 2012-03-06 at 14:50 +0100, Patrick Ohly wrote:
 I haven't look into this yet, but still have it on my radar.

Done in the meego.gitorious.org master branch. I found that checking for
collisions is hard (not all records are in memory), so I settled for
making the chance of collisions smaller in the string case by including
a running count.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] 409 item merged in client + multiple sync cycles in a single session

2012-02-13 Thread Patrick Ohly
On Tue, 2012-02-07 at 16:05 +0100, Patrick Ohly wrote:
 On Mon, 2012-02-06 at 21:29 +0100, Patrick Ohly wrote:
  I'm currently experimenting with a different approach for handling the
  409 in the binfile client: when an Add fails with 409, catch it as it is
  done at the moment, but then tell the server that it was mapped to a
  dummy LUID. Mark that LUID as deleted in the change log. Then in the
  next session, delete the redundant item on the server.
  
  I'm combining that with running multiple SyncML sessions in the same
  context.
  
  Will post code soon...
 
 The result is in the internal-sync branch in the meego.gitorious.org
 repo of libsynthesis. It's called internal-sync because I am working
 on an extension of the SyncML protocol that is only understand when
 SyncEvolution talks to SyncEvolution (either in the SyncEvolution local
 sync mode - see the
 http://syncevolution.org/blogs/pohly/2012/fosdem-2012 talk for a diagram
 illustrating that) or in SyncEvolution client to SyncEvolution server
 mode.
 
 Instead of repeating myself, let me quote the commit messages of the
 relevant commits on that branch below. There are a few more commits in
 that branch. Lukas, what do you think?
 
 This is not done yet, but if possible I'd like to get feedback before
 going down an entirely wrong path. Some tests for this new code are in
 SyncEvolution (not pushed yet) and pass as expected. I'll keep working
 on this, in particular the temporary problem part and add more data
 in second cycle cases.

I've also pushed the internal-sync branch for SyncEvolution. It has
tests for the 409 in client of dumb SyncML server problem
(testAddBothSides when configured to use SyncEvolution server with file
backend), restarting a two-way sync with
SyncContext::requestAnotherSync() (testTwoWayRestart) and the extended
SyncSource semantic. All of that works fine.

It took a bit longer than expected because writing these tests required
quite a bit of code refactoring.

Speaking of the extended semantic that beginSync() may be called
multiple times: right now this is mandatory. My hope is that backend
implementers will adapt to that change before releasing 1.3, or that no
such changes are necessary. EDS and file backends worked fine without
changes. I prefer that approach because it avoids special cases.

Mikel, most relevant for you is the new
SyncSource/SyncContext::requestAnotherSync() API call. You might be able
to implement the two-phase transfer of contacts like this:
 1. In first beginSync() call:
  * only retrieve contacts without PHOTO data
  * ask for another cycle with requestAnotherSync()
 2. In the second beginSync():
  * also retrieve PHOTO data
  * mark all contacts with new or updated PHOTO data as
updated

I also implemented the backend is read-only part. The Synthesis engine
already had that, it was just a matter of making that available in
SyncEvolution.

You can rebase the PBAP branch onto internal-sync. I'll refrain from
rebasing internal-sync from now on.


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] 409 item merged in client

2012-02-06 Thread Patrick Ohly
On Mon, 2012-01-30 at 18:04 +0100, Patrick Ohly wrote:
 Should it have removed one item while processing the Map?
 
 IMHO it can't, because it doesn't have enough information to determine
 which of its two items are up-to-date. It only knows that the client
 must have merged two items, but not yet which one won.
 
 In the second session, the server gets an updated item with client ID
 foo. Now it could update one copy and delete the other, but because it
 only kept a link between its item 0 and foo, it only does the update
 part.
 
 Would something break if the server allowed the same client item to map
 to multiple items on the server and then did a remove in its database
 when receiving an update?
 
 I suspect that the client is simply doing something not expected by
 typical SyncML servers. 

I'm currently experimenting with a different approach for handling the
409 in the binfile client: when an Add fails with 409, catch it as it is
done at the moment, but then tell the server that it was mapped to a
dummy LUID. Mark that LUID as deleted in the change log. Then in the
next session, delete the redundant item on the server.

I'm combining that with running multiple SyncML sessions in the same
context.

Will post code soon...

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] super data store: trying to read to check for existance

2011-10-28 Thread Patrick Ohly
On Tue, 2011-10-25 at 09:24 +0200, Lukas Zeller wrote:
 On Oct 24, 2011, at 16:55 , Patrick Ohly wrote:
 
  Why is it necessary to read before trying to delete? If the item exists,
  then reading it is a fairly expensive test.
 
 Unfortunately, with some some backends, this is the only test that reliably 
 works. For example, some SQL databases (or their ODBC driver) can't return a 
 correct number of affected rows for DELETE statements. So reading before 
 deleting was the only way to detect if any of the subdatastores really had 
 that item and correctly return 404 or 200.
 
  So far, my backends were written with the expectation that they have to
  cope with delete requests for items which are already deleted. This
  follows from the inherent race condition between syncing and some other
  process which might delete items while a sync runs.
  
  Are all backends expected to return 404 when an item doesn't exist?
 
 Not all backends (see above, built-in ODBC can't), but yes, for plugin
 backends, returning proper error codes is specified, also for delete.
 Still, if a plugin would not conform to that in its implementation of
 delete, that would probably have gone unnoticed so far.

I checked the API docs and did not see it mentioned explicitly.

In SyncEvolution I added some remarks about 404 (will probably not be
noticed) and also added automated Client::Source tests for it (which is
harder to ignore if someone runs the tests ;-)

I also changed the error logging so that 404 is reported to users in
ReadItem and not logged in DeleteItem (while still returned to the
engine).

 Of course, the test is a bit expensive - if that's a concern, one
 could differentiate between plugin datastores and others (all the
 builtin ones, including SQL/ODBC), and use the expensive read test
 only for the latter. Like a virtual dsDeleteDetectsItemPresence()
 which returns false by default, but can be overridden in plugin
 datastores to return true.

The patch below implements that idea (from the for-master/bmc23744
branch). SyncEvolution relies on that patch to avoid the (harmless)
ERROR messages for item not found in ReadItem(), although everything
should work okay also without the patch.

Does that look right?

From fb5cc0dc19fb60e40a4ca2dcfe44a52a75ec7354 Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Fri, 28 Oct 2011 15:42:57 +0200
Subject: [PATCH] server engine: more efficient deletion in superdatastore

Attempting to read an item just to check whether it exists is expensive.
It also may trigger error messages when the item does not exist (done by
SyncEvolution).

Therefore, if a data store is able to properly report whether it found
the item which is to be deleted, a different logic is used for
deletion in the superdatastore:
- attempt to delete until it succeeds in a subdatastore
- recreate the sync item from the copy after a failed delete attempt
  (which deletes the sync item), if there is another loop iteration

Deleting the copy of the sync item was moved to the function exit code
to avoid code duplication.

By default all data stores are assumed to not support 404 in its
delete operation. The only exception is the plugin API. The (somewhat
undocumented) assumption is that all methods properly report 404 when
the requested item does not exist. The attempt to read code already
relied on that. Now the code relies on that for the attempt to
delete.

Probably it even works when the plugin returns some other error
code (the regular value will be false in that case) or no error code
at all: the translation code between remote ID and local ID will
already detect that the item is not in the mapping table if it is not
in the subdatastore. So the actual plugin will not get called at all
in the case where its expected behavior would matter.
---
 src/DB_interfaces/api_db/pluginapids.h |4 ++
 src/sysync/superdatastore.cpp  |   80 ++--
 src/sysync/syncdatastore.h |2 +
 3 files changed, 62 insertions(+), 24 deletions(-)

diff --git a/src/DB_interfaces/api_db/pluginapids.h 
b/src/DB_interfaces/api_db/pluginapids.h
index 4fbfc79..f215094 100755
--- a/src/DB_interfaces/api_db/pluginapids.h
+++ b/src/DB_interfaces/api_db/pluginapids.h
@@ -172,6 +172,10 @@ public:
   virtual void dsResetDataStore(void) { InternalResetDataStore(); 
inherited::dsResetDataStore(); };
   virtual ~TPluginApiDS();
 
+  // override TSyncDataStore: the plugin must be able to return 404
+  // when an item is not found during delete
+  virtual bool dsDeleteDetectsItemPresence() const { return true; }
+
   #ifndef BINFILE_ALWAYS_ACTIVE
   /// @name api methods defining the interface from TCustomImplDS to 
TXXXApi actual API implementations
   /// @{
diff --git a/src/sysync/superdatastore.cpp b/src/sysync/superdatastore.cpp
index e70d7bb..5c0a2b5 100755
--- a/src/sysync/superdatastore.cpp
+++ b/src/sysync/superdatastore.cpp
@@ -530,7 +530,7 @@ bool TSuperDataStore

Re: [os-libsynthesis] super data store: trying to read to check for existance

2011-10-25 Thread Patrick Ohly
On Tue, 2011-10-25 at 09:24 +0200, Lukas Zeller wrote:
 Hello Patrick,
 
 On Oct 24, 2011, at 16:55 , Patrick Ohly wrote:
 
  Why is it necessary to read before trying to delete? If the item exists,
  then reading it is a fairly expensive test.
 
 Unfortunately, with some some backends, this is the only test that
 reliably works. For example, some SQL databases (or their ODBC driver)
 can't return a correct number of affected rows for DELETE
 statements. So reading before deleting was the only way to detect if
 any of the subdatastores really had that item and correctly return 404
 or 200.
 
  So far, my backends were written with the expectation that they have to
  cope with delete requests for items which are already deleted. This
  follows from the inherent race condition between syncing and some other
  process which might delete items while a sync runs.
  
  Are all backends expected to return 404 when an item doesn't exist?
 
 Not all backends (see above, built-in ODBC can't), but yes, for plugin
 backends, returning proper error codes is specified, also for delete.

Are these expectations documented somewhere? I'm still a bit fuzzy about
which error codes are expected. For example, should a delete of a
non-existent item succeed (200) or fail (404)?

 Still, if a plugin would not conform to that in its implementation of
 delete, that would probably have gone unnoticed so far.

Right. SyncEvolution has hardly ever (never?) returned 404 and that has
not been an issue until now ;-)

 Of course, the test is a bit expensive - if that's a concern, one
 could differentiate between plugin datastores and others (all the
 builtin ones, including SQL/ODBC), and use the expensive read test
 only for the latter. Like a virtual dsDeleteDetectsItemPresence()
 which returns false by default, but can be overridden in plugin
 datastores to return true.

That sounds like the right compromise. I'm much more comfortable
returning 404 in a delete and not reporting that to the user as an
error, compared to not reporting a 404 in a ReadItem call (as I have to
do now).

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] Google Calendar + per-item permission errors

2011-08-03 Thread Patrick Ohly
On Di, 2011-08-02 at 15:39 +0200, Lukas Zeller wrote:
 Hello Patrick,
 
 On Aug 1, 2011, at 20:39 , Patrick Ohly wrote:
 
  In a local slow sync between Evolution and Google Calendar I see the
  following problem:
  [...]
   * The server logs Status: 403: originator exception and
 WARNING: Aborting Session with Reason Status 403 (REMOTE
 problem).
  
  That says it all. The session ends here without finishing the slow sync.
  
  This is a bit too drastic. 
  [...]
  Should it be turned into a local error along the were somewhere? I
  remember vaguely that we discussed something like that and came to the
  conclusion that a backend can return errors in the range 500 to the
  Synthesis engine. That's what SyncEvolution is doing here.
 
 There's a place in localengineds.cpp (around line 3337) where all the
 error codes are catched in a switch/case statement that should NOT
 abort the session, but rather mark the item for resend later, which
 means in the next session.
 
 403 is not among these, because usually a auth problem is really fatal and 
 retry does not help.
 
 For your case at hand, I'd recommend to translate that kind of 403
 error to 417 (retry later) in the backend (or in the
 sentitemstatusscript), which means that the backend has some hope that
 a retry in the next session might help.

I followed that approach. It means that the problematic item will be
sent again and again, but that's better than the alternatives (abort
session or only logging the issue). 

I still need to understand better how I arrived at this situation,
though.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] Google Calendar + per-item permission errors

2011-08-01 Thread Patrick Ohly
Hello!

In a local slow sync between Evolution and Google Calendar I see the
following problem:
  * Both sides have a meeting event in almost the same state.
  * The Synthesis engine decides that the event in Google Calendar
needs to be updated.
  * The PUT command fails with 403 You don't have access to change
that event.
  * This error code is returned as SyncML status for Replace from
SyncML client to server.
  * The server logs Status: 403: originator exception and
WARNING: Aborting Session with Reason Status 403 (REMOTE
problem).

That says it all. The session ends here without finishing the slow sync.

This is a bit too drastic. I'd prefer to continue the session and merely
report that this one item couldn't be updated. Never mind that this is
my own calendar and that Google should allow me to modify all of the
events in it...

I wonder whether the 403 HTTP error really should be passed through like
that. It gets returned by the Synthesis backend:

  * [2011-08-01 18:20:56.785] PUT: bad HTTP status: status 1.1,
code 403, class 4, You don't have access to change that event.,
must not retry
  * [2011-08-01 18:20:56.786] Running destroy hooks.
  * [2011-08-01 18:20:56.786] Request ends.
  * [2011-08-01 18:20:56.786] exception thrown
at 
/home/pohly/syncevolution/syncevolution/src/backends/webdav/NeonCXX.cpp:685
  * [2011-08-01 18:20:56.786] error code from SyncEvolution access
denied (remote, status 403): PUT: bad HTTP status: status 1.1,
code 403, class 4, You don't have access to change that event.
  * [2011-08-01
18:20:56.786] 
aID=(04008200E00074C5B7101A82E008B0884FC7A4E8CB01159F761E3FE944408F8932B4E44FFBFD.ics/20110428T15Z,)
 res=403
  * [2011-08-01 18:20:56.786] cannot update record in database
(sta=403)
  * [2011-08-01 18:20:56.786] Database Error -- SyncML status 403
  * [2011-08-01 18:20:56.786] - Operation replace failed with SyncML
status=403
–[2011-08-01 18:20:56.786] End of 'Process_Item' [-top] [-enclosing]
  * [2011-08-01 18:20:56.786] processSyncOpItem: Error while processing
item, status=403

Should it be turned into a local error along the were somewhere? I
remember vaguely that we discussed something like that and came to the
conclusion that a backend can return errors in the range 500 to the
Synthesis engine. That's what SyncEvolution is doing here.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] dealing with PHOTO:file:// (BMC #19661)

2011-07-22 Thread Patrick Ohly
On Fr, 2011-07-22 at 15:30 +0200, Lukas Zeller wrote:
 Hello Patrick,
 
 thanks for the READ() script function! This is sure a useful extension of the 
 script toolset.

I'm still tempted to embed Python as scripting engine into libsynthesis
(optional, of course). The main advantage would be that we get such
generic operations like file read/write and string manipulations for
free. But in the current situation adding a normal function certainly
was easier :-)

Next on my TODO list is a WRITE() function: it'll be the inverse
operation for inlining data and will become useful once files can be
attached to contacts in Evolution Data Server.

 However, I'd like to mention in this context that the engine for a
 long time contains a mechanism for the general problem with large
 fields.

I know, but it didn't seem usable here, as you said.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] uri + binary PHOTO values (was: Re: field merging + parameters)

2011-07-21 Thread Patrick Ohly
On Do, 2011-07-21 at 12:21 +0200, Patrick Ohly wrote:
 Now there is only one other problem with PHOTO uris. They get encoded as
 binary data:
 
 PHOTO;VALUE=uri:http://example.com/photo.jpg
 =
 PHOTO;ENCODING=B;VALUE=uri:aHR0cDovL2V4YW1wbGUuY29tL3Bob3RvLmpwZw==
 
 Is that because PHOTO is defined as blob?
 
 Would it make sense to be selective in the encoder for blob and only
 use binary encoding if the content contains non-printable characters?

This patch has the desired effect:

index 4105d03..616cb68 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -23,6 +23,7 @@
 
 #include syncagent.h
 
+#include ctype.h
 
 using namespace sysync;
 
@@ -2274,9 +2275,17 @@ sInt16 TMimeDirProfileHandler::generateValue(
   }
   // append to existing string
   fldP-appendToString(outval,maxSiz);
-  // force B64 encoding
-  aEncoding=enc_base64;
-  aNonASCII=false;
+  // force B64 encoding if non-printable or non-ASCII characters
+  // are in the value
+  size_t len = outval.size();
+  for (size_t i = 0; i  len; i++) {
+char c = outval[i];
+if (!isascii(c) || !isprint(c)) {
+  aEncoding=enc_base64;
+  aNonASCII=false;
+  break;
+}
+  }
 }
 else {
   // apply custom field(s)-to-string translation if needed

I tried it with both binary PHOTO and VALUE=uri.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] adding or overriding CtCap

2011-06-21 Thread Patrick Ohly
On Mo, 2011-06-20 at 20:20 +0100, Patrick Ohly wrote:
 Verified with debugging output. I've not looked into setfieldoptions()
 for the exact logic which enables the field.
 
 This has the effect that my X-FOOBAR-EXTENSION and X-TEST extensions
 (stored locally in XPROPS) are not getting preserved when importing the
 updated contact from Google.
 
 What would be a proper fix for this?

I've come to the conclusion that wildcard properties should not be
marked as available by default. With the following commit I get what I
need, is this the right approach?


commit 92d2f367e72eccedb2cd1e103ec7770b6a426ef2
Author: Patrick Ohly patrick.o...@intel.com
Date:   Tue Jun 21 09:35:49 2011 +0200

engine: updated implementation of unprocessed wildcard properties

The 3529d3cb commit which introduced support for unprocessed wildcard
properties added the logic that such properties are always considered
available regardless of the actual CtCap of the peer.

This has the undesirable effect that the content of these properties
are removed when receiving an update from a peer which doesn't
support them.

Therefore this commit reverts that part of 3529d3cb: setfieldoptions()
with NULL as first parameter now only enables mandatory properties,
as it did before the introduction of unprocessed properties.

unprocessed properties need to be listed explicitly in the CtCap
like any other property. This is currently untested.

diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp
index 27b1abb..4105d03 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -5139,7 +5139,7 @@ bool 
TMimeDirProfileHandler::analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP, TSyncItem
   for (sInt16 i=0; iitemTypeP-fFieldDefinitionsP-numFields(); i++) {
 itemTypeP-getFieldOptions(i)-available=false;
   }
-  // force mandatory+unprocessed properties to be always available
+  // force mandatory properties to be always available
   setfieldoptions(NULL,fProfileDefinitionP,itemTypeP);
 }
 // now we have received fields
@@ -5174,9 +5174,9 @@ bool TMimeDirProfileHandler::setLevelOptions(const char 
*aLevelName, bool aEnabl
 
 
 // enable fields related to aPropP property in profiles recursively
-// or (if aPropP is NULL), enable fields of all mandatory (or wildcard) 
properties
+// or (if aPropP is NULL), enable fields of all mandatory properties
 void TMimeDirProfileHandler::setfieldoptions(
-  const SmlDevInfCTDataPtr_t aPropP, // property to enable fields for, NULL if 
all mandatory+unprocessed properties 
+  const SmlDevInfCTDataPtr_t aPropP, // property to enable fields for, NULL if 
all mandatory properties should be en
   const TProfileDefinition *aProfileP,
   TMimeDirItemType *aItemTypeP
 )
@@ -5233,7 +5233,7 @@ void TMimeDirProfileHandler::setfieldoptions(
   while (propdefP) {
 // compare
 if (
-  (propname==NULL  (propdefP-mandatory || propdefP-unprocessed)) ||
+  (propname==NULL  propdefP-mandatory) ||
   (propname  (strucmp(propname,TCFG_CSTR(propdefP-propname))==0))
 ) {
   // match (or enabling mandatory) - enable all fields that are related 
to this property

-- 
Best Regards

Patrick Ohly
Senior Software Engineer

Intel GmbH
Open Source Technology Center   
Pützstr. 5  Phone: +49-228-2493652
53129 Bonn
Germany


___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] adding or overriding CtCap

2011-06-20 Thread Patrick Ohly
On Mi, 2011-06-15 at 14:02 +0200, Patrick Ohly wrote:
 Hello!
 
 One of the problems that we have in SyncEvolution is the loss of
 properties not supported by SyncML servers, like Google:
 https://bugs.meego.com/show_bug.cgi?id=15029
 
 For example, BDAY is not supported and gets lost in a round-trip sync
 because the client doesn't know that the server didn't store the field.
 That's because the Google server does not provide CtCap as part of its
 DevInf.
 
 The attached patches address this problem by allowing a RemoteRule to
 provide CtCap information.
 
 It's not currently in the branch used by SyncEvolution, but I need to
 add something like it soon. Comments welcome.
 
 I'm a bit undecided whether the RemoteRule should provide a DevInf or
 only CtCap. Right now, only CtCap is used and the rest is ignored, but
 perhaps that might change someday?

Any comments about this patch and/or the approach?

Thanks to Lukas' hint about the updateallfields option I continued
testing. It almost works as intended, except for the chat information.

They are defined as fields like this:
  field name=AIM_HANDLEarray=yes type=string 
compare=conflict/
  field name=AIM_SLOT  array=yes type=string 
compare=conflict/

And in the profile:
property name=X-AIM suppressempty=yes rule=KDE/
property name=X-AIM suppressempty=yes rule=other
  value field=AIM_HANDLE/
  parameter name=X-EVOLUTION-UI-SLOT positional=no show=no 
rule=HAVE-EVOLUTION-UI-SLOT
value field=AIM_SLOT/
  /parameter
/property
property name=X-messaging/aim-All suppressempty=yes rule=KDE
  value field=AIM_HANDLE/
/property

The logic in our profile is this: when talking to KDE in the Akonadi
backend, avoid using X-AIM and enable X-messaging/aim-All instead.
When talking to a SyncML peer or Evolution, use X-AIM.

Now when parsing a CtCap which does not mentioned
PropertyPropNameX-AIM/PropName/Property at all, the engine
concludes that:

- AIM_HANDLE   : AVAILABLEmaxoccur=1, maxsize=0 (unlimited)
- AIM_SLOT : n/a  maxoccur=0, maxsize=0 (unlimited)

The AIM_HANDLE = AVAILABLE is wrong here.

I also tried it with the simpler profile:
property name=X-AIM suppressempty=yes
  value field=AIM_HANDLE/
  parameter name=X-EVOLUTION-UI-SLOT positional=no show=no
value field=AIM_SLOT/
  /parameter
/property

Then it works. So apparently something in the rule parameter confuses
the CtCap parser.

Any idea?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] compare scripts

2011-06-20 Thread Patrick Ohly
On Fr, 2011-06-17 at 14:41 +0100, Lukas Zeller wrote:
 See the attached patch for a new script function COMPARISONMODE(), compiles 
 but is UNTESTED.

I can confirm that it works. Thanks a lot. I'm going to add it as a
commit to the master branch on meego.gitorious.org.

 With this, your comparescript could probably look like:
 
if (COMPARISONMODE!=age 
TARGET.UID == REFERENCE.UID 
TARGET.ORIGSTART == REFERENCE.ORIGSTART) {
  RES = 0;
} else {
RES = COMPARE(TARGET.DMODIFIED, REFERENCE.DMODIFIED);
}

Are you sure that the else clause for UID or RECURRENCE-ID not matching
should be another content comparison? If the comparison mode is not
age, then I want to rely exclusively on UID/RECURRENCE-ID for
equal/not equal, and thus I have the following logic:

INTEGER RES;
if (COMPARISONMODE() != age  SESSIONVAR(VCALENDAR_COMPARE_UID) ) {
if (TARGET.UID == REFERENCE.UID 
TARGET.ORIGSTART == REFERENCE.ORIGSTART) {
RES = 0;
} else {
RES = -999;
}
} else {
RES = COMPAREFIELDS();
}

The VCALENDAR_COMPARE_UID session variable will be false when I want the
default behavior. Does this look right?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] adding or overriding CtCap

2011-06-20 Thread Patrick Ohly
On Mo, 2011-06-20 at 15:03 +0100, Lukas Zeller wrote:
 Hello,
 
 I don't see why it should work in the simple profile but not work in the 
 complex one.
 
 However, maybe this is a red herring and the problem lies in the
 fReceivedFieldDefs (in TMimeDirItemType) flag. This is a per-type flag
 which is set once a property list from devInf was parsed with
 TMimeDirProfileHandler::analyzeCTCap().

That function is only called once during a sync session. The updated or
added CtCap is inserted into TSyncSession::analyzeRemoteDevInf() by the
checkRemoteSpecifics() call, which runs before the analyzeCTCap() call
later in analyzeRemoteDevInf().

  Its effect is that when parsing a CTCap again (which is still
 possible), the available status of the fields are NOT reset before
 parsing the CTCap, such that possibly more fields get enabled, but
 those that are already enabled from a previous CTCap scan remain
 enabled. This is needed e.g. for combining vCalendar subtypes
 VEVENT/VTODO.
 
 Could it be that the new OverrideDevInf somehow causes this flag to be
 reset in an early stage, such that parsing the without X-AIM will
 still result in AIM_HANDLE enabled, because it was set somehow
 previously?

So that doesn't seem to be it.

I'm now looking at the actual parser code... gdb to the rescue.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] adding or overriding CtCap

2011-06-20 Thread Patrick Ohly
On Mo, 2011-06-20 at 17:27 +0100, Patrick Ohly wrote:
 Problem solved...

Except for one field:

  !-- store extensions that don't match any of the other fields --
  field name=XPROPS array=yes type=string compare=never/

Profile:
property name=X-* suppressempty=yes show=false
  value field=XPROPS/
  position field=XPROPS repeat=array increment=1 minshow=0/
/property

This is getting set to AVAILABLE here:

  if (proplistP) {
if (!itemTypeP-fReceivedFieldDefs) {
  // there is a propList, and we haven't scanned one already for this type
  // (could be the case for DS 1.2 vCalendar where we get events  tasks 
separately)
  // so disable all non-mandatory fields first (available ones will be 
re-enabled)
  for (sInt16 i=0; iitemTypeP-fFieldDefinitionsP-numFields(); i++) {
itemTypeP-getFieldOptions(i)-available=false;
  }
  // force mandatory+unprocessed properties to be always available
=setfieldoptions(NULL,fProfileDefinitionP,itemTypeP);
}
// now we have received fields
itemTypeP-fReceivedFieldDefs=true;
  }

Verified with debugging output. I've not looked into setfieldoptions()
for the exact logic which enables the field.

This has the effect that my X-FOOBAR-EXTENSION and X-TEST extensions
(stored locally in XPROPS) are not getting preserved when importing the
updated contact from Google.

What would be a proper fix for this?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] temporary UID mapping

2010-12-19 Thread Patrick Ohly
On Fr, 2010-12-17 at 14:08 +, Lukas Zeller wrote:
 On Dec 17, 2010, at 8:47 , Patrick Ohly wrote:
  Now it turns out that there's a bad bug here, which probably explains
  all this (and maybe other) weird behaviour.
  
  I'm glad that you got to the bottom of this. Much better than pampering
  over the symptoms. So my question now is: should the code that I added
  to detect collisions remain in the code?
  
  The loop which detects non-unique temporary IDs is harmless. But the one
  which iterates over all mappings to find a previous mapping to the same
  local ID has a real performance impact.
  
  My preference would be this:
  - turn the messages in these loops into real errors
  - keep them for a while
  - remove after the real fix has proven to be effective
 
 I fully agree with this, just go ahead!

Okay, working on it.

I wondered why this bug did not surface in my interrupted sync tests.
SyncEvolution's client-test simulates a whole range of different
scenarios (items added/removed/modified) and a loss of network
connection at any point in the sync session. I'm 100% certain that this
passed when I declared SyncEvolution's server support ready for users.

Looking at my test setup, I see that the server side was configured to
use the file data stores. Those use very simple numbers as ID, and thus
the whole temporary ID mapping code wasn't exercised. Rerunning the
tests with the Evolution calendar store (which uses UID as local ID and
thus depends on the mapping code) shows that the mapping problems *do*
occur. My workarounds are triggered (visible in the logs), so the tests
themselves finish successfully.

With your patch applied, the are no longer triggered. IMHO this confirms
that you found the root cause.

An additional benefit is that the old meta data seems to be erased
reliably. I don't think there's any further need for the erase mapping
on refresh-sync feature that I was proposing.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] temporary UID mapping

2010-12-16 Thread Patrick Ohly
On Do, 2010-12-16 at 17:35 +, Lukas Zeller wrote:
 Hello Patrick,
 
 On Dec 9, 2010, at 17:47 , Patrick Ohly wrote:
 
  I might have found it.
  
  Scenario:
  - SERVER is the ID on the server, CLIENT on the client
  - server has a mapping from SERVER to #35 (ident 2) and to CLIENT (ident 1)
 
 Where is this from? I assume it is from a previous session (that has
 not completed, otherwise it should not be there).

Anecdotes indicate that it indeed happens when a previous session did
not complete correctly.

 Now it turns out that there's a bad bug here, which probably explains
 all this (and maybe other) weird behaviour.

I'm glad that you got to the bottom of this. Much better than pampering
over the symptoms. So my question now is: should the code that I added
to detect collisions remain in the code?

The loop which detects non-unique temporary IDs is harmless. But the one
which iterates over all mappings to find a previous mapping to the same
local ID has a real performance impact.

My preference would be this:
- turn the messages in these loops into real errors
- keep them for a while
- remove after the real fix has proven to be effective

-- 
Best Regards

Patrick Ohly
Senior Software Engineer

Intel GmbH
Open Source Technology Center   
Pützstr. 5  Phone: +49-228-2493652
53129 Bonn
Germany


___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] libsynthesissdk.a built without -fPIC

2010-12-14 Thread Patrick Ohly
On Do, 2010-12-09 at 06:47 +, Andris Pavenis wrote:
 The patch is not sufficient. One must also set CFLAGS, not only
 CXXFLAGS as libsynthesissdk contains also C cources.

Oh, I thought it was C++ only. Sorry!

  See attached
 patch for details (complete updated patch, not incremental).

Merged into the meego.gitorious.org repo.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] sending iCalendar 2.0 recurrence rule to Nokia phone: rule ignored (BMC #11241)

2010-12-14 Thread Patrick Ohly
On Di, 2010-12-14 at 11:43 +, Lukas Zeller wrote:
 Hello Patrick,
 
 On Dec 13, 2010, at 13:22 , Patrick Ohly wrote:
 
  From http://bugs.meego.com/show_bug.cgi?id=11241. Problem summary below,
  patch attached. I'm a bit unsure about hard-coding UTC as time context
  in that code, please suggest how this might be improved.
  
  [... - stored in iCalendar 2.0 format as:]
  RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20111231T10
  
  [... - rendered by libsynthesis as]
 
  RRULE:D1 20111231
  [...]
 
  The spec says that the end date must contain a time:
  
  enddate::= ISO 8601_date_time value(e.g., 19940712T101530Z)
 
 I agree. There are no date-only values in vCalendar 1.0 at all.
 
 However what I don't understand is why and where the the original
 timestamp as represented by UNTIL=20111231T10 becomes a date-only
 value as shown in the vCalendar 1.0?
 
 IMHO, this should be a date+time long before it gets into
 mimedirprofile. So I'd like to understand why this happens in this
 case.
 
 I see however a case that needs some treatment - which is when a
 date-only iCalendar 2.0 is the input (which then also can have a
 date-only UNTIL= part in the RRULE). Such a record would be rendered
 incorrectly in vCalendar 1.0 (as date-only).

That's exactly the situation here.

 The until date/time should IMHO be handled exactly like dates with the
 CONVMODE_AUTOENDDATE conversion mode, which renders date-only values
 as floating date+time in mimo_old (vCalendar xxx), but as date-only
 values in MIME-DIR (iCalendar 2.0).

You are not suggesting to use convmode=auto[end]date as it is, right?
If I read the documentation right, it will turn 20101231 into either
20101231T235959 (autoenddateinclusive) or 20101231T00. In both
cases it would cut off the last occurrence on day 20101231.

But I can see how converting to 20101231T235959 might work. My goal in
the patch was to recreate exactly the same RRULE as sent by the Nokia
phone, with the right time embedded in it. Not sure whether that is
really necessary, perhaps something larger would also work.

  What time it should insert as fallback might be a bit tricky, but I think 
  the start time of
  the event should do.
 
 My suggestion (I'll propose a patch soon) would be to make RR_END
 behave like CONVMODE_AUTOENDDATE to handle the case of an input
 timestamp which is a date-only.

Okay. Let me know when it is ready and I'll redo my tests.


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] sending iCalendar 2.0 recurrence rule to Nokia phone: rule ignored (BMC #11241)

2010-12-13 Thread Patrick Ohly
Hello!

From http://bugs.meego.com/show_bug.cgi?id=11241. Problem summary below,
patch attached. I'm a bit unsure about hard-coding UTC as time context
in that code, please suggest how this might be improved.

-

This was sent to us by the phone:

BEGIN:VCALENDAR
VERSION:1.0
TZ:+01
DAYLIGHT:TRUE;+02;20100328T01Z;20101031T01Z;;
DAYLIGHT:TRUE;+02;20110327T01Z;20111030T01Z;;
BEGIN:VEVENT
SUMMARY:Phone
DTSTART:20101212T09Z
DTEND:20101212T09Z
CLASS:PRIVATE
RRULE:D1 20111231T10
AALARM;TYPE=X-EPOCSOUND:20101212T084500Z;;;
LAST-MODIFIED:20101213T081626Z
PRIORITY:2
END:VEVENT
END:VCALENDAR

Translated into:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Synthesis AG//NONSGML SyncML Engine V3.4.0.8//EN
BEGIN:VTIMEZONE
TZID:Europe/Zurich
BEGIN:STANDARD
DTSTART:19671029T03
RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=-1SU
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870329T02
RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=-1SU
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
LAST-MODIFIED:20101213T081626Z
CLASS:PRIVATE
PRIORITY:2
SUMMARY:Phone
DESCRIPTION:Phone
DTSTART;TZID=Europe/Zurich:20101212T10
RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20111231T10
DTEND;TZID=Europe/Zurich:20101212T10
BEGIN:VALARM
TRIGGER;VALUE=DATE-TIME:20101212T084500Z
ACTION:DISPLAY
END:VALARM
END:VEVENT
END:VCALENDAR

After changing the summary, it is sent back to the phone as an update as:

BEGIN:VCALENDAR
VERSION:1.0
TZ:+01:00
DAYLIGHT;ENCODING=QUOTED-PRINTABLE:TRUE;+02;20110327T01Z;20111=
030T01Z;CET;CEST
BEGIN:VEVENT
LAST-MODIFIED:20101213T091201Z
CLASS:PRIVATE
PRIORITY:2
SUMMARY:Phone mod
DESCRIPTION:Phone
DTSTART:20101212T09Z
RRULE:D1 20111231
DTEND:20101212T09Z
AALARM:20101212T084500Z;;;Phone mod
DALARM:20101212T084500Z;;;Phone mod
END:VEVENT
END:VCALENDAR

One relevant difference might be the explicit time in the RRULE. The phone
includes it, the Synthesis engine doesn't. Yep, that seems to be it. Both
forever (RRULE:D1 #0) and fixed number of times work. The later one works
because the Synthesis engine internally converts it into a fixed end date/time.

The spec says that the end date must contain a time:

enddate::= ISO 8601_date_time value(e.g., 19940712T101530Z)

It does not say whether that end datetime is included in the recurrence, but
experiments show that this is the interpretation on the phone (vCalendar 1.0)
and in Evolution (iCalendar 2.0).

Given that vCalendar does not allow floating end dates, I think the encoder for
vCalendar RRULE should be fixed to not generate such broken rules. What time it
should insert as fallback might be a bit tricky, but I think the start time of
the event should do.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.

From 400b471a43d02dbcdf2c6affdde7ac1b1d7171a8 Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Mon, 13 Dec 2010 13:08:40 +0100
Subject: [PATCH] vCalendar 1.0: avoid RRULE end date without time

When parsing an iCalendar 2.0 event, it is possible to arrive at
an rrule until date/time which contains no time value. vCalendar 1.0
requires such a time. Not sending it, as the engine did before, causes
Nokia phones to ignore the recurrence rule (bugs.meego.com #11241).

This patch avoids this case by looking at the time of the event start
and adds that time to the recurrence until date. The comment in the
default config says:
  !-- recurrence rule block, fields must be in that order, including
   DTSTART as last field !! --

But it doesn't seem like DTSTART was really used before. Therefore this
patch tries to deal with not finding a timestamp after the recurrence rule
block by clearing the TCTX_DATEONLY, without actually setting a time. Probably
not quite correct, but perhaps better than not changing anything.

Another problematic aspect is to match the time zone context of the
until clause with the start date/time of the event. Currently the patch
assumes that the start time is going to be encoded as UTC.
---
 src/sysync/mimedirprofile.cpp |   30 ++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp
index 2cbce65..1314240 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -1700,6 +1700,12 @@ bool TMimeDirProfileHandler::fieldToMIMEString(
   // - until
   if (!(tsFldP = ITEMFIELD_DYNAMIC_CAST_PTR(TTimestampField,fty_timestamp,aItem.getArrayField(aFid,aArrIndex,true return false;
   aFid++; // do NOT INCREMENT in macro, as it would get incremented twice
+  // - start time (according to comment for recurrence rule block, this must

[os-libsynthesis] importing time zone definitions + TZID

2010-12-12 Thread Patrick Ohly
Hello Beat, Lukas!

While debugging an issue (http://bugs.meego.com/show_bug.cgi?id=9600) I
noticed that SyncEvolution was sending broken vCalendar 1.0 DAYLIGHT
properties.

I tracked it down to the assumption that tz_entry::name is composed of
standard and daylight saving zone names (CET/CEST), which I broken in
the libical timezone import code on Linux.

I'd like to suggest that this assumption gets relaxed such that the
original TZID can be stored together with these two names in a tz_entry.
See attached patches, which I also committed to master on
meego.gitorious.org.

Is that okay and suitable for merging back?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.

From d9f9af69176d776d09f99d85789973fd5d3b10f4 Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Sun, 12 Dec 2010 21:19:16 +0100
Subject: [PATCH 1/2] vtimezones: explicitly store std and dst TZNAME

In vCalendar 1.0, the DAYLIGHT property must list standard and daylight
saving zone names, for example CET;CEST.

ContextToTzDaylight() used to extract these two names from the
tz_entry::name field. This was rather implicit and not documented, so
the Linux timezone import code got it wrong and stored the original
TZID (like
/freeassociation.sourceforge.net/Tzfile/Australia/Melbourne), leading
to an invalid DAYLIGHT property with too many components. Such an
entry is accepted by Nokia phones in an ADD, but not an UPDATE
(bugs.meego.com #9600).

The code would also have failed for a (hypothetical) VTTIMEZONE
definition with TZNAMEs that contain slashes.

To make the code more robust and easier to understand, this patch
introduces explicit dstName and stdName fields in
tz_entry. VTIMEZONEtoTZEntry() sets them directly, thus allowing the
removal of two parameters in that function.

ContextToTzDaylight() still falls back to splitting the tz_entry::name
field if dstName or stdName are not set when needed, so these new
fields are strictly optional. In particular the code which creates
tz_entry from the builtin table can work as before.

The code which replaces the original TZID in tz_entry::name with a
combination of its TZNAMEs is still active, although it is no longer
needed. It probably was added in the first place to preserve the two
names so that they can be exported again.
---
 src/platform_adapters/linux/platform_timezones.cpp |3 -
 src/sysync/timezones.h |   14 +++-
 src/sysync/vtimezone.cpp   |   83 +++-
 src/sysync/vtimezone.h |2 -
 4 files changed, 76 insertions(+), 26 deletions(-)

diff --git a/src/platform_adapters/linux/platform_timezones.cpp b/src/platform_adapters/linux/platform_timezones.cpp
index d65f868..3fdc15b 100644
--- a/src/platform_adapters/linux/platform_timezones.cpp
+++ b/src/platform_adapters/linux/platform_timezones.cpp
@@ -191,12 +191,9 @@ void finalizeSystemZoneDefinitions(GZones* aGZones)
   continue;
 PLOGDEBUGPUTSX(aGZones-getDbgLogger, DBG_PARSE+DBG_EXOTIC, vtimezone);
 tz_entry t;
-string dstName, stdName;
 if (VTIMEZONEtoTZEntry(
 	vtimezone,
   t,
-  stdName,
-  dstName,
   #ifdef SYDEBUG
 aGZones-getDbgLogger
   #endif
diff --git a/src/sysync/timezones.h b/src/sysync/timezones.h
index d3f30d4..6d16e90 100755
--- a/src/sysync/timezones.h
+++ b/src/sysync/timezones.h
@@ -66,7 +66,19 @@ typedef struct tChangeStruct {
 
 class tz_entry {
 public:
-  std::string name;  /** name, same as TZID in VTIMEZONE, e.g. CET/CEST or /softwarestudio.org/Tzfile/Europe/Berlin */
+  std::string name;  /** name, same as TZID in
+VTIMEZONE, e.g. CET/CEST or
+/softwarestudio.org/Tzfile/Europe/Berlin;
+see also dst/stdName */
+  std::string stdName;   /** optional standard time name, e.g. CEST; must be
+set if name is not a concatenation of
+standard and daylight name (CET/CEST);
+the vCalendar 1.0 code relies on that */
+  std::string dstName;   /** used instead of splitting
+name if (and only if)
+stdName is set; may be empty
+in zones without daylight
+saving */
   std::string location;  /** location string as used in Olson TZID, e.g. Europe/Berlin */
   short   bias;  /** minutes difference to UTC (west negative, east positive */
   short

Re: [os-libsynthesis] temporary UID mapping

2010-12-09 Thread Patrick Ohly
On Do, 2010-12-09 at 11:26 +, Lukas Zeller wrote:
 Still, the thing is that there's never a deletion of a single tempGUID
 map entry (of course, there ARE deletions of map entries with other
 types, but not of mapentry_tempidmap).

Does that type map to sysync::cMapID::ident?

In my mapping on disk I currently see only entries with ident == 2 and a
a remote ID.

So you are saying that entries with ident == 2 are never meant to be
removed from the mapping? Won't that overflow the disk after (some
admittedly rather long) usage with many new items transferred?

 If you see the number of mapentry_tempidmaps decreasing during a sync
 session (counted from that anchorpoint at line 5852 in
 localengineds.cpp), there must be a problem with making these
 persistent and loading them later on (or some other not yet discovered
 bug - in the engine or the DB plugins). 

There definitely were missing entries. I'll keep watching :-/

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] temporary UID mapping

2010-12-09 Thread Patrick Ohly
On Do, 2010-12-09 at 13:18 +, Lukas Zeller wrote:
  So you are saying that entries with ident == 2 are never meant to be
  removed from the mapping?
 
 Not exactly that - what I'm saying is that these are (or should)
 always be removed all together. So either the list is still growing,
 or all of its items should go away at the same time, which cleans up
 the ID space.

I might have found it.

Scenario:
- SERVER is the ID on the server, CLIENT on the client
- server has a mapping from SERVER to #35 (ident 2) and to CLIENT (ident 1)
- item is deleted on server
- two-way sync

What I now see in the log is this:
fTempGUIDMap: restore mapping from #35 to SERVER
Item LocalID='SERVER', RemoteID='CLIENT', operation=delete
SyncOp=delete: LocalID=SERVER RemoteID=CLIENT
fTempGUIDMap: translated realLocalID='SERVER' to tempLocalID='#63'

The fTempGUIDMap is a map tempLocalID-ID. It now contains #65-SERVER and 
#35-SERVER.

But the map in the DB AP is a map from (ID, ident) - ([remote ID], flags).
It cannot hold both #65-SERVER and #35-SERVER. So what I see next is the 
saving of these two entries:

ModifyMap called: aEntryType=tempidmap, aLocalID='SERVER, aRemoteid='#35', 
aMapflags=0x0, aDelete=0
found entry by entrytype/localID='SERVER' - remoteid='#35', mapflags=0x0, 
changed=0, deleted=1, added=0, markforresume=0, savedmark=0
ModifyMap called: aEntryType=tempidmap, aLocalID='SERVER, aRemoteid='#63', 
aMapflags=0x0, aDelete=0
found entry by entrytype/localID='SERVER' - remoteid='#35', mapflags=0x0, 
changed=0, deleted=0, added=0, markforresume=0, savedmark=0
apiSaveAdminData: entryType=normal, localid='SERVER', remoteID='CLIENT', 
mapflags=0x8, changed=0, deleted=0, added=0, markforresume=1, savedmark=0
UpdateMapItem 'SERVER' + 1 = 'CLIENT' + 9, res=0
apiSaveAdminData: entryType=tempidmap, localid='SERVER', remoteID='#63', 
mapflags=0x0, changed=1, deleted=0, added=0, markforresume=0, savedmark=0
UpdateMapItem 'SERVER' + 2 = '#63' + 0, res=0

The last UpdateMapItem overwrites the entry for #35, because it uses the
same ID + ident.

The next sync then populates fTempGUIDMap with entry #63, but has no #35
and thus the size() + 1 assumption no longer holds.

I remember that I was confused about the map item DB calls. Originally I
implemented that as (ID) - (ident, [remote ID], flags). But after we
discussed it, I changed that to (ID, ident) - ([remote ID], flags),
which IMHO is what the API description says:

/*! Map table handling: Update a map item of this context
 *
 *  @param  aContext   The datastore context
 *  @param  mIDMapID ( with \localID,\remoteID, \flags and 
\ident ).
 *   If there is already a MapID element with \localID 
and \ident,
 *   it will be updated, else created.
 *
 *  @return  error code, if this MapID can't be updated (e.g. not yet existing).
 *
 *  USED ONLY WITH \plugin_datastoredadmin
 */
_ENTRY_ TSyError UpdateMapItem( CContext aContext, cMapID mID );

So, what is the solution to this problem? Do I still misunderstand
something or is there a genuine problem? ;-/

FWIW, there was one DeleteMapItem for item SERVER in the sessions above,
but it was for ident 1 (after deleting it).

-- 
Best Regards

Patrick Ohly
Senior Software Engineer

Intel GmbH
Open Source Technology Center   
Pützstr. 5  Phone: +49-228-2493652
53129 Bonn
Germany


___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] temporary UID mapping - maximum ID size

2010-12-08 Thread Patrick Ohly
On Mi, 2010-12-08 at 12:22 +0100, Patrick Ohly wrote:
 I'm currently (involuntarily ;-) stress-testing this code by running
 SyncEvolution-SyncEvolution syncs with lots of iCalendar 2.0 items,
 which happen to have very long IDs.

Related to this: is there some way to increase the maximum ID size
advertised by the Synthesis engine? Does that make sense - tradeoff
between sending long IDs in messages and having to deal with the
mapping?

It seems that currently the size is hard-coded, with different values
for binfile client and server.

Server:
libsynthesis/src/sysync/localengineds.cpp:  fMaxGUIDSize = 64;

Client:
libsynthesis/src/sysync/binfileimplds.cpp:fMaxGUIDSize=BINFILE_MAXGUIDSIZE;
libsynthesis/src/sysync/binfileimplds.h:#define BINFILE_MAXGUIDSIZE 63

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] temporary UID mapping

2010-12-08 Thread Patrick Ohly
Hello!

The Synthesis engine has the feature that its backends are allowed to
use IDs of arbitrary length. The engine will translate into IDs shorter
than the maximum ID size supported by the peer.

TLocalEngineDS::adjustLocalIDforSize() creates these temporary IDs,
using:
  fTempGUIDMap.size() + 1
  // as list only grows, we have unique tempuids for sure

I'm currently (involuntarily ;-) stress-testing this code by running
SyncEvolution-SyncEvolution syncs with lots of iCalendar 2.0 items,
which happen to have very long IDs.

I see failures where the server assigns the same temporary ID to
different items in the same sync.

I've added debug logging. It shows that the following happens:
 1. fTempGUIDMap is restored from the map file such that it has 105
entries, *but* these are non-contiguous (from #1 to #124).
 2. fTempGUIDMap.size() + 1 is #106, which already exists in
fTempGUIDMap.
 3. Overwriting that entry does not increase fTempGUIDMap.size().
 4. A second item is assigned the same #106 temp ID.

I don't know exactly how I arrived at this state. Is the on-disk dump of
fTempGUIDMap really meant to preserve all temporary IDs in perpetuity? I
don't think so, because that would fill up the disk and there is a
delete map item operation.

Unless there is some additional constraint, then the assumption that
the list only grows is wrong. I have added a workaround which checks
for ID collisions in TLocalEngineDS::adjustLocalIDforSize(). Is that the
right solution or do I need to search for the reason why the mapping has
gaps?

Also note that I end up with a temporary ID which must have been used
before in an older sync session. Could that be a problem?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] libsynthesissdk.a built without -fPIC

2010-12-06 Thread Patrick Ohly
On Mi, 2010-11-24 at 14:07 +, Andris Pavenis wrote:
 libsynthesissdk.a can be linked into external libsynthesis plugins, but
 is built without -fPIC. It works OK for 32 bit Linux but not 64 bit Linux.
 
 I'm getting error message:
 /usr/bin/ld: 
 /usr/lib64/libsynthesissdk.a(libsynthesissdk_la-SDK_support.o): 
 relocation R_X86_64_32 against `a local symbol' can not be used when 
 making a shared object; recompile with -fPIC
 /usr/lib64/libsynthesissdk.a: could not read symbols: Bad value
 collect2: ld returned 1 exit status

I'm aware of the need for -fPIC on 64 bit. What I don't quite understand
is that I'm not seeing that problem when compiling on it myself and that
we haven't heard of the problem elsewhere before. libsyncevolution.so
links fine against a libsynthesissdk.a.

What I see is that libtool invokes g++ with -fPIC -DPIC when compiling
libsynthesissdk.a source files. This is with libtool 2.2.6b on Debian
Testing, with --enable-shared --enable-static. Also works in other
combinations, expect with an explicit --disable-shared, but then also
libsynthesis.a is compiled without PIC mode.

In that case I wouldn't expect libsynthesissdk.a to work inside a shared
library, although I don't know whether that is formally defined anywhere
in libtool or what the common way of handling these configure flags is.
PIC mode causes a slight performance degradation, so it makes sense to
not use it in static libs which are meant to be used in executables.

 I added following patch when building own RPM package 
 (libsynthesis-3.4.0.16)
 
 --- libsynthesis_3.4.0.16/src/Makefile.am.in.orig   2010-11-24 
 15:52:52.0 +0200
 +++ libsynthesis_3.4.0.16/src/Makefile.am.in2010-11-24 
 15:53:24.0 +0200
 @@ -115,6 +115,7 @@ else
   libsynthesissdk_la_SOURCES += @LIBSYNTHESISSDK_SOURCES_BOTH@
   endif
   libsynthesissdk_la_CPPFLAGS = \
 +   -fPIC \
  -D_GNU_SOURCE=1 \
  -include $(top_builddir)/config.h \
  -I$(srcdir)/Targets/ReleasedProducts/SDK \

I'm a bit reluctant to hard-code -fPIC in the makefile - what if the
compiler doesn't support it? Unlikely, but not impossible.

Does the attached patch work for you? If it does, then I can include it
in the next Linux libsynthesis update (which usually happens via
SyncEvolution) and it trickle into upstream libsynthesis the next time
Lukas merges back changes.


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.

From 8c8c2b243de4e1a3f013881eef48369c437156eb Mon Sep 17 00:00:00 2001
From: Patrick Ohly patrick.o...@intel.com
Date: Mon, 6 Dec 2010 10:43:49 +0100
Subject: [PATCH] autotools: always enforce PIC mode for libsynthesissdk.a

Some versions of libtool use PIC mode automatically for static
libraries, others don't (?!). See the [os-libsynthesis]
libsynthesissdk.a built without -fPIC for a problem report.

This patch extracts PIC flags from libtool configure flags and
uses them for the two static libraries (libsynthesissdk.a and
libsynthesisstubs.a). This is a bit more portable than hard-coding
the -fPIC flag, albeit making an assumption about the naming
of libtool internal variables.
---
 configure.in   |7 +++
 src/Makefile.am.in |2 ++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/configure.in b/configure.in
index b0ee64a..e2a0c14 100644
--- a/configure.in
+++ b/configure.in
@@ -12,6 +12,13 @@ AC_PROG_LIBTOOL
 AC_PROG_MAKE_SET
 AM_PROG_CC_C_O
 
+dnl Extract PIC flags from libtool configure for libsynthesissdk.a
+dnl (makes assumptions about libtool var naming!). Some versions
+dnl of libtool use PIC mode automatically for static libraries,
+dnl others don't (?!). See [os-libsynthesis] libsynthesissdk.a built without -fPIC.
+PIC_CXXFLAGS=$lt_prog_compiler_pic_CXX
+AC_SUBST(PIC_CXXFLAGS)
+
 AC_ARG_ENABLE(debug-logs,
   AS_HELP_STRING([--debug-logs],
  [For developers: add links to call location to HTML log files. Depends on Doxygen (for HTML version of source) and g++ (for __PRETTY_FUNCTION__).]),
diff --git a/src/Makefile.am.in b/src/Makefile.am.in
index e412171..7be4a00 100644
--- a/src/Makefile.am.in
+++ b/src/Makefile.am.in
@@ -108,6 +108,7 @@ XMLPARSE_CFLAGS_BUILTIN = -I$(srcdir)/Targets/ReleasedProducts/clientEngine_auto
 endif
 
 libsynthesissdk_la_LDFLAGS = -static
+libsynthesissdk_la_CXXFLAGS = $(PIC_CXXFLAGS)
 libsynthesissdk_la_SOURCES = @LIBSYNTHESISSDK_HEADERS@
 if COND_STATIC
 libsynthesissdk_la_SOURCES += @LIBSYNTHESISSDK_SOURCES_SDK_ONLY@
@@ -128,6 +129,7 @@ libsynthesissdk_la_CPPFLAGS = \
 	-I$(srcdir)/syncml_tk/src/sml/mgr/inc/ 
 
 libsynthesisstubs_la_LDFLAGS = -static
+libsynthesisstubs_la_CXXFLAGS = $(libsynthesissdk_la_CXXFLAGS)
 libsynthesisstubs_la_SOURCES = sysync_SDK/Sources/enginestubs.c

Re: [os-libsynthesis] slow-sync matching

2010-11-16 Thread Patrick Ohly
On Mo, 2010-11-15 at 16:50 +, Patrick Ohly wrote:
 Now that I had that sorted out, I was running into another configuration
 issue: slowsyncstrategyduplicate/slowsyncstrategy is set in the
 syncserv_sample_config.xml and SyncEvolution copied that. Therefore the
 engine ended up trying to duplicate events despite a UID match. This is
 not possible in the backend, which will always overwrite the existing
 event. So what I need in this case is newer-wins with server-wins or
 client-wins as fallback instead of duplicate - such a setting does
 not exist, does it?

After some more thinking I came to the conclusion that the fallback is
not needed for my iCalendar 2.0 case: because UID/RECURRENCE-ID will
always find pairs (if they exist) and LAST-MODIFIED is always there,
there will always be a newer item, so the duplicate fallback will
never trigger.

 Finally, remember that I had intentionally created differences in the
 SUMMARY of my two events. My expectation was that this difference would
 be resolved during syncing.
[...]
 Note that I made another change for my iCalendar 2.0 case: all fields
 have compare=never, only UID/RECURRENCE-ID has compare=always. Could
 that have an effect on merging once pairs are found? After looking at
 the code it seems so. compareWith() returns that the items are identical
 enough, despite the change in SUMMARY.

Yes, that was it. I had the idea of introducing a new compare level
between never and conflict to mark fields which are relevant for the
user (and thus changes must be stored), without using them to find pairs
(which levels = conflict would do).

It turned out that Lukas already was ahead of me, as usual ;-) The new
level already exists, although in this case the purpose was a bit
different:

commit d96d05611cf7d35459927328e18b7f0f0a74571e
Author: Lukas Zeller l...@synthesis.ch
Date:   Tue Aug 24 17:41:53 2010 +0200

engine: added new compare mode for fields: scripted

These are NOT included in standard comparisons, so the
comparison can be done in a script, but they are
considered relevant otherwise, in particular these
are included when calculating CRC for change detection.

I'm happy to report that using compare=scripted solves the SUMMARY
not updated problem. Solved for me.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] slow-sync matching

2010-11-15 Thread Patrick Ohly
On Do, 2010-11-11 at 14:52 +, Patrick Ohly wrote:
 Hello!
 
 I have a question about matching items. Here's my situation:
   * Client and server both have the same iCalendar 2.0 VEVENT (UID
 is identical).
   * SUMMARY is changed on server, one line is added to description.
   * SUMMARY is changed on client.
   * Slow sync.
 
 I had changed the calendar field list so that all fields have
 compare=never, except for UID and ORIGSTART, which have
 compare=always. The rationale is that if it is known that both sides
 support UID, that alone should be used to find matches.
 
 What I expect in this case is that:
  1. Synthesis engine finds the match.
  2. The more recently modified SUMMARY from the client is preserved
 (DMODIFIED = LAST-MODIFIED is marked as age=yes).
  3. The additional line of the description is preserved (DESCRIPTION
 has merge=lines).
 
 What happens instead is that the engine finds the match, but then skips
 merging the items and updating them on server and client, leaving them
 unsynchronized. Is that the desired behavior? Do I have to configure the
 engine differently?

Yes. Lukas told me that there are configuration options, and then I also
found them in the documentation:

11.36.6 updateclientinslowsync: update client records
during slowsync
Contained in:  remoterule or server (settings in server are 
defaults for sessions with-
   out a remote rule applied or with a remote rule applied 
that does not specify a
   value for this particular option)
Can contain:   boolean value
Attributes:none
Default:   off
If this option is set in a remoterule, the SyncML server will try to update 
client records with
server data if comparison shows that the server has additional data that the 
client does not have
during non-first time slow sync. Note that this updating always takes place in 
first-time sync, regardless of this
options's setting. It is off by default because many clients cannot store some 
data but also cannot
inform the server what they can store exactly, so turning this option on will 
cause much un-
needed client updates at slow sync. For clients that store everything they 
report in devinf how-
ever, this feature can be switched on resulting in better data consistency 
after a slow sync. See
also corresponding function in 6.14.6.

11.36.7 updateserverinslowsync: update server records
during slowsync
Contained in:  remoterule or server (settings in server are 
defaults for sessions with-
   out a remote rule applied or with a remote rule applied 
that does not specify a
   value for this particular option)
Can contain:   boolean value
Attributes:none
Default:   off
If this option is set in a remoterule, the SyncML server will try to update 
server records with cli-
ent data if comparison shows that the client has additional data that the 
server does not have
during non-first time slow sync. Note that this updating always takes place in 
first-time sync, regardless of this
options's setting. It is off by default because differences in client and 
server database layouts often
cause uneeded updates which will cause other clients to be updated on the next 
sync as well. For
clients that store everything they report in devinf however, this feature can 
be switched on result-
ing in better data consistency after a slow sync. See also corresponding 
function in 6.14.6.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] slow-sync matching

2010-11-11 Thread Patrick Ohly
Hello!

I have a question about matching items. Here's my situation:
  * Client and server both have the same iCalendar 2.0 VEVENT (UID
is identical).
  * SUMMARY is changed on server, one line is added to description.
  * SUMMARY is changed on client.
  * Slow sync.

I had changed the calendar field list so that all fields have
compare=never, except for UID and ORIGSTART, which have
compare=always. The rationale is that if it is known that both sides
support UID, that alone should be used to find matches.

What I expect in this case is that:
 1. Synthesis engine finds the match.
 2. The more recently modified SUMMARY from the client is preserved
(DMODIFIED = LAST-MODIFIED is marked as age=yes).
 3. The additional line of the description is preserved (DESCRIPTION
has merge=lines).

What happens instead is that the engine finds the match, but then skips
merging the items and updating them on server and client, leaving them
unsynchronized. Is that the desired behavior? Do I have to configure the
engine differently?

From the log file:
# [2010-11-11 15:40:44.964] Testing filter '' against item:
# [2010-11-11 15:40:44.964] Filter test result is TRUE
# [2010-11-11 15:40:44.964] comparing (this) local item 
localID='2010t135424z-8821-33500-1...@pohly-mobl1-rid' with incoming 
(other) item remoteID='2010t135424z-8821-33500-1...@pohly-mobl1.ics'
# [2010-11-11 15:40:44.964] Compared 
[loc=2010t135424z-8821-33500-1...@pohly-mobl1-rid,REM=] with 
[LOC=,rem=2010t135424z-8821-33500-1...@pohly-mobl1.ics] (eqMode=1), cmpres=0
# [2010-11-11 15:40:44.964] TStdLogicDS::getMatchingItem, found 
remoteID='2010t135424z-8821-33500-1...@pohly-mobl1.ics' is equal in content 
with localID='2010t135424z-8821-33500-1...@pohly-mobl1-rid'
# [2010-11-11 15:40:44.964] Slow Sync Match detected - 
localID='2010t135424z-8821-33500-1...@pohly-mobl1-rid' matches incoming item
# [2010-11-11 15:40:44.964] Compared 
[loc=2010t135424z-8821-33500-1...@pohly-mobl1-rid,REM=] with 
[LOC=,rem=2010t135424z-8821-33500-1...@pohly-mobl1.ics] (eqMode=2), cmpres=0
# [2010-11-11 15:40:44.964] calendar: testState=TRUE - expected 
state='sync_mode_stable', found state=='sync_set_ready'
# [2010-11-11 15:40:44.964] ModifyMap called: aEntryType=normal, 
aLocalID='2010t135424z-8821-33500-1...@pohly-mobl1-rid, 
aRemoteid='2010t135424z-8821-33500-1...@pohly-mobl1.ics', aMapflags=0x0, 
aDelete=0
# [2010-11-11 15:40:44.964] - found entry by 
entrytype/localID='2010t135424z-8821-33500-1...@pohly-mobl1-rid' - 
remoteid='2010t135424z-8821-33500-1...@pohly-mobl1.ics', mapflags=0x0, 
changed=0, deleted=1, added=0, markforresume=0, savedmark=0
# [2010-11-11 15:40:44.964] - matching entry found - re-activating deleted 
and/or updating contents if needed
# [2010-11-11 15:40:44.964] Map entry updated: 
LocalID='2010t135424z-8821-33500-1...@pohly-mobl1-rid', 
RemoteID='2010t135424z-8821-33500-1...@pohly-mobl1.ics'
# [2010-11-11 15:40:44.964] Preventing 
localID='2010t135424z-8821-33500-1...@pohly-mobl1-rid' to be sent to client
# [2010-11-11 15:40:44.964] Item with 
localID='2010t135424z-8821-33500-1...@pohly-mobl1-rid' will NOT be sent to 
client (usually due to slowsync match)
# [2010-11-11 15:40:44.964] Deleted command 'Status' (outgoing MsgID=0, CmdID=0)


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] libsynthesis update - 3.0.4.16 (was: Re: optional property parameters, sub/remoterules)

2010-09-29 Thread Patrick Ohly
On Do, 2010-09-23 at 02:30 -0700, Lukas Zeller wrote:
 I owe you an answer regarding commits 0e139ee311 and 4275e77001:

[...]

 But altough going back is possible here, the binfile store generally
 does not provide going back (that is, without loosing all settings),
 only forward. As soon as something changes in the data format, the DB
 version field in the binfile is incremented, and it will no longer be
 compatible with the previous version.

In general that approach is fine, I wasn't expecting anything else. It's
just that I'd like to warn users and whenever possible, give them the
choice of going back. That increases the number of people who can try
out an experimental snapshot, because they can try something and then
fall back to the stable version more easily.

Given that these two changes are fairly intrusive, I think I'll pass for
SyncEvolution 1.1. Instead I'll release with some specific fixes
backported, and then combine the libsynthesis update with some other
non-backward compatible changes in SyncEvolution itself.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] sending photo to Nokia phone (N97 mini): wrong CTCap

2010-08-30 Thread Patrick Ohly
On Thu, 2010-08-26 at 23:00 +0100, Lukas Zeller wrote:
 it's a known bug in many Nokia phones that they have a maxSize of 255
 on all fields, including the PHOTO. 
 
 And yes, there is a remoterule option called ignoredevinfmaxsize for
 that. It applies to all fields, however I agree that those constant
 255 maxsizes are probably meaningless anyway.

Ah, excellent. I was sure there would be something, and I wasn't
disappointed ;-)

Speaking of CtCap, do you happen to know what Nokia's involvement was in
the definition of that part of the spec? Or speaking more generally,
what was the desired usage of CtCap?

I've just been in another discussion around that, where the Synthesis
use of CtCap to determine unsupported properties was questioned.

One interpretation of CtCap is limitations for some properties. In
that interpretation, unlisted properties might still be supported.

The other interpretation is that CtCap has to be complete and accurate,
and thus anything not covered by it (value too long, unknown property)
is not stored by the device. This is the interpretation used by
Synthesis. FWIW, it sounds more plausible to me.

But is there anything in the standard which supports one or the other
interpretation? Or perhaps it was part of meeting minutes?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] DB API + simple type

2010-05-14 Thread Patrick Ohly
Hello!

I'm working on a modification of the engine which bypasses the
obligatory data conversion via field lists and profiles. The use case
for this are client and server which perfectly agree on some proprietary
item data and thus need no conversion, or plugins which want to handle
the data conversion themselves.

So far I have hooked up the existing TSimpleItem with the config parsing
(added type and config for it). Now I try to figure out how to read and
write the item data and possibly meta data via the plugin API.

My initial thought was to expose certain pre-defined field names and use
the *AsKey variants of the API, but that seems to depend on inheriting
from TMultiFieldItem (pluginapids.cpp needs to down-cast to that if
fPluginDSConfigP-fItemAsKey is true).

Now I'm looking at the traditional API instead (the #ifdef
DBAPI_TEXTITEMS part).

In that context I have a question about the API as defined in
sync_dbapi.h:


 *  NOTE:   By default, the SyncML engine asks for \aID only.
 *  \aItemData can be returned, if anyway available or
 *  \aItemData must be returned, if the engine asks for it
 *  (when calling ReadNextItem:allfields at 'ContextSupport' 
with \allfields).
 */
_ENTRY_ TSyError ReadNextItem ( CContext aContext, ItemID aID, 
appCharP *aItemData,
 sInt32 *aStatus,bool aFirst );

The sentence in the NOTE is a bit long and I don't understand the if
the engine asks for it part. How does it call ReadNextItem:allfields?

After reading the documentation of ContextSupport() it becomes a bit
clearer, but not much. Where is the complete list of support rules
that the plugin might have to handle?

If I understand this right, the plugin can choose to support the initial
n rules, but not some specific ones. I assume the ordering of rules is
chosen so that there's never a need to not support, say rule #1 but
support rules #2 and #3?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] DB API + simple type

2010-05-14 Thread Patrick Ohly
On Fri, 2010-05-14 at 10:46 +0100, Beat Forster wrote:
 Hello Patrick
 
 
  I'm working on a modification of the engine which bypasses the
  obligatory data conversion via field lists and profiles. The use
  case
  for this are client and server which perfectly agree on some
  proprietary
  item data and thus need no conversion, or plugins which want to
  handle
  the data conversion themselves.
 You're talking about LoadAdminData/SaveAdminData ?

No, I'm thinking about the actual item content.

  After reading the documentation of ContextSupport() it becomes a bit
  clearer, but not much. Where is the complete list of support rules
  that the plugin might have to handle?
 There is currently only this rule supported by the engine. Originally
 we thought there would be much more of them, but this wasn't the case
 until today.

Ah, okay.

So what exactly is the meaning of ReadNextItem:allfields? What effect
does it have when the plugin refuses to acknowledge that rule?


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] DB API + simple type

2010-05-14 Thread Patrick Ohly
On Fri, 2010-05-14 at 17:28 +0100, Lukas Zeller wrote:
 Hello Patrick,
 
 I think by far the simplest method would be NOT to try to bypass
 MultifieldItem, but derive it with an implementation that puts/gets
 data (and maybe metadata) into/from well-known string or BLOB fields.
 
 The entire DB API thing was developed long after we more or less
 settled for TMultiFieldItem as a common denomiantor for all data
 types.

Yeah, I noticed. I have a sync starting based on the TSimpleItem and the
string-based API, but now I run into more places where a TMultiFieldItem
is expected, like for example in customimplds.cpp:

3118  // - create dummy item
3119  TStatusCommand dummy(getSession());
3120  TMultiFieldItem *delitemP =
3121static_castTMultiFieldItem *(newItemForRemote(ity_multifield));
3122  delitemP-setSyncOp(sop_delete);
3123  PDEBUGPRINTFX(DBG_DATA,(
3124Zapping datastore: deleting %ld items from database,
3125(long)fSyncSetList.size()


  The TField mechanism has proven so useful in various contexts, like
 the API itself, but also for scripting etc. that while deriving from
 beyond TMultiFieldItem would still be possible, I see no benefit (and
 a lot of drawbacks) actually doing so.

Initializing a TMultiFieldItem(Type) seemed more complex than necessary,
but I agree, it probably is easier to set it up right and just use it.

 If it's of any help for you, I could offer to add such a thing real soon 
 (this weekend?).

That would be a big help. I'm fairly confident that I would get it done
myself (in particular after having spent some time with the code), but
there might be snags that'll delay me that you know how to avoid.

My goal was to have something rudimentary next Monday, so if it is not
too much bother for you, then I'll punt the problem to you.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] logging the source code location of debug messages

2010-05-12 Thread Patrick Ohly
On Wed, 2010-05-12 at 17:43 +0100, Lukas Zeller wrote:
 that's a very cool addition indeed :-) Thanks!

Glad you like it :-)

 I'm about to integrate it here, and I have added config options for
 it, such that I can choose to create txmt:// links (which directly
 open TextMate or BBEdit code editors on my Mac with the cursor on the
 right line) instead of doxygen. A second config option allows to
 override the default base path (the one you define with
 SYDEBUG_LOCATION).

Something similar might also be useful on Linux. These Doxygen runs are
fairly slow. Something for later...

 I'll post the changes soon together with the other pending changes on my 
 branch.

Note that I updated master and doxygen once more today. Please pull
again before merging.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] wrong interpretation of timezone information

2010-05-11 Thread Patrick Ohly
On Mon, 2010-05-10 at 16:48 +0100, Lukas Zeller wrote:
 Hi Patrick,
 
 On May 10, 2010, at 9:04 , Patrick Ohly wrote:
 
  Confirmed, works for me.
 
 Thanks!
 
  I should have mentioned that I had already made similar changes as you
  on the moblin.org master branch (check for NULL obj in debug macros,
  enable debug logging inside vtimezone code when invoked by mimedir
  profile parser).
  
  My own debug logging patches go a bit further:
  - log an error when parsing a VTIMEZONE fails
  - logging of libical timezone conversion
  - logging of timezone matching
  
  I'm trying to track down an unexpected timezone failure with this which
  occurs when normal Evolution events are involved.
  
  Do you agree with these changes? Would you mind merging them? I rebased
  them on your luz branch.
 
 The attempt to init the time zones after reading config (fc000b0f45
 (TSyncAppBase: moved system time zone parsing after config reading))
 creates a chicken and egg problem. The config reading process relies
 itself on the time zone stuff being initialized, most prominently for
 definetimezone, but also for other tags that have ISO8601 timestamp
 values.

I see.

 Maybe the dilemma can be solved by adding an optional, second
 initialize run after config reading that can be switched on
 specifically to track down timezone init problems.

That would imply redoing some of the work. What about the following
(code in master, as I need to fix that anyway):


commit 7bbec4fd20cde059973d4d1c840fcee85d947e60
Author: Patrick Ohly patrick.o...@intel.com
Date:   Tue May 11 16:57:35 2010 +0200

time zone init and logging: split into part before and after config parsing

This patch reverts the move system time zone parsing after config
reading part of commit fc000b0f45. As Lukas pointed out, config parsing
already depends on time zones, for example for definetimezone.

But this patch keeps the finishConfig() callback and uses it to invoke
a second global time zone function. On Linux, that function is used
to add the libical time zone definitions and logs them at the same time.
Builtin time zones are added at the original time, before parsing the
config.

This is a compromise between having no time zones while parsing the config
and not logging the libical time zones. It works for SyncEvolution, because
it doesn't reference the additional time zones in the config.

  Another option would be to use the ConferrPuts() channel, which is
 ready before config is read by definition.

That won't help, because I need this information in the normal log file
to simplify remote debugging.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] UID in iCalendar 2.0

2010-04-19 Thread Patrick Ohly
Hello!

I tracked down a problem caused by Evolution not being able to store two
iCalendar 2.0 items with the same UID. The root cause is that the server
doesn't know this, leading to
http://bugzilla.moblin.org/show_bug.cgi?id=9682

- clear all items on a server which uses the file backend
- slow sync with one item on client A
- modify item on client A so that a key element differs (like SUMMARY in task)
- slow sync again

Expected result:
- client and server in sync, either with one item or two

Actual result:
- server has two items, client one (the unmodified one from the initial sync)

The root cause is that the server treats these two items as different when
using the file backend, because neither that backend nor the engine know about
the significance of the UID property, which happens to be identical here.

In the second slow sync, it sends an Add command with the item that it had
from the initial sync. The client then turns the Add into a Replace of the
item that it just sent to the server, overwriting the local, more recent data
with the older copy from the server.

The client uses the EDS backend, which detects that the new item from the
server has the same UID as a local item, and therefore it *replaces* that item
instead of adding it anew.

IMHO the correct solution would be for the server to detect that two
conflicting items have the same UID. The UID of the item on the server then
must be replaced with something which satisfies the iCalendar 2.0 globally
unique criteria before it is sent to the client in an Add. Or the property
must be cleared, which will cause the client to create a value.

I have no idea how to implement either one or the other, though. Suggestions?

Solutions which don't work:
- Compare only the UID property. A) we don't know whether the client really
  provides a stable, globally unique UID and b) we would end up with only
  one item even when both items were modified and thus should both be preserved.
- Don't store UID on the server. We want it there for backup/restore of
  iCalendar 2.0 clients.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] X-Synthesis-Ref and X-CustomLabel- TYPE extensions

2010-04-15 Thread Patrick Ohly
On Wed, 2010-04-07 at 13:45 +0100, Patrick Ohly wrote:
 Hello!
 
 This is related to http://bugzilla.moblin.org/show_bug.cgi?id=10462
[...]
 I suppose for SyncEvolution 1.0 we should simply remove the extension
 from the XML config used by us. There's a slight loss of functionality
 when SyncEvolution is used as server for a Synthesis (iPhone) client,
 but that is not its primary role anyway.

I've implemented this. I'm still interested in hearing about how these
extensions should be handled by a server.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] X-Synthesis-Ref and X-CustomLabel- TYPE extensions

2010-04-07 Thread Patrick Ohly
Hello!

This is related to http://bugzilla.moblin.org/show_bug.cgi?id=10462

Steps to reproduce:
- sync Synthesis iPhone client, SyncEvolution server, Evolution
- modify contact on iPhone
- send to server and Evolution
- TYPE=X-Synthesis-Ref0 is added to ADR, EMAIL, TEL

Outcome:
- Evolution shows email as other (might be right, there was no
TYPE=HOME/WORK)
- ADR is not shown (NOT right!)

Our XML configuration contains the TYPE=X-Synthesis-x extensions. We 
inherited
those from the Synthesis example config. Having them is useful when 
operating
as server with the file backend, because the iPhone client can store 
and later
retrieve its extensions.

But when storing an item in Evolution, we should not add these 
extensions.

Implementing that is tricky, because we don't want to maintain two 
different
sets of vcard profiles. Not sure how to do this yet.


I have a few questions about this. First, X-Synthesis-Refx maps to the
field ADR_STREET_ID with value x. What is the semantic of this? Same for
ADR_STREET_LABEL, which would show up as X-CustomLabel-label. I'm
asking to figure out whether this might be worth mapping to something in
Evolution or elsewhere.

Second, how does the Synthesis server handle synchronization between
clients which support this extensions and those that don't? The DevInf
does not contain entries for these extensions, so the server cannot tell
whether a client supports them or not.

Third, are there perhaps other clients which get confused by these
extensions? At least ScheduleWorld might preserve them (not entirely
sure).

Regarding solving this problem, the obvious choice would be to make
X-Synthesis-Ref depend on a specific rule: when encoding for Evolution,
don't enable the extension. But this is not possible at the moment.

I suppose for SyncEvolution 1.0 we should simply remove the extension
from the XML config used by us. There's a slight loss of functionality
when SyncEvolution is used as server for a Synthesis (iPhone) client,
but that is not its primary role anyway.

Then later on we should either enhance the rule mechanism or go for
some dynamic pre-processing of profiles. That way we can turn the
general purpose vCard mimeprofile into a vCard-Evolution mimeprofile
which matches exactly what Evolution supports.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] suspend failure

2010-03-18 Thread Patrick Ohly
On Tue, 2010-03-16 at 14:40 +, Lukas Zeller wrote:
 Most probably, there should be an extra check for that too late
 suspend.

Your patch in the luz branch works, thanks a lot.

Now I just have the inverse problem: the tests pass even if the suspend
requests were ignored entirely. Manually checking the next log shows
that we did resume and we get the progress event which tells us that the
session was resumed.

But it would be nice if this could be checked already before running
that next sync. Is there a possibility to retrieve the datastore is
suspended information from a binfile-based client? Is it possible in a
server?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] suspend failure

2010-03-18 Thread Patrick Ohly
On Thu, 2010-03-18 at 14:05 +, Lukas Zeller wrote:
 Hello Patrick,
 
 On Mar 18, 2010, at 14:00 , Patrick Ohly wrote:
 
  On Tue, 2010-03-16 at 14:40 +, Lukas Zeller wrote:
  Most probably, there should be an extra check for that too late
  suspend.
  
  Your patch in the luz branch works, thanks a lot.
 
 Thanks for the feedback. After pushing I suddenly had the impression
 it could still be wrong for another case, I have to follow that
 thought first to make sure. So that's why I did not announce the patch
 out loud...

It has passed all of my tests, so I'll go ahead and use this in the next
SyncEvolution snapshot. If you have more thoughts on what I should test,
please let me know.

  But it would be nice if this could be checked already before running
  that next sync. Is there a possibility to retrieve the datastore is
  suspended information from a binfile-based client? Is it possible in a
  server?
 
 In both cases, it's the resumeAlertCode target field. If it is not
 zero, the datastore is resumable - i.e. a client will try to resume
 and a server will accept a resume.
 In binfile based setups, you can use
 the /profiles/xx/targets/dbid/resumeAlertCode settings key to access
 that value.

In both cases - there are no targets in a server, so how would that
work there? I suppose it is part of the admin data, but that is internal
and and peeking inside it would bypass the official API.


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] suspend failure

2010-03-18 Thread Patrick Ohly
On Thu, 2010-03-18 at 15:36 +, Lukas Zeller wrote:
[server admin data]
 Yes, it would bypass the API, but unlike with binfiles, in the server
 case YOU are the provider of the storage for that admin data, and how
 the fields are stored is under YOUR control, and not a secret of the
 SyncML engine. So I'd guess it is ok to have a look at them (or even
 modify them - such as setting resumeAlertCode to zero to prevent a
 resume, or blank out the anchor to force a slow sync).

So the format is part of the API? I guess it has to be even though it is
not documented (or is it?), because changes to it would break server
software upgrades.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] suspend/resume + datastore + tokens

2010-03-16 Thread Patrick Ohly
On Fr, 2010-02-26 at 15:12 +, Patrick Ohly wrote:
 Hello!
 
 When we started with SyncEvolution, we discussed the StartDataRead()
 resumeToken parameter. At that time, we came to the conclusion that a
 binfile based client doesn't have to distinguish between different
 tokens. Always reporting the changes since the last sync is good enough,
 the binfile layer takes care of merging the recent changes with those
 that haven't been sent.
 
 Now, on the server side I think tokens are relevant, right?
 SyncEvolution as server doesn't support multiple tokens yet, and I was
 hoping that one of the existing tests would fail because of that, but no
 luck so far. I found two problems (see other emails), but none that I
 could attribute to SyncEvolution ;-}
 
 In which situation on the server side is the distinction between
 lastToken and resumeToken relevant?

I discussed this with Lukas. Here's my write up of the answer:
http://bugzilla.moblin.org/show_bug.cgi?id=2425#c5


(In reply to comment #4)
  True. However, I learned in the meantime that the binfile support is not
  enabled for SyncML servers. Once we turn SyncEvolution also into a server, 
  we
  need to revisit this issue.
 
 ... so now we need to solve this issue. Without it, our suspend/resume tests
 against our own server should fail.

Only in some very constructed situation, and one which is not currently covered
by any of our tests. Here's where the two anchors make a difference:
1. client and server in sync
2. item added on server
3. client and server sync
4. suspend after sending that new item to client
5. a second item added on server
5.1 resume = send changes since step 4
5.2 two-way sync instead of resume,
using anchors from step 1 = send changes since
step 1

Our server fails in 5.2, because it will always only send changes since the
last sync (step 4 in this example).

The relevance of this is debatable. It depends on clients actually being able
to roll back to a previous state. Our own client can't do that, so it would
have to do a slow sync in 5.2 instead of resuming.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] LibSynthesis internal data structure and conversion...

2010-03-15 Thread Patrick Ohly
On Di, 2010-03-09 at 22:28 +, paul wrote:

 LibSynthesis uses an internal data structure formatted as multiline
 aa:bbCRLF...

The internal representation is the field list. This aa:bbCRLF format
is an external format for it, as far as I remember. I'm not entirely
sure where exactly it is used. I never had to use it in SyncEvolution.

   Is there any API available in LibSynthesis to convert that to vCard
 format?  I see a function recently added DataConversion, but I'm not
 sure if that is just used for testing or if it will work.

It won't work. The DataConversion() function will convert from one
format into another. The format is defined by a datatype in the XML
configuration. The aa:bbCRLF format is not such a datatype.

Can you describe what you are trying to accomplish? Perhaps there are
other ways to do it, or it is useful enough to add something.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] LibSynthesis internal data structure and conversion...

2010-03-15 Thread Patrick Ohly
On Mo, 2010-03-15 at 10:11 +, paul wrote:
 Well I wrote my database plugin in copying the example of SDK_demodb,
 because for whatever reason I couldn't get the SDK_textdb example to
 work.  So now I have a plugin written in C for a client.  Now the the
 libsynthesis engine calls this plugin for example with an
 InsertItem(), I get data in the aa:bbCRLF format.  However I have no
 why of interpreting that data and I need it in vcard format without
 rewriting code to convert it based on the configuration xml file.

This is exactly what SyncEvolution does. Here's an outline how it works,
for details see the SyncEvolution source code:
  * in the plugin's Module_Capabilities, set CA_ItemAsKey to
:yes (SynthesisDBPlugin.cpp)
  * instead of the normal Item() callbacks implement the ItemAsKey()
variants (SynthesisDBPlugin.cpp)
  * in the initscript of the data store, create a variable
(itemdata in SyncSource.cpp) and map it so that it can be
accessed from the AsKey() code (map name='data'
references='itemdata' type='string'/)
  * in the before/afterwritescript, call the
MAKE/PARSETEXTWITHPROFILE() macros to convert to/from the field
list (SyncSource.cpp)
  * in your AsKey() implementations, read/write the data field
(SyncSourceSerialize::readItemAsKey,
SyncSourceSerialize::insertItemAsKey)

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] resume Add second half

2010-03-15 Thread Patrick Ohly
On So, 2010-03-07 at 01:56 +0100, Patrick Ohly wrote:
 Anyway, it fails in one case when the item was split:
  1. client has a new big item
  2. client sends Add with MoreData/
  3. server buffers the item
  4. client sends second half
  5. server processes the complete item, removes the PIStored blob,
 sends reply

5.5. admin data is stored with lastitemstatus=0, in contrast to the 201
status stored there when the item is not split across messages.

  6. reply never reaches client
  7. client and server suspend
  8. upon resume, client resends the second half
 (ItemSourceLocURI2273/LocURI/Source
 MetaEMIdatapos=19241/EMI/MetaData...)
  9. server attempts to parse the item, fails and returns 415
 
 The logs don't tell me what the relevant difference is, so I'll have to
 dive into the debugger.

I found something and got it working with the following patch. Lukas,
does this make sense?

commit ce704f6f521e9153d801f47d750a9a45fcc6f507
Author: Patrick Ohly patrick.o...@intel.com
Date:   Mon Mar 15 16:16:32 2010 +0100

resume + pending item fix in SyncML server

When an item that was split among messages was finally reassembled
and processed by the server, the status sent to the client was not
properly stored in the admin data. As a result of that, when the
session got suspended directly after sending that status, the client
would resume, send the last item chunk again, but then not get
the previous status. Instead the server attempted to parse the
incomplete item and failed.

The root cause was that TSyncSession::process() was called
recursively. The inner one for the incomplete command saved the
status in fLastItemStatus. The outer one then later didn't have
a status pointer, fell back to status 0 and overwrote the valid
status.

This patch solves this by suppressing that second updating of
fLastItemStatus and all related fields if the item was handled
by an inner process() call.

diff --git a/src/sysync/synccommand.cpp b/src/sysync/synccommand.cpp
index 1892b24..73560cc 100755
--- a/src/sysync/synccommand.cpp
+++ b/src/sysync/synccommand.cpp
@@ -2270,6 +2270,7 @@ bool TSyncOpCommand::execute(void)
   localstatus sta;
   TSyncOpCommand *incompleteCmdP;
   bool queueforlater,processitem;
+  bool nostatus;
   SmlItemListPtr_t tobequeueditems=NULL;
 
   SYSYNC_TRY {
@@ -2292,6 +2293,7 @@ bool TSyncOpCommand::execute(void)
 while (*itemnodePP) {
   queueforlater=false; // do no queue by default
   processitem=true; // process by default
+  nostatus=false; // set to true if someone else is responsible for 
updating fLastItemStatus
   thisitemnode = *itemnodePP;
   // no result nor status so far
   statusCmdP=NULL;
@@ -2531,7 +2533,10 @@ bool TSyncOpCommand::execute(void)
   // - first remove global link to it to avoid recursion
   fSessionP-fIncompleteDataCommandP=NULL;
   // - execute now (and pass ownership)
-  //   issues appropriate statuses
+  //   issues appropriate statuses, so we don't need to deal with 
it;
+  //   in fact, we must not touch fLastItemStatus because we don't
+  //   know the status
+  nostatus=true;
   fSessionP-process(incompleteCmdP);
   // - this item is processed now, continue in loop if there are 
more items
   processitem=false; // do not process the item normally
@@ -2628,7 +2633,7 @@ bool TSyncOpCommand::execute(void)
 // item processed
 // - remember status (final only) for possible suspend and resume
 sta= statusCmdP ? statusCmdP-getStatusCode() : 0;
-if (sta!=213) {
+if (!nostatus  sta!=213) {
   // final status received, save it for possible resend
   fDataStoreP-fLastItemStatus = sta;
   // but forget data stored at DS level


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] [PATCH] SAN 1.1 generation support: Moved utility code from engine to sdk

2010-03-08 Thread Patrick Ohly
On Mon, 2010-03-08 at 08:27 -0800, Beat Forster wrote:
 Our SDK is using stringutil.h/stringutil.cpp for 
 standalone application, so you can't just remove 
 them, because they are missing then for these 
 projects.

But if these files were kept and stringutils.h/cpp were moved into the
SDK, the change was okay?

As before, because moving files into the SDK implies a relicensing, this
change would have to be made in the synthesis.ch git repo by Synthesis.
Can we make that fairly soon so that we can remove the hack which
exposes these functions in the libsynthesis.so?


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] resend Delete

2010-03-06 Thread Patrick Ohly
Hello!

Another resume problem, probably caused by SyncEvolution:
 1. item deleted on server
 2. Delete sent to client
 3. client processes it, its next message to server gets lost
 4. client and server suspend
 5. after resume, Delete is sent again
 6. client backend returns 10500 in DeleteItem
(sysync::LOCAL_STATUS_CODE + 500)
 7. 10500 is sent to server
 8. server shuts down session *without* reply
 9. client encounters network problem due to missing reply

The client should not treat removal of an already removed item as error.
This happens here because I was using the file backend, not the
Evolution backends, which already work like that (step 6).

I suppose I'm still a bit uncertain about local status codes. Is the
plugin allowed to return an error marked as local to the Synthesis
engine? If yes, then the engine should have sent 500 to the server, not
10500 (step 7).

If no, then I need to be more careful in the exception handling code
which creates the status code. If the consumer of the status is the
engine, we must not mark the error as local. If the consumer is
SyncEvolution above the engine, then they should be marked as local,
just as if they came out of the engine.

Client and server don't agree on whether the session should continue
(steps 8 and 9). Not sure who is right here.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


[os-libsynthesis] resume Add second half

2010-03-06 Thread Patrick Ohly
Hello!

Lukas, your fix with not processing a resent Add works when the item
fits into one message. I'm not entirely sure why, though. What I see in
the log file is:
[2010-03-06 07:30:58.009] Started processing Command 'Add' (incoming
MsgID=2, CmdID=5)
  * +–[2010-03-06 07:30:58.009] 'processCmd' - Processing incoming
command, Cmd=Add, IncomingMsgID=2,
CmdID=5 [--][++] [-end] [-enclosing]
  * [2010-03-06 07:30:58.009] command started processing
  * [2010-03-06 07:30:58.009] Received last chunk for already
processed item - just resending status 201
  * [2010-03-06 07:30:58.009] Created command 'Status' (outgoing)

The already processed message is not from your recent patch.

Anyway, it fails in one case when the item was split:
 1. client has a new big item
 2. client sends Add with MoreData/
 3. server buffers the item
 4. client sends second half
 5. server processes the complete item, removes the PIStored blob,
sends reply
 6. reply never reaches client
 7. client and server suspend
 8. upon resume, client resends the second half
(ItemSourceLocURI2273/LocURI/Source
MetaEMIdatapos=19241/EMI/MetaData...)
 9. server attempts to parse the item, fails and returns 415

The logs don't tell me what the relevant difference is, so I'll have to
dive into the debugger.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] resume + double Add

2010-03-04 Thread Patrick Ohly
On Fri, 2010-02-26 at 15:05 +, Patrick Ohly wrote:
[...]
 So it seems that the engine does check for the remote ID, but only after
 having already added the item again.

I think this was due to not enabling resumesupport. After setting
that, the same test passes. Sorry for the confusion - I hadn't quite
realized that suspend/resume was optional.

Shouldn't the server have refused to resume with resumesupport off?
Just wondering, we'll certainly turn it on now...

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] resume + double Add

2010-03-04 Thread Patrick Ohly
On Thu, 2010-03-04 at 23:49 +, Lukas Zeller wrote:
 On Mar 4, 2010, at 18:49 , Patrick Ohly wrote:
 
  On Fri, 2010-02-26 at 15:05 +, Patrick Ohly wrote:
 However, while tracking through the code I found that indeed in the
 server, the case of a client sending duplicate Adds was not handled
 at all. So even with resumesupport a repeated add from the client
 IMHO would have created a duplicate in the server DB.
 As most clients always send Replace (including libsynthesis not so
 long ago), this case did not surface.
 
 I now added a check for that in 3e687ddfca (server engine: added
 missing check for re-sent Add during resume.)

Then my testing wasn't all in vain, even though it doesn't seem to be
100% reliable - see below.

I'll continue testing with your patch included.

 ...and resumesupport is irrelevant (so what I said in the previous
 message is not entirely correct - old plugins will AUTOMATICALLY
 disable resume; resumesupport is only relevant for SQL backends).
 
 So it's even stranger that enabling resumesupport should have made
 the tests to pass now. ???

I also enable blob support, but that shouldn't be relevant for these
tests. But I might have been wrong about it working: rerunning it shows
that the results are not always reproducable. I need to look into that.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


Re: [os-libsynthesis] Newbie question on setting the target locuri...

2010-03-01 Thread Patrick Ohly
On Mon, 2010-03-01 at 08:36 +, paul wrote:

 It seems like I should be able to set the target locuri in the
 configuration file, but I don't see an example for that.  Can I set
 the target locuri in the config xml file and if yes what is the form?

I don't think you can. URIs on the client side are set via a key in the
profile that corresponds to the data source. I'm sure this is in the
documentation somewhere. Here's how we do it in SyncEvolution:
http://git.moblin.org/cgit.cgi/syncevolution/tree/src/syncevo/SyncContext.cpp?id=syncevolution-0-9-2#n1646


-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



___
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis


  1   2   >