Usage
=====

The "pbap" backend provides access to an addressbook stored in a
remote device using the Bluetooth PBAP protocol. This is achieved
using the D-Bus services from obex-client (obexd), which needs to
be running.

The "database" property specifies the Bluetooth address of the
device to be connected.

The "databaseFormat" can be used as follows:

      [(2.1|3.0)][:][^]propname,propname,...

      3.0 = download in vCard 3.0 instead of the default 2.1
      3.0:^PHOTO = download in vCard 3.0 format, excluding PHOTO
      PHOTO = download in vCard 2.1 format, only the PHOTO

Valid property names are the ones listed by obexd in
ListFilterFields(). These fields may include:
     VERSION
     FN
     N
     PHOTO
     BDAY
     ADR
     LABEL
     TEL
     EMAIL
     MAILER
     TZ
     GEO
     TITLE
     ROLE
     LOGO
     AGENT
     ORG
     NOTE
     REV
     SOUND
     URL
     UID
     KEY
     NICKNAME
     CATEGORIES
     CLASS
     BITxy (for different values of xy)

Set "SYNCEVOLUTION_DEBUG=1" as environment variable when using the
backend to see a list of filter fields supported by obexd.

Syncing
=======

The backend itself is not able to detect changes since the last
sync, mostly because PBAP as a protocol makes that hard. For example,
it makes no guarantee that an item has the same ID in two different
sessions.

The intended use for the PBAP backend therefore is in the "slow local
cache" sync mode: always pull all data and let the sync engine update
a local database. The local database is not allowed to be modified
outside of the sync. Any such change may get lost at any time.


# configure backend
#
#
# Preventing a slow sync is possible in local-cache mode. It
# makes no sense for PBAP and thus has to be turned off.
syncevolution --configure \
                syncURL= \
                addressbook/backend=pbap \
		addressbook/database=obex-bt://XX:XX:XX:XX:XX:XX \
                preventSlowSync=false \
                target-config@pbap addressbook

# print items
syncevolution --print-items \
 	        target-config@pbap addressbook

# Configure synchronization.
#
# 'local-cache' expands to 'local-cache-incremental', which will try
# to do an incremental sync but be turned into a slow sync by
# the PBAP backend.
syncevolution --configure \
                --template SyncEvolution_Client \
                syncURL=local://@pbap \
                sync=local-cache \
                pbap addressbook

# run synchronization
syncevolution pbap


It may or may not be desirable to sync only the text properties of a
contact. This can be considerably faster, because the PHOTO property
is large and increases the download and processing time. SyncEvolution
supports that in three different ways, chosen via the
SYNCEVOLUTION_PBAP_SYNC env variable:

SYNCEVOLUTION_PBAP_SYNC=text syncevolution pbap
  Synchronize only the text properties by excluding the PHOTO property,
  keep all photos already stored locally.

SYNCEVOLUTION_PBAP_SYNC=all syncevolution pbap
  Synchronize all properties according to the databaseFormat in one go,
  adding/updating/removing photos locally to match the phone.

SYNCEVOLUTION_PBAP_SYNC=incremental syncevolution pbap
  Synchronize first text, then all data. Conceptually this is the same
  as two invocations with "text" and then "all". Because the implementation
  reuses the same PBAP session and sync session, it is slightly faster.
  It is slower than a single "all" sync because the entire set of contacts
  must be downloaded and synced twice, once without photo, then with.

SYNCEVOLUTION_PBAP_SYNC has side effect on the entire sync and thus
may only be used in a sync config which synchronizes contacts via
PBAP.

The PIM Manager defaults to SYNCEVOLUTION_PBAP_SYNC=incremental. This
can be overriden by setting the env variable when starting
syncevo-dbus-server, for example by patching
src/dbus/server/syncevo-dbus-server-startup.sh.in =
/usr/libexec/syncevo-dbus-server-startup.sh, or using the new
SyncPeerWithFlags() and 'pbap-sync' flag.


Transfering in chunks
=====================

The default is to pull all contacts in one transfer. This can be
changed to transfer in chunks. Optionally the size of the chunks can
be adjusted dynamically at runtime to achieve a certain time per
transfer.

The purpose of transferring in chunks is twofold:
  1. It avoids having to pull the entire address book into a file
     which then has to be kept around until syncing is complete.
  2. By randomly starting at different offsets, eventually all
     data gets added to the local cache even if no sync ever
     completes.

This gets configured with environment variables:

SYNCEVOLUTION_PBAP_CHUNK_MAX_COUNT_PHOTO=<number of contacts>
  A value larger 0 enables chunking when transferring contacts with photo data.

SYNCEVOLUTION_PBAP_CHUNK_MAX_COUNT_NO_PHOTO=<number of contacts>
  A value larger 0 enables chunking when transferring contacts without photo data.

SYNCEVOLUTION_PBAP_CHUNK_TRANSFER_TIME=<seconds>
  The desired duration of each transfer. Indirectly also controls the amount
  of data which has to be buffered. Defaults to 30 seconds, turned off
  with any value <= 0 seconds.

SYNCEVOLUTION_PBAP_CHUNK_TIME_LAMBDA=<0 to 1>
  Controls how quickly new measurements adapt the chunk size. 0 is fastest
  (= next transfer uses exactly the calculated number of contacts), 1 is not
  at all (= all transfers use the intitial number). Defaults to 0.1.

SYNCEVOLUTION_PBAP_CHUNK_OFFSET=<0 to number of contacts in phone>
  Overrides the random selection of the start offset. Useful for debugging.
  Offsets which are out of range get mapped into a valid offset.

For example, consider a Samsung Galaxy S3, Android 4.3, average
contact size 6KB with photo data and 235B without. The transfer rate
is 40KB/s with photo data, 17KB/s without. To achieve 30s per chunk,
one needs to choose 243 contacts per chunk with photo data resp. 2500
without. A transfer of 1000 contacts without photos completes in under
17 seconds, with photos under 2:05 minutes. In this case, downloading
in chunks was almost as fast as transferring all at once.

To debug transferring in chunks, run
  SYNCEVOLUTION_DEBUG=1 syncevolution --daemon=no --export - \
     backend=pbap loglevel=4 \
     database=obex-bt://64:B3:10:C0:8C:2E 2>&1 | grep -e transferred -e "pullall" -e "max count"
