1*dfbf818aSplunky /* $NetBSD: sdp_record.c,v 1.1 2009/05/12 10:05:06 plunky Exp $ */
2*dfbf818aSplunky
3*dfbf818aSplunky /*-
4*dfbf818aSplunky * Copyright (c) 2009 The NetBSD Foundation, Inc.
5*dfbf818aSplunky * All rights reserved.
6*dfbf818aSplunky *
7*dfbf818aSplunky * This code is derived from software contributed to The NetBSD Foundation
8*dfbf818aSplunky * by Iain Hibbert.
9*dfbf818aSplunky *
10*dfbf818aSplunky * Redistribution and use in source and binary forms, with or without
11*dfbf818aSplunky * modification, are permitted provided that the following conditions
12*dfbf818aSplunky * are met:
13*dfbf818aSplunky * 1. Redistributions of source code must retain the above copyright
14*dfbf818aSplunky * notice, this list of conditions and the following disclaimer.
15*dfbf818aSplunky * 2. Redistributions in binary form must reproduce the above copyright
16*dfbf818aSplunky * notice, this list of conditions and the following disclaimer in the
17*dfbf818aSplunky * documentation and/or other materials provided with the distribution.
18*dfbf818aSplunky *
19*dfbf818aSplunky * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*dfbf818aSplunky * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*dfbf818aSplunky * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*dfbf818aSplunky * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*dfbf818aSplunky * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*dfbf818aSplunky * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*dfbf818aSplunky * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*dfbf818aSplunky * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*dfbf818aSplunky * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*dfbf818aSplunky * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*dfbf818aSplunky * POSSIBILITY OF SUCH DAMAGE.
30*dfbf818aSplunky */
31*dfbf818aSplunky
32*dfbf818aSplunky #include <sys/cdefs.h>
33*dfbf818aSplunky __RCSID("$NetBSD: sdp_record.c,v 1.1 2009/05/12 10:05:06 plunky Exp $");
34*dfbf818aSplunky
35*dfbf818aSplunky #include <errno.h>
36*dfbf818aSplunky #include <sdp.h>
37*dfbf818aSplunky #include <stdlib.h>
38*dfbf818aSplunky #include <string.h>
39*dfbf818aSplunky #include <unistd.h>
40*dfbf818aSplunky
41*dfbf818aSplunky #include "sdp-int.h"
42*dfbf818aSplunky
43*dfbf818aSplunky /*
44*dfbf818aSplunky * This is the interface to sdpd(8); These PDU IDs are NOT part
45*dfbf818aSplunky * of the Bluetooth specification.
46*dfbf818aSplunky */
47*dfbf818aSplunky
48*dfbf818aSplunky bool
sdp_record_insert(struct sdp_session * ss,bdaddr_t * bdaddr,uint32_t * handle,const sdp_data_t * rec)49*dfbf818aSplunky sdp_record_insert(struct sdp_session *ss, bdaddr_t *bdaddr,
50*dfbf818aSplunky uint32_t *handle, const sdp_data_t *rec)
51*dfbf818aSplunky {
52*dfbf818aSplunky struct iovec req[4];
53*dfbf818aSplunky sdp_data_t hdr;
54*dfbf818aSplunky uint8_t data[5];
55*dfbf818aSplunky ssize_t len;
56*dfbf818aSplunky bdaddr_t ba;
57*dfbf818aSplunky uint16_t ec;
58*dfbf818aSplunky
59*dfbf818aSplunky /*
60*dfbf818aSplunky * setup BluetoothDeviceAddress
61*dfbf818aSplunky */
62*dfbf818aSplunky bdaddr_copy(&ba, (bdaddr == NULL) ? BDADDR_ANY : bdaddr);
63*dfbf818aSplunky req[1].iov_base = &ba;
64*dfbf818aSplunky req[1].iov_len = sizeof(bdaddr_t);
65*dfbf818aSplunky
66*dfbf818aSplunky /*
67*dfbf818aSplunky * setup ServiceRecord
68*dfbf818aSplunky */
69*dfbf818aSplunky len = rec->end - rec->next;
70*dfbf818aSplunky if (len < 0 || len > UINT16_MAX) {
71*dfbf818aSplunky errno = EINVAL;
72*dfbf818aSplunky return false;
73*dfbf818aSplunky }
74*dfbf818aSplunky
75*dfbf818aSplunky hdr.next = data;
76*dfbf818aSplunky hdr.end = data + sizeof(data) + len;
77*dfbf818aSplunky sdp_put_seq(&hdr, len);
78*dfbf818aSplunky req[2].iov_base = data;
79*dfbf818aSplunky req[2].iov_len = hdr.next - data;
80*dfbf818aSplunky
81*dfbf818aSplunky req[3].iov_base = rec->next;
82*dfbf818aSplunky req[3].iov_len = len;
83*dfbf818aSplunky
84*dfbf818aSplunky /*
85*dfbf818aSplunky * InsertRecord Transaction
86*dfbf818aSplunky */
87*dfbf818aSplunky if (!_sdp_send_pdu(ss, SDP_PDU_RECORD_INSERT_REQUEST,
88*dfbf818aSplunky req, __arraycount(req)))
89*dfbf818aSplunky return false;
90*dfbf818aSplunky
91*dfbf818aSplunky len = _sdp_recv_pdu(ss, SDP_PDU_ERROR_RESPONSE);
92*dfbf818aSplunky if (len == -1)
93*dfbf818aSplunky return false;
94*dfbf818aSplunky
95*dfbf818aSplunky if (len != sizeof(uint16_t) + sizeof(uint32_t)) {
96*dfbf818aSplunky errno = EIO;
97*dfbf818aSplunky return false;
98*dfbf818aSplunky }
99*dfbf818aSplunky
100*dfbf818aSplunky /*
101*dfbf818aSplunky * extract and check ErrorCode (success == 0)
102*dfbf818aSplunky */
103*dfbf818aSplunky ec = be16dec(ss->ibuf);
104*dfbf818aSplunky if (ec != 0) {
105*dfbf818aSplunky errno = _sdp_errno(ec);
106*dfbf818aSplunky return false;
107*dfbf818aSplunky }
108*dfbf818aSplunky
109*dfbf818aSplunky /*
110*dfbf818aSplunky * extract ServiceRecordHandle if required
111*dfbf818aSplunky */
112*dfbf818aSplunky if (handle != NULL)
113*dfbf818aSplunky *handle = be32dec(ss->ibuf + sizeof(uint16_t));
114*dfbf818aSplunky
115*dfbf818aSplunky return true;
116*dfbf818aSplunky }
117*dfbf818aSplunky
118*dfbf818aSplunky bool
sdp_record_update(struct sdp_session * ss,uint32_t handle,const sdp_data_t * rec)119*dfbf818aSplunky sdp_record_update(struct sdp_session *ss, uint32_t handle,
120*dfbf818aSplunky const sdp_data_t *rec)
121*dfbf818aSplunky {
122*dfbf818aSplunky struct iovec req[4];
123*dfbf818aSplunky sdp_data_t hdr;
124*dfbf818aSplunky uint8_t data[5];
125*dfbf818aSplunky ssize_t len;
126*dfbf818aSplunky uint16_t ec;
127*dfbf818aSplunky
128*dfbf818aSplunky /*
129*dfbf818aSplunky * setup ServiceRecordHandle
130*dfbf818aSplunky */
131*dfbf818aSplunky handle = htobe32(handle);
132*dfbf818aSplunky req[1].iov_base = &handle;
133*dfbf818aSplunky req[1].iov_len = sizeof(handle);
134*dfbf818aSplunky
135*dfbf818aSplunky /*
136*dfbf818aSplunky * setup ServiceRecord
137*dfbf818aSplunky */
138*dfbf818aSplunky len = rec->end - rec->next;
139*dfbf818aSplunky if (len < 0 || len > UINT16_MAX) {
140*dfbf818aSplunky errno = EINVAL;
141*dfbf818aSplunky return false;
142*dfbf818aSplunky }
143*dfbf818aSplunky
144*dfbf818aSplunky hdr.next = data;
145*dfbf818aSplunky hdr.end = data + sizeof(data) + len;
146*dfbf818aSplunky sdp_put_seq(&hdr, len);
147*dfbf818aSplunky req[2].iov_base = data;
148*dfbf818aSplunky req[2].iov_len = hdr.next - data;
149*dfbf818aSplunky
150*dfbf818aSplunky req[3].iov_base = rec->next;
151*dfbf818aSplunky req[3].iov_len = len;
152*dfbf818aSplunky
153*dfbf818aSplunky /*
154*dfbf818aSplunky * UpdateRecord Transaction
155*dfbf818aSplunky */
156*dfbf818aSplunky if (!_sdp_send_pdu(ss, SDP_PDU_RECORD_UPDATE_REQUEST,
157*dfbf818aSplunky req, __arraycount(req)))
158*dfbf818aSplunky return false;
159*dfbf818aSplunky
160*dfbf818aSplunky len = _sdp_recv_pdu(ss, SDP_PDU_ERROR_RESPONSE);
161*dfbf818aSplunky if (len == -1)
162*dfbf818aSplunky return false;
163*dfbf818aSplunky
164*dfbf818aSplunky if (len != sizeof(uint16_t)) {
165*dfbf818aSplunky errno = EIO;
166*dfbf818aSplunky return false;
167*dfbf818aSplunky }
168*dfbf818aSplunky
169*dfbf818aSplunky /*
170*dfbf818aSplunky * extract and check ErrorCode (success == 0)
171*dfbf818aSplunky */
172*dfbf818aSplunky if ((ec = be16dec(ss->ibuf)) != 0) {
173*dfbf818aSplunky errno = _sdp_errno(ec);
174*dfbf818aSplunky return false;
175*dfbf818aSplunky }
176*dfbf818aSplunky
177*dfbf818aSplunky return true;
178*dfbf818aSplunky }
179*dfbf818aSplunky
180*dfbf818aSplunky bool
sdp_record_remove(struct sdp_session * ss,uint32_t handle)181*dfbf818aSplunky sdp_record_remove(struct sdp_session *ss, uint32_t handle)
182*dfbf818aSplunky {
183*dfbf818aSplunky struct iovec req[2];
184*dfbf818aSplunky ssize_t len;
185*dfbf818aSplunky uint16_t ec;
186*dfbf818aSplunky
187*dfbf818aSplunky /*
188*dfbf818aSplunky * setup ServiceRecordHandle
189*dfbf818aSplunky */
190*dfbf818aSplunky handle = htobe32(handle);
191*dfbf818aSplunky req[1].iov_base = &handle;
192*dfbf818aSplunky req[1].iov_len = sizeof(handle);
193*dfbf818aSplunky
194*dfbf818aSplunky /*
195*dfbf818aSplunky * RemoveRecord Transaction
196*dfbf818aSplunky */
197*dfbf818aSplunky if (!_sdp_send_pdu(ss, SDP_PDU_RECORD_REMOVE_REQUEST,
198*dfbf818aSplunky req, __arraycount(req)))
199*dfbf818aSplunky return false;
200*dfbf818aSplunky
201*dfbf818aSplunky len = _sdp_recv_pdu(ss, SDP_PDU_ERROR_RESPONSE);
202*dfbf818aSplunky if (len == -1)
203*dfbf818aSplunky return false;
204*dfbf818aSplunky
205*dfbf818aSplunky if (len != sizeof(uint16_t)) {
206*dfbf818aSplunky errno = EIO;
207*dfbf818aSplunky return false;
208*dfbf818aSplunky }
209*dfbf818aSplunky
210*dfbf818aSplunky /*
211*dfbf818aSplunky * extract and check ErrorCode (success == 0)
212*dfbf818aSplunky */
213*dfbf818aSplunky ec = be16dec(ss->ibuf);
214*dfbf818aSplunky if (ec != 0) {
215*dfbf818aSplunky errno = _sdp_errno(ec);
216*dfbf818aSplunky return false;
217*dfbf818aSplunky }
218*dfbf818aSplunky
219*dfbf818aSplunky return true;
220*dfbf818aSplunky }
221