~ubuntu-branches/ubuntu/wily/bluez/wily

« back to all changes in this revision

Viewing changes to tools/sdptool.c

ImportĀ upstreamĀ versionĀ 4.81

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 *
5
5
 *  Copyright (C) 2001-2002  Nokia Corporation
6
6
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
7
 
 *  Copyright (C) 2002-2009  Marcel Holtmann <marcel@holtmann.org>
 
7
 *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
8
8
 *  Copyright (C) 2002-2003  Stephen Crane <steve.crane@rococosoft.com>
9
9
 *  Copyright (C) 2002-2003  Jean Tourrilhes <jt@hpl.hp.com>
10
10
 *
322
322
        { 0x1303, "VideoSource", NULL, 0 },
323
323
        { 0x1304, "VideoSink", NULL, 0 },
324
324
        { 0x1305, "VideoDistribution", NULL, 0 },
325
 
        { 0x1400, "MDP", NULL, 0 },
326
 
        { 0x1401, "MDPSource", NULL, 0 },
327
 
        { 0x1402, "MDPSink", NULL, 0 },
 
325
        { 0x1400, "HDP", NULL, 0 },
 
326
        { 0x1401, "HDPSource", NULL, 0 },
 
327
        { 0x1402, "HDPSink", NULL, 0 },
328
328
        { 0x2112, "AppleAgent", NULL, 0 },
329
329
};
330
330
 
513
513
 */
514
514
static void print_tree_attr_func(void *value, void *userData)
515
515
{
516
 
        sdp_data_t *sdpdata = NULL;
 
516
        sdp_data_t *sdpdata = value;
517
517
        uint16_t attrId;
518
518
        struct service_context *service = (struct service_context *) userData;
519
519
        struct attrib_context context;
520
520
        struct attrib_def *attrDef = NULL;
521
521
        int i;
522
522
 
523
 
        sdpdata = (sdp_data_t *)value;
 
523
        if (!sdpdata)
 
524
                return;
 
525
 
524
526
        attrId = sdpdata->attrId;
525
527
        /* Search amongst the generic attributes */
526
528
        for (i = 0; i < attrib_max; i++)
549
551
        context.attrib = attrDef;
550
552
        context.member_index = 0;
551
553
        /* Parse attribute members */
552
 
        if (sdpdata)
553
 
                sdp_data_printf(sdpdata, &context, 2);
554
 
        else
555
 
                printf("  NULL value\n");
 
554
        sdp_data_printf(sdpdata, &context, 2);
556
555
        /* Update service */
557
556
        service->service = context.service;
558
557
}
723
722
        struct attrib_def *def = NULL;
724
723
        int i;
725
724
 
 
725
        if (!data)
 
726
                return;
 
727
 
726
728
        /* Search amongst the generic attributes */
727
729
        for (i = 0; i < attrib_max; i++)
728
730
                if (attrib_names[i].num == data->attrId) {
735
737
        else
736
738
                printf("\tAttribute 0x%04x\n", data->attrId);
737
739
 
738
 
        if (data)
739
 
                print_raw_data(data, 2);
740
 
        else
741
 
                printf("  NULL value\n");
 
740
        print_raw_data(data, 2);
742
741
}
743
742
 
744
743
static void print_raw_attr(sdp_record_t *rec)
753
752
 * Set attributes with single values in SDP record
754
753
 * Jean II
755
754
 */
756
 
static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value) 
 
755
static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value)
757
756
{
758
757
        sdp_list_t *attrid_list;
759
758
        uint32_t range = 0x0000ffff;
783
782
                sdp_attr_add_new(rec, attrib, SDP_UUID16, &value_uuid.value.uuid16);
784
783
        } else if (!strncasecmp(value, "0x", 2)) {
785
784
                /* Int */
786
 
                uint32_t value_int;  
 
785
                uint32_t value_int;
787
786
                value_int = strtoul(value + 2, NULL, 16);
788
787
                printf("Adding attrib 0x%X int 0x%X to record 0x%X\n",
789
788
                        attrib, value_int, handle);
811
810
        { 0, 0, 0, 0 }
812
811
};
813
812
 
