1*86d7f5d3SJohn Marino /* $NetBSD: session.c,v 1.2 2007/04/07 21:08:46 plunky Exp $ */
2*86d7f5d3SJohn Marino /* $DragonFly: src/lib/libsdp/session.c,v 1.1 2008/01/03 11:47:53 hasso Exp $ */
3*86d7f5d3SJohn Marino
4*86d7f5d3SJohn Marino /*-
5*86d7f5d3SJohn Marino * Copyright (c) 2006 Itronix Inc.
6*86d7f5d3SJohn Marino * All rights reserved.
7*86d7f5d3SJohn Marino *
8*86d7f5d3SJohn Marino * Written by Iain Hibbert for Itronix Inc.
9*86d7f5d3SJohn Marino *
10*86d7f5d3SJohn Marino * Redistribution and use in source and binary forms, with or without
11*86d7f5d3SJohn Marino * modification, are permitted provided that the following conditions
12*86d7f5d3SJohn Marino * are met:
13*86d7f5d3SJohn Marino * 1. Redistributions of source code must retain the above copyright
14*86d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer.
15*86d7f5d3SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
16*86d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer in the
17*86d7f5d3SJohn Marino * documentation and/or other materials provided with the distribution.
18*86d7f5d3SJohn Marino * 3. The name of Itronix Inc. may not be used to endorse
19*86d7f5d3SJohn Marino * or promote products derived from this software without specific
20*86d7f5d3SJohn Marino * prior written permission.
21*86d7f5d3SJohn Marino *
22*86d7f5d3SJohn Marino * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
23*86d7f5d3SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*86d7f5d3SJohn Marino * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25*86d7f5d3SJohn Marino * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
26*86d7f5d3SJohn Marino * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27*86d7f5d3SJohn Marino * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28*86d7f5d3SJohn Marino * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29*86d7f5d3SJohn Marino * ON ANY THEORY OF LIABILITY, WHETHER IN
30*86d7f5d3SJohn Marino * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31*86d7f5d3SJohn Marino * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32*86d7f5d3SJohn Marino * POSSIBILITY OF SUCH DAMAGE.
33*86d7f5d3SJohn Marino */
34*86d7f5d3SJohn Marino /*
35*86d7f5d3SJohn Marino * session.c
36*86d7f5d3SJohn Marino *
37*86d7f5d3SJohn Marino * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
38*86d7f5d3SJohn Marino * All rights reserved.
39*86d7f5d3SJohn Marino *
40*86d7f5d3SJohn Marino * Redistribution and use in source and binary forms, with or without
41*86d7f5d3SJohn Marino * modification, are permitted provided that the following conditions
42*86d7f5d3SJohn Marino * are met:
43*86d7f5d3SJohn Marino * 1. Redistributions of source code must retain the above copyright
44*86d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer.
45*86d7f5d3SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
46*86d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer in the
47*86d7f5d3SJohn Marino * documentation and/or other materials provided with the distribution.
48*86d7f5d3SJohn Marino *
49*86d7f5d3SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
50*86d7f5d3SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51*86d7f5d3SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52*86d7f5d3SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
53*86d7f5d3SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54*86d7f5d3SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55*86d7f5d3SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56*86d7f5d3SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57*86d7f5d3SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58*86d7f5d3SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59*86d7f5d3SJohn Marino * SUCH DAMAGE.
60*86d7f5d3SJohn Marino *
61*86d7f5d3SJohn Marino * $Id: session.c,v 1.2 2007/04/07 21:08:46 plunky Exp $
62*86d7f5d3SJohn Marino * $FreeBSD: src/lib/libsdp/session.c,v 1.3 2004/01/09 22:44:28 emax Exp $
63*86d7f5d3SJohn Marino */
64*86d7f5d3SJohn Marino
65*86d7f5d3SJohn Marino #include <sys/types.h>
66*86d7f5d3SJohn Marino #include <sys/un.h>
67*86d7f5d3SJohn Marino #include <bluetooth.h>
68*86d7f5d3SJohn Marino #include <errno.h>
69*86d7f5d3SJohn Marino #include <stdlib.h>
70*86d7f5d3SJohn Marino #include <string.h>
71*86d7f5d3SJohn Marino #include <unistd.h>
72*86d7f5d3SJohn Marino
73*86d7f5d3SJohn Marino #include <sdp-int.h>
74*86d7f5d3SJohn Marino #include <sdp.h>
75*86d7f5d3SJohn Marino
76*86d7f5d3SJohn Marino void *
sdp_open(bdaddr_t const * l,bdaddr_t const * r)77*86d7f5d3SJohn Marino sdp_open(bdaddr_t const *l, bdaddr_t const *r)
78*86d7f5d3SJohn Marino {
79*86d7f5d3SJohn Marino sdp_session_p ss = NULL;
80*86d7f5d3SJohn Marino struct sockaddr_bt sa;
81*86d7f5d3SJohn Marino struct linger li;
82*86d7f5d3SJohn Marino socklen_t size;
83*86d7f5d3SJohn Marino
84*86d7f5d3SJohn Marino if ((ss = calloc(1, sizeof(*ss))) == NULL)
85*86d7f5d3SJohn Marino goto fail;
86*86d7f5d3SJohn Marino
87*86d7f5d3SJohn Marino if (l == NULL || r == NULL) {
88*86d7f5d3SJohn Marino ss->error = EINVAL;
89*86d7f5d3SJohn Marino goto fail;
90*86d7f5d3SJohn Marino }
91*86d7f5d3SJohn Marino
92*86d7f5d3SJohn Marino ss->s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
93*86d7f5d3SJohn Marino if (ss->s < 0) {
94*86d7f5d3SJohn Marino ss->error = errno;
95*86d7f5d3SJohn Marino goto fail;
96*86d7f5d3SJohn Marino }
97*86d7f5d3SJohn Marino
98*86d7f5d3SJohn Marino memset(&li, 0, sizeof(li));
99*86d7f5d3SJohn Marino li.l_onoff = 1;
100*86d7f5d3SJohn Marino li.l_linger = 5;
101*86d7f5d3SJohn Marino if (setsockopt(ss->s, SOL_SOCKET, SO_LINGER, &li, sizeof(li)) < 0) {
102*86d7f5d3SJohn Marino ss->error = errno;
103*86d7f5d3SJohn Marino goto fail;
104*86d7f5d3SJohn Marino }
105*86d7f5d3SJohn Marino
106*86d7f5d3SJohn Marino memset(&sa, 0, sizeof(sa));
107*86d7f5d3SJohn Marino sa.bt_len = sizeof(sa);
108*86d7f5d3SJohn Marino sa.bt_family = AF_BLUETOOTH;
109*86d7f5d3SJohn Marino bdaddr_copy(&sa.bt_bdaddr, l);
110*86d7f5d3SJohn Marino if (bind(ss->s, (void *) &sa, sizeof(sa)) < 0) {
111*86d7f5d3SJohn Marino ss->error = errno;
112*86d7f5d3SJohn Marino goto fail;
113*86d7f5d3SJohn Marino }
114*86d7f5d3SJohn Marino
115*86d7f5d3SJohn Marino sa.bt_psm = L2CAP_PSM_SDP;
116*86d7f5d3SJohn Marino bdaddr_copy(&sa.bt_bdaddr, r);
117*86d7f5d3SJohn Marino if (connect(ss->s, (void *) &sa, sizeof(sa)) < 0) {
118*86d7f5d3SJohn Marino ss->error = errno;
119*86d7f5d3SJohn Marino goto fail;
120*86d7f5d3SJohn Marino }
121*86d7f5d3SJohn Marino
122*86d7f5d3SJohn Marino size = sizeof(ss->omtu);
123*86d7f5d3SJohn Marino if (getsockopt(ss->s, BTPROTO_L2CAP, SO_L2CAP_OMTU, &ss->omtu, &size) < 0) {
124*86d7f5d3SJohn Marino ss->error = errno;
125*86d7f5d3SJohn Marino goto fail;
126*86d7f5d3SJohn Marino }
127*86d7f5d3SJohn Marino if ((ss->req = malloc((size_t)ss->omtu)) == NULL) {
128*86d7f5d3SJohn Marino ss->error = ENOMEM;
129*86d7f5d3SJohn Marino goto fail;
130*86d7f5d3SJohn Marino }
131*86d7f5d3SJohn Marino ss->req_e = ss->req + ss->omtu;
132*86d7f5d3SJohn Marino
133*86d7f5d3SJohn Marino size = sizeof(ss->imtu);
134*86d7f5d3SJohn Marino if (getsockopt(ss->s, BTPROTO_L2CAP, SO_L2CAP_IMTU, &ss->imtu, &size) < 0) {
135*86d7f5d3SJohn Marino ss->error = errno;
136*86d7f5d3SJohn Marino goto fail;
137*86d7f5d3SJohn Marino }
138*86d7f5d3SJohn Marino if ((ss->rsp = malloc((size_t)ss->imtu)) == NULL) {
139*86d7f5d3SJohn Marino ss->error = ENOMEM;
140*86d7f5d3SJohn Marino goto fail;
141*86d7f5d3SJohn Marino }
142*86d7f5d3SJohn Marino ss->rsp_e = ss->rsp + ss->imtu;
143*86d7f5d3SJohn Marino ss->error = 0;
144*86d7f5d3SJohn Marino fail:
145*86d7f5d3SJohn Marino return ((void *) ss);
146*86d7f5d3SJohn Marino }
147*86d7f5d3SJohn Marino
148*86d7f5d3SJohn Marino void *
sdp_open_local(char const * control)149*86d7f5d3SJohn Marino sdp_open_local(char const *control)
150*86d7f5d3SJohn Marino {
151*86d7f5d3SJohn Marino sdp_session_p ss = NULL;
152*86d7f5d3SJohn Marino struct sockaddr_un sa;
153*86d7f5d3SJohn Marino
154*86d7f5d3SJohn Marino if ((ss = calloc(1, sizeof(*ss))) == NULL)
155*86d7f5d3SJohn Marino goto fail;
156*86d7f5d3SJohn Marino
157*86d7f5d3SJohn Marino ss->s = socket(PF_LOCAL, SOCK_STREAM, 0);
158*86d7f5d3SJohn Marino if (ss->s < 0) {
159*86d7f5d3SJohn Marino ss->error = errno;
160*86d7f5d3SJohn Marino goto fail;
161*86d7f5d3SJohn Marino }
162*86d7f5d3SJohn Marino
163*86d7f5d3SJohn Marino if (control == NULL)
164*86d7f5d3SJohn Marino control = SDP_LOCAL_PATH;
165*86d7f5d3SJohn Marino
166*86d7f5d3SJohn Marino sa.sun_len = sizeof(sa);
167*86d7f5d3SJohn Marino sa.sun_family = AF_LOCAL;
168*86d7f5d3SJohn Marino strlcpy(sa.sun_path, control, sizeof(sa.sun_path));
169*86d7f5d3SJohn Marino
170*86d7f5d3SJohn Marino if (connect(ss->s, (void *) &sa, sizeof(sa)) < 0) {
171*86d7f5d3SJohn Marino ss->error = errno;
172*86d7f5d3SJohn Marino goto fail;
173*86d7f5d3SJohn Marino }
174*86d7f5d3SJohn Marino
175*86d7f5d3SJohn Marino ss->flags |= SDP_SESSION_LOCAL;
176*86d7f5d3SJohn Marino ss->imtu = ss->omtu = SDP_LOCAL_MTU;
177*86d7f5d3SJohn Marino
178*86d7f5d3SJohn Marino if ((ss->req = malloc((size_t)ss->omtu)) == NULL) {
179*86d7f5d3SJohn Marino ss->error = ENOMEM;
180*86d7f5d3SJohn Marino goto fail;
181*86d7f5d3SJohn Marino }
182*86d7f5d3SJohn Marino ss->req_e = ss->req + ss->omtu;
183*86d7f5d3SJohn Marino
184*86d7f5d3SJohn Marino if ((ss->rsp = malloc((size_t)ss->imtu)) == NULL) {
185*86d7f5d3SJohn Marino ss->error = ENOMEM;
186*86d7f5d3SJohn Marino goto fail;
187*86d7f5d3SJohn Marino }
188*86d7f5d3SJohn Marino ss->rsp_e = ss->rsp + ss->imtu;
189*86d7f5d3SJohn Marino ss->error = 0;
190*86d7f5d3SJohn Marino fail:
191*86d7f5d3SJohn Marino return ((void *) ss);
192*86d7f5d3SJohn Marino }
193*86d7f5d3SJohn Marino
194*86d7f5d3SJohn Marino int32_t
sdp_close(void * xss)195*86d7f5d3SJohn Marino sdp_close(void *xss)
196*86d7f5d3SJohn Marino {
197*86d7f5d3SJohn Marino sdp_session_p ss = (sdp_session_p) xss;
198*86d7f5d3SJohn Marino
199*86d7f5d3SJohn Marino if (ss != NULL) {
200*86d7f5d3SJohn Marino if (ss->s >= 0)
201*86d7f5d3SJohn Marino close(ss->s);
202*86d7f5d3SJohn Marino
203*86d7f5d3SJohn Marino if (ss->req != NULL)
204*86d7f5d3SJohn Marino free(ss->req);
205*86d7f5d3SJohn Marino if (ss->rsp != NULL)
206*86d7f5d3SJohn Marino free(ss->rsp);
207*86d7f5d3SJohn Marino
208*86d7f5d3SJohn Marino memset(ss, 0, sizeof(*ss));
209*86d7f5d3SJohn Marino free(ss);
210*86d7f5d3SJohn Marino }
211*86d7f5d3SJohn Marino
212*86d7f5d3SJohn Marino return (0);
213*86d7f5d3SJohn Marino }
214*86d7f5d3SJohn Marino
215*86d7f5d3SJohn Marino int32_t
sdp_error(void * xss)216*86d7f5d3SJohn Marino sdp_error(void *xss)
217*86d7f5d3SJohn Marino {
218*86d7f5d3SJohn Marino sdp_session_p ss = (sdp_session_p) xss;
219*86d7f5d3SJohn Marino
220*86d7f5d3SJohn Marino return ((ss != NULL)? ss->error : EINVAL);
221*86d7f5d3SJohn Marino }
222