5
* Copyright (C) 2007-2008 Intel Corporation
6
* Copyright (C) 2007-2009 Marcel Holtmann <marcel@holtmann.org>
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36
#define ERROR_INF PBAP_INTERFACE ".Error"
38
#define FORMAT_VCARD21 0x0
39
#define FORMAT_VCARD30 0x1
41
#define ORDER_INDEXED 0x0
42
#define ORDER_ALPHANUMERIC 0x1
43
#define ORDER_PHONETIC 0x2
45
#define ATTRIB_NAME 0x0
46
#define ATTRIB_NUMBER 0x1
47
#define ATTRIB_SOUND 0x2
49
#define DEFAULT_COUNT 65535
50
#define DEFAULT_OFFSET 0
52
#define PULLPHONEBOOK 0x1
53
#define GETPHONEBOOKSIZE 0x2
55
#define ORDER_TAG 0x01
56
#define SEARCHVALUE_TAG 0x02
57
#define SEARCHATTRIB_TAG 0x03
58
#define MAXLISTCOUNT_TAG 0x04
59
#define LISTSTARTOFFSET_TAG 0x05
60
#define FILTER_TAG 0x06
61
#define FORMAT_TAG 0X07
62
#define PHONEBOOKSIZE_TAG 0X08
63
#define NEWMISSEDCALLS_TAG 0X09
65
/* The following length is in the unit of byte */
67
#define SEARCHATTRIB_LEN 1
68
#define MAXLISTCOUNT_LEN 2
69
#define LISTSTARTOFFSET_LEN 2
72
#define PHONEBOOKSIZE_LEN 2
73
#define NEWMISSEDCALLS_LEN 1
75
#define get_be16(val) GUINT16_FROM_BE(bt_get_unaligned((guint16 *) val))
77
static const char *filter_list[] = {
106
"X-IRMC-CALL-DATETIME",
110
#define FILTER_BIT_MAX 63
111
#define FILTER_ALL 0xFFFFFFFFFFFFFFFFULL
113
struct pullphonebook_apparam {
120
uint8_t maxlistcount_tag;
121
uint8_t maxlistcount_len;
122
uint16_t maxlistcount;
123
uint8_t liststartoffset_tag;
124
uint8_t liststartoffset_len;
125
uint16_t liststartoffset;
126
} __attribute__ ((packed));
128
struct pullvcardentry_apparam {
135
} __attribute__ ((packed));
141
} __attribute__ ((packed));
143
#define APPARAM_HDR_SIZE 2
145
static void listing_element(GMarkupParseContext *ctxt,
146
const gchar *element,
148
const gchar **values,
152
DBusMessageIter *item = user_data, entry;
154
const gchar *handle = NULL, *vcardname = NULL;
156
if (g_str_equal(element, "card") != TRUE)
159
for (key = (gchar **) names; *key; key++, values++) {
160
if (g_str_equal(*key, "handle") == TRUE)
162
else if (g_str_equal(*key, "name") == TRUE)
166
if (!handle || !vcardname)
169
dbus_message_iter_open_container(item, DBUS_TYPE_STRUCT, NULL, &entry);
170
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &handle);
171
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &vcardname);
172
dbus_message_iter_close_container(item, &entry);
175
static const GMarkupParser listing_parser = {
182
static gchar *build_phonebook_path(const char *location, const char *item)
184
gchar *path = NULL, *tmp, *tmp1;
186
if (!g_ascii_strcasecmp(location, "INT") ||
187
!g_ascii_strcasecmp(location, "INTERNAL"))
188
path = g_strdup("telecom");
189
else if (!g_ascii_strncasecmp(location, "SIM", 3)) {
190
if (strlen(location) == 3)
191
tmp = g_strdup("SIM1");
193
tmp = g_ascii_strup(location, 4);
195
path = g_build_filename(tmp, "telecom", NULL);
200
if (!g_ascii_strcasecmp(item, "PB") ||
201
!g_ascii_strcasecmp(item, "ICH") ||
202
!g_ascii_strcasecmp(item, "OCH") ||
203
!g_ascii_strcasecmp(item, "MCH") ||
204
!g_ascii_strcasecmp(item, "CCH")) {
206
tmp1 = g_ascii_strdown(item, -1);
207
path = g_build_filename(tmp, tmp1, NULL);
218
/* should only be called inside pbap_set_path */
219
static void pbap_reset_path(struct session_data *session)
222
char **paths = NULL, **item;
223
struct pbap_data *pbapdata = session_get_data(session);
228
gw_obex_chdir(session->obex, "", &err);
230
paths = g_strsplit(pbapdata->path, "/", 3);
232
for (item = paths; *item; item++)
233
gw_obex_chdir(session->obex, *item, &err);
238
static gint pbap_set_path(struct session_data *session, const char *path)
241
char **paths = NULL, **item;
242
struct pbap_data *pbapdata = session_get_data(session);
245
return OBEX_RSP_BAD_REQUEST;
247
if (pbapdata->path != NULL && g_str_equal(pbapdata->path, path))
250
if (gw_obex_chdir(session->obex, "", &err) == FALSE) {
251
if (err == OBEX_RSP_NOT_IMPLEMENTED)
256
paths = g_strsplit(path, "/", 3);
257
for (item = paths; *item; item++) {
258
if (gw_obex_chdir(session->obex, *item, &err) == FALSE) {
259
/* we need to reset the path to the saved one on fail*/
260
pbap_reset_path(session);
268
g_free(pbapdata->path);
269
pbapdata->path = g_strdup(path);
279
static void read_return_apparam(struct session_data *session,
280
guint16 *phone_book_size, guint8 *new_missed_calls)
282
GwObexXfer *xfer = session->xfer;
286
*phone_book_size = 0;
287
*new_missed_calls = 0;
292
buf = gw_obex_xfer_object_apparam(xfer, &size);
294
if (size < APPARAM_HDR_SIZE)
297
while (size > APPARAM_HDR_SIZE) {
298
struct apparam_hdr *hdr = (struct apparam_hdr *) buf;
300
if (hdr->len > size - APPARAM_HDR_SIZE) {
301
fprintf(stderr, "Unexpected PBAP pullphonebook app"
302
" length, tag %d, len %d\n",
308
case PHONEBOOKSIZE_TAG:
309
if (hdr->len == PHONEBOOKSIZE_LEN)
310
*phone_book_size = get_be16(hdr->val);
312
case NEWMISSEDCALLS_TAG:
313
if (hdr->len == NEWMISSEDCALLS_LEN)
314
*new_missed_calls = hdr->val[0];
317
fprintf(stderr, "Unexpected PBAP pullphonebook app"
318
" parameter, tag %d, len %d\n",
322
buf += APPARAM_HDR_SIZE + hdr->len;
323
size -= APPARAM_HDR_SIZE + hdr->len;
327
static void pull_phonebook_callback(struct session_data *session,
333
reply = dbus_message_new_method_return(session->msg);
335
if (session->filled > 0)
336
buf = session->buffer;
338
dbus_message_append_args(reply,
339
DBUS_TYPE_STRING, &buf,
343
g_dbus_send_message(session->conn, reply);
344
dbus_message_unref(session->msg);
348
static void phonebook_size_callback(struct session_data *session,
352
guint16 phone_book_size;
353
guint8 new_missed_calls;
355
reply = dbus_message_new_method_return(session->msg);
357
read_return_apparam(session, &phone_book_size, &new_missed_calls);
359
dbus_message_append_args(reply,
360
DBUS_TYPE_UINT16, &phone_book_size,
364
g_dbus_send_message(session->conn, reply);
365
dbus_message_unref(session->msg);
369
static void pull_vcard_listing_callback(struct session_data *session,
372
GMarkupParseContext *ctxt;
374
DBusMessageIter iter, array;
377
reply = dbus_message_new_method_return(session->msg);
379
if (session->filled == 0)
382
for (i = session->filled - 1; i > 0; i--) {
383
if (session->buffer[i] != '\0')
389
dbus_message_iter_init_append(reply, &iter);
390
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
391
DBUS_STRUCT_BEGIN_CHAR_AS_STRING
392
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING
393
DBUS_STRUCT_END_CHAR_AS_STRING, &array);
394
ctxt = g_markup_parse_context_new(&listing_parser, 0, &array, NULL);
395
g_markup_parse_context_parse(ctxt, session->buffer,
396
session->filled, NULL);
397
g_markup_parse_context_free(ctxt);
398
dbus_message_iter_close_container(&iter, &array);
403
g_dbus_send_message(session->conn, reply);
404
dbus_message_unref(session->msg);
408
static DBusMessage *pull_phonebook(struct session_data *session,
409
DBusMessage *message, guint8 type,
410
const char *name, uint64_t filter,
411
guint8 format, guint16 maxlistcount,
412
guint16 liststartoffset)
414
struct pullphonebook_apparam apparam;
415
session_callback_t func;
418
return g_dbus_create_error(message,
419
"org.openobex.Error.InProgress",
420
"Transfer in progress");
422
apparam.filter_tag = FILTER_TAG;
423
apparam.filter_len = FILTER_LEN;
424
apparam.filter = GUINT64_TO_BE(filter);
425
apparam.format_tag = FORMAT_TAG;
426
apparam.format_len = FORMAT_LEN;
427
apparam.format = format;
428
apparam.maxlistcount_tag = MAXLISTCOUNT_TAG;
429
apparam.maxlistcount_len = MAXLISTCOUNT_LEN;
430
apparam.maxlistcount = GUINT16_TO_BE(maxlistcount);
431
apparam.liststartoffset_tag = LISTSTARTOFFSET_TAG;
432
apparam.liststartoffset_len = LISTSTARTOFFSET_LEN;
433
apparam.liststartoffset = GUINT16_TO_BE(liststartoffset);
437
func = pull_phonebook_callback;
439
case GETPHONEBOOKSIZE:
440
func = phonebook_size_callback;
443
fprintf(stderr, "Unexpected type : 0x%2x\n", type);
447
if (session_get(session, "x-bt/phonebook", name, NULL,
448
(guint8 *) &apparam, sizeof(apparam),
450
return g_dbus_create_error(message,
451
"org.openobex.Error.Failed",
454
session->msg = dbus_message_ref(message);
460
static guint8 *fill_apparam(guint8 *dest, void *buf, guint8 tag, guint8 len)
465
memcpy(dest, buf, len);
472
static DBusMessage *pull_vcard_listing(struct session_data *session,
473
DBusMessage *message, const char *name,
474
guint8 order, char *searchval, guint8 attrib,
475
guint16 count, guint16 offset)
477
guint8 *p, *apparam = NULL;
482
return g_dbus_create_error(message,
483
"org.openobex.Error.InProgress",
484
"Transfer in progress");
486
/* trunc the searchval string if it's length exceed the max value of guint8 */
487
if (strlen(searchval) > 254)
488
searchval[255] = '\0';
490
apparam_size = APPARAM_HDR_SIZE + ORDER_LEN +
491
(APPARAM_HDR_SIZE + strlen(searchval) + 1) +
492
(APPARAM_HDR_SIZE + SEARCHATTRIB_LEN) +
493
(APPARAM_HDR_SIZE + MAXLISTCOUNT_LEN) +
494
(APPARAM_HDR_SIZE + LISTSTARTOFFSET_LEN);
495
apparam = g_try_malloc0(apparam_size);
497
return g_dbus_create_error(message,
498
ERROR_INF ".Failed", "No Memory");
502
p = fill_apparam(p, &order, ORDER_TAG, ORDER_LEN);
503
p = fill_apparam(p, searchval, SEARCHVALUE_TAG, strlen(searchval) + 1);
504
p = fill_apparam(p, &attrib, SEARCHATTRIB_TAG, SEARCHATTRIB_LEN);
506
count = GUINT16_TO_BE(count);
507
p = fill_apparam(p, &count, MAXLISTCOUNT_TAG, MAXLISTCOUNT_LEN);
509
offset = GUINT16_TO_BE(offset);
510
p = fill_apparam(p, &offset, LISTSTARTOFFSET_TAG, LISTSTARTOFFSET_LEN);
512
err = session_get(session, "x-bt/vcard-listing", name, NULL,
513
apparam, apparam_size, pull_vcard_listing_callback);
516
return g_dbus_create_error(message,
517
"org.openobex.Error.Failed",
520
session->msg = dbus_message_ref(message);
526
static int set_format(struct session_data *session, const char *formatstr)
528
struct pbap_data *pbapdata = session_get_data(session);
530
if (!formatstr || g_str_equal(formatstr, "")) {
531
pbapdata->format = FORMAT_VCARD21;
535
if (!g_ascii_strcasecmp(formatstr, "vcard21"))
536
pbapdata->format = FORMAT_VCARD21;
537
else if (!g_ascii_strcasecmp(formatstr, "vcard30"))
538
pbapdata->format = FORMAT_VCARD30;
545
static int set_order(struct session_data *session, const char *orderstr)
547
struct pbap_data *pbapdata = session_get_data(session);
549
if (!orderstr || g_str_equal(orderstr, "")) {
550
pbapdata->order = ORDER_INDEXED;
554
if (!g_ascii_strcasecmp(orderstr, "indexed"))
555
pbapdata->order = ORDER_INDEXED;
556
else if (!g_ascii_strcasecmp(orderstr, "alphanumeric"))
557
pbapdata->order = ORDER_ALPHANUMERIC;
558
else if (!g_ascii_strcasecmp(orderstr, "phonetic"))
559
pbapdata->order = ORDER_PHONETIC;
566
static uint64_t get_filter_mask(const char *filterstr)
573
if (!g_ascii_strcasecmp(filterstr, "ALL"))
576
for (i = 0; filter_list[i] != NULL; i++)
577
if (!g_ascii_strcasecmp(filterstr, filter_list[i]))
580
if (strlen(filterstr) < 4 || strlen(filterstr) > 5
581
|| g_ascii_strncasecmp(filterstr, "bit", 3) != 0)
584
sscanf(&filterstr[3], "%d", &bit);
585
if (bit >= 0 && bit <= FILTER_BIT_MAX)
591
static int add_filter(struct session_data *session, const char *filterstr)
593
struct pbap_data *pbapdata = session_get_data(session);
596
mask = get_filter_mask(filterstr);
601
pbapdata->filter |= mask;
605
static int remove_filter(struct session_data *session, const char *filterstr)
607
struct pbap_data *pbapdata = session_get_data(session);
610
mask = get_filter_mask(filterstr);
615
pbapdata->filter &= ~mask;
619
static gchar **get_filter_strs(uint64_t filter, gint *size)
621
gchar **list, **item;
623
gint filter_list_size = sizeof(filter_list) / sizeof(filter_list[0]) - 1;
625
list = g_try_malloc0(sizeof(gchar **) * (FILTER_BIT_MAX + 2));
632
for (i = 0; i < filter_list_size; i++)
633
if (filter & (1ULL << i))
634
*(item++) = g_strdup(filter_list[i]);
636
for (i = filter_list_size; i <= FILTER_BIT_MAX; i++)
637
if (filter & (1ULL << i))
638
*(item++) = g_strdup_printf("%s%d", "BIT", i);
645
static DBusMessage *pbap_select(DBusConnection *connection,
646
DBusMessage *message, void *user_data)
648
struct session_data *session = user_data;
649
const char *item, *location;
653
if (dbus_message_get_args(message, NULL,
654
DBUS_TYPE_STRING, &location,
655
DBUS_TYPE_STRING, &item,
656
DBUS_TYPE_INVALID) == FALSE)
657
return g_dbus_create_error(message,
658
ERROR_INF ".InvalidArguments", NULL);
660
path = build_phonebook_path(location, item);
662
return g_dbus_create_error(message,
663
ERROR_INF ".InvalidArguments", "InvalidPhonebook");
665
err = pbap_set_path(session, path);
668
return g_dbus_create_error(message,
670
OBEX_ResponseToString(err));
672
return dbus_message_new_method_return(message);
675
static DBusMessage *pbap_pull_all(DBusConnection *connection,
676
DBusMessage *message, void *user_data)
678
struct session_data *session = user_data;
679
struct pbap_data *pbapdata = session_get_data(session);
684
return g_dbus_create_error(message,
685
ERROR_INF ".Forbidden", "Call Select first of all");
687
name = g_strconcat(pbapdata->path, ".vcf", NULL);
689
err = pull_phonebook(session, message, PULLPHONEBOOK, name,
690
pbapdata->filter, pbapdata->format,
691
DEFAULT_COUNT, DEFAULT_OFFSET);
696
static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
697
DBusMessage *message, void *user_data)
699
struct session_data *session = user_data;
700
struct pbap_data *pbapdata = session_get_data(session);
701
struct pullvcardentry_apparam apparam;
705
return g_dbus_create_error(message,
706
ERROR_INF ".Forbidden", "Call Select first of all");
708
if (dbus_message_get_args(message, NULL,
709
DBUS_TYPE_STRING, &name,
710
DBUS_TYPE_INVALID) == FALSE)
711
return g_dbus_create_error(message,
712
ERROR_INF ".InvalidArguments", NULL);
715
return g_dbus_create_error(message,
716
"org.openobex.Error.InProgress",
717
"Transfer in progress");
719
apparam.filter_tag = FILTER_TAG;
720
apparam.filter_len = FILTER_LEN;
721
apparam.filter = GUINT64_TO_BE(pbapdata->filter);
722
apparam.format_tag = FORMAT_TAG;
723
apparam.format_len = FORMAT_LEN;
724
apparam.format = pbapdata->format;
726
if (session_get(session, "x-bt/vcard", name, NULL,
727
(guint8 *)&apparam, sizeof(apparam),
728
pull_phonebook_callback) < 0)
729
return g_dbus_create_error(message,
730
"org.openobex.Error.Failed",
733
session->msg = dbus_message_ref(message);
739
static DBusMessage *pbap_list(DBusConnection *connection,
740
DBusMessage *message, void *user_data)
742
struct session_data *session = user_data;
743
struct pbap_data *pbapdata = session_get_data(session);
746
return g_dbus_create_error(message,
747
ERROR_INF ".Forbidden", "Call Select first of all");
749
return pull_vcard_listing(session, message, "", pbapdata->order, "",
750
ATTRIB_NAME, DEFAULT_COUNT, DEFAULT_OFFSET);
753
static DBusMessage *pbap_search(DBusConnection *connection,
754
DBusMessage *message, void *user_data)
756
struct session_data *session = user_data;
757
struct pbap_data *pbapdata = session_get_data(session);
761
if (dbus_message_get_args(message, NULL,
762
DBUS_TYPE_STRING, &field,
763
DBUS_TYPE_STRING, &value,
764
DBUS_TYPE_INVALID) == FALSE)
765
return g_dbus_create_error(message,
766
ERROR_INF ".InvalidArguments", NULL);
769
return g_dbus_create_error(message,
770
ERROR_INF ".Forbidden", "Call Select first of all");
772
if (!field || g_str_equal(field, ""))
773
attrib = ATTRIB_NAME;
774
else if (!g_ascii_strcasecmp(field, "name"))
775
attrib = ATTRIB_NAME;
776
else if (!g_ascii_strcasecmp(field, "number"))
777
attrib = ATTRIB_NUMBER;
778
else if (!g_ascii_strcasecmp(field, "sound"))
779
attrib = ATTRIB_SOUND;
781
return g_dbus_create_error(message,
782
ERROR_INF ".InvalidArguments", NULL);
784
return pull_vcard_listing(session, message, "", pbapdata->order, value,
785
attrib, DEFAULT_COUNT, DEFAULT_OFFSET);
788
static DBusMessage *pbap_get_size(DBusConnection *connection,
789
DBusMessage *message, void *user_data)
791
struct session_data *session = user_data;
792
struct pbap_data *pbapdata = session_get_data(session);
797
return g_dbus_create_error(message,
798
ERROR_INF ".Forbidden", "Call Select first of all");
800
name = g_strconcat(pbapdata->path, ".vcf", NULL);
802
err = pull_phonebook(session, message, GETPHONEBOOKSIZE, name,
803
pbapdata->filter, pbapdata->format,
809
static DBusMessage *pbap_set_format(DBusConnection *connection,
810
DBusMessage *message, void *user_data)
812
struct session_data *session = user_data;
815
if (dbus_message_get_args(message, NULL,
816
DBUS_TYPE_STRING, &format,
817
DBUS_TYPE_INVALID) == FALSE)
818
return g_dbus_create_error(message,
819
ERROR_INF ".InvalidArguments", NULL);
821
if (set_format(session, format) < 0)
822
return g_dbus_create_error(message,
823
ERROR_INF ".InvalidArguments", "InvalidFormat");
825
return dbus_message_new_method_return(message);
828
static DBusMessage *pbap_set_order(DBusConnection *connection,
829
DBusMessage *message, void *user_data)
831
struct session_data *session = user_data;
834
if (dbus_message_get_args(message, NULL,
835
DBUS_TYPE_STRING, &order,
836
DBUS_TYPE_INVALID) == FALSE)
837
return g_dbus_create_error(message,
838
ERROR_INF ".InvalidArguments", NULL);
840
if (set_order(session, order) < 0)
841
return g_dbus_create_error(message,
842
ERROR_INF ".InvalidArguments", "InvalidFilter");
844
return dbus_message_new_method_return(message);
847
static DBusMessage *pbap_set_filter(DBusConnection *connection,
848
DBusMessage *message, void *user_data)
850
struct session_data *session = user_data;
851
struct pbap_data *pbapdata = session_get_data(session);
852
char **filters, **item;
854
uint64_t oldfilter = pbapdata->filter;
856
if (dbus_message_get_args(message, NULL, DBUS_TYPE_ARRAY,
857
DBUS_TYPE_STRING, &filters, &size,
858
DBUS_TYPE_INVALID) == FALSE)
859
return g_dbus_create_error(message,
860
ERROR_INF ".InvalidArguments", NULL);
862
remove_filter(session, "ALL");
866
for (item = filters; *item; item++) {
867
if (add_filter(session, *item) < 0) {
868
pbapdata->filter = oldfilter;
870
return g_dbus_create_error(message,
871
ERROR_INF ".InvalidArguments", "InvalidFilters");
877
return dbus_message_new_method_return(message);
880
static DBusMessage *pbap_get_filter(DBusConnection *connection,
881
DBusMessage *message, void *user_data)
883
struct session_data *session = user_data;
884
struct pbap_data *pbapdata = session_get_data(session);
885
gchar **filters = NULL;
889
filters = get_filter_strs(pbapdata->filter, &size);
890
reply = dbus_message_new_method_return(message);
891
dbus_message_append_args(reply, DBUS_TYPE_ARRAY,
892
DBUS_TYPE_STRING, &filters, size,
899
static DBusMessage *pbap_list_filter_fields(DBusConnection *connection,
900
DBusMessage *message, void *user_data)
902
gchar **filters = NULL;
906
filters = get_filter_strs(FILTER_ALL, &size);
907
reply = dbus_message_new_method_return(message);
908
dbus_message_append_args(reply, DBUS_TYPE_ARRAY,
909
DBUS_TYPE_STRING, &filters, size,
916
static GDBusMethodTable pbap_methods[] = {
917
{ "Select", "ss", "", pbap_select },
918
{ "PullAll", "", "s", pbap_pull_all,
919
G_DBUS_METHOD_FLAG_ASYNC },
920
{ "Pull", "s", "s", pbap_pull_vcard,
921
G_DBUS_METHOD_FLAG_ASYNC },
922
{ "List", "", "a(ss)", pbap_list,
923
G_DBUS_METHOD_FLAG_ASYNC },
924
{ "Search", "ss", "a(ss)", pbap_search,
925
G_DBUS_METHOD_FLAG_ASYNC },
926
{ "GetSize", "", "q", pbap_get_size,
927
G_DBUS_METHOD_FLAG_ASYNC },
928
{ "SetFormat", "s", "", pbap_set_format },
929
{ "SetOrder", "s", "", pbap_set_order },
930
{ "SetFilter", "as", "", pbap_set_filter },
931
{ "GetFilter", "", "as", pbap_get_filter },
932
{ "ListFilterFields", "", "as", pbap_list_filter_fields },
936
gboolean pbap_register_interface(DBusConnection *connection, const char *path,
937
void *user_data, GDBusDestroyFunction destroy)
939
struct session_data *session = user_data;
942
priv = g_try_malloc0(sizeof(struct pbap_data));
946
session_set_data(session, priv);
948
return g_dbus_register_interface(connection, path, PBAP_INTERFACE,
949
pbap_methods, NULL, NULL, user_data, destroy);
952
void pbap_unregister_interface(DBusConnection *connection, const char *path,
955
struct session_data *session = user_data;
956
void *priv = session_get_data(session);
958
g_dbus_unregister_interface(connection, path, PBAP_INTERFACE);