1 /* $NetBSD: service.c,v 1.1 2006/06/19 15:44:36 gdamore Exp $ */
2 /* $DragonFly: src/lib/libsdp/service.c,v 1.1 2008/01/03 11:47:53 hasso Exp $ */
5 * Copyright (c) 2006 Itronix Inc.
8 * Written by Iain Hibbert for Itronix Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of Itronix Inc. may not be used to endorse
19 * or promote products derived from this software without specific
20 * prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 * ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
37 * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
38 * All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
49 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * $Id: service.c,v 1.1 2006/06/19 15:44:36 gdamore Exp $
62 * $FreeBSD: src/lib/libsdp/service.c,v 1.1 2004/01/20 20:48:25 emax Exp $
66 #include <netinet/in.h>
67 #include <arpa/inet.h>
68 #include <bluetooth.h>
76 static int32_t sdp_receive_error_pdu(sdp_session_p ss
);
79 sdp_register_service(void *xss
, uint16_t uuid
, bdaddr_t
*bdaddr
,
80 uint8_t *data
, uint32_t datalen
, uint32_t *handle
)
82 sdp_session_p ss
= (sdp_session_p
) xss
;
89 if (bdaddr
== NULL
|| data
== NULL
||
90 datalen
== 0 || !(ss
->flags
& SDP_SESSION_LOCAL
)) {
94 if (sizeof(pdu
)+sizeof(uuid
)+sizeof(*bdaddr
)+datalen
> SDP_LOCAL_MTU
) {
99 pdu
.pid
= SDP_PDU_SERVICE_REGISTER_REQUEST
;
100 pdu
.tid
= htons(++ss
->tid
);
101 pdu
.len
= htons(sizeof(uuid
) + sizeof(*bdaddr
) + datalen
);
105 iov
[0].iov_base
= (void *) &pdu
;
106 iov
[0].iov_len
= sizeof(pdu
);
108 iov
[1].iov_base
= (void *) &uuid
;
109 iov
[1].iov_len
= sizeof(uuid
);
111 iov
[2].iov_base
= (void *) bdaddr
;
112 iov
[2].iov_len
= sizeof(*bdaddr
);
114 iov
[3].iov_base
= (void *) data
;
115 iov
[3].iov_len
= datalen
;
118 len
= writev(ss
->s
, iov
, sizeof(iov
)/sizeof(iov
[0]));
119 } while (len
< 0 && errno
== EINTR
);
126 len
= sdp_receive_error_pdu(ss
);
129 if (len
!= sizeof(pdu
) + sizeof(uint16_t) + sizeof(uint32_t)) {
134 if (handle
!= NULL
) {
135 *handle
= (uint32_t) ss
->rsp
[--len
];
136 *handle
|= (uint32_t) ss
->rsp
[--len
] << 8;
137 *handle
|= (uint32_t) ss
->rsp
[--len
] << 16;
138 *handle
|= (uint32_t) ss
->rsp
[--len
] << 24;
145 sdp_unregister_service(void *xss
, uint32_t handle
)
147 sdp_session_p ss
= (sdp_session_p
) xss
;
154 if (!(ss
->flags
& SDP_SESSION_LOCAL
)) {
159 if (sizeof(pdu
) + sizeof(handle
) > SDP_LOCAL_MTU
) {
160 ss
->error
= EMSGSIZE
;
165 pdu
.pid
= SDP_PDU_SERVICE_UNREGISTER_REQUEST
;
166 pdu
.tid
= htons(++ss
->tid
);
167 pdu
.len
= htons(sizeof(handle
));
169 handle
= htonl(handle
);
171 iov
[0].iov_base
= (void *) &pdu
;
172 iov
[0].iov_len
= sizeof(pdu
);
174 iov
[1].iov_base
= (void *) &handle
;
175 iov
[1].iov_len
= sizeof(handle
);
178 len
= writev(ss
->s
, iov
, sizeof(iov
)/sizeof(iov
[0]));
179 } while (len
< 0 && errno
== EINTR
);
186 return ((sdp_receive_error_pdu(ss
) < 0)? -1 : 0);
190 sdp_change_service(void *xss
, uint32_t handle
,
191 uint8_t *data
, uint32_t datalen
)
193 sdp_session_p ss
= (sdp_session_p
) xss
;
200 if (data
== NULL
|| datalen
== 0 || !(ss
->flags
& SDP_SESSION_LOCAL
)) {
204 if (sizeof(pdu
) + sizeof(handle
) + datalen
> SDP_LOCAL_MTU
) {
205 ss
->error
= EMSGSIZE
;
209 pdu
.pid
= SDP_PDU_SERVICE_CHANGE_REQUEST
;
210 pdu
.tid
= htons(++ss
->tid
);
211 pdu
.len
= htons(sizeof(handle
) + datalen
);
213 handle
= htons(handle
);
215 iov
[0].iov_base
= (void *) &pdu
;
216 iov
[0].iov_len
= sizeof(pdu
);
218 iov
[1].iov_base
= (void *) &handle
;
219 iov
[1].iov_len
= sizeof(handle
);
221 iov
[2].iov_base
= (void *) data
;
222 iov
[2].iov_len
= datalen
;
225 len
= writev(ss
->s
, iov
, sizeof(iov
)/sizeof(iov
[0]));
226 } while (len
< 0 && errno
== EINTR
);
233 return ((sdp_receive_error_pdu(ss
) < 0)? -1 : 0);
237 sdp_receive_error_pdu(sdp_session_p ss
)
244 len
= read(ss
->s
, ss
->rsp
, (size_t)(ss
->rsp_e
- ss
->rsp
));
245 } while (len
< 0 && errno
== EINTR
);
252 memcpy(&pdu
, ss
->rsp
, sizeof(pdu
));
253 pdu
.tid
= ntohs(pdu
.tid
);
254 pdu
.len
= ntohs(pdu
.len
);
255 memcpy(ss
->rsp
, &pdu
, sizeof(pdu
));
257 if (pdu
.pid
!= SDP_PDU_ERROR_RESPONSE
|| pdu
.tid
!= ss
->tid
||
258 pdu
.len
< 2 || pdu
.len
!= len
- sizeof(pdu
)) {
263 error
= (uint16_t) ss
->rsp
[sizeof(pdu
)] << 8;
264 error
|= (uint16_t) ss
->rsp
[sizeof(pdu
) + 1];