xref: /dflybsd-src/lib/libsdp/session.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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