summaryrefslogtreecommitdiffstats
path: root/cups/sdp.c
diff options
context:
space:
mode:
Diffstat (limited to 'cups/sdp.c')
-rw-r--r--cups/sdp.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/cups/sdp.c b/cups/sdp.c
new file mode 100644
index 00000000..7491ab1f
--- /dev/null
+++ b/cups/sdp.c
@@ -0,0 +1,155 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+ * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ * SOFTWARE IS DISCLAIMED.
+ *
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#define HCRP_CTRL_UUID 0x0012
+#define HCRP_DATA_UUID 0x0014
+
+#define HCR_PROFILE_ID 0x1125
+#define HCR_PRINT_SVCLASS_ID 0x1126
+
+#define SDP_ATTR_ADD_PROTO_DESC_LIST 0x000d
+
+static int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
+{
+ sdp_data_t *pdlist, *curr;
+ sdp_list_t *ap = 0;
+
+ pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
+ if (pdlist == NULL) {
+ errno = ENODATA;
+ return -1;
+ }
+
+ pdlist = pdlist->val.dataseq;
+
+ for (; pdlist; pdlist = pdlist->next) {
+ sdp_list_t *pds = 0;
+ for (curr = pdlist->val.dataseq; curr; curr = curr->next)
+ pds = sdp_list_append(pds, curr->val.dataseq);
+ ap = sdp_list_append(ap, pds);
+ }
+
+ *pap = ap;
+
+ return 0;
+}
+
+int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm)
+{
+ sdp_list_t *srch, *attrs, *rsp;
+ uuid_t svclass;
+ uint16_t attr1, attr2;
+ int err;
+
+ if (!sdp)
+ return -1;
+
+ sdp_uuid16_create(&svclass, HCR_PRINT_SVCLASS_ID);
+ srch = sdp_list_append(NULL, &svclass);
+
+ attr1 = SDP_ATTR_PROTO_DESC_LIST;
+ attrs = sdp_list_append(NULL, &attr1);
+ attr2 = SDP_ATTR_ADD_PROTO_DESC_LIST;
+ attrs = sdp_list_append(attrs, &attr2);
+
+ err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
+ if (err)
+ return -1;
+
+ for (; rsp; rsp = rsp->next) {
+ sdp_record_t *rec = (sdp_record_t *) rsp->data;
+ sdp_list_t *protos;
+
+ if (!sdp_get_access_protos(rec, &protos)) {
+ unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID);
+ if (psm > 0) {
+ *ctrl_psm = psm;
+ }
+ }
+
+ if (!sdp_get_add_access_protos(rec, &protos)) {
+ unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID);
+ if (psm > 0 && *ctrl_psm > 0) {
+ *data_psm = psm;
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
+int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel)
+{
+ sdp_list_t *srch, *attrs, *rsp;
+ uuid_t svclass;
+ uint16_t attr;
+ int err;
+
+ if (!sdp)
+ return -1;
+
+ sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID);
+ srch = sdp_list_append(NULL, &svclass);
+
+ attr = SDP_ATTR_PROTO_DESC_LIST;
+ attrs = sdp_list_append(NULL, &attr);
+
+ err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
+ if (err)
+ return -1;
+
+ for (; rsp; rsp = rsp->next) {
+ sdp_record_t *rec = (sdp_record_t *) rsp->data;
+ sdp_list_t *protos;
+
+ if (!sdp_get_access_protos(rec, &protos)) {
+ uint8_t ch = sdp_get_proto_port(protos, RFCOMM_UUID);
+ if (ch > 0) {
+ *channel = ch;
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}