814
 
static const char *set_help = 
 
813
static const char *set_help =
815
814
        "Usage:\n"
816
815
        "\tget record_handle attrib_id attrib_value\n";
817
816
 
949
948
        { 0, 0, 0, 0 }
950
949
};
951
950
 
952
 
static const char *seq_help = 
 
951
static const char *seq_help =
953
952
        "Usage:\n"
954
953
        "\tget record_handle attrib_id attrib_values\n";
955
954
 
1478
1477
        sdp_list_t *aproto, *proto[2];
1479
1478
        sdp_record_t record;
1480
1479
        uint8_t u8 = si->channel ? si->channel : 7;
1481
 
        uint16_t u16 = 0x17;
1482
 
        sdp_data_t *channel, *features;
 
1480
        sdp_data_t *channel;
1483
1481
        uint8_t netid = si->network ? si->network : 0x01; // ???? profile document
1484
1482
        sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
1485
1483
        int ret = 0;
1512
1510
        proto[1] = sdp_list_append(proto[1], channel);
1513
1511
        apseq = sdp_list_append(apseq, proto[1]);
1514
1512
 
1515
 
        features = sdp_data_alloc(SDP_UINT16, &u16);
1516
 
        sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
1517
 
 
1518
1513
        aproto = sdp_list_append(0, apseq);
1519
1514
        sdp_set_access_protos(&record, aproto);
1520
1515
 
1685
1680
        sdp_record_t record;
1686
1681
        uint8_t u8 = si->channel? si->channel : 8;
1687
1682
        uint16_t u16 = 0x31;
1688
 
        sdp_data_t *channel, *features; 
 
1683
        sdp_data_t *channel, *features;
1689
1684
        int ret = 0;
1690
1685
 
1691
1686
        memset((void *)&record, 0, sizeof(sdp_record_t));
1751
1746
        sdp_record_t record;
1752
1747
        uint8_t chan = si->channel ? si->channel : 9;
1753
1748
        sdp_data_t *channel;
1754
 
        uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
1755
 
        //uint8_t formats[] = { 0xff };
 
1749
        uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff };
1756
1750
        void *dtds[sizeof(formats)], *values[sizeof(formats)];
1757
1751
        unsigned int i;
1758
1752
        uint8_t dtd = SDP_UINT8;
1820
1814
        return ret;
1821
1815
}
1822
1816
 
 
1817
static int add_pbap(sdp_session_t *session, svc_info_t *si)
 
