1/*
2 *
3 *  BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2003-2010  Marcel Holtmann <marcel@holtmann.org>
6 *
7 *
8 *  This program is free software; you can redistribute it and/or modify
9 *  it under the terms of the GNU General Public License as published by
10 *  the Free Software Foundation; either version 2 of the License, or
11 *  (at your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *  GNU General Public License for more details.
17 *
18 *  You should have received a copy of the GNU General Public License
19 *  along with this program; if not, write to the Free Software
20 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include <stdio.h>
29#include <errno.h>
30#include <unistd.h>
31#include <signal.h>
32#include <sys/socket.h>
33
34#include <bluetooth/bluetooth.h>
35#include <bluetooth/sdp.h>
36#include <bluetooth/sdp_lib.h>
37
38#include "cups.h"
39
40int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm)
41{
42	sdp_list_t *srch, *attrs, *rsp;
43	uuid_t svclass;
44	uint16_t attr1, attr2;
45	int err;
46
47	if (!sdp)
48		return -1;
49
50	sdp_uuid16_create(&svclass, HCR_PRINT_SVCLASS_ID);
51	srch = sdp_list_append(NULL, &svclass);
52
53	attr1 = SDP_ATTR_PROTO_DESC_LIST;
54	attrs = sdp_list_append(NULL, &attr1);
55	attr2 = SDP_ATTR_ADD_PROTO_DESC_LIST;
56	attrs = sdp_list_append(attrs, &attr2);
57
58	err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
59	if (err)
60		return -1;
61
62	for (; rsp; rsp = rsp->next) {
63		sdp_record_t *rec = (sdp_record_t *) rsp->data;
64		sdp_list_t *protos;
65
66		if (!sdp_get_access_protos(rec, &protos)) {
67			unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID);
68			if (psm > 0) {
69				*ctrl_psm = psm;
70			}
71		}
72
73		if (!sdp_get_add_access_protos(rec, &protos)) {
74			unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID);
75			if (psm > 0 && *ctrl_psm > 0) {
76				*data_psm = psm;
77				return 0;
78			}
79		}
80	}
81
82	return -1;
83}
84
85int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel)
86{
87	sdp_list_t *srch, *attrs, *rsp;
88	uuid_t svclass;
89	uint16_t attr;
90	int err;
91
92	if (!sdp)
93		return -1;
94
95	sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID);
96	srch = sdp_list_append(NULL, &svclass);
97
98	attr = SDP_ATTR_PROTO_DESC_LIST;
99	attrs = sdp_list_append(NULL, &attr);
100
101	err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
102	if (err)
103		return -1;
104
105	for (; rsp; rsp = rsp->next) {
106		sdp_record_t *rec = (sdp_record_t *) rsp->data;
107		sdp_list_t *protos;
108
109		if (!sdp_get_access_protos(rec, &protos)) {
110			uint8_t ch = sdp_get_proto_port(protos, RFCOMM_UUID);
111			if (ch > 0) {
112				*channel = ch;
113				return 0;
114			}
115		}
116	}
117
118	return -1;
119}
120