1818
{
 
1819
        sdp_list_t *svclass_id, *pfseq, *apseq, *root;
 
1820
        uuid_t root_uuid, pbap_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
 
1821
        sdp_profile_desc_t profile[1];
 
1822
        sdp_list_t *aproto, *proto[3];
 
1823
        sdp_record_t record;
 
1824
        uint8_t chan = si->channel ? si->channel : 19;
 
1825
        sdp_data_t *channel;
 
1826
        uint8_t formats[] = {0x01};
 
1827
        uint8_t dtd = SDP_UINT8;
 
1828
        sdp_data_t *sflist;
 
1829
        int ret = 0;
 
1830
 
 
1831
        memset(&record, 0, sizeof(sdp_record_t));
 
1832
        record.handle = si->handle;
 
1833
 
 
1834
        sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
 
1835
        root = sdp_list_append(0, &root_uuid);
 
1836
        sdp_set_browse_groups(&record, root);
 
1837
 
 
1838
        sdp_uuid16_create(&pbap_uuid, PBAP_PSE_SVCLASS_ID);
 
1839
        svclass_id = sdp_list_append(0, &pbap_uuid);
 
1840
        sdp_set_service_classes(&record, svclass_id);
 
1841
 
 
1842
        sdp_uuid16_create(&profile[0].uuid, PBAP_PROFILE_ID);
 
1843
        profile[0].version = 0x0100;
 
1844
        pfseq = sdp_list_append(0, profile);
 
1845
        sdp_set_profile_descs(&record, pfseq);
 
1846
 
 
1847
        sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
 
1848
        proto[0] = sdp_list_append(0, &l2cap_uuid);
 
1849
        apseq = sdp_list_append(0, proto[0]);
 
1850
 
 
1851
        sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
 
1852
        proto[1] = sdp_list_append(0, &rfcomm_uuid);
 
1853
        channel = sdp_data_alloc(SDP_UINT8, &chan);
 
1854
        proto[1] = sdp_list_append(proto[1], channel);
 
1855
        apseq = sdp_list_append(apseq, proto[1]);
 
1856
 
 
1857
        sdp_uuid16_create(&obex_uuid, OBEX_UUID);
 
1858
        proto[2] = sdp_list_append(0, &obex_uuid);
 
1859
        apseq = sdp_list_append(apseq, proto[2]);
 
1860
 
 
1861
        aproto = sdp_list_append(0, apseq);
 
1862
        sdp_set_access_protos(&record, aproto);
 
1863
 
 
1864
        sflist = sdp_data_alloc(dtd,formats);
 
1865
        sdp_attr_add(&record, SDP_ATTR_SUPPORTED_REPOSITORIES, sflist);
 
1866
 
 
1867
        sdp_set_info_attr(&record, "OBEX Phonebook Access Server", 0, 0);
 
1868
 
 
1869
        if (sdp_device_record_register(session, &interface, &record,
 
1870
                        SDP_RECORD_PERSIST) < 0) {
 
1871
                printf("Service Record registration failed\n");
 
1872
                ret = -1;
 
1873
                goto end;
 
1874
        }
 
1875
 
 
1876
        printf("PBAP service registered\n");
 
1877
 
 
1878
end:
 
1879
        sdp_data_free(channel);
 
1880
        sdp_list_free(proto[0], 0);
 
1881
        sdp_list_free(proto[1], 0);
 
1882
        sdp_list_free(proto[2], 0);
 
1883
        sdp_list_free(apseq, 0);
 
1884
        sdp_list_free(aproto, 0);
 
1885
 
 
1886
        return ret;
 
1887
}
 
1888
 
1823
1889
static int add_ftp(sdp_session_t *session, svc_info_t *si)
1824
1890
{
1825
1891
        sdp_list_t *svclass_id, *pfseq, *apseq, *root;
2179
2245
        static const uint16_t intr = 0x13;
2180
2246
        static const uint16_t hid_attr[] = { 0x100, 0x111, 0x40, 0x0d, 0x01, 0x01 };
2181
2247
        static const uint16_t hid_attr2[] = { 0x0, 0x01, 0x100, 0x1f40, 0x01, 0x01 };
2182
 
        const uint8_t hid_spec[] = { 
 
2248
        const uint8_t hid_spec[] = {
2183
2249
                0x05, 0x01, // usage page
2184
2250
                0x09, 0x06, // keyboard
2185
2251
                0xa1, 0x01, // key codes
2192
2258
                0x75, 0x01, // input data variable absolute
2193
2259
                0x95, 0x08, // report count
2194
2260
                0x81, 0x02, // report size
2195
 
                0x75, 0x08, 
2196
 
                0x95, 0x01, 
2197
 
                0x81, 0x01, 
2198
 
                0x75, 0x01, 
 
2261
                0x75, 0x08,
 
2262
                0x95, 0x01,
 
2263
                0x81, 0x01,
 
2264
                0x75, 0x01,
2199
2265
                0x95, 0x05,
2200
2266
                0x05, 0x08,
2201
2267
                0x19, 0x01,
2202
 
                0x29, 0x05, 
 
2268
                0x29, 0x05,
2203
2269
                0x91, 0x02,
2204
2270
                0x75, 0x03,
2205
2271
                0x95, 0x01,
3355
3421
        return 0;
3356
3422
}
3357
3423
 
 
3424
static int add_gatt(sdp_session_t *session, svc_info_t *si)
 
3425
{
 
3426
        sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto;
 
3427
        uuid_t root_uuid, proto_uuid, gatt_uuid, l2cap;
 
3428
        sdp_profile_desc_t profile;
 
3429
        sdp_record_t record;
 
3430
        sdp_data_t *psm, *sh, *eh;
 
3431
        uint16_t att_psm = 27, start = 0x0001, end = 0x000f;
 
3432
        int ret;
 
3433
 
 
3434
        memset(&record, 0, sizeof(sdp_record_t));
 
3435
        record.handle = si->handle;
 
3436
        sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
 
3437
        root = sdp_list_append(NULL, &root_uuid);
 
3438
        sdp_set_browse_groups(&record, root);
 
3439
        sdp_list_free(root, NULL);
 
3440
 
 
3441
        sdp_uuid16_create(&gatt_uuid, GENERIC_ATTRIB_SVCLASS_ID);
 
3442
        svclass_id = sdp_list_append(NULL, &gatt_uuid);
 
3443
        sdp_set_service_classes(&record, svclass_id);
 
3444
        sdp_list_free(svclass_id, NULL);
 
3445
 
 
3446
        sdp_uuid16_create(&profile.uuid, GENERIC_ATTRIB_PROFILE_ID);
 
3447
        profile.version = 0x0100;
 
3448
        profiles = sdp_list_append(NULL, &profile);
 
3449
        sdp_set_profile_descs(&record, profiles);
 
3450
        sdp_list_free(profiles, NULL);
 
3451
 
 
3452
        sdp_uuid16_create(&l2cap, L2CAP_UUID);
 
3453
        proto[0] = sdp_list_append(NULL, &l2cap);
 
3454
        psm = sdp_data_alloc(SDP_UINT16, &att_psm);
 
3455
        proto[0] = sdp_list_append(proto[0], psm);
 
3456
        apseq = sdp_list_append(NULL, proto[0]);
 
3457
 
 
3458
        sdp_uuid16_create(&proto_uuid, ATT_UUID);
 
3459
        proto[1] = sdp_list_append(NULL, &proto_uuid);
 
3460
        sh = sdp_data_alloc(SDP_UINT16, &start);
 
3461
        proto[1] = sdp_list_append(proto[1], sh);
 
3462
        eh = sdp_data_alloc(SDP_UINT16, &end);
 
3463
        proto[1] = sdp_list_append(proto[1], eh);
 
3464
        apseq = sdp_list_append(apseq, proto[1]);
 
3465
 
 
3466
        aproto = sdp_list_append(NULL, apseq);
 
3467
        sdp_set_access_protos(&record, aproto);
 
3468
 
 
3469
        sdp_set_info_attr(&record, "Generic Attribute Profile", "BlueZ", NULL);
 
3470
 
 
3471
        sdp_set_url_attr(&record, "http://www.bluez.org/",
 
3472
                        "http://www.bluez.org/", "http://www.bluez.org/");
 
3473
 
 
3474
        sdp_set_service_id(&record, gatt_uuid);
 
3475
 
 
3476
        ret = sdp_device_record_register(session, &interface, &record,
 
3477
                                                        SDP_RECORD_PERSIST);
 
3478
        if (ret < 0)
 
3479
                printf("Service Record registration failed\n");
 
3480
        else
 
3481
                printf("Generic Attribute Profile Service registered\n");
 
3482
 
 
3483
        sdp_data_free(psm);
 
3484
        sdp_data_free(sh);
 
3485
        sdp_data_free(eh);
 
3486
        sdp_list_free(proto[0], NULL);
 
3487
        sdp_list_free(proto[1], NULL);
 
3488
        sdp_list_free(apseq, NULL);
 
3489
        sdp_list_free(aproto, NULL);
 
3490
 
 
3491
        return ret;
 
3492
}
 
3493
 
3358
3494
struct {
3359
3495
        char            *name;
3360
3496
        uint32_t        class;
3376
3512
        { "HF",         HANDSFREE_SVCLASS_ID,           add_handsfree   },
3377
3513
        { "HFAG",       HANDSFREE_AGW_SVCLASS_ID,       add_handsfree_ag},
3378
3514
        { "SAP",        SAP_SVCLASS_ID,                 add_simaccess   },
3379
 
        { "PBAP",       PBAP_SVCLASS_ID,                NULL,           },
 
3515
        { "PBAP",       PBAP_SVCLASS_ID,                add_pbap,       },
3380
3516
 
3381
3517
        { "NAP",        NAP_SVCLASS_ID,                 add_nap         },
3382
3518
        { "GN",         GN_SVCLASS_ID,                  add_gn          },
3413
3549
        { "APPLE",      0,                              add_apple,      apple_uuid      },
3414
3550
 
3415
3551
        { "ISYNC",      APPLE_AGENT_SVCLASS_ID,         add_isync,      },
 
3552
        { "GATT",       GENERIC_ATTRIB_SVCLASS_ID,      add_gatt,       },
3416
3553
 
3417
3554
        { 0 }
3418
3555
};
3455
3592
        { 0, 0, 0, 0 }
3456
3593
};
3457
3594
 
3458
 
static const char *add_help = 
 
3595
static const char *add_help =
3459
3596
        "Usage:\n"
3460
3597
        "\tadd [--handle=RECORD_HANDLE --channel=CHANNEL] service\n";
3461
3598
 
3520
3657
        sdp_session_t *sess;
3521
3658
        sdp_record_t *rec;
3522
3659
 
3523
 
        if (!arg) { 
 
3660
        if (!arg) {
3524
3661
                printf("Record handle was not specified.\n");
3525
3662
                return -1;
3526
3663
        }
3559
3696
        { 0, 0, 0, 0 }
3560
3697
};
3561
3698
 
3562
 
static const char *del_help = 
 
3699
static const char *del_help =
3563
3700
        "Usage:\n"
3564
3701
        "\tdel record_handle\n";
3565
3702
 
3700
3837
        { 0, 0, 0, 0 }
3701
3838
};
3702
3839
 
3703
 
static const char *browse_help = 
 
3840
static const char *browse_help =
3704
3841
        "Usage:\n"
3705
3842
        "\tbrowse [--tree] [--raw] [--xml] [--uuid uuid] [--l2cap] [bdaddr]\n";
3706
3843
 
3766
3903
        { 0, 0, 0, 0}
3767
3904
};
3768
3905
 
3769
 
static const char *search_help = 
 
3906
static const char *search_help =
3770
3907
        "Usage:\n"
3771
3908
        "\tsearch [--bdaddr bdaddr] [--tree] [--raw] [--xml] SERVICE\n"
3772
3909
        "SERVICE is a name (string) or UUID (0x1002)\n";
3925
4062
        { 0, 0, 0, 0 }
3926
4063
};
3927
4064
 
3928
 
static const char *records_help = 
 
4065
static const char *records_help =
3929
4066
        "Usage:\n"
3930
4067
        "\trecords [--tree] [--raw] [--xml] bdaddr\n";
3931
4068
 
3995
4132
        { 0, 0, 0, 0 }
3996
4133
};
3997
4134
 
3998
 
static const char *get_help = 
 
4135
static const char *get_help =
3999
4136
        "Usage:\n"
4000
4137
        "\tget [--tree] [--raw] [--xml] [--bdaddr bdaddr] record_handle\n";
4001
4138