From c787259b854f12bd827d1e05ccde53d748d22b30 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 20:37:21 +0000 Subject: Add sdpd server daemon --- sdpd/Makefile.am | 9 + sdpd/cstate.c | 96 +++++++ sdpd/main.c | 471 ++++++++++++++++++++++++++++++ sdpd/request.c | 849 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ sdpd/sdpd.h | 75 +++++ sdpd/service.c | 241 ++++++++++++++++ sdpd/servicedb.c | 209 ++++++++++++++ 7 files changed, 1950 insertions(+) create mode 100644 sdpd/Makefile.am create mode 100644 sdpd/cstate.c create mode 100644 sdpd/main.c create mode 100644 sdpd/request.c create mode 100644 sdpd/sdpd.h create mode 100644 sdpd/service.c create mode 100644 sdpd/servicedb.c (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am new file mode 100644 index 00000000..9536bf04 --- /dev/null +++ b/sdpd/Makefile.am @@ -0,0 +1,9 @@ +# +# $Id$ +# + +mandir = $(prefix)/usr/share/man + +sbin_PROGRAMS = sdpd + +sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h diff --git a/sdpd/cstate.c b/sdpd/cstate.c new file mode 100644 index 00000000..e9b51832 --- /dev/null +++ b/sdpd/cstate.c @@ -0,0 +1,96 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + 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. +*/ + +/* + Fixes: + Guruprasad Krishnamurthy +*/ + +/* + * $Id$ + */ + +#include +#include + +#include +#include +#include + +#include "sdpd.h" + +typedef struct _sdp_cstate_list sdp_cstate_list_t; + +struct _sdp_cstate_list { + sdp_cstate_list_t *next; + long timestamp; + sdp_buf_t buf; +}; + +static sdp_cstate_list_t *cstates; + +// FIXME: should probably remove it when it's found +sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) +{ + sdp_cstate_list_t *p; + + for (p = cstates; p; p = p->next) + if (p->timestamp == cstate->timestamp) + return &p->buf; + return 0; +} + +long sdp_cstate_alloc_buf(sdp_buf_t *buf) +{ + sdp_cstate_list_t *cstate = (sdp_cstate_list_t *)malloc(sizeof(sdp_cstate_list_t)); + char *data = (char *)malloc(buf->data_size); + + memcpy(data, buf->data, buf->data_size); + memset((char *)cstate, 0, sizeof(sdp_cstate_list_t)); + cstate->buf.data = data; + cstate->buf.data_size = buf->data_size; + cstate->buf.buf_size = buf->data_size; + cstate->timestamp = sdp_get_time(); + cstate->next = cstates; + cstates = cstate; + return cstate->timestamp; +} + +/* + * A simple function which returns the time of day in + * seconds. Used for updating the service db state + * attribute of the service record of the SDP server + */ +long sdp_get_time() +{ + /* + * To handle failure in gettimeofday, so an old + * value is returned and service does not fail + */ + static struct timeval tm; + + gettimeofday(&tm, NULL); + return tm.tv_sec; +} diff --git a/sdpd/main.c b/sdpd/main.c new file mode 100644 index 00000000..fea283f2 --- /dev/null +++ b/sdpd/main.c @@ -0,0 +1,471 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + 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. +*/ + +/* + SDP server initialization and connection handling + + Fixes: + Guruprasad Krishnamurthy + Imre Deak +*/ + +/* + * $Id$ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sdpd.h" + +static int l2cap_sock, unix_sock; +static fd_set active_fdset; +static int active_maxfd; + +sdp_record_t *server; + +/* + * List of version numbers supported by the SDP server. + * Add to this list when newer versions are supported. + */ +static sdp_version_t sdpVnumArray[1] = { + {1, 0} +}; +const int sdpServerVnumEntries = 1; + +/* + * The service database state is an attribute of the service record + * of the SDP server itself. This attribute is guaranteed to + * change if any of the contents of the service repository + * changes. This function updates the timestamp of value of + * the svcDBState attribute + * Set the SDP server DB. Simply a timestamp which is the marker + * when the DB was modified. + */ +void update_db_timestamp(void) +{ + uint32_t dbts = sdp_get_time(); + sdp_data_t *d = sdp_data_alloc(SDP_UINT32, &dbts); + sdp_attr_replace(server, SDP_ATTR_SVCDB_STATE, d); +} + +static void add_lang_attr(sdp_record_t *r) +{ + sdp_lang_attr_t base_lang; + sdp_list_t *langs = 0; + + base_lang.code_ISO639 = (0x65 << 8) | 0x6e; + // UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) + base_lang.encoding = 106; + base_lang.base_offset = SDP_PRIMARY_LANG_BASE; + langs = sdp_list_append(0, &base_lang); + sdp_set_lang_attr(r, langs); + sdp_list_free(langs, 0); +} + +static void register_public_browse_group(void) +{ + sdp_list_t *browselist; + uuid_t bgscid, pbgid; + sdp_data_t *sdpdata; + sdp_record_t *browse = sdp_record_alloc(); + + browse->handle = (uint32_t)browse; + sdp_record_add(browse); + sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); + sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); + + add_lang_attr(browse); + sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", "Root of public browse hierarchy"); + + sdp_uuid16_create(&bgscid, BROWSE_GRP_DESC_SVCLASS_ID); + browselist = sdp_list_append(0, &bgscid); + sdp_set_service_classes(browse, browselist); + sdp_list_free(browselist, 0); + + sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); + sdp_set_group_id(browse, pbgid); +} + +/* + * The SDP server must present its own service record to + * the service repository. This can be accessed by service + * discovery clients. This method constructs a service record + * and stores it in the repository + */ +static void register_server_service(void) +{ + int i; + sdp_list_t *classIDList, *browseList; + sdp_list_t *access_proto = 0; + uuid_t l2cap, classID, browseGroupId, sdpSrvUUID; + void **versions, **versionDTDs; + uint8_t dtd; + uint16_t version, port; + sdp_data_t *pData, *port_data, *version_data; + sdp_list_t *pd, *seq; + + server = sdp_record_alloc(); + server->pattern = NULL; + + /* Force the record to be SDP_SERVER_RECORD_HANDLE */ + server->handle = SDP_SERVER_RECORD_HANDLE; + + sdp_record_add(server); + sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); + + /* + * Add all attributes to service record. (No need to commit since we + * are the server and this record is already in the database.) + */ + add_lang_attr(server); + sdp_set_info_attr(server, "SDP Server", "BlueZ", "Bluetooth service discovery server"); + + sdp_uuid16_create(&classID, SDP_SERVER_SVCLASS_ID); + classIDList = sdp_list_append(0, &classID); + sdp_set_service_classes(server, classIDList); + sdp_list_free(classIDList, 0); + + /* + * Set the version numbers supported, these are passed as arguments + * to the server on command line. Now defaults to 1.0 + * Build the version number sequence first + */ + versions = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); + versionDTDs = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); + dtd = SDP_UINT16; + for (i = 0; i < sdpServerVnumEntries; i++) { + uint16_t *version = (uint16_t *)malloc(sizeof(uint16_t)); + *version = sdpVnumArray[i].major; + *version = (*version << 8); + *version |= sdpVnumArray[i].minor; + versions[i] = version; + versionDTDs[i] = &dtd; + } + pData = sdp_seq_alloc(versionDTDs, versions, sdpServerVnumEntries); + for (i = 0; i < sdpServerVnumEntries; i++) + free(versions[i]); + free(versions); + free(versionDTDs); + sdp_attr_add(server, SDP_ATTR_VERSION_NUM_LIST, pData); + + sdp_uuid16_create(&sdpSrvUUID, SDP_UUID); + sdp_set_service_id(server, sdpSrvUUID); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + pd = sdp_list_append(0, &l2cap); + port = SDP_PSM; + port_data = sdp_data_alloc(SDP_UINT16, &port); + pd = sdp_list_append(pd, port_data); + version = 1; + version_data = sdp_data_alloc(SDP_UINT16, &version); + pd = sdp_list_append(pd, version_data); + seq = sdp_list_append(0, pd); + + access_proto = sdp_list_append(0, seq); + sdp_set_access_protos(server, access_proto); + sdp_list_free(access_proto, free); + sdp_data_free(port_data); + sdp_data_free(version_data); + sdp_list_free(pd, 0); + + sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); + browseList = sdp_list_append(0, &browseGroupId); + sdp_set_browse_groups(server, browseList); + sdp_list_free(browseList, 0); + + update_db_timestamp(); +} + +/* + * SDP server initialization on startup includes creating the + * l2cap and unix sockets over which discovery and registration clients + * access us respectively + */ +int init_server(int master) +{ + struct sockaddr_l2 l2addr; + struct sockaddr_un unaddr; + + /* Register the public browse group root */ + register_public_browse_group(); + + /* Register the SDP server's service record */ + register_server_service(); + + /* Create L2CAP socket */ + l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (l2cap_sock == -1) { + SDPERR("opening L2CAP socket: %s", strerror(errno)); + return -1; + } + + l2addr.l2_bdaddr = *BDADDR_ANY; + l2addr.l2_family = AF_BLUETOOTH; + l2addr.l2_psm = htobs(SDP_PSM); + if (0 > bind(l2cap_sock, (struct sockaddr *)&l2addr, sizeof(l2addr))) { + SDPERR("binding L2CAP socket: %s", strerror(errno)); + return -1; + } + + if (master) { + int opt = L2CAP_LM_MASTER; + if (0 > setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt))) { + SDPERR("setsockopt: %s", strerror(errno)); + return -1; + } + } + listen(l2cap_sock, 5); + FD_SET(l2cap_sock, &active_fdset); + active_maxfd = l2cap_sock; + + /* Create local Unix socket */ + unix_sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (unix_sock == -1) { + SDPERR("opening UNIX socket: %s", strerror(errno)); + return -1; + } + unaddr.sun_family = AF_UNIX; + strcpy(unaddr.sun_path, SDP_UNIX_PATH); + unlink(unaddr.sun_path); + if (0 > bind(unix_sock, (struct sockaddr *)&unaddr, sizeof(unaddr))) { + SDPERR("binding UNIX socket: %s", strerror(errno)); + return -1; + } + listen(unix_sock, 5); + FD_SET(unix_sock, &active_fdset); + active_maxfd = unix_sock; + chmod(SDP_UNIX_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + return 0; +} + +void sig_term(int sig) +{ + SDPINF("terminating... \n"); + sdp_svcdb_reset(); + close(l2cap_sock); + close(unix_sock); + exit(0); +} + +int become_daemon(void) +{ + int fd; + + if (getppid() != 1) { + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + if (fork()) + return 0; + setsid(); + } + for (fd = 0; fd < 3; fd++) + close(fd); + + chdir("/"); + return 1; +} + +static inline void handle_request(int sk, char *data, int len) +{ + struct sockaddr_l2 sa; + int size; + sdp_req_t req; + + size = sizeof(sa); + if (getpeername(sk, (struct sockaddr *)&sa, &size) < 0) + return; + + if (sa.l2_family == AF_BLUETOOTH) { + struct l2cap_options lo; + size = sizeof(lo); + getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); + req.bdaddr = sa.l2_bdaddr; + req.mtu = lo.omtu; + req.local = 0; + } else { + req.bdaddr = *BDADDR_LOCAL; + req.mtu = 2048; + req.local = 1; + } + req.sock = sk; + req.buf = data; + req.len = len; + process_request(&req); +} + +static void close_sock(int fd, int r) +{ + if (r < 0) + SDPERR("Read error: %s", strerror(errno)); + FD_CLR(fd, &active_fdset); + close(fd); + sdp_svcdb_collect_all(fd); + if (fd == active_maxfd) + active_maxfd--; +} + +static void check_active(fd_set *mask, int num) +{ + sdp_pdu_hdr_t hdr; + int size, fd, count, r; + char *buf; + + for (fd = 0, count = 0; fd <= active_maxfd && count < num; fd++) { + if (fd == l2cap_sock || fd == unix_sock || !FD_ISSET(fd, mask)) + continue; + + count++; + + r = recv(fd, (void *)&hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK); + if (r <= 0) { + close_sock(fd, r); + continue; + } + + size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen); + buf = malloc(size); + if (!buf) + continue; + + r = recv(fd, buf, size, 0); + if (r <= 0) + close_sock(fd, r); + else + handle_request(fd, buf, r); + } +} + +void usage(void) +{ + printf("sdpd version %s\n", VERSION); + printf("Usage:\n" + "sdpd [-n] [-m]\n" + ); +} + +static struct option main_options[] = { + {"help", 0,0, 'h'}, + {"nodaemon", 0,0, 'n'}, + {"master", 0,0, 'm'}, + {0, 0, 0, 0} +}; + +int main(int argc, char **argv) +{ + int daemon = 1; + int master = 0; + int opt; + + while ((opt = getopt_long(argc, argv, "nm", main_options, NULL)) != -1) + switch (opt) { + case 'n': + daemon = 0; + break; + case 'm': + master = 1; + break; + default: + usage(); + exit(0); + } + openlog("sdpd", LOG_PID | LOG_NDELAY, LOG_DAEMON); + + if (daemon && !become_daemon()) + return 0; + + argc -= optind; + argv += optind; + + if (init_server(master) < 0) { + SDPERR("Server initialization failed"); + return -1; + } + + SDPINF("sdpd v%s started", VERSION); + + signal(SIGINT, sig_term); + signal(SIGTERM, sig_term); + signal(SIGABRT, sig_term); + signal(SIGQUIT, sig_term); + signal(SIGPIPE, SIG_IGN); + + for (;;) { + int num, nfd; + fd_set mask; + + FD_ZERO(&mask); + mask = active_fdset; + + num = select(active_maxfd + 1, &mask, NULL, NULL, NULL); + if (num <= 0) { + SDPDBG("Select error:%s", strerror(errno)); + goto exit; + } + + if (FD_ISSET(l2cap_sock, &mask)) { + /* New L2CAP connection */ + struct sockaddr_l2 caddr; + socklen_t len = sizeof(caddr); + + nfd = accept(l2cap_sock, (struct sockaddr *)&caddr, &len); + if (nfd >= 0) { + if (nfd > active_maxfd) + active_maxfd = nfd; + FD_SET(nfd, &active_fdset); + } + } else if (FD_ISSET(unix_sock, &mask)) { + /* New unix connection */ + struct sockaddr_un caddr; + socklen_t len = sizeof(caddr); + + nfd = accept(unix_sock, (struct sockaddr *)&caddr, &len); + if (nfd != -1) { + if (nfd > active_maxfd) + active_maxfd = nfd; + FD_SET(nfd, &active_fdset); + } + } else + check_active(&mask, num); + } +exit: + sdp_svcdb_reset(); + return 0; +} diff --git a/sdpd/request.c b/sdpd/request.c new file mode 100644 index 00000000..2354e40e --- /dev/null +++ b/sdpd/request.c @@ -0,0 +1,849 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + 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. +*/ + +/* + SDP request handling code. + + Fixes: + Guruprasad Krishnamurthy + Dmitry Kasatkin - Continuation mechanism +*/ + +/* + * $Id$ + */ + +#include + +#include +#include +#include + +#include "sdpd.h" + +#define MIN(x, y) ((x) < (y))? (x): (y) + +/* Additional values for checking datatype (not in spec) */ +#define SDP_TYPE_UUID 0xfe +#define SDP_TYPE_ANY 0xff + +/* + * Generic data element sequence extractor. Builds + * a list whose elements are those found in the + * sequence. The data type of elements found in the + * sequence is returned in the reference pDataType + */ +static int extract_des(char *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType) +{ + uint8_t seqType; + int data_size = 0; + int scanned = sdp_extract_seqtype(buf, &seqType, &data_size); + short numberOfElements = 0; + int seqlen = 0; + sdp_list_t *pSeq = NULL; + uint8_t dataType; + int status = 0; + const char *p; + + SDPDBG("Seq type : %d\n", seqType); + if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) { + SDPERR("Unknown seq type \n"); + return -1; + } + p = buf + scanned; + + SDPDBG("Data size : %d\n", data_size); + for (;;) { + char *pElem = NULL; + int localSeqLength = 0; + + dataType = *(uint8_t *)p; + SDPDBG("Data type: 0x%02x\n", dataType); + + if (expectedType == SDP_TYPE_UUID) { + if (dataType != SDP_UUID16 && dataType != SDP_UUID32 && dataType != SDP_UUID128) { + SDPDBG("->Unexpected Data type (expected UUID_ANY)\n"); + return -1; + } + } else if (expectedType != SDP_TYPE_ANY && dataType != expectedType) { + SDPDBG("->Unexpected Data type (expected 0x%02x)\n", expectedType); + return -1; + } + + switch (dataType) { + case SDP_UINT16: + p += sizeof(uint8_t); + seqlen += sizeof(uint8_t); + pElem = (char *)malloc(sizeof(uint16_t)); + sdp_put_unaligned(ntohs(sdp_get_unaligned((uint16_t *)p)), (uint16_t *)pElem); + p += sizeof(uint16_t); + seqlen += sizeof(uint16_t); + break; + case SDP_UINT32: + p += sizeof(uint8_t); + seqlen += sizeof(uint8_t); + pElem = (char *)malloc(sizeof(uint32_t)); + sdp_put_unaligned(ntohl(sdp_get_unaligned((uint32_t *)p)), (uint32_t *)pElem); + p += sizeof(uint32_t); + seqlen += sizeof(uint32_t); + break; + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + pElem = (char *)malloc(sizeof(uuid_t)); + status = sdp_uuid_extract(p, (uuid_t *)pElem, &localSeqLength); + if (status == 0) { + seqlen += localSeqLength; + p += localSeqLength; + } + break; + } + if (status == 0) { + pSeq = sdp_list_append(pSeq, pElem); + numberOfElements++; + SDPDBG("No of elements : %d\n", numberOfElements); + + if (seqlen == data_size) + break; + else if (seqlen > data_size) + return -1; + } else + free(pElem); + } + *svcReqSeq = pSeq; + scanned += seqlen; + *pDataType = dataType; + return scanned; +} + +static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate) +{ + char *pdata = buf->data + buf->data_size; + int length = 0; + + if (cstate) { + SDPDBG("Non null sdp_cstate_t id : 0x%lx\n", cstate->timestamp); + *(uint8_t *)pdata = sizeof(sdp_cont_state_t); + pdata += sizeof(uint8_t); + length += sizeof(uint8_t); + memcpy(pdata, cstate, sizeof(sdp_cont_state_t)); + length += sizeof(sdp_cont_state_t); + } else { + // set "null" continuation state + *(uint8_t *)pdata = 0; + pdata += sizeof(uint8_t); + length += sizeof(uint8_t); + } + buf->data_size += length; + return length; +} + +static sdp_cont_state_t *sdp_cstate_get(char *buffer) +{ + char *pdata = buffer; + uint8_t cStateSize = *(uint8_t *)pdata; + + /* + * Check if continuation state exists, if yes attempt + * to get response remainder from cache, else send error + */ + SDPDBG("Continuation State size : %d\n", cStateSize); + + pdata += sizeof(uint8_t); + if (cStateSize != 0) { + sdp_cont_state_t *cstate = (sdp_cont_state_t *)pdata; + SDPDBG("Cstate TS : 0x%lx\n", cstate->timestamp); + SDPDBG("Bytes sent : %d\n", cstate->cStateValue.maxBytesSent); + return cstate; + } + return NULL; +} + +/* + * The matching process is defined as "each and every UUID + * specified in the "search pattern" must be present in the + * "target pattern". Here "search pattern" is the set of UUIDs + * specified by the service discovery client and "target pattern" + * is the set of UUIDs present in a service record. + * + * Return 1 if each and every UUID in the search + * pattern exists in the target pattern, 0 if the + * match succeeds and -1 on error. + */ +static int sdp_match_uuid(sdp_list_t *search, sdp_list_t *pattern) +{ + /* + * The target is a sorted list, so we need not look + * at all elements to confirm existence of an element + * from the search pattern + */ + int patlen = sdp_list_len(pattern); + + SDPDBG(""); + + if (patlen < sdp_list_len(search)) + return -1; + for (; search; search = search->next) { + uuid_t *uuid128; + void *data = search->data; + sdp_list_t *list; + if (data == NULL) + return -1; + + // create 128-bit form of the search UUID + uuid128 = sdp_uuid_to_uuid128((uuid_t *)data); + list = sdp_list_find(pattern, uuid128, sdp_uuid128_cmp); + free(uuid128); + if (!list) + return 0; + } + return 1; +} + +/* + * Service search request PDU. This method extracts the search pattern + * (a sequence of UUIDs) and calls the matching function + * to find matching services + */ +static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) +{ + int status = 0, i, plen, mlen; + sdp_list_t *pattern = NULL; + int expected, actual; + uint8_t dtd; + sdp_cont_state_t *cstate = NULL; + char *pCacheBuffer = NULL; + int handleSize = 0; + long cStateId = -1; + short rsp_count = 0; + short *pTotalRecordCount, *pCurrentRecordCount; + int mtu; + char *pdata = req->buf + sizeof(sdp_pdu_hdr_t); + int scanned = extract_des(pdata, &pattern, &dtd, SDP_TYPE_UUID); + + SDPDBG(""); + + if (scanned == -1) { + status = SDP_INVALID_SYNTAX; + goto done; + } + pdata += scanned; + + plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen); + mlen = scanned + sizeof(uint16_t) + 1; + // ensure we don't read past buffer + if (plen < mlen || plen != mlen + *(uint8_t *)(pdata+sizeof(uint16_t))) { + status = SDP_INVALID_SYNTAX; + goto done; + } + + expected = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + + SDPDBG("Expected count: %d\n", expected); + SDPDBG("Bytes scanned : %d\n", scanned); + + pdata += sizeof(uint16_t); + + /* + * Check if continuation state exists, if yes attempt + * to get rsp remainder from cache, else send error + */ + cstate = sdp_cstate_get(pdata); + + mtu = req->mtu - sizeof(sdp_pdu_hdr_t) - sizeof(uint16_t) - sizeof(uint16_t) - SDP_CONT_STATE_SIZE; + actual = MIN(expected, mtu >> 2); + + /* make space in the rsp buffer for total and current record counts */ + pdata = buf->data; + + /* total service record count = 0 */ + pTotalRecordCount = (short *)pdata; + sdp_put_unaligned(0, (uint16_t *)pdata); + pdata += sizeof(uint16_t); + buf->data_size += sizeof(uint16_t); + + /* current service record count = 0 */ + pCurrentRecordCount = (short *)pdata; + sdp_put_unaligned(0, (uint16_t *)pdata); + pdata += sizeof(uint16_t); + buf->data_size += sizeof(uint16_t); + + if (cstate == NULL) { + /* for every record in the DB, do a pattern search */ + sdp_list_t *list = sdp_get_record_list(); + + handleSize = 0; + for (; list && rsp_count < expected; list = list->next) { + sdp_record_t *rec = (sdp_record_t *)list->data; + + SDPDBG("Checking svcRec : 0x%x\n", rec->handle); + + if (sdp_match_uuid(pattern, rec->pattern) > 0) { + rsp_count++; + sdp_put_unaligned(htonl(rec->handle), (uint32_t *)pdata); + pdata += sizeof(uint32_t); + handleSize += sizeof(uint32_t); + } + } + + SDPDBG("Match count: %d\n", rsp_count); + + buf->data_size += handleSize; + sdp_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); + sdp_put_unaligned(htons(rsp_count), (uint16_t *)pCurrentRecordCount); + + if (rsp_count > actual) { + /* cache the rsp and generate a continuation state */ + cStateId = sdp_cstate_alloc_buf(buf); + /* + * subtract handleSize since we now send only + * a subset of handles + */ + buf->data_size -= handleSize; + } else { + /* NULL continuation state */ + sdp_set_cstate_pdu(buf, NULL); + } + } + + /* under both the conditions below, the rsp buffer is not built yet */ + if (cstate || cStateId != -1) { + short lastIndex = 0; + + if (cstate) { + /* + * Get the previous sdp_cont_state_t and obtain + * the cached rsp + */ + sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); + if (pCache) { + pCacheBuffer = pCache->data; + /* get the rsp_count from the cached buffer */ + rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pCacheBuffer)); + + /* get index of the last sdp_record_t sent */ + lastIndex = cstate->cStateValue.lastIndexSent; + } else { + status = SDP_INVALID_CSTATE; + goto done; + } + } else { + pCacheBuffer = buf->data; + lastIndex = 0; + } + + /* + * Set the local buffer pointer to after the + * current record count and increment the cached + * buffer pointer to beyond the counters + */ + pdata = (char *)pCurrentRecordCount + sizeof(uint16_t); + + /* increment beyond the totalCount and the currentCount */ + pCacheBuffer += 2 * sizeof(uint16_t); + + if (cstate) { + handleSize = 0; + for (i = lastIndex; (i - lastIndex) < actual && i < rsp_count; i++) { + sdp_put_unaligned(sdp_get_unaligned((uint32_t *)(pCacheBuffer + i * sizeof(uint32_t))), (uint32_t *)pdata); + pdata += sizeof(uint32_t); + handleSize += sizeof(uint32_t); + } + } else { + handleSize = actual << 2; + i = actual; + } + + buf->data_size += handleSize; + sdp_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); + sdp_put_unaligned(htons(i - lastIndex), (uint16_t *)pCurrentRecordCount); + + if (i == rsp_count) { + /* set "null" continuationState */ + sdp_set_cstate_pdu(buf, NULL); + } else { + /* + * there's more: set lastIndexSent to + * the new value and move on + */ + sdp_cont_state_t newState; + + SDPDBG("Setting non-NULL sdp_cstate_t\n"); + + if (cstate) + memcpy((char *)&newState, cstate, sizeof(sdp_cont_state_t)); + else { + memset((char *)&newState, 0, sizeof(sdp_cont_state_t)); + newState.timestamp = cStateId; + } + newState.cStateValue.lastIndexSent = i; + sdp_set_cstate_pdu(buf, &newState); + } + } + +done: + if (pattern) + sdp_list_free(pattern, free); + + return status; +} + +/* + * Extract attribute identifiers from the request PDU. + * Clients could request a subset of attributes (by id) + * from a service record, instead of the whole set. The + * requested identifiers are present in the PDU form of + * the request + */ +static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_buf_t *buf) +{ + if (!rec) + return SDP_INVALID_RECORD_HANDLE; + +#ifdef SDP_DEBUG + if (seq) + SDPDBG("Entries in attr seq : %d\n", sdp_list_len(seq)); + else + SDPDBG("NULL attribute descriptor\n"); + SDPDBG("AttrDataType : %d\n", dtd); +#endif + if (seq == NULL) { + SDPDBG("Attribute sequence is NULL\n"); + return 0; + } + if (dtd == SDP_UINT16) + for (; seq; seq = seq->next) { + uint16_t attr = sdp_get_unaligned((uint16_t *)seq->data); + sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr); + if (a) + sdp_append_to_pdu(buf, a); + } + else if (dtd == SDP_UINT32) { + sdp_buf_t pdu; + sdp_gen_record_pdu(rec, &pdu); + for (; seq; seq = seq->next) { + uint32_t range = sdp_get_unaligned((uint32_t *)seq->data); + uint16_t attr; + uint16_t low = (0xffff0000 & range) >> 16; + uint16_t high = 0x0000ffff & range; + + SDPDBG("attr range : 0x%x\n", range); + SDPDBG("Low id : 0x%x\n", low); + SDPDBG("High id : 0x%x\n", high); + + if (low == 0x0000 && high == 0xffff && pdu.data_size <= buf->buf_size) { + /* copy it */ + memcpy(buf->data, pdu.data, pdu.data_size); + buf->data_size = pdu.data_size; + break; + } + /* (else) sub-range of attributes */ + for (attr = low; attr <= high; attr++) { + sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr); + if (a) + sdp_append_to_pdu(buf, a); + } + } + free(pdu.data); + } else { + SDPERR("Unexpected data type : 0x%x\n", dtd); + SDPERR("Expect uint16_t or uint32_t\n"); + return SDP_INVALID_SYNTAX; + } + return 0; +} + +/* + * A request for the attributes of a service record. + * First check if the service record (specified by + * service record handle) exists, then call the attribute + * streaming function + */ +static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) +{ + sdp_cont_state_t *cstate = NULL; + char *pResponse = NULL; + short cstate_size = 0; + sdp_list_t *seq = NULL; + uint8_t dtd = 0; + int scanned = 0; + int max_rsp_size; + int status = 0, plen, mlen; + char *pdata = req->buf + sizeof(sdp_pdu_hdr_t); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)pdata)); + + SDPDBG(""); + + pdata += sizeof(uint32_t); + max_rsp_size = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + pdata += sizeof(uint16_t); + + /* extract the attribute list */ + scanned = extract_des(pdata, &seq, &dtd, SDP_TYPE_ANY); + if (scanned == -1) { + status = SDP_INVALID_SYNTAX; + goto done; + } + pdata += scanned; + + plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen); + mlen = scanned + sizeof(uint32_t) + sizeof(uint16_t) + 1; + // ensure we don't read past buffer + if (plen < mlen || plen != mlen + *(uint8_t *)pdata) { + status = SDP_INVALID_SYNTAX; + goto done; + } + + /* + * if continuation state exists, attempt + * to get rsp remainder from cache, else send error + */ + cstate = sdp_cstate_get(pdata); + + SDPDBG("SvcRecHandle : 0x%x\n", handle); + SDPDBG("max_rsp_size : %d\n", max_rsp_size); + + /* + * Calculate Attribute size acording to MTU + * We can send only (MTU - sizeof(sdp_pdu_hdr_t) - sizeof(sdp_cont_state_t)) + */ + max_rsp_size = MIN(max_rsp_size, req->mtu - sizeof(sdp_pdu_hdr_t) - + sizeof(uint32_t) - SDP_CONT_STATE_SIZE - sizeof(uint16_t)); + + /* pull header for AttributeList byte count */ + buf->data += sizeof(uint16_t); + buf->buf_size -= sizeof(uint16_t); + + if (cstate) { + sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); + + SDPDBG("Obtained cached rsp : %p\n", pCache); + + if (pCache) { + short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent); + pResponse = pCache->data; + memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); + buf->data_size += sent; + cstate->cStateValue.maxBytesSent += sent; + + SDPDBG("Response size : %d sending now : %d bytes sent so far : %d\n", + pCache->data_size, sent, cstate->cStateValue.maxBytesSent); + if (cstate->cStateValue.maxBytesSent == pCache->data_size) + cstate_size = sdp_set_cstate_pdu(buf, NULL); + else + cstate_size = sdp_set_cstate_pdu(buf, cstate); + } else { + status = SDP_INVALID_CSTATE; + SDPERR("NULL cache buffer and non-NULL continuation state\n"); + } + } else { + sdp_record_t *rec = sdp_record_find(handle); + status = extract_attrs(rec, seq, dtd, buf); + if (buf->data_size > max_rsp_size) { + sdp_cont_state_t newState; + + memset((char *)&newState, 0, sizeof(sdp_cont_state_t)); + newState.timestamp = sdp_cstate_alloc_buf(buf); + /* + * Reset the buffer size to the maximum expected and + * set the sdp_cont_state_t + */ + SDPDBG("Creating continuation state of size : %d\n", buf->data_size); + buf->data_size = max_rsp_size; + newState.cStateValue.maxBytesSent = max_rsp_size; + cstate_size = sdp_set_cstate_pdu(buf, &newState); + } else { + if (buf->data_size == 0) + sdp_append_to_buf(buf, 0, 0); + cstate_size = sdp_set_cstate_pdu(buf, NULL); + } + } + + // push header + buf->data -= sizeof(uint16_t); + buf->buf_size += sizeof(uint16_t); + +done: + if (seq) + sdp_list_free(seq, free); + if (status) + return status; + + /* set attribute list byte count */ + sdp_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data); + buf->data_size += sizeof(uint16_t); + return 0; +} + +/* + * combined service search and attribute extraction + */ +static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) +{ + int status = 0, plen, totscanned; + char *pdata, *pResponse = NULL; + int scanned, max, rsp_count = 0; + sdp_list_t *pattern = NULL, *seq = NULL, *svcList; + sdp_cont_state_t *cstate = NULL; + short cstate_size = 0; + uint8_t dtd = 0; + sdp_buf_t tmpbuf; + + tmpbuf.data = NULL; + pdata = req->buf + sizeof(sdp_pdu_hdr_t); + scanned = extract_des(pdata, &pattern, &dtd, SDP_TYPE_UUID); + if (scanned == -1) { + status = SDP_INVALID_SYNTAX; + goto done; + } + totscanned = scanned; + + SDPDBG("Bytes scanned: %d", scanned); + + pdata += scanned; + max = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + pdata += sizeof(uint16_t); + + SDPDBG("Max Attr expected: %d", max); + + /* extract the attribute list */ + scanned = extract_des(pdata, &seq, &dtd, SDP_TYPE_ANY); + if (scanned == -1) { + status = SDP_INVALID_SYNTAX; + goto done; + } + pdata += scanned; + totscanned += scanned + sizeof(uint16_t) + 1; + + plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen); + if (plen < totscanned || plen != totscanned + *(uint8_t *)pdata) { + status = SDP_INVALID_SYNTAX; + goto done; + } + + /* + * if continuation state exists attempt + * to get rsp remainder from cache, else send error + */ + cstate = sdp_cstate_get(pdata); // continuation information + + svcList = sdp_get_record_list(); + + tmpbuf.data = (char *)malloc(USHRT_MAX); + tmpbuf.data_size = 0; + tmpbuf.buf_size = USHRT_MAX; + memset(tmpbuf.data, 0, USHRT_MAX); + + /* + * Calculate Attribute size acording to MTU + * We can send only (MTU - sizeof(sdp_pdu_hdr_t) - sizeof(sdp_cont_state_t)) + */ + max = MIN(max, req->mtu - sizeof(sdp_pdu_hdr_t) - SDP_CONT_STATE_SIZE - sizeof(uint16_t)); + + /* pull header for AttributeList byte count */ + buf->data += sizeof(uint16_t); + buf->buf_size -= sizeof(uint16_t); + + if (cstate == NULL) { + /* no continuation state -> create new response */ + sdp_list_t *p; + for (p = svcList; p; p = p->next) { + sdp_record_t *rec = (sdp_record_t *)p->data; + if (sdp_match_uuid(pattern, rec->pattern) > 0) { + rsp_count++; + status = extract_attrs(rec, seq, dtd, &tmpbuf); + + SDPDBG("Response count : %d\n", rsp_count); + SDPDBG("Local PDU size : %d\n", tmpbuf.data_size); + if (status) { + SDPDBG("Extract attr from record returns err\n"); + break; + } + if (buf->data_size + tmpbuf.data_size < buf->buf_size) { + // to be sure no relocations + sdp_append_to_buf(buf, tmpbuf.data, tmpbuf.data_size); + tmpbuf.data_size = 0; + memset(tmpbuf.data, 0, USHRT_MAX); + } else { + SDPERR("Relocation needed\n"); + break; + } + SDPDBG("Net PDU size : %d\n", buf->data_size); + } + } + if (buf->data_size > max) { + sdp_cont_state_t newState; + + memset((char *)&newState, 0, sizeof(sdp_cont_state_t)); + newState.timestamp = sdp_cstate_alloc_buf(buf); + /* + * Reset the buffer size to the maximum expected and + * set the sdp_cont_state_t + */ + buf->data_size = max; + newState.cStateValue.maxBytesSent = max; + cstate_size = sdp_set_cstate_pdu(buf, &newState); + } else + cstate_size = sdp_set_cstate_pdu(buf, NULL); + } else { + /* continuation State exists -> get from cache */ + sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); + if (pCache) { + uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); + pResponse = pCache->data; + memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); + buf->data_size += sent; + cstate->cStateValue.maxBytesSent += sent; + if (cstate->cStateValue.maxBytesSent == pCache->data_size) + cstate_size = sdp_set_cstate_pdu(buf, NULL); + else + cstate_size = sdp_set_cstate_pdu(buf, cstate); + } else { + status = SDP_INVALID_CSTATE; + SDPDBG("Non-null continuation state, but null cache buffer\n"); + } + } + + if (!rsp_count && !cstate) { + // found nothing + buf->data_size = 0; + sdp_append_to_buf(buf, tmpbuf.data, tmpbuf.data_size); + sdp_set_cstate_pdu(buf, NULL); + } + + // push header + buf->data -= sizeof(uint16_t); + buf->buf_size += sizeof(uint16_t); + + if (!status) { + /* set attribute list byte count */ + sdp_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data); + buf->data_size += sizeof(uint16_t); + } + +done: + if (tmpbuf.data) + free(tmpbuf.data); + if (pattern) + sdp_list_free(pattern, free); + if (seq) + sdp_list_free(seq, free); + return status; +} + +/* + * Top level request processor. Calls the appropriate processing + * function based on request type. Handles service registration + * client requests also. + */ +void process_request(sdp_req_t *req) +{ + sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)req->buf; + sdp_pdu_hdr_t *rsphdr; + sdp_buf_t rsp; + char *buf = (char *)malloc(USHRT_MAX); + int sent = 0; + int status = SDP_INVALID_SYNTAX; + + SDPDBG(""); + + memset((void *)buf, 0, USHRT_MAX); + rsp.data = buf + sizeof(sdp_pdu_hdr_t); + rsp.data_size = 0; + rsp.buf_size = USHRT_MAX - sizeof(sdp_pdu_hdr_t); + rsphdr = (sdp_pdu_hdr_t *)buf; + + if (ntohs(reqhdr->plen) != req->len - sizeof(sdp_pdu_hdr_t)) { + status = SDP_INVALID_PDU_SIZE; + goto send_rsp; + } + switch (reqhdr->pdu_id) { + case SDP_SVC_SEARCH_REQ: + SDPDBG("Got a svc srch req\n"); + status = service_search_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_SEARCH_RSP; + break; + case SDP_SVC_ATTR_REQ: + SDPDBG("Got a svc attr req\n"); + status = service_attr_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_ATTR_RSP; + break; + case SDP_SVC_SEARCH_ATTR_REQ: + SDPDBG("Got a svc srch attr req\n"); + status = service_search_attr_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_SEARCH_ATTR_RSP; + break; + /* Following requests are allowed only for local connections */ + case SDP_SVC_REGISTER_REQ: + SDPDBG("Service register request\n"); + if (req->local) { + status = service_register_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_REGISTER_RSP; + } + break; + case SDP_SVC_UPDATE_REQ: + SDPDBG("Service update request\n"); + if (req->local) { + status = service_update_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_UPDATE_RSP; + } + break; + case SDP_SVC_REMOVE_REQ: + SDPDBG("Service removal request\n"); + if (req->local) { + status = service_remove_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_REMOVE_RSP; + } + break; + default: + SDPERR("Unknown PDU ID : 0x%x received\n", reqhdr->pdu_id); + status = SDP_INVALID_SYNTAX; + break; + } + +send_rsp: + if (status) { + rsphdr->pdu_id = SDP_ERROR_RSP; + sdp_put_unaligned(htons(status), (uint16_t *)rsp.data); + rsp.data_size = sizeof(uint16_t); + } + + SDPDBG("Sending rsp. status %d", status); + + rsphdr->tid = reqhdr->tid; + rsphdr->plen = htons(rsp.data_size); + + /* point back to the real buffer start and set the real rsp length */ + rsp.data_size += sizeof(sdp_pdu_hdr_t); + rsp.data = buf; + + /* stream the rsp PDU */ + sent = send(req->sock, rsp.data, rsp.data_size, 0); + + SDPDBG("Bytes Sent : %d\n", sent); + + free(rsp.data); + free(req->buf); +} diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h new file mode 100644 index 00000000..1f0d7e47 --- /dev/null +++ b/sdpd/sdpd.h @@ -0,0 +1,75 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + 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$ + */ + +#ifndef SDPD_H +#define SDPD_H + +typedef struct request { + bdaddr_t bdaddr; + int local; + int sock; + int mtu; + int flags; + char *buf; + int len; +} sdp_req_t; + +void process_request(sdp_req_t *req); + +int service_register_req(sdp_req_t *req, sdp_buf_t *rsp); +int service_update_req(sdp_req_t *req, sdp_buf_t *rsp); +int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp); + +typedef struct { + long timestamp; + union { + uint16_t maxBytesSent; + uint16_t lastIndexSent; + } cStateValue; +} sdp_cont_state_t; + +#define SDP_CONT_STATE_SIZE (sizeof(uint8_t) + sizeof(sdp_cont_state_t)) + +sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate); +void sdp_cstate_cache_init(void); +void sdp_cstate_clean_buf(void); +long sdp_cstate_alloc_buf(sdp_buf_t *buf); + +void sdp_svcdb_reset(void); +void sdp_svcdb_collect_all(int sock); +void sdp_svcdb_set_collectable(sdp_record_t *rec, int sock); +void sdp_svcdb_collect(sdp_record_t *rec); +sdp_record_t *sdp_record_find(uint32_t handle); +void sdp_record_add(sdp_record_t *rec); +int sdp_record_remove(uint32_t handle); +sdp_list_t *sdp_get_record_list(); + +long sdp_get_time(); + +#endif diff --git a/sdpd/service.c b/sdpd/service.c new file mode 100644 index 00000000..171a086d --- /dev/null +++ b/sdpd/service.c @@ -0,0 +1,241 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + 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. +*/ + +/* + Service registration requests. + + Fixes: + Guruprasad Krishnamurthy +*/ + +/* + * $Id$ + */ + +#include +#include +#include + +#include "sdpd.h" + +extern void update_db_timestamp(void); + +// FIXME: refactor for server-side +static sdp_record_t *extract_pdu_server(char *p, uint32_t handleExpected, int *scanned) +{ + int extractStatus = -1, localExtractedLength = 0; + uint8_t dtd; + int seqlen = 0; + sdp_record_t *rec = NULL; + uint16_t attrId, lookAheadAttrId; + sdp_data_t *pAttr = NULL; + uint32_t handle = 0xffffffff; + + *scanned = sdp_extract_seqtype(p, &dtd, &seqlen); + p += *scanned; + lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *)(p + sizeof(uint8_t)))); + + SDPDBG("Look ahead attr id : %d\n", lookAheadAttrId); + + if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { + handle = ntohl(sdp_get_unaligned((uint32_t *)(p + + sizeof(uint8_t) + sizeof(uint16_t) + + sizeof(uint8_t)))); + SDPDBG("SvcRecHandle : 0x%x\n", handle); + rec = sdp_record_find(handle); + } else if (handleExpected != 0xffffffff) + rec = sdp_record_find(handleExpected); + + if (rec == NULL) { + rec = sdp_record_alloc(); + rec->attrlist = NULL; + if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { + rec->handle = handle; + sdp_record_add(rec); + } else if (handleExpected != 0xffffffff) { + rec->handle = handleExpected; + sdp_record_add(rec); + } + } + + while (localExtractedLength < seqlen) { + int attrSize = sizeof(uint8_t); + int attrValueLength = 0; + + SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength); + dtd = *(uint8_t *)p; + + attrId = ntohs(sdp_get_unaligned((uint16_t *)(p + attrSize))); + attrSize += sizeof(uint16_t); + + SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attrId); + + pAttr = sdp_extract_attr(p + attrSize, &attrValueLength, rec); + + SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attrId, attrValueLength); + + attrSize += attrValueLength; + if (pAttr == NULL) { + SDPDBG("Terminating extraction of attributes"); + break; + } + localExtractedLength += attrSize; + p += attrSize; + sdp_attr_replace(rec, attrId, pAttr); + extractStatus = 0; + SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", + seqlen, localExtractedLength); + } + + if (extractStatus == 0) { + SDPDBG("Successful extracting of Svc Rec attributes\n"); +#ifdef SDP_DEBUG + sdp_print_service_attr(rec->attrlist); +#endif + *scanned += seqlen; + } + return rec; +} + +/* + * Add the newly created service record to the service repository + */ +int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) +{ + int scanned = 0; + sdp_data_t *handle; + char *p = req->buf + sizeof(sdp_pdu_hdr_t); + sdp_record_t *rec; + + req->flags = *p++; + + // save image of PDU: we need it when clients request this attribute + rec = extract_pdu_server(p, 0xffffffff, &scanned); + if (rec == NULL) { + sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *)rsp->data); + rsp->data_size = sizeof(uint16_t); + return -1; + } + + rec->handle = (uint32_t)rec; + sdp_record_add(rec); + if (!(req->flags & SDP_RECORD_PERSIST)) + sdp_svcdb_set_collectable(rec, req->sock); + handle = sdp_data_alloc(SDP_UINT32, &rec->handle); + sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, handle); + /* + * if the browse group descriptor is NULL, + * ensure that the record belongs to the ROOT group + */ + if (sdp_data_get(rec, SDP_ATTR_BROWSE_GRP_LIST) == NULL) { + uuid_t uuid; + sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); + sdp_pattern_add_uuid(rec, &uuid); + } + update_db_timestamp(); + + /* Build a rsp buffer */ + sdp_put_unaligned(htonl(rec->handle), (uint32_t *)rsp->data); + rsp->data_size = sizeof(uint32_t); + return 0; +} + +/* + * Update a service record + */ +int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) +{ + sdp_record_t *orec; + int status = 0, scanned = 0; + char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + + SDPDBG(""); + + SDPDBG("Svc Rec Handle: 0x%x\n", handle); + + p += sizeof(uint32_t); + + orec = sdp_record_find(handle); + + SDPDBG("SvcRecOld: 0x%x\n", (uint32_t)orec); + + if (orec) { + sdp_record_t *nrec = extract_pdu_server(p, handle, &scanned); + if (nrec && handle == nrec->handle) + update_db_timestamp(); + else { + SDPDBG("SvcRecHandle : 0x%x\n", handle); + SDPDBG("SvcRecHandleNew : 0x%x\n", nrec->handle); + SDPDBG("SvcRecNew : 0x%x\n", (uint32_t) nrec); + SDPDBG("SvcRecOld : 0x%x\n", (uint32_t) orec); + SDPDBG("Failure to update, restore old value\n"); + + if (nrec) + sdp_record_free(nrec); + status = SDP_INVALID_SYNTAX; + } + } else + status = SDP_INVALID_RECORD_HANDLE; + + p = rsp->data; + sdp_put_unaligned(htons(status), (uint16_t *)p); + rsp->data_size = sizeof(uint16_t); + return status; +} + +/* + * Remove a registered service record + */ +int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) +{ + char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + sdp_record_t *rec; + int status = 0; + + SDPDBG(""); + + /* extract service record handle */ + p += sizeof(uint32_t); + + rec = sdp_record_find(handle); + if (rec) { + sdp_svcdb_collect(rec); + status = sdp_record_remove(handle); + sdp_record_free(rec); + if (status == 0) + update_db_timestamp(); + } else { + status = SDP_INVALID_RECORD_HANDLE; + SDPDBG("Could not find record : 0x%x\n", handle); + } + + p = rsp->data; + sdp_put_unaligned(htons(status), (uint16_t *)p); + rsp->data_size = sizeof(uint16_t); + + return status; +} diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c new file mode 100644 index 00000000..d0b2b85e --- /dev/null +++ b/sdpd/servicedb.c @@ -0,0 +1,209 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + 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. +*/ + +/* + Service repository. + Has methods to create and clean the repository, besides + methods to add/find/modify/delete individual entries + + Fixes: + Guruprasad Krishnamurthy + Manel Guerrero Zapata +*/ + +/* + * $Id$ + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "sdpd.h" + +static sdp_list_t *service_db; + +/* + * Ordering function called when inserting a service record. + * The service repository is a linked list in sorted order + * and the service record handle is the sort key + */ +static int record_sort(const void *r1, const void *r2) +{ + const sdp_record_t *rec1 = (const sdp_record_t *)r1; + const sdp_record_t *rec2 = (const sdp_record_t *)r2; + + if (!rec1 || !rec2) { + SDPERR("NULL RECORD LIST FATAL\n"); + return -1; + } + return rec1->handle - rec2->handle; +} + +/* + * Reset the service repository by deleting its contents + */ +void sdp_svcdb_reset() +{ + sdp_list_free(service_db, (sdp_free_func_t)sdp_record_free); +} + +typedef struct _indexed { + int sock; + sdp_record_t *record; +} sdp_indexed_t; + +static sdp_list_t *socket_index; + +/* + * collect all services registered over this socket + */ +void sdp_svcdb_collect_all(int sock) +{ + sdp_list_t *p, *q; + + for (p=socket_index, q=0; p; ) { + sdp_indexed_t *item = (sdp_indexed_t *)p->data; + if (item->sock == sock) { + sdp_list_t *next = p->next; + sdp_record_remove(item->record->handle); + free(item); + if (q) + q->next = next; + else + socket_index = next; + free(p); + p = next; + } else if (item->sock > sock) + return; + else { + q = p; + p = p->next; + } + } +} + +void sdp_svcdb_collect(sdp_record_t *rec) +{ + sdp_list_t *p, *q; + + for (p=socket_index, q=0; p; q=p, p=p->next) { + sdp_indexed_t *item = (sdp_indexed_t *)p->data; + if (rec == item->record) { + free(item); + if (q) + q->next = p->next; + else + socket_index = p->next; + free(p); + return; + } + } +} + +static int compare_indices(const void *i1, const void *i2) +{ + const sdp_indexed_t *s1 = (const sdp_indexed_t *)i1; + const sdp_indexed_t *s2 = (const sdp_indexed_t *)i2; + return s1->sock - s2->sock; +} + +void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) +{ + sdp_indexed_t *item = (sdp_indexed_t *)malloc(sizeof(sdp_indexed_t)); + item->sock = sock; + item->record = record; + socket_index = sdp_list_insert_sorted(socket_index, item, compare_indices); +} + +/* + * Add a service record to the repository + */ +void sdp_record_add(sdp_record_t *rec) +{ +#ifdef SDP_DEBUG + SDPDBG("Adding rec : 0x%lx\n", (long)rec); + SDPDBG("with handle : 0x%lx\n", (long)rec->handle); +#endif + service_db = sdp_list_insert_sorted(service_db, rec, record_sort); +} + +static sdp_list_t *record_locate(uint32_t handle) +{ + if (service_db) { + sdp_list_t *p; + sdp_record_t r; + + r.handle = handle; + p = sdp_list_find(service_db, &r, record_sort); + return p; + } + SDPDBG("Could not find svcRec for : 0x%x\n", handle); + return 0; +} + +/* + * Given a service record handle, find the record associated with it. + */ +sdp_record_t *sdp_record_find(uint32_t handle) +{ + sdp_list_t *p = record_locate(handle); + + if (p) + return (sdp_record_t *)p->data; + SDPDBG("Couldn't find record for : 0x%x\n", handle); + return 0; +} + +/* + * Given a service record handle, remove its record from the repository + */ +int sdp_record_remove(uint32_t handle) +{ + sdp_list_t *p = record_locate(handle); + + if (p) { + sdp_record_t *r = (sdp_record_t *)p->data; + if (r) { + service_db = sdp_list_remove(service_db, r); + return 0; + } + } + SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); + return -1; +} + +/* + * Return a pointer to the linked list containing the records in sorted order + */ +sdp_list_t *sdp_get_record_list() +{ + return service_db; +} -- cgit From 15ddb98b422f139ab70f03e96b090f9a80f62e2d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 21:39:09 +0000 Subject: Add sdpd manpage --- sdpd/Makefile.am | 4 +++ sdpd/sdpd.8 | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 sdpd/sdpd.8 (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 9536bf04..8f50c596 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -7,3 +7,7 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h + +man_MANS = sdpd.8 + +EXTRA_DIST = $(man_MANS) diff --git a/sdpd/sdpd.8 b/sdpd/sdpd.8 new file mode 100644 index 00000000..34ce987d --- /dev/null +++ b/sdpd/sdpd.8 @@ -0,0 +1,88 @@ +.\" $Header$ +.\" +.\" transcript compatibility for postscript use. +.\" +.\" synopsis: .P! +.\" +.de P! +.fl +\!!1 setgray +.fl +\\&.\" +.fl +\!!0 setgray +.fl \" force out current output buffer +\!!save /psv exch def currentpoint translate 0 0 moveto +\!!/showpage{}def +.fl \" prolog +.sy sed -e 's/^/!/' \\$1\" bring in postscript file +\!!psv restore +. +.de pF +.ie \\*(f1 .ds f1 \\n(.f +.el .ie \\*(f2 .ds f2 \\n(.f +.el .ie \\*(f3 .ds f3 \\n(.f +.el .ie \\*(f4 .ds f4 \\n(.f +.el .tm ? font overflow +.ft \\$1 +.. +.de fP +.ie !\\*(f4 \{\ +. ft \\*(f4 +. ds f4\" +' br \} +.el .ie !\\*(f3 \{\ +. ft \\*(f3 +. ds f3\" +' br \} +.el .ie !\\*(f2 \{\ +. ft \\*(f2 +. ds f2\" +' br \} +.el .ie !\\*(f1 \{\ +. ft \\*(f1 +. ds f1\" +' br \} +.el .tm ? font underflow +.. +.ds f1\" +.ds f2\" +.ds f3\" +.ds f4\" +'\" t +.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n +.TH "sdpd" "8" +.SH "NAME" +sdpd \(em SDP daemon +.SH "SYNOPSIS" +.PP +\fBsdpd\fR [\fIoptions\fR] +.SH "DESCRIPTION" +.PP +\fBsdpd\fR allows Bluetooth devices +connected to the host to advertise via SDP the Bluetooth services +available. + +.SH "OPTIONS" +.IP "\fB-n\fP" 10 +Don't detach from the controlling terminal. + +.SH "BUGS" +.PP +None yet known. +.SH "AUTHOR" +.PP +Maxim Krasnyansky , +Stephen Crane . Man page written +by Edd Dumbill . + +.PP +Based on work done by Guruprasad Krishnamurthy +, Dmitry Kasatkin + and Manel Guerrero Zapata +. + +.SH "SEE ALSO" +.PP +sdptool(1) +.\" created by instant / docbook-to-man, Thu 15 Jan 2004, 21:01 -- cgit From b4e62d0942cc975be9f427d444231d5f104c87d0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 21:19:18 +0000 Subject: Change default prefix to /usr --- sdpd/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 8f50c596..c1dcb253 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -mandir = $(prefix)/usr/share/man +mandir = $(prefix)/share/man sbin_PROGRAMS = sdpd -- cgit From 719873a6b8d26c78b0a9a2380647e83c8e4bc05c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Apr 2004 00:08:19 +0000 Subject: Modifying $mandir is no longer needed --- sdpd/Makefile.am | 2 -- 1 file changed, 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index c1dcb253..81c248ce 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -2,8 +2,6 @@ # $Id$ # -mandir = $(prefix)/share/man - sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h -- cgit From 1d3715db11f573060cb02a2b7b7c44f06607d337 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 06:04:35 +0000 Subject: Update BlueZ library configuration --- sdpd/Makefile.am | 4 ++++ sdpd/main.c | 8 +++++++- sdpd/sdpd.h | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 81c248ce..97f9b9e1 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -6,6 +6,10 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + man_MANS = sdpd.8 EXTRA_DIST = $(man_MANS) diff --git a/sdpd/main.c b/sdpd/main.c index fea283f2..132539d5 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -34,23 +34,29 @@ /* * $Id$ */ + +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include -#include #include "sdpd.h" diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 1f0d7e47..37c685e2 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -30,6 +30,15 @@ #ifndef SDPD_H #define SDPD_H +#define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg) +#define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg) + +#ifdef SDP_DEBUG +#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg) +#else +#define SDPDBG(fmt...) +#endif + typedef struct request { bdaddr_t bdaddr; int local; -- cgit From f06f701cd50b80c01081b40e69943adbb405e665 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 06:11:19 +0000 Subject: Don't include sdp_internal.h --- sdpd/cstate.c | 1 - sdpd/request.c | 3 ++- sdpd/service.c | 3 ++- sdpd/servicedb.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index e9b51832..494292ac 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -37,7 +37,6 @@ #include #include -#include #include "sdpd.h" diff --git a/sdpd/request.c b/sdpd/request.c index 2354e40e..ff3b5642 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -36,10 +36,11 @@ */ #include +#include +#include #include #include -#include #include "sdpd.h" diff --git a/sdpd/service.c b/sdpd/service.c index 171a086d..4d03c917 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -34,9 +34,10 @@ * $Id$ */ +#include + #include #include -#include #include "sdpd.h" diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index d0b2b85e..36035a81 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -38,13 +38,13 @@ */ #include +#include #include #include #include #include #include -#include #include "sdpd.h" -- cgit From f3b2f00568b83b26308e0e84bf20316f65747f86 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 08:27:06 +0000 Subject: Use unaligned access functions from core library --- sdpd/request.c | 2 ++ sdpd/sdpd.h | 3 +++ sdpd/service.c | 2 ++ 3 files changed, 7 insertions(+) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index ff3b5642..f587cada 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -38,7 +38,9 @@ #include #include #include +#include +#include #include #include diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 37c685e2..c669e603 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -30,6 +30,9 @@ #ifndef SDPD_H #define SDPD_H +#define sdp_get_unaligned bt_get_unaligned +#define sdp_put_unaligned bt_put_unaligned + #define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg) #define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg) diff --git a/sdpd/service.c b/sdpd/service.c index 4d03c917..c69aa509 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -35,7 +35,9 @@ */ #include +#include +#include #include #include -- cgit From e343e0fee7fdaf96156fb35b431ddb0503755843 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 12:15:04 +0000 Subject: Unify copyright and license information --- sdpd/cstate.c | 67 ++++++++++++++++++++++++++++--------------------------- sdpd/main.c | 62 +++++++++++++++++++++++---------------------------- sdpd/request.c | 66 ++++++++++++++++++++++++++---------------------------- sdpd/sdpd.h | 56 ++++++++++++++++++++++++---------------------- sdpd/service.c | 65 ++++++++++++++++++++++++++--------------------------- sdpd/servicedb.c | 68 ++++++++++++++++++++++++++------------------------------ 6 files changed, 187 insertions(+), 197 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index 494292ac..8f9db218 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -1,37 +1,38 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - 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. -*/ - -/* - Fixes: - Guruprasad Krishnamurthy -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * 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 +#endif + #include #include @@ -44,8 +45,8 @@ typedef struct _sdp_cstate_list sdp_cstate_list_t; struct _sdp_cstate_list { sdp_cstate_list_t *next; - long timestamp; - sdp_buf_t buf; + long timestamp; + sdp_buf_t buf; }; static sdp_cstate_list_t *cstates; diff --git a/sdpd/main.c b/sdpd/main.c index 132539d5..b2262acd 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -1,38 +1,32 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - 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. -*/ - -/* - SDP server initialization and connection handling - - Fixes: - Guruprasad Krishnamurthy - Imre Deak -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * 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 diff --git a/sdpd/request.c b/sdpd/request.c index f587cada..7bdecb7a 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -1,40 +1,38 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - 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. -*/ - -/* - SDP request handling code. - - Fixes: - Guruprasad Krishnamurthy - Dmitry Kasatkin - Continuation mechanism -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * 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 +#endif + #include #include #include diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index c669e603..30eb1de3 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -1,30 +1,32 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - 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$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * 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$ */ #ifndef SDPD_H @@ -47,7 +49,7 @@ typedef struct request { int local; int sock; int mtu; - int flags; + int flags; char *buf; int len; } sdp_req_t; diff --git a/sdpd/service.c b/sdpd/service.c index c69aa509..0834122d 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -1,39 +1,38 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - 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. -*/ - -/* - Service registration requests. - - Fixes: - Guruprasad Krishnamurthy -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * 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 +#endif + #include #include diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 36035a81..5a6469f5 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -1,42 +1,38 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - 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. -*/ - -/* - Service repository. - Has methods to create and clean the repository, besides - methods to add/find/modify/delete individual entries - - Fixes: - Guruprasad Krishnamurthy - Manel Guerrero Zapata -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * 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 +#endif + #include #include #include -- cgit From 7b767cdc03c44f2626eb80129fc0b78460f882fc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 23:11:23 +0000 Subject: Fix server information --- sdpd/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index b2262acd..8b6089d4 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -419,7 +419,7 @@ int main(int argc, char **argv) return -1; } - SDPINF("sdpd v%s started", VERSION); + SDPINF("Bluetooth SDP daemon"); signal(SIGINT, sig_term); signal(SIGTERM, sig_term); -- cgit From 7ac6ede99ac309c7e28f3c2993fbc9bbbe28a68b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 May 2004 10:39:50 +0000 Subject: Use LIBS instead of LDFLAGS --- sdpd/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 97f9b9e1..6fb5411f 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -6,7 +6,7 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ -- cgit From 43f017c9527dd4f64670831114f3c85f5defebbd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:05:27 +0000 Subject: Use AM_CFLAGS instead of INCLUDES --- sdpd/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 6fb5411f..0f4460b5 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -8,7 +8,7 @@ sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = sdpd.8 -- cgit From 15c1cf1ca0d2fc45dff471d71339db49deecd1cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:20:28 +0000 Subject: Make use of MAINTAINERCLEANFILES --- sdpd/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 0f4460b5..44d4ba8d 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -13,3 +13,5 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = sdpd.8 EXTRA_DIST = $(man_MANS) + +MAINTAINERCLEANFILES = Makefile.in -- cgit From c8c2b3ffa0c932033a5c666a49481122e58cec27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 1 Oct 2004 11:40:15 +0000 Subject: Change dynamic assignment of record handles to a more standard one --- sdpd/main.c | 5 ++++- sdpd/sdpd.h | 1 + sdpd/service.c | 5 ++++- sdpd/servicedb.c | 10 ++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 8b6089d4..0efc7d50 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -106,7 +106,10 @@ static void register_public_browse_group(void) sdp_data_t *sdpdata; sdp_record_t *browse = sdp_record_alloc(); - browse->handle = (uint32_t)browse; + browse->handle = sdp_next_handle(); + if (browse->handle < 0x10000) + return; + sdp_record_add(browse); sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 30eb1de3..bc085c83 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -83,6 +83,7 @@ sdp_record_t *sdp_record_find(uint32_t handle); void sdp_record_add(sdp_record_t *rec); int sdp_record_remove(uint32_t handle); sdp_list_t *sdp_get_record_list(); +uint32_t sdp_next_handle(void); long sdp_get_time(); diff --git a/sdpd/service.c b/sdpd/service.c index 0834122d..a8d93994 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -141,7 +141,10 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) return -1; } - rec->handle = (uint32_t)rec; + rec->handle = sdp_next_handle(); + if (rec->handle < 0x10000) + return -1; + sdp_record_add(rec); if (!(req->flags & SDP_RECORD_PERSIST)) sdp_svcdb_set_collectable(rec, req->sock); diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 5a6469f5..9f87eca6 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -203,3 +203,13 @@ sdp_list_t *sdp_get_record_list() { return service_db; } + +uint32_t sdp_next_handle(void) +{ + uint32_t handle = 0x10000; + + while (sdp_record_find(handle)) + handle++; + + return handle; +} -- cgit From bbda499067067aefc8e642a2784d247ac0331eae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 25 Dec 2004 17:43:16 +0000 Subject: Add memset() to different places to initialize the structures --- sdpd/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 0efc7d50..eb59a6fa 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -318,6 +318,7 @@ static inline void handle_request(int sk, char *data, int len) if (sa.l2_family == AF_BLUETOOTH) { struct l2cap_options lo; + memset(&lo, 0, sizeof(lo)); size = sizeof(lo); getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); req.bdaddr = sa.l2_bdaddr; -- cgit From fa8b3a2161c997be308438040641dc0445f9d494 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 15:21:59 +0000 Subject: Always include the stdio.h header file --- sdpd/cstate.c | 1 + sdpd/request.c | 1 + sdpd/service.c | 1 + sdpd/servicedb.c | 1 + 4 files changed, 4 insertions(+) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index 8f9db218..735d5850 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include diff --git a/sdpd/request.c b/sdpd/request.c index 7bdecb7a..dbb3ff37 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include #include diff --git a/sdpd/service.c b/sdpd/service.c index a8d93994..f2457e1f 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 9f87eca6..5006fbb4 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include #include -- cgit From f5b612c1e96b3bf7d5c695417ed88a26dd5be776 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 4 Mar 2005 14:31:40 +0000 Subject: Hide the server record and the public browse group root --- sdpd/main.c | 64 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 26 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index eb59a6fa..fc3dd22d 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -58,16 +58,16 @@ static int l2cap_sock, unix_sock; static fd_set active_fdset; static int active_maxfd; -sdp_record_t *server; +static sdp_record_t *server; /* * List of version numbers supported by the SDP server. * Add to this list when newer versions are supported. */ static sdp_version_t sdpVnumArray[1] = { - {1, 0} + { 1, 0 } }; -const int sdpServerVnumEntries = 1; +static const int sdpServerVnumEntries = 1; /* * The service database state is an attribute of the service record @@ -99,16 +99,19 @@ static void add_lang_attr(sdp_record_t *r) sdp_list_free(langs, 0); } -static void register_public_browse_group(void) +static void register_public_browse_group(int public) { sdp_list_t *browselist; uuid_t bgscid, pbgid; sdp_data_t *sdpdata; sdp_record_t *browse = sdp_record_alloc(); - browse->handle = sdp_next_handle(); - if (browse->handle < 0x10000) - return; + if (public) { + browse->handle = sdp_next_handle(); + if (browse->handle < 0x10000) + return; + } else + browse->handle = SDP_SERVER_RECORD_HANDLE + 1; sdp_record_add(browse); sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); @@ -122,8 +125,10 @@ static void register_public_browse_group(void) sdp_set_service_classes(browse, browselist); sdp_list_free(browselist, 0); - sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); - sdp_set_group_id(browse, pbgid); + if (public) { + sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); + sdp_set_group_id(browse, pbgid); + } } /* @@ -132,7 +137,7 @@ static void register_public_browse_group(void) * discovery clients. This method constructs a service record * and stores it in the repository */ -static void register_server_service(void) +static void register_server_service(int public) { int i; sdp_list_t *classIDList, *browseList; @@ -208,10 +213,12 @@ static void register_server_service(void) sdp_data_free(version_data); sdp_list_free(pd, 0); - sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); - browseList = sdp_list_append(0, &browseGroupId); - sdp_set_browse_groups(server, browseList); - sdp_list_free(browseList, 0); + if (public) { + sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); + browseList = sdp_list_append(0, &browseGroupId); + sdp_set_browse_groups(server, browseList); + sdp_list_free(browseList, 0); + } update_db_timestamp(); } @@ -221,16 +228,16 @@ static void register_server_service(void) * l2cap and unix sockets over which discovery and registration clients * access us respectively */ -int init_server(int master) +static int init_server(int master, int public) { struct sockaddr_l2 l2addr; struct sockaddr_un unaddr; /* Register the public browse group root */ - register_public_browse_group(); + register_public_browse_group(public); /* Register the SDP server's service record */ - register_server_service(); + register_server_service(public); /* Create L2CAP socket */ l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); @@ -278,7 +285,7 @@ int init_server(int master) return 0; } -void sig_term(int sig) +static void sig_term(int sig) { SDPINF("terminating... \n"); sdp_svcdb_reset(); @@ -287,7 +294,7 @@ void sig_term(int sig) exit(0); } -int become_daemon(void) +static int become_daemon(void) { int fd; @@ -377,7 +384,7 @@ static void check_active(fd_set *mask, int num) } } -void usage(void) +static void usage(void) { printf("sdpd version %s\n", VERSION); printf("Usage:\n" @@ -386,19 +393,21 @@ void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"nodaemon", 0,0, 'n'}, - {"master", 0,0, 'm'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "nodaemon", 0, 0, 'n' }, + { "master", 0, 0, 'm' }, + { "public", 0, 0, 'p' }, + { 0, 0, 0, 0} }; int main(int argc, char **argv) { int daemon = 1; int master = 0; + int public = 0; int opt; - while ((opt = getopt_long(argc, argv, "nm", main_options, NULL)) != -1) + while ((opt = getopt_long(argc, argv, "nmp", main_options, NULL)) != -1) switch (opt) { case 'n': daemon = 0; @@ -406,6 +415,9 @@ int main(int argc, char **argv) case 'm': master = 1; break; + case 'p': + public = 1; + break; default: usage(); exit(0); @@ -418,7 +430,7 @@ int main(int argc, char **argv) argc -= optind; argv += optind; - if (init_server(master) < 0) { + if (init_server(master, public) < 0) { SDPERR("Server initialization failed"); return -1; } -- cgit From cfb680f0660169fe231c575cb2a0c7f72826f4f4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Mar 2005 17:27:17 +0000 Subject: Use uint32_t instead of long --- sdpd/cstate.c | 10 ++++++---- sdpd/request.c | 4 ++-- sdpd/sdpd.h | 6 +++--- sdpd/servicedb.c | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index 735d5850..dd532943 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -36,7 +36,9 @@ #include #include #include +#include +#include #include #include @@ -46,7 +48,7 @@ typedef struct _sdp_cstate_list sdp_cstate_list_t; struct _sdp_cstate_list { sdp_cstate_list_t *next; - long timestamp; + uint32_t timestamp; sdp_buf_t buf; }; @@ -63,7 +65,7 @@ sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) return 0; } -long sdp_cstate_alloc_buf(sdp_buf_t *buf) +uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf) { sdp_cstate_list_t *cstate = (sdp_cstate_list_t *)malloc(sizeof(sdp_cstate_list_t)); char *data = (char *)malloc(buf->data_size); @@ -84,7 +86,7 @@ long sdp_cstate_alloc_buf(sdp_buf_t *buf) * seconds. Used for updating the service db state * attribute of the service record of the SDP server */ -long sdp_get_time() +uint32_t sdp_get_time() { /* * To handle failure in gettimeofday, so an old @@ -93,5 +95,5 @@ long sdp_get_time() static struct timeval tm; gettimeofday(&tm, NULL); - return tm.tv_sec; + return (uint32_t) tm.tv_sec; } diff --git a/sdpd/request.c b/sdpd/request.c index dbb3ff37..6a62e55f 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -238,7 +238,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) sdp_cont_state_t *cstate = NULL; char *pCacheBuffer = NULL; int handleSize = 0; - long cStateId = -1; + uint32_t cStateId = 0; short rsp_count = 0; short *pTotalRecordCount, *pCurrentRecordCount; int mtu; @@ -331,7 +331,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) } /* under both the conditions below, the rsp buffer is not built yet */ - if (cstate || cStateId != -1) { + if (cstate || cStateId > 0) { short lastIndex = 0; if (cstate) { diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index bc085c83..6d9c856a 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -61,7 +61,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp); int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp); typedef struct { - long timestamp; + uint32_t timestamp; union { uint16_t maxBytesSent; uint16_t lastIndexSent; @@ -73,7 +73,7 @@ typedef struct { sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate); void sdp_cstate_cache_init(void); void sdp_cstate_clean_buf(void); -long sdp_cstate_alloc_buf(sdp_buf_t *buf); +uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf); void sdp_svcdb_reset(void); void sdp_svcdb_collect_all(int sock); @@ -85,6 +85,6 @@ int sdp_record_remove(uint32_t handle); sdp_list_t *sdp_get_record_list(); uint32_t sdp_next_handle(void); -long sdp_get_time(); +uint32_t sdp_get_time(); #endif diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 5006fbb4..45f45b91 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -146,8 +146,8 @@ void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) void sdp_record_add(sdp_record_t *rec) { #ifdef SDP_DEBUG - SDPDBG("Adding rec : 0x%lx\n", (long)rec); - SDPDBG("with handle : 0x%lx\n", (long)rec->handle); + SDPDBG("Adding rec : 0x%lx\n", (long) rec); + SDPDBG("with handle : 0x%x\n", rec->handle); #endif service_db = sdp_list_insert_sorted(service_db, rec, record_sort); } -- cgit From adbb22a47c9356e0c191a75daec0439e8d941bd1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 21:34:08 +0000 Subject: Use LDADD instead of LIBS --- sdpd/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 44d4ba8d..f2d55754 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -5,8 +5,7 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h - -LIBS = @BLUEZ_LIBS@ +sdpd_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ -- cgit From 1f422e5f2b343d35a8c77ce4be16f74b2819b2bf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 21:15:41 +0000 Subject: Fix some GCC 4.0 warnings --- sdpd/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index fc3dd22d..b80fc0bb 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -316,7 +316,7 @@ static int become_daemon(void) static inline void handle_request(int sk, char *data, int len) { struct sockaddr_l2 sa; - int size; + socklen_t size; sdp_req_t req; size = sizeof(sa); -- cgit From e2a54220b404119a2516a3cac5edc5b2bcf6089a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 6 Jul 2005 00:12:58 +0000 Subject: Fix more GCC 4.0 warnings --- sdpd/cstate.c | 2 +- sdpd/main.c | 4 ++-- sdpd/request.c | 30 +++++++++++++++--------------- sdpd/sdpd.h | 2 +- sdpd/service.c | 8 ++++---- 5 files changed, 23 insertions(+), 23 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index dd532943..c983ef74 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -68,7 +68,7 @@ sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf) { sdp_cstate_list_t *cstate = (sdp_cstate_list_t *)malloc(sizeof(sdp_cstate_list_t)); - char *data = (char *)malloc(buf->data_size); + uint8_t *data = malloc(buf->data_size); memcpy(data, buf->data, buf->data_size); memset((char *)cstate, 0, sizeof(sdp_cstate_list_t)); diff --git a/sdpd/main.c b/sdpd/main.c index b80fc0bb..51accc9a 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -313,7 +313,7 @@ static int become_daemon(void) return 1; } -static inline void handle_request(int sk, char *data, int len) +static inline void handle_request(int sk, uint8_t *data, int len) { struct sockaddr_l2 sa; socklen_t size; @@ -357,7 +357,7 @@ static void check_active(fd_set *mask, int num) { sdp_pdu_hdr_t hdr; int size, fd, count, r; - char *buf; + uint8_t *buf; for (fd = 0, count = 0; fd <= active_maxfd && count < num; fd++) { if (fd == l2cap_sock || fd == unix_sock || !FD_ISSET(fd, mask)) diff --git a/sdpd/request.c b/sdpd/request.c index 6a62e55f..356ce1d8 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -57,7 +57,7 @@ * sequence. The data type of elements found in the * sequence is returned in the reference pDataType */ -static int extract_des(char *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType) +static int extract_des(uint8_t *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType) { uint8_t seqType; int data_size = 0; @@ -67,7 +67,7 @@ static int extract_des(char *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, ui sdp_list_t *pSeq = NULL; uint8_t dataType; int status = 0; - const char *p; + const uint8_t *p; SDPDBG("Seq type : %d\n", seqType); if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) { @@ -142,7 +142,7 @@ static int extract_des(char *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, ui static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate) { - char *pdata = buf->data + buf->data_size; + uint8_t *pdata = buf->data + buf->data_size; int length = 0; if (cstate) { @@ -162,9 +162,9 @@ static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate) return length; } -static sdp_cont_state_t *sdp_cstate_get(char *buffer) +static sdp_cont_state_t *sdp_cstate_get(uint8_t *buffer) { - char *pdata = buffer; + uint8_t *pdata = buffer; uint8_t cStateSize = *(uint8_t *)pdata; /* @@ -233,16 +233,16 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) { int status = 0, i, plen, mlen; sdp_list_t *pattern = NULL; - int expected, actual; + uint16_t expected, actual; uint8_t dtd; sdp_cont_state_t *cstate = NULL; - char *pCacheBuffer = NULL; + uint8_t *pCacheBuffer = NULL; int handleSize = 0; uint32_t cStateId = 0; short rsp_count = 0; short *pTotalRecordCount, *pCurrentRecordCount; int mtu; - char *pdata = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); int scanned = extract_des(pdata, &pattern, &dtd, SDP_TYPE_UUID); SDPDBG(""); @@ -361,7 +361,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) * current record count and increment the cached * buffer pointer to beyond the counters */ - pdata = (char *)pCurrentRecordCount + sizeof(uint16_t); + pdata = (uint8_t *) pCurrentRecordCount + sizeof(uint16_t); /* increment beyond the totalCount and the currentCount */ pCacheBuffer += 2 * sizeof(uint16_t); @@ -486,14 +486,14 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) { sdp_cont_state_t *cstate = NULL; - char *pResponse = NULL; + uint8_t *pResponse = NULL; short cstate_size = 0; sdp_list_t *seq = NULL; uint8_t dtd = 0; int scanned = 0; int max_rsp_size; int status = 0, plen, mlen; - char *pdata = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)pdata)); SDPDBG(""); @@ -605,7 +605,7 @@ done: static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) { int status = 0, plen, totscanned; - char *pdata, *pResponse = NULL; + uint8_t *pdata, *pResponse = NULL; int scanned, max, rsp_count = 0; sdp_list_t *pattern = NULL, *seq = NULL, *svcList; sdp_cont_state_t *cstate = NULL; @@ -653,7 +653,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) svcList = sdp_get_record_list(); - tmpbuf.data = (char *)malloc(USHRT_MAX); + tmpbuf.data = malloc(USHRT_MAX); tmpbuf.data_size = 0; tmpbuf.buf_size = USHRT_MAX; memset(tmpbuf.data, 0, USHRT_MAX); @@ -765,13 +765,13 @@ void process_request(sdp_req_t *req) sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)req->buf; sdp_pdu_hdr_t *rsphdr; sdp_buf_t rsp; - char *buf = (char *)malloc(USHRT_MAX); + uint8_t *buf = malloc(USHRT_MAX); int sent = 0; int status = SDP_INVALID_SYNTAX; SDPDBG(""); - memset((void *)buf, 0, USHRT_MAX); + memset(buf, 0, USHRT_MAX); rsp.data = buf + sizeof(sdp_pdu_hdr_t); rsp.data_size = 0; rsp.buf_size = USHRT_MAX - sizeof(sdp_pdu_hdr_t); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 6d9c856a..3df83fca 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -50,7 +50,7 @@ typedef struct request { int sock; int mtu; int flags; - char *buf; + uint8_t *buf; int len; } sdp_req_t; diff --git a/sdpd/service.c b/sdpd/service.c index f2457e1f..843371ea 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -46,7 +46,7 @@ extern void update_db_timestamp(void); // FIXME: refactor for server-side -static sdp_record_t *extract_pdu_server(char *p, uint32_t handleExpected, int *scanned) +static sdp_record_t *extract_pdu_server(uint8_t *p, uint32_t handleExpected, int *scanned) { int extractStatus = -1, localExtractedLength = 0; uint8_t dtd; @@ -129,7 +129,7 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) { int scanned = 0; sdp_data_t *handle; - char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); sdp_record_t *rec; req->flags = *p++; @@ -175,7 +175,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) { sdp_record_t *orec; int status = 0, scanned = 0; - char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); SDPDBG(""); @@ -217,7 +217,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) */ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) { - char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); sdp_record_t *rec; int status = 0; -- cgit From b0ba2fc57a3da851aa0bb7ff6bbf78347c838221 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 3 Aug 2005 07:57:12 +0000 Subject: Add device specific register functionality --- sdpd/main.c | 11 ++++++++--- sdpd/sdpd.h | 3 ++- sdpd/service.c | 20 ++++++++++++-------- sdpd/servicedb.c | 2 +- 4 files changed, 23 insertions(+), 13 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 51accc9a..734b8bda 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -113,7 +113,7 @@ static void register_public_browse_group(int public) } else browse->handle = SDP_SERVER_RECORD_HANDLE + 1; - sdp_record_add(browse); + sdp_record_add(BDADDR_ANY, browse); sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); @@ -155,7 +155,7 @@ static void register_server_service(int public) /* Force the record to be SDP_SERVER_RECORD_HANDLE */ server->handle = SDP_SERVER_RECORD_HANDLE; - sdp_record_add(server); + sdp_record_add(BDADDR_ANY, server); sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); /* @@ -320,7 +320,7 @@ static inline void handle_request(int sk, uint8_t *data, int len) sdp_req_t req; size = sizeof(sa); - if (getpeername(sk, (struct sockaddr *)&sa, &size) < 0) + if (getpeername(sk, (struct sockaddr *) &sa, &size) < 0) return; if (sa.l2_family == AF_BLUETOOTH) { @@ -331,7 +331,12 @@ static inline void handle_request(int sk, uint8_t *data, int len) req.bdaddr = sa.l2_bdaddr; req.mtu = lo.omtu; req.local = 0; + memset(&sa, 0, sizeof(sa)); + size = sizeof(sa); + getsockname(sk, (struct sockaddr *) &sa, &size); + req.device = sa.l2_bdaddr; } else { + req.device = *BDADDR_ANY; req.bdaddr = *BDADDR_LOCAL; req.mtu = 2048; req.local = 1; diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 3df83fca..0bca315f 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -45,6 +45,7 @@ #endif typedef struct request { + bdaddr_t device; bdaddr_t bdaddr; int local; int sock; @@ -80,7 +81,7 @@ void sdp_svcdb_collect_all(int sock); void sdp_svcdb_set_collectable(sdp_record_t *rec, int sock); void sdp_svcdb_collect(sdp_record_t *rec); sdp_record_t *sdp_record_find(uint32_t handle); -void sdp_record_add(sdp_record_t *rec); +void sdp_record_add(bdaddr_t *device, sdp_record_t *rec); int sdp_record_remove(uint32_t handle); sdp_list_t *sdp_get_record_list(); uint32_t sdp_next_handle(void); diff --git a/sdpd/service.c b/sdpd/service.c index 843371ea..437bcd69 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -46,7 +46,7 @@ extern void update_db_timestamp(void); // FIXME: refactor for server-side -static sdp_record_t *extract_pdu_server(uint8_t *p, uint32_t handleExpected, int *scanned) +static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t handleExpected, int *scanned) { int extractStatus = -1, localExtractedLength = 0; uint8_t dtd; @@ -71,15 +71,15 @@ static sdp_record_t *extract_pdu_server(uint8_t *p, uint32_t handleExpected, int } else if (handleExpected != 0xffffffff) rec = sdp_record_find(handleExpected); - if (rec == NULL) { + if (!rec) { rec = sdp_record_alloc(); rec->attrlist = NULL; if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { rec->handle = handle; - sdp_record_add(rec); + sdp_record_add(device, rec); } else if (handleExpected != 0xffffffff) { rec->handle = handleExpected; - sdp_record_add(rec); + sdp_record_add(device, rec); } } @@ -133,10 +133,14 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_record_t *rec; req->flags = *p++; + if (req->flags & SDP_DEVICE_RECORD) { + bacpy(&req->device, (bdaddr_t *) p); + p += sizeof(bdaddr_t); + } // save image of PDU: we need it when clients request this attribute - rec = extract_pdu_server(p, 0xffffffff, &scanned); - if (rec == NULL) { + rec = extract_pdu_server(&req->device, p, 0xffffffff, &scanned); + if (!rec) { sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *)rsp->data); rsp->data_size = sizeof(uint16_t); return -1; @@ -146,7 +150,7 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) if (rec->handle < 0x10000) return -1; - sdp_record_add(rec); + sdp_record_add(&req->device, rec); if (!(req->flags & SDP_RECORD_PERSIST)) sdp_svcdb_set_collectable(rec, req->sock); handle = sdp_data_alloc(SDP_UINT32, &rec->handle); @@ -189,7 +193,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) SDPDBG("SvcRecOld: 0x%x\n", (uint32_t)orec); if (orec) { - sdp_record_t *nrec = extract_pdu_server(p, handle, &scanned); + sdp_record_t *nrec = extract_pdu_server(BDADDR_ANY, p, handle, &scanned); if (nrec && handle == nrec->handle) update_db_timestamp(); else { diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 45f45b91..c977bc81 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -143,7 +143,7 @@ void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) /* * Add a service record to the repository */ -void sdp_record_add(sdp_record_t *rec) +void sdp_record_add(bdaddr_t *device, sdp_record_t *rec) { #ifdef SDP_DEBUG SDPDBG("Adding rec : 0x%lx\n", (long) rec); -- cgit From 028619a565a8dd60da011170f8ce326de78a1e47 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 02:59:23 +0000 Subject: Add support for device specific SDP records --- sdpd/main.c | 16 +++---- sdpd/request.c | 10 ++-- sdpd/sdpd.h | 4 +- sdpd/servicedb.c | 138 +++++++++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 131 insertions(+), 37 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 734b8bda..27d2f800 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -328,18 +328,18 @@ static inline void handle_request(int sk, uint8_t *data, int len) memset(&lo, 0, sizeof(lo)); size = sizeof(lo); getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); - req.bdaddr = sa.l2_bdaddr; - req.mtu = lo.omtu; - req.local = 0; + bacpy(&req.bdaddr, &sa.l2_bdaddr); + req.mtu = lo.omtu; + req.local = 0; memset(&sa, 0, sizeof(sa)); size = sizeof(sa); getsockname(sk, (struct sockaddr *) &sa, &size); - req.device = sa.l2_bdaddr; + bacpy(&req.device, &sa.l2_bdaddr); } else { - req.device = *BDADDR_ANY; - req.bdaddr = *BDADDR_LOCAL; - req.mtu = 2048; - req.local = 1; + bacpy(&req.device, BDADDR_ANY); + bacpy(&req.bdaddr, BDADDR_LOCAL); + req.mtu = 2048; + req.local = 1; } req.sock = sk; req.buf = data; diff --git a/sdpd/request.c b/sdpd/request.c index 356ce1d8..07051f9f 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -298,11 +298,12 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) handleSize = 0; for (; list && rsp_count < expected; list = list->next) { - sdp_record_t *rec = (sdp_record_t *)list->data; + sdp_record_t *rec = (sdp_record_t *) list->data; SDPDBG("Checking svcRec : 0x%x\n", rec->handle); - if (sdp_match_uuid(pattern, rec->pattern) > 0) { + if (sdp_match_uuid(pattern, rec->pattern) > 0 && + sdp_check_access(rec->handle, &req->device)) { rsp_count++; sdp_put_unaligned(htonl(rec->handle), (uint32_t *)pdata); pdata += sizeof(uint32_t); @@ -672,8 +673,9 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) /* no continuation state -> create new response */ sdp_list_t *p; for (p = svcList; p; p = p->next) { - sdp_record_t *rec = (sdp_record_t *)p->data; - if (sdp_match_uuid(pattern, rec->pattern) > 0) { + sdp_record_t *rec = (sdp_record_t *) p->data; + if (sdp_match_uuid(pattern, rec->pattern) > 0 && + sdp_check_access(rec->handle, &req->device)) { rsp_count++; status = extract_attrs(rec, seq, dtd, &tmpbuf); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 0bca315f..af028a4f 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -83,7 +83,9 @@ void sdp_svcdb_collect(sdp_record_t *rec); sdp_record_t *sdp_record_find(uint32_t handle); void sdp_record_add(bdaddr_t *device, sdp_record_t *rec); int sdp_record_remove(uint32_t handle); -sdp_list_t *sdp_get_record_list(); +sdp_list_t *sdp_get_record_list(void); +sdp_list_t *sdp_get_access_list(void); +int sdp_check_access(uint32_t handle, bdaddr_t *device); uint32_t sdp_next_handle(void); uint32_t sdp_get_time(); diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index c977bc81..6a1e2279 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -46,6 +46,12 @@ #include "sdpd.h" static sdp_list_t *service_db; +static sdp_list_t *access_db; + +typedef struct { + uint32_t handle; + bdaddr_t device; +} sdp_access_t; /* * Ordering function called when inserting a service record. @@ -54,22 +60,42 @@ static sdp_list_t *service_db; */ static int record_sort(const void *r1, const void *r2) { - const sdp_record_t *rec1 = (const sdp_record_t *)r1; - const sdp_record_t *rec2 = (const sdp_record_t *)r2; + const sdp_record_t *rec1 = (const sdp_record_t *) r1; + const sdp_record_t *rec2 = (const sdp_record_t *) r2; if (!rec1 || !rec2) { SDPERR("NULL RECORD LIST FATAL\n"); return -1; } + return rec1->handle - rec2->handle; } +static int access_sort(const void *r1, const void *r2) +{ + const sdp_access_t *rec1 = (const sdp_access_t *) r1; + const sdp_access_t *rec2 = (const sdp_access_t *) r2; + + if (!rec1 || !rec2) { + SDPERR("NULL RECORD LIST FATAL\n"); + return -1; + } + + return rec1->handle - rec2->handle; +} + +static void access_free(void *p) +{ + free(p); +} + /* * Reset the service repository by deleting its contents */ void sdp_svcdb_reset() { - sdp_list_free(service_db, (sdp_free_func_t)sdp_record_free); + sdp_list_free(service_db, (sdp_free_func_t) sdp_record_free); + sdp_list_free(access_db, access_free); } typedef struct _indexed { @@ -86,8 +112,8 @@ void sdp_svcdb_collect_all(int sock) { sdp_list_t *p, *q; - for (p=socket_index, q=0; p; ) { - sdp_indexed_t *item = (sdp_indexed_t *)p->data; + for (p = socket_index, q = 0; p; ) { + sdp_indexed_t *item = (sdp_indexed_t *) p->data; if (item->sock == sock) { sdp_list_t *next = p->next; sdp_record_remove(item->record->handle); @@ -111,8 +137,8 @@ void sdp_svcdb_collect(sdp_record_t *rec) { sdp_list_t *p, *q; - for (p=socket_index, q=0; p; q=p, p=p->next) { - sdp_indexed_t *item = (sdp_indexed_t *)p->data; + for (p = socket_index, q = 0; p; q = p, p = p->next) { + sdp_indexed_t *item = (sdp_indexed_t *) p->data; if (rec == item->record) { free(item); if (q) @@ -127,14 +153,14 @@ void sdp_svcdb_collect(sdp_record_t *rec) static int compare_indices(const void *i1, const void *i2) { - const sdp_indexed_t *s1 = (const sdp_indexed_t *)i1; - const sdp_indexed_t *s2 = (const sdp_indexed_t *)i2; + const sdp_indexed_t *s1 = (const sdp_indexed_t *) i1; + const sdp_indexed_t *s2 = (const sdp_indexed_t *) i2; return s1->sock - s2->sock; } void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) { - sdp_indexed_t *item = (sdp_indexed_t *)malloc(sizeof(sdp_indexed_t)); + sdp_indexed_t *item = malloc(sizeof(sdp_indexed_t)); item->sock = sock; item->record = record; socket_index = sdp_list_insert_sorted(socket_index, item, compare_indices); @@ -145,11 +171,22 @@ void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) */ void sdp_record_add(bdaddr_t *device, sdp_record_t *rec) { + sdp_access_t *dev; + #ifdef SDP_DEBUG SDPDBG("Adding rec : 0x%lx\n", (long) rec); SDPDBG("with handle : 0x%x\n", rec->handle); #endif service_db = sdp_list_insert_sorted(service_db, rec, record_sort); + + dev = malloc(sizeof(*dev)); + if (!dev) + return; + + bacpy(&dev->device, device); + dev->handle = rec->handle; + + access_db = sdp_list_insert_sorted(access_db, dev, access_sort); } static sdp_list_t *record_locate(uint32_t handle) @@ -162,8 +199,24 @@ static sdp_list_t *record_locate(uint32_t handle) p = sdp_list_find(service_db, &r, record_sort); return p; } + SDPDBG("Could not find svcRec for : 0x%x\n", handle); - return 0; + return NULL; +} + +static sdp_list_t *access_locate(uint32_t handle) +{ + if (access_db) { + sdp_list_t *p; + sdp_access_t a; + + a.handle = handle; + p = sdp_list_find(access_db, &a, access_sort); + return p; + } + + SDPDBG("Could not find access data for : 0x%x\n", handle); + return NULL; } /* @@ -171,12 +224,14 @@ static sdp_list_t *record_locate(uint32_t handle) */ sdp_record_t *sdp_record_find(uint32_t handle) { - sdp_list_t *p = record_locate(handle); + sdp_list_t *p = record_locate(handle); + + if (!p) { + SDPDBG("Couldn't find record for : 0x%x\n", handle); + return 0; + } - if (p) - return (sdp_record_t *)p->data; - SDPDBG("Couldn't find record for : 0x%x\n", handle); - return 0; + return (sdp_record_t *) p->data; } /* @@ -185,26 +240,61 @@ sdp_record_t *sdp_record_find(uint32_t handle) int sdp_record_remove(uint32_t handle) { sdp_list_t *p = record_locate(handle); + sdp_record_t *r; + sdp_access_t *a; + + if (!p) { + SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); + return -1; + } + + r = (sdp_record_t *) p->data; + if (r) + service_db = sdp_list_remove(service_db, r); + p = access_locate(handle); if (p) { - sdp_record_t *r = (sdp_record_t *)p->data; - if (r) { - service_db = sdp_list_remove(service_db, r); - return 0; - } + a = (sdp_access_t *) p->data; + if (a) + access_db = sdp_list_remove(access_db, a); } - SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); - return -1; + + return 0; } /* * Return a pointer to the linked list containing the records in sorted order */ -sdp_list_t *sdp_get_record_list() +sdp_list_t *sdp_get_record_list(void) { return service_db; } +sdp_list_t *sdp_get_access_list(void) +{ + return access_db; +} + +int sdp_check_access(uint32_t handle, bdaddr_t *device) +{ + sdp_list_t *p = access_locate(handle); + sdp_access_t *a; + + if (!p) + return 1; + + a = (sdp_access_t *) p->data; + if (!a) + return 1; + + if (bacmp(&a->device, device) && + bacmp(&a->device, BDADDR_ANY) && + bacmp(device, BDADDR_ANY)) + return 0; + + return 1; +} + uint32_t sdp_next_handle(void) { uint32_t handle = 0x10000; -- cgit From 632a9432774ff3a0c6e556e8f32a565b38890767 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 22:36:31 +0000 Subject: Big cleanup of CVS relics --- sdpd/Makefile.am | 3 --- sdpd/cstate.c | 28 ++++++++++++---------------- sdpd/main.c | 37 ++++++++++++++++--------------------- sdpd/request.c | 31 ++++++++++++++----------------- sdpd/sdpd.h | 32 +++++++++++--------------------- sdpd/service.c | 31 ++++++++++++++----------------- sdpd/servicedb.c | 28 ++++++++++++---------------- 7 files changed, 79 insertions(+), 111 deletions(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index f2d55754..018a66f1 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# sbin_PROGRAMS = sdpd diff --git a/sdpd/cstate.c b/sdpd/cstate.c index c983ef74..6cb8abbd 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -4,29 +4,24 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * 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; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,6 +29,7 @@ #endif #include +#include #include #include #include diff --git a/sdpd/main.c b/sdpd/main.c index 27d2f800..0181657c 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -4,54 +4,49 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * 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; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H #include #endif -#include -#include #include #include +#include +#include #include #include #include -#include -#include #include #include #include -#include #include #include #include #include +#include +#include + #include "sdpd.h" static int l2cap_sock, unix_sock; diff --git a/sdpd/request.c b/sdpd/request.c index 07051f9f..e0331683 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -4,29 +4,24 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * 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; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,15 +29,17 @@ #endif #include +#include #include #include -#include #include #include #include #include +#include + #include "sdpd.h" #define MIN(x, y) ((x) < (y))? (x): (y) diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index af028a4f..94bd9056 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -4,34 +4,26 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * 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; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ -#ifndef SDPD_H -#define SDPD_H - #define sdp_get_unaligned bt_get_unaligned #define sdp_put_unaligned bt_put_unaligned @@ -89,5 +81,3 @@ int sdp_check_access(uint32_t handle, bdaddr_t *device); uint32_t sdp_next_handle(void); uint32_t sdp_get_time(); - -#endif diff --git a/sdpd/service.c b/sdpd/service.c index 437bcd69..71b141bc 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -4,29 +4,24 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * 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; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,13 +29,15 @@ #endif #include -#include +#include #include #include #include #include +#include + #include "sdpd.h" extern void update_db_timestamp(void); diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 6a1e2279..d2c08493 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -4,29 +4,24 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * 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; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,6 +29,7 @@ #endif #include +#include #include #include #include -- cgit From f2e48c44a7e4c9ee31b8ce2e302186f6047cfeab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 13:28:56 +0000 Subject: Update copyright information --- sdpd/cstate.c | 2 +- sdpd/main.c | 2 +- sdpd/request.c | 2 +- sdpd/sdpd.h | 2 +- sdpd/service.c | 2 +- sdpd/servicedb.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index 6cb8abbd..d09e9423 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/main.c b/sdpd/main.c index 0181657c..dd725c81 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/request.c b/sdpd/request.c index e0331683..9e3f966f 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 94bd9056..e73936c3 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/service.c b/sdpd/service.c index 71b141bc..0bdc87fb 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index d2c08493..7e8b5d19 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * -- cgit From ea30752670dc9a522c0ef29c431c3a4cefd9cc83 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jan 2006 15:08:42 +0000 Subject: Fix service record registration --- sdpd/service.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index 0bdc87fb..cd40541b 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -137,21 +137,25 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) // save image of PDU: we need it when clients request this attribute rec = extract_pdu_server(&req->device, p, 0xffffffff, &scanned); - if (!rec) { - sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *)rsp->data); - rsp->data_size = sizeof(uint16_t); - return -1; - } + if (!rec) + goto invalid; - rec->handle = sdp_next_handle(); - if (rec->handle < 0x10000) - return -1; + if (rec->handle == 0xffffffff) { + rec->handle = sdp_next_handle(); + if (rec->handle < 0x10000) + goto invalid; + } else { + if (sdp_record_find(rec->handle)) + goto invalid; + } sdp_record_add(&req->device, rec); if (!(req->flags & SDP_RECORD_PERSIST)) sdp_svcdb_set_collectable(rec, req->sock); + handle = sdp_data_alloc(SDP_UINT32, &rec->handle); sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, handle); + /* * if the browse group descriptor is NULL, * ensure that the record belongs to the ROOT group @@ -161,12 +165,20 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); sdp_pattern_add_uuid(rec, &uuid); } + update_db_timestamp(); /* Build a rsp buffer */ sdp_put_unaligned(htonl(rec->handle), (uint32_t *)rsp->data); rsp->data_size = sizeof(uint32_t); + return 0; + +invalid: + sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *) rsp->data); + rsp->data_size = sizeof(uint16_t); + + return -1; } /* -- cgit From fc073b9af90ff44efcbb318633d026e754f86907 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jan 2006 16:19:28 +0000 Subject: Redirect stdin, stdout, stderr to /dev/null for daemon --- sdpd/main.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index dd725c81..685ffa8b 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -301,8 +302,16 @@ static int become_daemon(void) return 0; setsid(); } - for (fd = 0; fd < 3; fd++) - close(fd); + + fd = open("/dev/null", O_RDWR); + if (fd != -1) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + + if (fd > STDERR_FILENO) + close(fd); + } chdir("/"); return 1; -- cgit From 3b5b20a3873b4d52041baf1cb11fbd0965ed39b8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:32:28 +0000 Subject: Make use of the daemon() function --- sdpd/main.c | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 685ffa8b..663200be 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -30,7 +30,6 @@ #include #include -#include #include #include #include @@ -290,33 +289,6 @@ static void sig_term(int sig) exit(0); } -static int become_daemon(void) -{ - int fd; - - if (getppid() != 1) { - signal(SIGTTOU, SIG_IGN); - signal(SIGTTIN, SIG_IGN); - signal(SIGTSTP, SIG_IGN); - if (fork()) - return 0; - setsid(); - } - - fd = open("/dev/null", O_RDWR); - if (fd != -1) { - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - - if (fd > STDERR_FILENO) - close(fd); - } - - chdir("/"); - return 1; -} - static inline void handle_request(int sk, uint8_t *data, int len) { struct sockaddr_l2 sa; @@ -411,7 +383,7 @@ static struct option main_options[] = { int main(int argc, char **argv) { - int daemon = 1; + int daemonize = 1; int master = 0; int public = 0; int opt; @@ -419,7 +391,7 @@ int main(int argc, char **argv) while ((opt = getopt_long(argc, argv, "nmp", main_options, NULL)) != -1) switch (opt) { case 'n': - daemon = 0; + daemonize = 0; break; case 'm': master = 1; @@ -431,10 +403,13 @@ int main(int argc, char **argv) usage(); exit(0); } + openlog("sdpd", LOG_PID | LOG_NDELAY, LOG_DAEMON); - - if (daemon && !become_daemon()) - return 0; + + if (daemonize && daemon(0, 0)) { + SDPERR("Server startup failed: %s (%d)", strerror(errno), errno); + return -1; + } argc -= optind; argv += optind; @@ -490,6 +465,7 @@ int main(int argc, char **argv) } else check_active(&mask, num); } + exit: sdp_svcdb_reset(); return 0; -- cgit From 7d71cc206923e2eedbd3192dcc5f0b3fd9f63cef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:36:43 +0000 Subject: Some whitespace cleanups --- sdpd/service.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index cd40541b..aa62a559 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -55,12 +55,12 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h *scanned = sdp_extract_seqtype(p, &dtd, &seqlen); p += *scanned; - lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *)(p + sizeof(uint8_t)))); + lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *) (p + sizeof(uint8_t)))); SDPDBG("Look ahead attr id : %d\n", lookAheadAttrId); if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { - handle = ntohl(sdp_get_unaligned((uint32_t *)(p + + handle = ntohl(sdp_get_unaligned((uint32_t *) (p + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t)))); SDPDBG("SvcRecHandle : 0x%x\n", handle); @@ -85,9 +85,9 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h int attrValueLength = 0; SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength); - dtd = *(uint8_t *)p; + dtd = *(uint8_t *) p; - attrId = ntohs(sdp_get_unaligned((uint16_t *)(p + attrSize))); + attrId = ntohs(sdp_get_unaligned((uint16_t *) (p + attrSize))); attrSize += sizeof(uint16_t); SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attrId); @@ -169,7 +169,7 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) update_db_timestamp(); /* Build a rsp buffer */ - sdp_put_unaligned(htonl(rec->handle), (uint32_t *)rsp->data); + sdp_put_unaligned(htonl(rec->handle), (uint32_t *) rsp->data); rsp->data_size = sizeof(uint32_t); return 0; @@ -189,16 +189,16 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_record_t *orec; int status = 0, scanned = 0; uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); - uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *) p)); SDPDBG(""); SDPDBG("Svc Rec Handle: 0x%x\n", handle); - + p += sizeof(uint32_t); orec = sdp_record_find(handle); - + SDPDBG("SvcRecOld: 0x%x\n", (uint32_t)orec); if (orec) { @@ -220,7 +220,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) status = SDP_INVALID_RECORD_HANDLE; p = rsp->data; - sdp_put_unaligned(htons(status), (uint16_t *)p); + sdp_put_unaligned(htons(status), (uint16_t *) p); rsp->data_size = sizeof(uint16_t); return status; } @@ -231,7 +231,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) { uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); - uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *) p)); sdp_record_t *rec; int status = 0; @@ -253,7 +253,7 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) } p = rsp->data; - sdp_put_unaligned(htons(status), (uint16_t *)p); + sdp_put_unaligned(htons(status), (uint16_t *) p); rsp->data_size = sizeof(uint16_t); return status; -- cgit From 8c364889e14720e85caf6a84313f11d6a5d9f2be Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jan 2006 10:07:40 +0000 Subject: Update manual page title --- sdpd/sdpd.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/sdpd.8 b/sdpd/sdpd.8 index 34ce987d..c2e90837 100644 --- a/sdpd/sdpd.8 +++ b/sdpd/sdpd.8 @@ -53,7 +53,7 @@ .ta 8n 16n 24n 32n 40n 48n 56n 64n 72n .TH "sdpd" "8" .SH "NAME" -sdpd \(em SDP daemon +sdpd \(em Bluetooth SDP daemon .SH "SYNOPSIS" .PP \fBsdpd\fR [\fIoptions\fR] -- cgit From 5de33324633a5239a57a2d1ce6ab322950bb4b77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 3 Feb 2006 03:38:47 +0000 Subject: In debug mode the syslog headers are needed --- sdpd/service.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index aa62a559..781555fb 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -30,6 +30,7 @@ #include #include +#include #include #include -- cgit From ce9b410db80d60fbc6d12c02255319d8ff0c3a53 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 3 Feb 2006 03:39:33 +0000 Subject: Fix an endless if an attribute range has been requested --- sdpd/request.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index 9e3f966f..1fdbdbe5 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -448,6 +448,7 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu uint16_t attr; uint16_t low = (0xffff0000 & range) >> 16; uint16_t high = 0x0000ffff & range; + sdp_data_t *data; SDPDBG("attr range : 0x%x\n", range); SDPDBG("Low id : 0x%x\n", low); @@ -460,11 +461,14 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu break; } /* (else) sub-range of attributes */ - for (attr = low; attr <= high; attr++) { - sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr); - if (a) - sdp_append_to_pdu(buf, a); + for (attr = low; attr < high; attr++) { + data = sdp_data_get(rec, attr); + if (data) + sdp_append_to_pdu(buf, data); } + data = sdp_data_get(rec, high); + if (data) + sdp_append_to_pdu(buf, data); } free(pdu.data); } else { -- cgit From 7bfc46464d3c9c68bb0718d07f0d95764afb8c3b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Feb 2006 17:03:28 +0000 Subject: Add option to decrease the input MTU --- sdpd/main.c | 64 ++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 663200be..d5aac4da 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -223,10 +223,12 @@ static void register_server_service(int public) * l2cap and unix sockets over which discovery and registration clients * access us respectively */ -static int init_server(int master, int public) +static int init_server(uint16_t mtu, int master, int public) { + struct l2cap_options opts; struct sockaddr_l2 l2addr; struct sockaddr_un unaddr; + socklen_t optlen; /* Register the public browse group root */ register_public_browse_group(public); @@ -236,7 +238,7 @@ static int init_server(int master, int public) /* Create L2CAP socket */ l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (l2cap_sock == -1) { + if (l2cap_sock < 0) { SDPERR("opening L2CAP socket: %s", strerror(errno)); return -1; } @@ -244,39 +246,60 @@ static int init_server(int master, int public) l2addr.l2_bdaddr = *BDADDR_ANY; l2addr.l2_family = AF_BLUETOOTH; l2addr.l2_psm = htobs(SDP_PSM); - if (0 > bind(l2cap_sock, (struct sockaddr *)&l2addr, sizeof(l2addr))) { + if (bind(l2cap_sock, (struct sockaddr *)&l2addr, sizeof(l2addr)) < 0) { SDPERR("binding L2CAP socket: %s", strerror(errno)); return -1; } if (master) { int opt = L2CAP_LM_MASTER; - if (0 > setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt))) { + if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { SDPERR("setsockopt: %s", strerror(errno)); return -1; } } + + if (mtu > 0) { + memset(&opts, 0, sizeof(opts)); + optlen = sizeof(opts); + + if (getsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + SDPERR("getsockopt: %s", strerror(errno)); + return -1; + } + + opts.imtu = mtu; + + if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { + SDPERR("setsockopt: %s", strerror(errno)); + return -1; + } + } + listen(l2cap_sock, 5); FD_SET(l2cap_sock, &active_fdset); active_maxfd = l2cap_sock; /* Create local Unix socket */ unix_sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (unix_sock == -1) { + if (unix_sock < 0) { SDPERR("opening UNIX socket: %s", strerror(errno)); return -1; } + unaddr.sun_family = AF_UNIX; strcpy(unaddr.sun_path, SDP_UNIX_PATH); unlink(unaddr.sun_path); - if (0 > bind(unix_sock, (struct sockaddr *)&unaddr, sizeof(unaddr))) { + if (bind(unix_sock, (struct sockaddr *)&unaddr, sizeof(unaddr)) < 0) { SDPERR("binding UNIX socket: %s", strerror(errno)); return -1; } + listen(unix_sock, 5); FD_SET(unix_sock, &active_fdset); active_maxfd = unix_sock; chmod(SDP_UNIX_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + return 0; } @@ -317,9 +340,11 @@ static inline void handle_request(int sk, uint8_t *data, int len) req.mtu = 2048; req.local = 1; } + req.sock = sk; req.buf = data; req.len = len; + process_request(&req); } @@ -351,17 +376,17 @@ static void check_active(fd_set *mask, int num) close_sock(fd, r); continue; } - + size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen); buf = malloc(size); if (!buf) continue; - + r = recv(fd, buf, size, 0); if (r <= 0) close_sock(fd, r); else - handle_request(fd, buf, r); + handle_request(fd, buf, r); } } @@ -369,36 +394,39 @@ static void usage(void) { printf("sdpd version %s\n", VERSION); printf("Usage:\n" - "sdpd [-n] [-m]\n" + "sdpd [-n]\n" ); } static struct option main_options[] = { { "help", 0, 0, 'h' }, { "nodaemon", 0, 0, 'n' }, - { "master", 0, 0, 'm' }, + { "mtu", 1, 0, 'm' }, { "public", 0, 0, 'p' }, - { 0, 0, 0, 0} + { "master", 0, 0, 'M' }, + { 0, 0, 0, 0} }; int main(int argc, char **argv) { - int daemonize = 1; - int master = 0; - int public = 0; + uint16_t mtu = 0; + int daemonize = 1, public = 0, master = 0; int opt; - while ((opt = getopt_long(argc, argv, "nmp", main_options, NULL)) != -1) + while ((opt = getopt_long(argc, argv, "nm:pM", main_options, NULL)) != -1) switch (opt) { case 'n': daemonize = 0; break; case 'm': - master = 1; + mtu = atoi(optarg); break; case 'p': public = 1; break; + case 'M': + master = 1; + break; default: usage(); exit(0); @@ -414,7 +442,7 @@ int main(int argc, char **argv) argc -= optind; argv += optind; - if (init_server(master, public) < 0) { + if (init_server(mtu, master, public) < 0) { SDPERR("Server initialization failed"); return -1; } -- cgit From 403066f6cd6f4df68f68178acc2db0926370e95c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Apr 2006 14:30:59 +0000 Subject: Cleanup main function declarations --- sdpd/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index d5aac4da..269d5af8 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -407,7 +407,7 @@ static struct option main_options[] = { { 0, 0, 0, 0} }; -int main(int argc, char **argv) +int main(int argc, char *argv[]) { uint16_t mtu = 0; int daemonize = 1, public = 0, master = 0; -- cgit From 6bbb9743fdac4afc24bc35a09f3b9c407c3825f0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Jun 2006 11:22:19 +0000 Subject: Fix busy loop in UUID extraction routine --- sdpd/request.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index 1fdbdbe5..8f7949b1 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -54,11 +54,10 @@ * sequence. The data type of elements found in the * sequence is returned in the reference pDataType */ -static int extract_des(uint8_t *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType) +static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType) { uint8_t seqType; - int data_size = 0; - int scanned = sdp_extract_seqtype(buf, &seqType, &data_size); + int scanned, data_size = 0; short numberOfElements = 0; int seqlen = 0; sdp_list_t *pSeq = NULL; @@ -66,6 +65,8 @@ static int extract_des(uint8_t *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, int status = 0; const uint8_t *p; + scanned = sdp_extract_seqtype(buf, &seqType, &data_size); + SDPDBG("Seq type : %d\n", seqType); if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) { SDPERR("Unknown seq type \n"); @@ -118,6 +119,8 @@ static int extract_des(uint8_t *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, p += localSeqLength; } break; + default: + return -1; } if (status == 0) { pSeq = sdp_list_append(pSeq, pElem); @@ -126,7 +129,7 @@ static int extract_des(uint8_t *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, if (seqlen == data_size) break; - else if (seqlen > data_size) + else if (seqlen > data_size || seqlen > len) return -1; } else free(pElem); @@ -228,7 +231,7 @@ static int sdp_match_uuid(sdp_list_t *search, sdp_list_t *pattern) */ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) { - int status = 0, i, plen, mlen; + int status = 0, i, plen, mlen, mtu, scanned; sdp_list_t *pattern = NULL; uint16_t expected, actual; uint8_t dtd; @@ -238,12 +241,13 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) uint32_t cStateId = 0; short rsp_count = 0; short *pTotalRecordCount, *pCurrentRecordCount; - int mtu; uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); - int scanned = extract_des(pdata, &pattern, &dtd, SDP_TYPE_UUID); SDPDBG(""); + scanned = extract_des(pdata, req->len - sizeof(sdp_pdu_hdr_t), + &pattern, &dtd, SDP_TYPE_UUID); + if (scanned == -1) { status = SDP_INVALID_SYNTAX; goto done; @@ -505,7 +509,8 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) pdata += sizeof(uint16_t); /* extract the attribute list */ - scanned = extract_des(pdata, &seq, &dtd, SDP_TYPE_ANY); + scanned = extract_des(pdata, req->len - sizeof(sdp_pdu_hdr_t), + &seq, &dtd, SDP_TYPE_ANY); if (scanned == -1) { status = SDP_INVALID_SYNTAX; goto done; @@ -617,7 +622,8 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) tmpbuf.data = NULL; pdata = req->buf + sizeof(sdp_pdu_hdr_t); - scanned = extract_des(pdata, &pattern, &dtd, SDP_TYPE_UUID); + scanned = extract_des(pdata, req->len - sizeof(sdp_pdu_hdr_t), + &pattern, &dtd, SDP_TYPE_UUID); if (scanned == -1) { status = SDP_INVALID_SYNTAX; goto done; @@ -633,7 +639,8 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) SDPDBG("Max Attr expected: %d", max); /* extract the attribute list */ - scanned = extract_des(pdata, &seq, &dtd, SDP_TYPE_ANY); + scanned = extract_des(pdata, req->len - sizeof(sdp_pdu_hdr_t), + &seq, &dtd, SDP_TYPE_ANY); if (scanned == -1) { status = SDP_INVALID_SYNTAX; goto done; -- cgit From a1bc48d15a5d6e78efe744eb7b27b6421cb7222f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 16 Aug 2006 10:54:06 +0000 Subject: Convert to using ppoll() and pselect() --- sdpd/Makefile.am | 2 ++ sdpd/main.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 018a66f1..a82c2756 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -6,6 +6,8 @@ sdpd_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ +INCLUDES = -I$(top_srcdir)/common + man_MANS = sdpd.8 EXTRA_DIST = $(man_MANS) diff --git a/sdpd/main.c b/sdpd/main.c index 269d5af8..fbc7f5e6 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -409,6 +409,7 @@ static struct option main_options[] = { int main(int argc, char *argv[]) { + sigset_t sigs; uint16_t mtu = 0; int daemonize = 1, public = 0, master = 0; int opt; @@ -455,6 +456,8 @@ int main(int argc, char *argv[]) signal(SIGQUIT, sig_term); signal(SIGPIPE, SIG_IGN); + sigfillset(&sigs); + for (;;) { int num, nfd; fd_set mask; @@ -462,7 +465,7 @@ int main(int argc, char *argv[]) FD_ZERO(&mask); mask = active_fdset; - num = select(active_maxfd + 1, &mask, NULL, NULL, NULL); + num = pselect(active_maxfd + 1, &mask, NULL, NULL, NULL, &sigs); if (num <= 0) { SDPDBG("Select error:%s", strerror(errno)); goto exit; -- cgit From 73b9315e56f5f635eaf82a08271e8f462b731972 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 16 Aug 2006 11:44:52 +0000 Subject: Don't forget to unblock signals for ppoll() --- sdpd/main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index fbc7f5e6..5e415f4a 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -457,6 +457,11 @@ int main(int argc, char *argv[]) signal(SIGPIPE, SIG_IGN); sigfillset(&sigs); + sigdelset(&sigs, SIGINT); + sigdelset(&sigs, SIGTERM); + sigdelset(&sigs, SIGABRT); + sigdelset(&sigs, SIGQUIT); + sigdelset(&sigs, SIGPIPE); for (;;) { int num, nfd; -- cgit From 9d960d25c193812b19f14a47d3592bca0b2f194f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 Aug 2006 15:08:16 +0000 Subject: Fix malloc() and bt_malloc() usage --- sdpd/cstate.c | 2 +- sdpd/main.c | 2 +- sdpd/request.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index d09e9423..ad23f4ec 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -63,7 +63,7 @@ sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf) { - sdp_cstate_list_t *cstate = (sdp_cstate_list_t *)malloc(sizeof(sdp_cstate_list_t)); + sdp_cstate_list_t *cstate = malloc(sizeof(sdp_cstate_list_t)); uint8_t *data = malloc(buf->data_size); memcpy(data, buf->data, buf->data_size); diff --git a/sdpd/main.c b/sdpd/main.c index 5e415f4a..15a95b05 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -174,7 +174,7 @@ static void register_server_service(int public) versionDTDs = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); dtd = SDP_UINT16; for (i = 0; i < sdpServerVnumEntries; i++) { - uint16_t *version = (uint16_t *)malloc(sizeof(uint16_t)); + uint16_t *version = malloc(sizeof(uint16_t)); *version = sdpVnumArray[i].major; *version = (*version << 8); *version |= sdpVnumArray[i].minor; diff --git a/sdpd/request.c b/sdpd/request.c index 8f7949b1..0c80d5a9 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -96,7 +96,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p case SDP_UINT16: p += sizeof(uint8_t); seqlen += sizeof(uint8_t); - pElem = (char *)malloc(sizeof(uint16_t)); + pElem = malloc(sizeof(uint16_t)); sdp_put_unaligned(ntohs(sdp_get_unaligned((uint16_t *)p)), (uint16_t *)pElem); p += sizeof(uint16_t); seqlen += sizeof(uint16_t); @@ -104,7 +104,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p case SDP_UINT32: p += sizeof(uint8_t); seqlen += sizeof(uint8_t); - pElem = (char *)malloc(sizeof(uint32_t)); + pElem = malloc(sizeof(uint32_t)); sdp_put_unaligned(ntohl(sdp_get_unaligned((uint32_t *)p)), (uint32_t *)pElem); p += sizeof(uint32_t); seqlen += sizeof(uint32_t); @@ -112,7 +112,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: - pElem = (char *)malloc(sizeof(uuid_t)); + pElem = malloc(sizeof(uuid_t)); status = sdp_uuid_extract(p, (uuid_t *)pElem, &localSeqLength); if (status == 0) { seqlen += localSeqLength; @@ -217,7 +217,7 @@ static int sdp_match_uuid(sdp_list_t *search, sdp_list_t *pattern) // create 128-bit form of the search UUID uuid128 = sdp_uuid_to_uuid128((uuid_t *)data); list = sdp_list_find(pattern, uuid128, sdp_uuid128_cmp); - free(uuid128); + bt_free(uuid128); if (!list) return 0; } -- cgit From bae1f49353c736eac337f2d5ad5cbe8826661c0d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Sep 2006 10:32:39 +0000 Subject: Include sys/select.h for pselect() --- sdpd/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 15a95b05..1de73368 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include -- cgit From 914bf7ce2fcc811ea8561c30e7a43394d8834555 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 12:36:56 +0000 Subject: Fix pselect() build warning --- sdpd/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 1de73368..5bb86951 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -37,9 +37,11 @@ #include #include #include -#include #include +#define _XOPEN_SOURCE 600 +#include + #include #include #include -- cgit From f3fc1efa4cbab8d6d107c6523d465d39c52e02c2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 13:01:49 +0000 Subject: Use common logging functions --- sdpd/Makefile.am | 3 +- sdpd/main.c | 35 +++++++++--------- sdpd/request.c | 106 +++++++++++++++++++++++++++---------------------------- sdpd/sdpd.h | 9 ----- sdpd/service.c | 38 ++++++++++---------- sdpd/servicedb.c | 18 +++++----- 6 files changed, 101 insertions(+), 108 deletions(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index a82c2756..226d1f5c 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -2,7 +2,8 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h -sdpd_LDADD = @BLUEZ_LIBS@ + +sdpd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/sdpd/main.c b/sdpd/main.c index 5bb86951..c21380cd 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -33,10 +33,8 @@ #include #include #include -#include #include #include -#include #include #define _XOPEN_SOURCE 600 @@ -51,6 +49,7 @@ #include #include "sdpd.h" +#include "logging.h" static int l2cap_sock, unix_sock; static fd_set active_fdset; @@ -242,7 +241,7 @@ static int init_server(uint16_t mtu, int master, int public) /* Create L2CAP socket */ l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (l2cap_sock < 0) { - SDPERR("opening L2CAP socket: %s", strerror(errno)); + error("opening L2CAP socket: %s", strerror(errno)); return -1; } @@ -250,14 +249,14 @@ static int init_server(uint16_t mtu, int master, int public) l2addr.l2_family = AF_BLUETOOTH; l2addr.l2_psm = htobs(SDP_PSM); if (bind(l2cap_sock, (struct sockaddr *)&l2addr, sizeof(l2addr)) < 0) { - SDPERR("binding L2CAP socket: %s", strerror(errno)); + error("binding L2CAP socket: %s", strerror(errno)); return -1; } if (master) { int opt = L2CAP_LM_MASTER; if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - SDPERR("setsockopt: %s", strerror(errno)); + error("setsockopt: %s", strerror(errno)); return -1; } } @@ -267,14 +266,14 @@ static int init_server(uint16_t mtu, int master, int public) optlen = sizeof(opts); if (getsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { - SDPERR("getsockopt: %s", strerror(errno)); + error("getsockopt: %s", strerror(errno)); return -1; } opts.imtu = mtu; if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { - SDPERR("setsockopt: %s", strerror(errno)); + error("setsockopt: %s", strerror(errno)); return -1; } } @@ -286,7 +285,7 @@ static int init_server(uint16_t mtu, int master, int public) /* Create local Unix socket */ unix_sock = socket(PF_UNIX, SOCK_STREAM, 0); if (unix_sock < 0) { - SDPERR("opening UNIX socket: %s", strerror(errno)); + error("opening UNIX socket: %s", strerror(errno)); return -1; } @@ -294,7 +293,7 @@ static int init_server(uint16_t mtu, int master, int public) strcpy(unaddr.sun_path, SDP_UNIX_PATH); unlink(unaddr.sun_path); if (bind(unix_sock, (struct sockaddr *)&unaddr, sizeof(unaddr)) < 0) { - SDPERR("binding UNIX socket: %s", strerror(errno)); + error("binding UNIX socket: %s", strerror(errno)); return -1; } @@ -308,7 +307,7 @@ static int init_server(uint16_t mtu, int master, int public) static void sig_term(int sig) { - SDPINF("terminating... \n"); + info("terminating... \n"); sdp_svcdb_reset(); close(l2cap_sock); close(unix_sock); @@ -354,7 +353,7 @@ static inline void handle_request(int sk, uint8_t *data, int len) static void close_sock(int fd, int r) { if (r < 0) - SDPERR("Read error: %s", strerror(errno)); + error("Read error: %s", strerror(errno)); FD_CLR(fd, &active_fdset); close(fd); sdp_svcdb_collect_all(fd); @@ -436,10 +435,14 @@ int main(int argc, char *argv[]) exit(0); } - openlog("sdpd", LOG_PID | LOG_NDELAY, LOG_DAEMON); + start_logging("sdpd", "Bluetooth SDP daemon"); + +#ifdef SDP_DEBUG + enable_debug(); +#endif if (daemonize && daemon(0, 0)) { - SDPERR("Server startup failed: %s (%d)", strerror(errno), errno); + error("Server startup failed: %s (%d)", strerror(errno), errno); return -1; } @@ -447,12 +450,10 @@ int main(int argc, char *argv[]) argv += optind; if (init_server(mtu, master, public) < 0) { - SDPERR("Server initialization failed"); + error("Server initialization failed"); return -1; } - SDPINF("Bluetooth SDP daemon"); - signal(SIGINT, sig_term); signal(SIGTERM, sig_term); signal(SIGABRT, sig_term); @@ -475,7 +476,7 @@ int main(int argc, char *argv[]) num = pselect(active_maxfd + 1, &mask, NULL, NULL, NULL, &sigs); if (num <= 0) { - SDPDBG("Select error:%s", strerror(errno)); + debug("Select error:%s", strerror(errno)); goto exit; } diff --git a/sdpd/request.c b/sdpd/request.c index 0c80d5a9..fbcbaa8c 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -41,6 +40,7 @@ #include #include "sdpd.h" +#include "logging.h" #define MIN(x, y) ((x) < (y))? (x): (y) @@ -67,28 +67,28 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p scanned = sdp_extract_seqtype(buf, &seqType, &data_size); - SDPDBG("Seq type : %d\n", seqType); + debug("Seq type : %d\n", seqType); if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) { - SDPERR("Unknown seq type \n"); + error("Unknown seq type \n"); return -1; } p = buf + scanned; - SDPDBG("Data size : %d\n", data_size); + debug("Data size : %d\n", data_size); for (;;) { char *pElem = NULL; int localSeqLength = 0; dataType = *(uint8_t *)p; - SDPDBG("Data type: 0x%02x\n", dataType); + debug("Data type: 0x%02x\n", dataType); if (expectedType == SDP_TYPE_UUID) { if (dataType != SDP_UUID16 && dataType != SDP_UUID32 && dataType != SDP_UUID128) { - SDPDBG("->Unexpected Data type (expected UUID_ANY)\n"); + debug("->Unexpected Data type (expected UUID_ANY)\n"); return -1; } } else if (expectedType != SDP_TYPE_ANY && dataType != expectedType) { - SDPDBG("->Unexpected Data type (expected 0x%02x)\n", expectedType); + debug("->Unexpected Data type (expected 0x%02x)\n", expectedType); return -1; } @@ -125,7 +125,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p if (status == 0) { pSeq = sdp_list_append(pSeq, pElem); numberOfElements++; - SDPDBG("No of elements : %d\n", numberOfElements); + debug("No of elements : %d\n", numberOfElements); if (seqlen == data_size) break; @@ -146,7 +146,7 @@ static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate) int length = 0; if (cstate) { - SDPDBG("Non null sdp_cstate_t id : 0x%lx\n", cstate->timestamp); + debug("Non null sdp_cstate_t id : 0x%lx\n", cstate->timestamp); *(uint8_t *)pdata = sizeof(sdp_cont_state_t); pdata += sizeof(uint8_t); length += sizeof(uint8_t); @@ -171,13 +171,13 @@ static sdp_cont_state_t *sdp_cstate_get(uint8_t *buffer) * Check if continuation state exists, if yes attempt * to get response remainder from cache, else send error */ - SDPDBG("Continuation State size : %d\n", cStateSize); + debug("Continuation State size : %d\n", cStateSize); pdata += sizeof(uint8_t); if (cStateSize != 0) { sdp_cont_state_t *cstate = (sdp_cont_state_t *)pdata; - SDPDBG("Cstate TS : 0x%lx\n", cstate->timestamp); - SDPDBG("Bytes sent : %d\n", cstate->cStateValue.maxBytesSent); + debug("Cstate TS : 0x%lx\n", cstate->timestamp); + debug("Bytes sent : %d\n", cstate->cStateValue.maxBytesSent); return cstate; } return NULL; @@ -203,7 +203,7 @@ static int sdp_match_uuid(sdp_list_t *search, sdp_list_t *pattern) */ int patlen = sdp_list_len(pattern); - SDPDBG(""); + debug(""); if (patlen < sdp_list_len(search)) return -1; @@ -243,7 +243,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) short *pTotalRecordCount, *pCurrentRecordCount; uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); - SDPDBG(""); + debug(""); scanned = extract_des(pdata, req->len - sizeof(sdp_pdu_hdr_t), &pattern, &dtd, SDP_TYPE_UUID); @@ -264,8 +264,8 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) expected = ntohs(sdp_get_unaligned((uint16_t *)pdata)); - SDPDBG("Expected count: %d\n", expected); - SDPDBG("Bytes scanned : %d\n", scanned); + debug("Expected count: %d\n", expected); + debug("Bytes scanned : %d\n", scanned); pdata += sizeof(uint16_t); @@ -301,7 +301,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) for (; list && rsp_count < expected; list = list->next) { sdp_record_t *rec = (sdp_record_t *) list->data; - SDPDBG("Checking svcRec : 0x%x\n", rec->handle); + debug("Checking svcRec : 0x%x\n", rec->handle); if (sdp_match_uuid(pattern, rec->pattern) > 0 && sdp_check_access(rec->handle, &req->device)) { @@ -312,7 +312,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) } } - SDPDBG("Match count: %d\n", rsp_count); + debug("Match count: %d\n", rsp_count); buf->data_size += handleSize; sdp_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); @@ -394,7 +394,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) */ sdp_cont_state_t newState; - SDPDBG("Setting non-NULL sdp_cstate_t\n"); + debug("Setting non-NULL sdp_cstate_t\n"); if (cstate) memcpy((char *)&newState, cstate, sizeof(sdp_cont_state_t)); @@ -428,13 +428,13 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu #ifdef SDP_DEBUG if (seq) - SDPDBG("Entries in attr seq : %d\n", sdp_list_len(seq)); + debug("Entries in attr seq : %d\n", sdp_list_len(seq)); else - SDPDBG("NULL attribute descriptor\n"); - SDPDBG("AttrDataType : %d\n", dtd); + debug("NULL attribute descriptor\n"); + debug("AttrDataType : %d\n", dtd); #endif if (seq == NULL) { - SDPDBG("Attribute sequence is NULL\n"); + debug("Attribute sequence is NULL\n"); return 0; } if (dtd == SDP_UINT16) @@ -454,9 +454,9 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu uint16_t high = 0x0000ffff & range; sdp_data_t *data; - SDPDBG("attr range : 0x%x\n", range); - SDPDBG("Low id : 0x%x\n", low); - SDPDBG("High id : 0x%x\n", high); + debug("attr range : 0x%x\n", range); + debug("Low id : 0x%x\n", low); + debug("High id : 0x%x\n", high); if (low == 0x0000 && high == 0xffff && pdu.data_size <= buf->buf_size) { /* copy it */ @@ -476,8 +476,8 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu } free(pdu.data); } else { - SDPERR("Unexpected data type : 0x%x\n", dtd); - SDPERR("Expect uint16_t or uint32_t\n"); + error("Unexpected data type : 0x%x\n", dtd); + error("Expect uint16_t or uint32_t\n"); return SDP_INVALID_SYNTAX; } return 0; @@ -502,7 +502,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)pdata)); - SDPDBG(""); + debug(""); pdata += sizeof(uint32_t); max_rsp_size = ntohs(sdp_get_unaligned((uint16_t *)pdata)); @@ -531,8 +531,8 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) */ cstate = sdp_cstate_get(pdata); - SDPDBG("SvcRecHandle : 0x%x\n", handle); - SDPDBG("max_rsp_size : %d\n", max_rsp_size); + debug("SvcRecHandle : 0x%x\n", handle); + debug("max_rsp_size : %d\n", max_rsp_size); /* * Calculate Attribute size acording to MTU @@ -548,7 +548,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) if (cstate) { sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); - SDPDBG("Obtained cached rsp : %p\n", pCache); + debug("Obtained cached rsp : %p\n", pCache); if (pCache) { short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent); @@ -557,7 +557,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) buf->data_size += sent; cstate->cStateValue.maxBytesSent += sent; - SDPDBG("Response size : %d sending now : %d bytes sent so far : %d\n", + debug("Response size : %d sending now : %d bytes sent so far : %d\n", pCache->data_size, sent, cstate->cStateValue.maxBytesSent); if (cstate->cStateValue.maxBytesSent == pCache->data_size) cstate_size = sdp_set_cstate_pdu(buf, NULL); @@ -565,7 +565,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) cstate_size = sdp_set_cstate_pdu(buf, cstate); } else { status = SDP_INVALID_CSTATE; - SDPERR("NULL cache buffer and non-NULL continuation state\n"); + error("NULL cache buffer and non-NULL continuation state\n"); } } else { sdp_record_t *rec = sdp_record_find(handle); @@ -579,7 +579,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) * Reset the buffer size to the maximum expected and * set the sdp_cont_state_t */ - SDPDBG("Creating continuation state of size : %d\n", buf->data_size); + debug("Creating continuation state of size : %d\n", buf->data_size); buf->data_size = max_rsp_size; newState.cStateValue.maxBytesSent = max_rsp_size; cstate_size = sdp_set_cstate_pdu(buf, &newState); @@ -630,13 +630,13 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) } totscanned = scanned; - SDPDBG("Bytes scanned: %d", scanned); + debug("Bytes scanned: %d", scanned); pdata += scanned; max = ntohs(sdp_get_unaligned((uint16_t *)pdata)); pdata += sizeof(uint16_t); - SDPDBG("Max Attr expected: %d", max); + debug("Max Attr expected: %d", max); /* extract the attribute list */ scanned = extract_des(pdata, req->len - sizeof(sdp_pdu_hdr_t), @@ -687,10 +687,10 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) rsp_count++; status = extract_attrs(rec, seq, dtd, &tmpbuf); - SDPDBG("Response count : %d\n", rsp_count); - SDPDBG("Local PDU size : %d\n", tmpbuf.data_size); + debug("Response count : %d\n", rsp_count); + debug("Local PDU size : %d\n", tmpbuf.data_size); if (status) { - SDPDBG("Extract attr from record returns err\n"); + debug("Extract attr from record returns err\n"); break; } if (buf->data_size + tmpbuf.data_size < buf->buf_size) { @@ -699,10 +699,10 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) tmpbuf.data_size = 0; memset(tmpbuf.data, 0, USHRT_MAX); } else { - SDPERR("Relocation needed\n"); + error("Relocation needed\n"); break; } - SDPDBG("Net PDU size : %d\n", buf->data_size); + debug("Net PDU size : %d\n", buf->data_size); } } if (buf->data_size > max) { @@ -734,7 +734,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) cstate_size = sdp_set_cstate_pdu(buf, cstate); } else { status = SDP_INVALID_CSTATE; - SDPDBG("Non-null continuation state, but null cache buffer\n"); + debug("Non-null continuation state, but null cache buffer\n"); } } @@ -779,7 +779,7 @@ void process_request(sdp_req_t *req) int sent = 0; int status = SDP_INVALID_SYNTAX; - SDPDBG(""); + debug(""); memset(buf, 0, USHRT_MAX); rsp.data = buf + sizeof(sdp_pdu_hdr_t); @@ -793,44 +793,44 @@ void process_request(sdp_req_t *req) } switch (reqhdr->pdu_id) { case SDP_SVC_SEARCH_REQ: - SDPDBG("Got a svc srch req\n"); + debug("Got a svc srch req\n"); status = service_search_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_SEARCH_RSP; break; case SDP_SVC_ATTR_REQ: - SDPDBG("Got a svc attr req\n"); + debug("Got a svc attr req\n"); status = service_attr_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_ATTR_RSP; break; case SDP_SVC_SEARCH_ATTR_REQ: - SDPDBG("Got a svc srch attr req\n"); + debug("Got a svc srch attr req\n"); status = service_search_attr_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_SEARCH_ATTR_RSP; break; /* Following requests are allowed only for local connections */ case SDP_SVC_REGISTER_REQ: - SDPDBG("Service register request\n"); + debug("Service register request\n"); if (req->local) { status = service_register_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_REGISTER_RSP; } break; case SDP_SVC_UPDATE_REQ: - SDPDBG("Service update request\n"); + debug("Service update request\n"); if (req->local) { status = service_update_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_UPDATE_RSP; } break; case SDP_SVC_REMOVE_REQ: - SDPDBG("Service removal request\n"); + debug("Service removal request\n"); if (req->local) { status = service_remove_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_REMOVE_RSP; } break; default: - SDPERR("Unknown PDU ID : 0x%x received\n", reqhdr->pdu_id); + error("Unknown PDU ID : 0x%x received\n", reqhdr->pdu_id); status = SDP_INVALID_SYNTAX; break; } @@ -842,7 +842,7 @@ send_rsp: rsp.data_size = sizeof(uint16_t); } - SDPDBG("Sending rsp. status %d", status); + debug("Sending rsp. status %d", status); rsphdr->tid = reqhdr->tid; rsphdr->plen = htons(rsp.data_size); @@ -854,7 +854,7 @@ send_rsp: /* stream the rsp PDU */ sent = send(req->sock, rsp.data, rsp.data_size, 0); - SDPDBG("Bytes Sent : %d\n", sent); + debug("Bytes Sent : %d\n", sent); free(rsp.data); free(req->buf); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index e73936c3..69c1446e 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -27,15 +27,6 @@ #define sdp_get_unaligned bt_get_unaligned #define sdp_put_unaligned bt_put_unaligned -#define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg) -#define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg) - -#ifdef SDP_DEBUG -#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg) -#else -#define SDPDBG(fmt...) -#endif - typedef struct request { bdaddr_t device; bdaddr_t bdaddr; diff --git a/sdpd/service.c b/sdpd/service.c index 781555fb..276f4481 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -30,7 +30,6 @@ #include #include -#include #include #include @@ -40,6 +39,7 @@ #include #include "sdpd.h" +#include "logging.h" extern void update_db_timestamp(void); @@ -58,13 +58,13 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h p += *scanned; lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *) (p + sizeof(uint8_t)))); - SDPDBG("Look ahead attr id : %d\n", lookAheadAttrId); + debug("Look ahead attr id : %d\n", lookAheadAttrId); if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { handle = ntohl(sdp_get_unaligned((uint32_t *) (p + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t)))); - SDPDBG("SvcRecHandle : 0x%x\n", handle); + debug("SvcRecHandle : 0x%x\n", handle); rec = sdp_record_find(handle); } else if (handleExpected != 0xffffffff) rec = sdp_record_find(handleExpected); @@ -85,33 +85,33 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h int attrSize = sizeof(uint8_t); int attrValueLength = 0; - SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength); + debug("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength); dtd = *(uint8_t *) p; attrId = ntohs(sdp_get_unaligned((uint16_t *) (p + attrSize))); attrSize += sizeof(uint16_t); - SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attrId); + debug("DTD of attrId : %d Attr id : 0x%x \n", dtd, attrId); pAttr = sdp_extract_attr(p + attrSize, &attrValueLength, rec); - SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attrId, attrValueLength); + debug("Attr id : 0x%x attrValueLength : %d\n", attrId, attrValueLength); attrSize += attrValueLength; if (pAttr == NULL) { - SDPDBG("Terminating extraction of attributes"); + debug("Terminating extraction of attributes"); break; } localExtractedLength += attrSize; p += attrSize; sdp_attr_replace(rec, attrId, pAttr); extractStatus = 0; - SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", + debug("Extract PDU, seqLength: %d localExtractedLength: %d", seqlen, localExtractedLength); } if (extractStatus == 0) { - SDPDBG("Successful extracting of Svc Rec attributes\n"); + debug("Successful extracting of Svc Rec attributes\n"); #ifdef SDP_DEBUG sdp_print_service_attr(rec->attrlist); #endif @@ -192,26 +192,26 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *) p)); - SDPDBG(""); + debug(""); - SDPDBG("Svc Rec Handle: 0x%x\n", handle); + debug("Svc Rec Handle: 0x%x\n", handle); p += sizeof(uint32_t); orec = sdp_record_find(handle); - SDPDBG("SvcRecOld: 0x%x\n", (uint32_t)orec); + debug("SvcRecOld: %p\n", orec); if (orec) { sdp_record_t *nrec = extract_pdu_server(BDADDR_ANY, p, handle, &scanned); if (nrec && handle == nrec->handle) update_db_timestamp(); else { - SDPDBG("SvcRecHandle : 0x%x\n", handle); - SDPDBG("SvcRecHandleNew : 0x%x\n", nrec->handle); - SDPDBG("SvcRecNew : 0x%x\n", (uint32_t) nrec); - SDPDBG("SvcRecOld : 0x%x\n", (uint32_t) orec); - SDPDBG("Failure to update, restore old value\n"); + debug("SvcRecHandle : 0x%x\n", handle); + debug("SvcRecHandleNew : 0x%x\n", nrec->handle); + debug("SvcRecNew : %p\n", nrec); + debug("SvcRecOld : %p\n", orec); + debug("Failure to update, restore old value\n"); if (nrec) sdp_record_free(nrec); @@ -236,7 +236,7 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_record_t *rec; int status = 0; - SDPDBG(""); + debug(""); /* extract service record handle */ p += sizeof(uint32_t); @@ -250,7 +250,7 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) update_db_timestamp(); } else { status = SDP_INVALID_RECORD_HANDLE; - SDPDBG("Could not find record : 0x%x\n", handle); + debug("Could not find record : 0x%x\n", handle); } p = rsp->data; diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 7e8b5d19..f433c5c3 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -40,6 +39,7 @@ #include #include "sdpd.h" +#include "logging.h" static sdp_list_t *service_db; static sdp_list_t *access_db; @@ -60,7 +60,7 @@ static int record_sort(const void *r1, const void *r2) const sdp_record_t *rec2 = (const sdp_record_t *) r2; if (!rec1 || !rec2) { - SDPERR("NULL RECORD LIST FATAL\n"); + error("NULL RECORD LIST FATAL\n"); return -1; } @@ -73,7 +73,7 @@ static int access_sort(const void *r1, const void *r2) const sdp_access_t *rec2 = (const sdp_access_t *) r2; if (!rec1 || !rec2) { - SDPERR("NULL RECORD LIST FATAL\n"); + error("NULL RECORD LIST FATAL\n"); return -1; } @@ -170,8 +170,8 @@ void sdp_record_add(bdaddr_t *device, sdp_record_t *rec) sdp_access_t *dev; #ifdef SDP_DEBUG - SDPDBG("Adding rec : 0x%lx\n", (long) rec); - SDPDBG("with handle : 0x%x\n", rec->handle); + debug("Adding rec : 0x%lx\n", (long) rec); + debug("with handle : 0x%x\n", rec->handle); #endif service_db = sdp_list_insert_sorted(service_db, rec, record_sort); @@ -196,7 +196,7 @@ static sdp_list_t *record_locate(uint32_t handle) return p; } - SDPDBG("Could not find svcRec for : 0x%x\n", handle); + debug("Could not find svcRec for : 0x%x\n", handle); return NULL; } @@ -211,7 +211,7 @@ static sdp_list_t *access_locate(uint32_t handle) return p; } - SDPDBG("Could not find access data for : 0x%x\n", handle); + debug("Could not find access data for : 0x%x\n", handle); return NULL; } @@ -223,7 +223,7 @@ sdp_record_t *sdp_record_find(uint32_t handle) sdp_list_t *p = record_locate(handle); if (!p) { - SDPDBG("Couldn't find record for : 0x%x\n", handle); + debug("Couldn't find record for : 0x%x\n", handle); return 0; } @@ -240,7 +240,7 @@ int sdp_record_remove(uint32_t handle) sdp_access_t *a; if (!p) { - SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); + error("Remove : Couldn't find record for : 0x%x\n", handle); return -1; } -- cgit From e487af3281692cdb05f9edef547b107c4cae6962 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 13:03:48 +0000 Subject: Remove unneeded SDP_DEBUG checks --- sdpd/request.c | 4 ++-- sdpd/servicedb.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index fbcbaa8c..059aec40 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -426,13 +426,13 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu if (!rec) return SDP_INVALID_RECORD_HANDLE; -#ifdef SDP_DEBUG if (seq) debug("Entries in attr seq : %d\n", sdp_list_len(seq)); else debug("NULL attribute descriptor\n"); + debug("AttrDataType : %d\n", dtd); -#endif + if (seq == NULL) { debug("Attribute sequence is NULL\n"); return 0; diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index f433c5c3..d4ebd7de 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -169,10 +169,9 @@ void sdp_record_add(bdaddr_t *device, sdp_record_t *rec) { sdp_access_t *dev; -#ifdef SDP_DEBUG debug("Adding rec : 0x%lx\n", (long) rec); debug("with handle : 0x%x\n", rec->handle); -#endif + service_db = sdp_list_insert_sorted(service_db, rec, record_sort); dev = malloc(sizeof(*dev)); -- cgit From 00ea526ab6b56994e727de46133d2eaaf9b40e84 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 13:12:29 +0000 Subject: Remove unneeded newlines in log messages --- sdpd/main.c | 2 +- sdpd/request.c | 99 ++++++++++++++++++++++++++------------------------------ sdpd/service.c | 30 ++++++++--------- sdpd/servicedb.c | 16 ++++----- 4 files changed, 68 insertions(+), 79 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index c21380cd..da14b967 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -307,7 +307,7 @@ static int init_server(uint16_t mtu, int master, int public) static void sig_term(int sig) { - info("terminating... \n"); + info("terminating..."); sdp_svcdb_reset(); close(l2cap_sock); close(unix_sock); diff --git a/sdpd/request.c b/sdpd/request.c index 059aec40..17aa9d99 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -67,28 +67,29 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p scanned = sdp_extract_seqtype(buf, &seqType, &data_size); - debug("Seq type : %d\n", seqType); + debug("Seq type : %d", seqType); if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) { - error("Unknown seq type \n"); + error("Unknown seq type"); return -1; } p = buf + scanned; - debug("Data size : %d\n", data_size); + debug("Data size : %d", data_size); + for (;;) { char *pElem = NULL; int localSeqLength = 0; dataType = *(uint8_t *)p; - debug("Data type: 0x%02x\n", dataType); + debug("Data type: 0x%02x", dataType); if (expectedType == SDP_TYPE_UUID) { if (dataType != SDP_UUID16 && dataType != SDP_UUID32 && dataType != SDP_UUID128) { - debug("->Unexpected Data type (expected UUID_ANY)\n"); + debug("->Unexpected Data type (expected UUID_ANY)"); return -1; } } else if (expectedType != SDP_TYPE_ANY && dataType != expectedType) { - debug("->Unexpected Data type (expected 0x%02x)\n", expectedType); + debug("->Unexpected Data type (expected 0x%02x)", expectedType); return -1; } @@ -125,7 +126,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p if (status == 0) { pSeq = sdp_list_append(pSeq, pElem); numberOfElements++; - debug("No of elements : %d\n", numberOfElements); + debug("No of elements : %d", numberOfElements); if (seqlen == data_size) break; @@ -146,7 +147,7 @@ static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate) int length = 0; if (cstate) { - debug("Non null sdp_cstate_t id : 0x%lx\n", cstate->timestamp); + debug("Non null sdp_cstate_t id : 0x%lx", cstate->timestamp); *(uint8_t *)pdata = sizeof(sdp_cont_state_t); pdata += sizeof(uint8_t); length += sizeof(uint8_t); @@ -171,13 +172,13 @@ static sdp_cont_state_t *sdp_cstate_get(uint8_t *buffer) * Check if continuation state exists, if yes attempt * to get response remainder from cache, else send error */ - debug("Continuation State size : %d\n", cStateSize); + debug("Continuation State size : %d", cStateSize); pdata += sizeof(uint8_t); if (cStateSize != 0) { sdp_cont_state_t *cstate = (sdp_cont_state_t *)pdata; - debug("Cstate TS : 0x%lx\n", cstate->timestamp); - debug("Bytes sent : %d\n", cstate->cStateValue.maxBytesSent); + debug("Cstate TS : 0x%lx", cstate->timestamp); + debug("Bytes sent : %d", cstate->cStateValue.maxBytesSent); return cstate; } return NULL; @@ -203,8 +204,6 @@ static int sdp_match_uuid(sdp_list_t *search, sdp_list_t *pattern) */ int patlen = sdp_list_len(pattern); - debug(""); - if (patlen < sdp_list_len(search)) return -1; for (; search; search = search->next) { @@ -243,8 +242,6 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) short *pTotalRecordCount, *pCurrentRecordCount; uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); - debug(""); - scanned = extract_des(pdata, req->len - sizeof(sdp_pdu_hdr_t), &pattern, &dtd, SDP_TYPE_UUID); @@ -264,8 +261,8 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) expected = ntohs(sdp_get_unaligned((uint16_t *)pdata)); - debug("Expected count: %d\n", expected); - debug("Bytes scanned : %d\n", scanned); + debug("Expected count: %d", expected); + debug("Bytes scanned : %d", scanned); pdata += sizeof(uint16_t); @@ -301,7 +298,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) for (; list && rsp_count < expected; list = list->next) { sdp_record_t *rec = (sdp_record_t *) list->data; - debug("Checking svcRec : 0x%x\n", rec->handle); + debug("Checking svcRec : 0x%x", rec->handle); if (sdp_match_uuid(pattern, rec->pattern) > 0 && sdp_check_access(rec->handle, &req->device)) { @@ -312,7 +309,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) } } - debug("Match count: %d\n", rsp_count); + debug("Match count: %d", rsp_count); buf->data_size += handleSize; sdp_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); @@ -394,7 +391,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) */ sdp_cont_state_t newState; - debug("Setting non-NULL sdp_cstate_t\n"); + debug("Setting non-NULL sdp_cstate_t"); if (cstate) memcpy((char *)&newState, cstate, sizeof(sdp_cont_state_t)); @@ -427,14 +424,14 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu return SDP_INVALID_RECORD_HANDLE; if (seq) - debug("Entries in attr seq : %d\n", sdp_list_len(seq)); + debug("Entries in attr seq : %d", sdp_list_len(seq)); else - debug("NULL attribute descriptor\n"); + debug("NULL attribute descriptor"); - debug("AttrDataType : %d\n", dtd); + debug("AttrDataType : %d", dtd); if (seq == NULL) { - debug("Attribute sequence is NULL\n"); + debug("Attribute sequence is NULL"); return 0; } if (dtd == SDP_UINT16) @@ -454,9 +451,9 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu uint16_t high = 0x0000ffff & range; sdp_data_t *data; - debug("attr range : 0x%x\n", range); - debug("Low id : 0x%x\n", low); - debug("High id : 0x%x\n", high); + debug("attr range : 0x%x", range); + debug("Low id : 0x%x", low); + debug("High id : 0x%x", high); if (low == 0x0000 && high == 0xffff && pdu.data_size <= buf->buf_size) { /* copy it */ @@ -476,8 +473,8 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu } free(pdu.data); } else { - error("Unexpected data type : 0x%x\n", dtd); - error("Expect uint16_t or uint32_t\n"); + error("Unexpected data type : 0x%x", dtd); + error("Expect uint16_t or uint32_t"); return SDP_INVALID_SYNTAX; } return 0; @@ -502,8 +499,6 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)pdata)); - debug(""); - pdata += sizeof(uint32_t); max_rsp_size = ntohs(sdp_get_unaligned((uint16_t *)pdata)); pdata += sizeof(uint16_t); @@ -531,8 +526,8 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) */ cstate = sdp_cstate_get(pdata); - debug("SvcRecHandle : 0x%x\n", handle); - debug("max_rsp_size : %d\n", max_rsp_size); + debug("SvcRecHandle : 0x%x", handle); + debug("max_rsp_size : %d", max_rsp_size); /* * Calculate Attribute size acording to MTU @@ -548,7 +543,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) if (cstate) { sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); - debug("Obtained cached rsp : %p\n", pCache); + debug("Obtained cached rsp : %p", pCache); if (pCache) { short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent); @@ -557,7 +552,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) buf->data_size += sent; cstate->cStateValue.maxBytesSent += sent; - debug("Response size : %d sending now : %d bytes sent so far : %d\n", + debug("Response size : %d sending now : %d bytes sent so far : %d", pCache->data_size, sent, cstate->cStateValue.maxBytesSent); if (cstate->cStateValue.maxBytesSent == pCache->data_size) cstate_size = sdp_set_cstate_pdu(buf, NULL); @@ -565,7 +560,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) cstate_size = sdp_set_cstate_pdu(buf, cstate); } else { status = SDP_INVALID_CSTATE; - error("NULL cache buffer and non-NULL continuation state\n"); + error("NULL cache buffer and non-NULL continuation state"); } } else { sdp_record_t *rec = sdp_record_find(handle); @@ -579,7 +574,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) * Reset the buffer size to the maximum expected and * set the sdp_cont_state_t */ - debug("Creating continuation state of size : %d\n", buf->data_size); + debug("Creating continuation state of size : %d", buf->data_size); buf->data_size = max_rsp_size; newState.cStateValue.maxBytesSent = max_rsp_size; cstate_size = sdp_set_cstate_pdu(buf, &newState); @@ -687,10 +682,10 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) rsp_count++; status = extract_attrs(rec, seq, dtd, &tmpbuf); - debug("Response count : %d\n", rsp_count); - debug("Local PDU size : %d\n", tmpbuf.data_size); + debug("Response count : %d", rsp_count); + debug("Local PDU size : %d", tmpbuf.data_size); if (status) { - debug("Extract attr from record returns err\n"); + debug("Extract attr from record returns err"); break; } if (buf->data_size + tmpbuf.data_size < buf->buf_size) { @@ -699,10 +694,10 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) tmpbuf.data_size = 0; memset(tmpbuf.data, 0, USHRT_MAX); } else { - error("Relocation needed\n"); + error("Relocation needed"); break; } - debug("Net PDU size : %d\n", buf->data_size); + debug("Net PDU size : %d", buf->data_size); } } if (buf->data_size > max) { @@ -734,7 +729,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) cstate_size = sdp_set_cstate_pdu(buf, cstate); } else { status = SDP_INVALID_CSTATE; - debug("Non-null continuation state, but null cache buffer\n"); + debug("Non-null continuation state, but null cache buffer"); } } @@ -779,8 +774,6 @@ void process_request(sdp_req_t *req) int sent = 0; int status = SDP_INVALID_SYNTAX; - debug(""); - memset(buf, 0, USHRT_MAX); rsp.data = buf + sizeof(sdp_pdu_hdr_t); rsp.data_size = 0; @@ -793,44 +786,44 @@ void process_request(sdp_req_t *req) } switch (reqhdr->pdu_id) { case SDP_SVC_SEARCH_REQ: - debug("Got a svc srch req\n"); + debug("Got a svc srch req"); status = service_search_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_SEARCH_RSP; break; case SDP_SVC_ATTR_REQ: - debug("Got a svc attr req\n"); + debug("Got a svc attr req"); status = service_attr_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_ATTR_RSP; break; case SDP_SVC_SEARCH_ATTR_REQ: - debug("Got a svc srch attr req\n"); + debug("Got a svc srch attr req"); status = service_search_attr_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_SEARCH_ATTR_RSP; break; /* Following requests are allowed only for local connections */ case SDP_SVC_REGISTER_REQ: - debug("Service register request\n"); + debug("Service register request"); if (req->local) { status = service_register_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_REGISTER_RSP; } break; case SDP_SVC_UPDATE_REQ: - debug("Service update request\n"); + debug("Service update request"); if (req->local) { status = service_update_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_UPDATE_RSP; } break; case SDP_SVC_REMOVE_REQ: - debug("Service removal request\n"); + debug("Service removal request"); if (req->local) { status = service_remove_req(req, &rsp); rsphdr->pdu_id = SDP_SVC_REMOVE_RSP; } break; default: - error("Unknown PDU ID : 0x%x received\n", reqhdr->pdu_id); + error("Unknown PDU ID : 0x%x received", reqhdr->pdu_id); status = SDP_INVALID_SYNTAX; break; } @@ -854,7 +847,7 @@ send_rsp: /* stream the rsp PDU */ sent = send(req->sock, rsp.data, rsp.data_size, 0); - debug("Bytes Sent : %d\n", sent); + debug("Bytes Sent : %d", sent); free(rsp.data); free(req->buf); diff --git a/sdpd/service.c b/sdpd/service.c index 276f4481..b6ac0ac1 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -58,13 +58,13 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h p += *scanned; lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *) (p + sizeof(uint8_t)))); - debug("Look ahead attr id : %d\n", lookAheadAttrId); + debug("Look ahead attr id : %d", lookAheadAttrId); if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { handle = ntohl(sdp_get_unaligned((uint32_t *) (p + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t)))); - debug("SvcRecHandle : 0x%x\n", handle); + debug("SvcRecHandle : 0x%x", handle); rec = sdp_record_find(handle); } else if (handleExpected != 0xffffffff) rec = sdp_record_find(handleExpected); @@ -91,11 +91,11 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h attrId = ntohs(sdp_get_unaligned((uint16_t *) (p + attrSize))); attrSize += sizeof(uint16_t); - debug("DTD of attrId : %d Attr id : 0x%x \n", dtd, attrId); + debug("DTD of attrId : %d Attr id : 0x%x", dtd, attrId); pAttr = sdp_extract_attr(p + attrSize, &attrValueLength, rec); - debug("Attr id : 0x%x attrValueLength : %d\n", attrId, attrValueLength); + debug("Attr id : 0x%x attrValueLength : %d", attrId, attrValueLength); attrSize += attrValueLength; if (pAttr == NULL) { @@ -111,7 +111,7 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h } if (extractStatus == 0) { - debug("Successful extracting of Svc Rec attributes\n"); + debug("Successful extracting of Svc Rec attributes"); #ifdef SDP_DEBUG sdp_print_service_attr(rec->attrlist); #endif @@ -192,26 +192,24 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *) p)); - debug(""); - - debug("Svc Rec Handle: 0x%x\n", handle); + debug("Svc Rec Handle: 0x%x", handle); p += sizeof(uint32_t); orec = sdp_record_find(handle); - debug("SvcRecOld: %p\n", orec); + debug("SvcRecOld: %p", orec); if (orec) { sdp_record_t *nrec = extract_pdu_server(BDADDR_ANY, p, handle, &scanned); if (nrec && handle == nrec->handle) update_db_timestamp(); else { - debug("SvcRecHandle : 0x%x\n", handle); - debug("SvcRecHandleNew : 0x%x\n", nrec->handle); - debug("SvcRecNew : %p\n", nrec); - debug("SvcRecOld : %p\n", orec); - debug("Failure to update, restore old value\n"); + debug("SvcRecHandle : 0x%x", handle); + debug("SvcRecHandleNew : 0x%x", nrec->handle); + debug("SvcRecNew : %p", nrec); + debug("SvcRecOld : %p", orec); + debug("Failure to update, restore old value"); if (nrec) sdp_record_free(nrec); @@ -236,8 +234,6 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_record_t *rec; int status = 0; - debug(""); - /* extract service record handle */ p += sizeof(uint32_t); @@ -250,7 +246,7 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) update_db_timestamp(); } else { status = SDP_INVALID_RECORD_HANDLE; - debug("Could not find record : 0x%x\n", handle); + debug("Could not find record : 0x%x", handle); } p = rsp->data; diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index d4ebd7de..0ae62e99 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -60,7 +60,7 @@ static int record_sort(const void *r1, const void *r2) const sdp_record_t *rec2 = (const sdp_record_t *) r2; if (!rec1 || !rec2) { - error("NULL RECORD LIST FATAL\n"); + error("NULL RECORD LIST FATAL"); return -1; } @@ -73,7 +73,7 @@ static int access_sort(const void *r1, const void *r2) const sdp_access_t *rec2 = (const sdp_access_t *) r2; if (!rec1 || !rec2) { - error("NULL RECORD LIST FATAL\n"); + error("NULL RECORD LIST FATAL"); return -1; } @@ -169,8 +169,8 @@ void sdp_record_add(bdaddr_t *device, sdp_record_t *rec) { sdp_access_t *dev; - debug("Adding rec : 0x%lx\n", (long) rec); - debug("with handle : 0x%x\n", rec->handle); + debug("Adding rec : 0x%lx", (long) rec); + debug("with handle : 0x%x", rec->handle); service_db = sdp_list_insert_sorted(service_db, rec, record_sort); @@ -195,7 +195,7 @@ static sdp_list_t *record_locate(uint32_t handle) return p; } - debug("Could not find svcRec for : 0x%x\n", handle); + debug("Could not find svcRec for : 0x%x", handle); return NULL; } @@ -210,7 +210,7 @@ static sdp_list_t *access_locate(uint32_t handle) return p; } - debug("Could not find access data for : 0x%x\n", handle); + debug("Could not find access data for : 0x%x", handle); return NULL; } @@ -222,7 +222,7 @@ sdp_record_t *sdp_record_find(uint32_t handle) sdp_list_t *p = record_locate(handle); if (!p) { - debug("Couldn't find record for : 0x%x\n", handle); + debug("Couldn't find record for : 0x%x", handle); return 0; } @@ -239,7 +239,7 @@ int sdp_record_remove(uint32_t handle) sdp_access_t *a; if (!p) { - error("Remove : Couldn't find record for : 0x%x\n", handle); + error("Remove : Couldn't find record for : 0x%x", handle); return -1; } -- cgit From 4c82b98bd90b389c616c71b5e75ef7096c3461c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 13:13:13 +0000 Subject: Fix definition of _XOPEN_SOURCE --- sdpd/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index da14b967..d3fba1ac 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -34,11 +34,10 @@ #include #include #include -#include -#include - #define _XOPEN_SOURCE 600 +#include #include +#include #include #include -- cgit From 569abc7679a7ba14d2d9edef7e000d28c21d955b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 13:17:00 +0000 Subject: Stop logging on exit --- sdpd/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index d3fba1ac..3065e200 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -476,7 +476,7 @@ int main(int argc, char *argv[]) num = pselect(active_maxfd + 1, &mask, NULL, NULL, NULL, &sigs); if (num <= 0) { debug("Select error:%s", strerror(errno)); - goto exit; + break; } if (FD_ISSET(l2cap_sock, &mask)) { @@ -505,7 +505,9 @@ int main(int argc, char *argv[]) check_active(&mask, num); } -exit: sdp_svcdb_reset(); + + stop_logging(); + return 0; } -- cgit From 118f6f9f013b38afc5b65dd0e4de97e9baad07e6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 13:19:28 +0000 Subject: Remove sdp_put_unaligned and sdp_get_unaligned macros --- sdpd/request.c | 40 ++++++++++++++++++++-------------------- sdpd/sdpd.h | 3 --- sdpd/service.c | 18 +++++++++--------- 3 files changed, 29 insertions(+), 32 deletions(-) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index 17aa9d99..471871d7 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -98,7 +98,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p p += sizeof(uint8_t); seqlen += sizeof(uint8_t); pElem = malloc(sizeof(uint16_t)); - sdp_put_unaligned(ntohs(sdp_get_unaligned((uint16_t *)p)), (uint16_t *)pElem); + bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)pElem); p += sizeof(uint16_t); seqlen += sizeof(uint16_t); break; @@ -106,7 +106,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p p += sizeof(uint8_t); seqlen += sizeof(uint8_t); pElem = malloc(sizeof(uint32_t)); - sdp_put_unaligned(ntohl(sdp_get_unaligned((uint32_t *)p)), (uint32_t *)pElem); + bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)pElem); p += sizeof(uint32_t); seqlen += sizeof(uint32_t); break; @@ -259,7 +259,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) goto done; } - expected = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + expected = ntohs(bt_get_unaligned((uint16_t *)pdata)); debug("Expected count: %d", expected); debug("Bytes scanned : %d", scanned); @@ -280,13 +280,13 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) /* total service record count = 0 */ pTotalRecordCount = (short *)pdata; - sdp_put_unaligned(0, (uint16_t *)pdata); + bt_put_unaligned(0, (uint16_t *)pdata); pdata += sizeof(uint16_t); buf->data_size += sizeof(uint16_t); /* current service record count = 0 */ pCurrentRecordCount = (short *)pdata; - sdp_put_unaligned(0, (uint16_t *)pdata); + bt_put_unaligned(0, (uint16_t *)pdata); pdata += sizeof(uint16_t); buf->data_size += sizeof(uint16_t); @@ -303,7 +303,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) if (sdp_match_uuid(pattern, rec->pattern) > 0 && sdp_check_access(rec->handle, &req->device)) { rsp_count++; - sdp_put_unaligned(htonl(rec->handle), (uint32_t *)pdata); + bt_put_unaligned(htonl(rec->handle), (uint32_t *)pdata); pdata += sizeof(uint32_t); handleSize += sizeof(uint32_t); } @@ -312,8 +312,8 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) debug("Match count: %d", rsp_count); buf->data_size += handleSize; - sdp_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); - sdp_put_unaligned(htons(rsp_count), (uint16_t *)pCurrentRecordCount); + bt_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); + bt_put_unaligned(htons(rsp_count), (uint16_t *)pCurrentRecordCount); if (rsp_count > actual) { /* cache the rsp and generate a continuation state */ @@ -342,7 +342,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) if (pCache) { pCacheBuffer = pCache->data; /* get the rsp_count from the cached buffer */ - rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pCacheBuffer)); + rsp_count = ntohs(bt_get_unaligned((uint16_t *)pCacheBuffer)); /* get index of the last sdp_record_t sent */ lastIndex = cstate->cStateValue.lastIndexSent; @@ -368,7 +368,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) if (cstate) { handleSize = 0; for (i = lastIndex; (i - lastIndex) < actual && i < rsp_count; i++) { - sdp_put_unaligned(sdp_get_unaligned((uint32_t *)(pCacheBuffer + i * sizeof(uint32_t))), (uint32_t *)pdata); + bt_put_unaligned(bt_get_unaligned((uint32_t *)(pCacheBuffer + i * sizeof(uint32_t))), (uint32_t *)pdata); pdata += sizeof(uint32_t); handleSize += sizeof(uint32_t); } @@ -378,8 +378,8 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) } buf->data_size += handleSize; - sdp_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); - sdp_put_unaligned(htons(i - lastIndex), (uint16_t *)pCurrentRecordCount); + bt_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); + bt_put_unaligned(htons(i - lastIndex), (uint16_t *)pCurrentRecordCount); if (i == rsp_count) { /* set "null" continuationState */ @@ -436,7 +436,7 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu } if (dtd == SDP_UINT16) for (; seq; seq = seq->next) { - uint16_t attr = sdp_get_unaligned((uint16_t *)seq->data); + uint16_t attr = bt_get_unaligned((uint16_t *)seq->data); sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr); if (a) sdp_append_to_pdu(buf, a); @@ -445,7 +445,7 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu sdp_buf_t pdu; sdp_gen_record_pdu(rec, &pdu); for (; seq; seq = seq->next) { - uint32_t range = sdp_get_unaligned((uint32_t *)seq->data); + uint32_t range = bt_get_unaligned((uint32_t *)seq->data); uint16_t attr; uint16_t low = (0xffff0000 & range) >> 16; uint16_t high = 0x0000ffff & range; @@ -497,10 +497,10 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) int max_rsp_size; int status = 0, plen, mlen; uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); - uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)pdata)); + uint32_t handle = ntohl(bt_get_unaligned((uint32_t *)pdata)); pdata += sizeof(uint32_t); - max_rsp_size = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + max_rsp_size = ntohs(bt_get_unaligned((uint16_t *)pdata)); pdata += sizeof(uint16_t); /* extract the attribute list */ @@ -596,7 +596,7 @@ done: return status; /* set attribute list byte count */ - sdp_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data); + bt_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data); buf->data_size += sizeof(uint16_t); return 0; } @@ -628,7 +628,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) debug("Bytes scanned: %d", scanned); pdata += scanned; - max = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + max = ntohs(bt_get_unaligned((uint16_t *)pdata)); pdata += sizeof(uint16_t); debug("Max Attr expected: %d", max); @@ -746,7 +746,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) if (!status) { /* set attribute list byte count */ - sdp_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data); + bt_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data); buf->data_size += sizeof(uint16_t); } @@ -831,7 +831,7 @@ void process_request(sdp_req_t *req) send_rsp: if (status) { rsphdr->pdu_id = SDP_ERROR_RSP; - sdp_put_unaligned(htons(status), (uint16_t *)rsp.data); + bt_put_unaligned(htons(status), (uint16_t *)rsp.data); rsp.data_size = sizeof(uint16_t); } diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 69c1446e..67ba4e78 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -24,9 +24,6 @@ * */ -#define sdp_get_unaligned bt_get_unaligned -#define sdp_put_unaligned bt_put_unaligned - typedef struct request { bdaddr_t device; bdaddr_t bdaddr; diff --git a/sdpd/service.c b/sdpd/service.c index b6ac0ac1..ce292292 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -56,12 +56,12 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h *scanned = sdp_extract_seqtype(p, &dtd, &seqlen); p += *scanned; - lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *) (p + sizeof(uint8_t)))); + lookAheadAttrId = ntohs(bt_get_unaligned((uint16_t *) (p + sizeof(uint8_t)))); debug("Look ahead attr id : %d", lookAheadAttrId); if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { - handle = ntohl(sdp_get_unaligned((uint32_t *) (p + + handle = ntohl(bt_get_unaligned((uint32_t *) (p + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t)))); debug("SvcRecHandle : 0x%x", handle); @@ -88,7 +88,7 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h debug("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength); dtd = *(uint8_t *) p; - attrId = ntohs(sdp_get_unaligned((uint16_t *) (p + attrSize))); + attrId = ntohs(bt_get_unaligned((uint16_t *) (p + attrSize))); attrSize += sizeof(uint16_t); debug("DTD of attrId : %d Attr id : 0x%x", dtd, attrId); @@ -170,13 +170,13 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) update_db_timestamp(); /* Build a rsp buffer */ - sdp_put_unaligned(htonl(rec->handle), (uint32_t *) rsp->data); + bt_put_unaligned(htonl(rec->handle), (uint32_t *) rsp->data); rsp->data_size = sizeof(uint32_t); return 0; invalid: - sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *) rsp->data); + bt_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *) rsp->data); rsp->data_size = sizeof(uint16_t); return -1; @@ -190,7 +190,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_record_t *orec; int status = 0, scanned = 0; uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); - uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *) p)); + uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p)); debug("Svc Rec Handle: 0x%x", handle); @@ -219,7 +219,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) status = SDP_INVALID_RECORD_HANDLE; p = rsp->data; - sdp_put_unaligned(htons(status), (uint16_t *) p); + bt_put_unaligned(htons(status), (uint16_t *) p); rsp->data_size = sizeof(uint16_t); return status; } @@ -230,7 +230,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) { uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); - uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *) p)); + uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p)); sdp_record_t *rec; int status = 0; @@ -250,7 +250,7 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) } p = rsp->data; - sdp_put_unaligned(htons(status), (uint16_t *) p); + bt_put_unaligned(htons(status), (uint16_t *) p); rsp->data_size = sizeof(uint16_t); return status; -- cgit From 24f75e0b15d73034bf75058f86d545fcb58314f0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 19:02:42 +0000 Subject: Another logging update --- sdpd/main.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 3065e200..9e3391a9 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -393,10 +393,9 @@ static void check_active(fd_set *mask, int num) static void usage(void) { - printf("sdpd version %s\n", VERSION); - printf("Usage:\n" - "sdpd [-n]\n" - ); + printf("sdpd - SDP daemon ver %s\n", VERSION); + printf("Usage: \n"); + printf("\tsdpd [-n]\n"); } static struct option main_options[] = { @@ -415,24 +414,34 @@ int main(int argc, char *argv[]) int daemonize = 1, public = 0, master = 0; int opt; - while ((opt = getopt_long(argc, argv, "nm:pM", main_options, NULL)) != -1) + while ((opt = getopt_long(argc, argv, "nm:pM", main_options, NULL)) != -1) { switch (opt) { case 'n': daemonize = 0; break; + case 'm': mtu = atoi(optarg); break; + case 'p': public = 1; break; + case 'M': master = 1; break; + default: usage(); - exit(0); + exit(1); } + } + + if (daemonize && daemon(0, 0)) { + error("Server startup failed: %s (%d)", strerror(errno), errno); + exit(1); + } start_logging("sdpd", "Bluetooth SDP daemon"); @@ -440,17 +449,9 @@ int main(int argc, char *argv[]) enable_debug(); #endif - if (daemonize && daemon(0, 0)) { - error("Server startup failed: %s (%d)", strerror(errno), errno); - return -1; - } - - argc -= optind; - argv += optind; - if (init_server(mtu, master, public) < 0) { error("Server initialization failed"); - return -1; + exit(1); } signal(SIGINT, sig_term); -- cgit From 0960d076f77e67d99592e76d83ecd36ea7182618 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 19:15:11 +0000 Subject: Create library for SDP server functionality --- sdpd/Makefile.am | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 226d1f5c..a520ac46 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -1,9 +1,13 @@ +noinst_LIBRARIES = libsdpserver.a + +libsdpserver_a_SOURCES = sdpd.h cstate.c request.c service.c servicedb.c + sbin_PROGRAMS = sdpd -sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h +sdpd_SOURCES = main.c -sdpd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a +sdpd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a libsdpserver.a AM_CFLAGS = @BLUEZ_CFLAGS@ -- cgit From 71094ca865f428f8ce699266c6d5037e60d525fb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 20:08:14 +0000 Subject: Make use of generic mainloop --- sdpd/main.c | 217 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 112 insertions(+), 105 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 9e3391a9..3a663218 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -34,9 +34,7 @@ #include #include #include -#define _XOPEN_SOURCE 600 #include -#include #include #include @@ -47,12 +45,14 @@ #include #include +#include "glib-ectomy.h" + #include "sdpd.h" #include "logging.h" +static GMainLoop *event_loop; + static int l2cap_sock, unix_sock; -static fd_set active_fdset; -static int active_maxfd; static sdp_record_t *server; @@ -244,10 +244,12 @@ static int init_server(uint16_t mtu, int master, int public) return -1; } - l2addr.l2_bdaddr = *BDADDR_ANY; + memset(&l2addr, 0, sizeof(l2addr)); l2addr.l2_family = AF_BLUETOOTH; - l2addr.l2_psm = htobs(SDP_PSM); - if (bind(l2cap_sock, (struct sockaddr *)&l2addr, sizeof(l2addr)) < 0) { + bacpy(&l2addr.l2_bdaddr, BDADDR_ANY); + l2addr.l2_psm = htobs(SDP_PSM); + + if (bind(l2cap_sock, (struct sockaddr *) &l2addr, sizeof(l2addr)) < 0) { error("binding L2CAP socket: %s", strerror(errno)); return -1; } @@ -278,8 +280,6 @@ static int init_server(uint16_t mtu, int master, int public) } listen(l2cap_sock, 5); - FD_SET(l2cap_sock, &active_fdset); - active_maxfd = l2cap_sock; /* Create local Unix socket */ unix_sock = socket(PF_UNIX, SOCK_STREAM, 0); @@ -288,31 +288,24 @@ static int init_server(uint16_t mtu, int master, int public) return -1; } + memset(&unaddr, 0, sizeof(unaddr)); unaddr.sun_family = AF_UNIX; strcpy(unaddr.sun_path, SDP_UNIX_PATH); + unlink(unaddr.sun_path); - if (bind(unix_sock, (struct sockaddr *)&unaddr, sizeof(unaddr)) < 0) { + + if (bind(unix_sock, (struct sockaddr *) &unaddr, sizeof(unaddr)) < 0) { error("binding UNIX socket: %s", strerror(errno)); return -1; } listen(unix_sock, 5); - FD_SET(unix_sock, &active_fdset); - active_maxfd = unix_sock; + chmod(SDP_UNIX_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); return 0; } -static void sig_term(int sig) -{ - info("terminating..."); - sdp_svcdb_reset(); - close(l2cap_sock); - close(unix_sock); - exit(0); -} - static inline void handle_request(int sk, uint8_t *data, int len) { struct sockaddr_l2 sa; @@ -349,46 +342,74 @@ static inline void handle_request(int sk, uint8_t *data, int len) process_request(&req); } -static void close_sock(int fd, int r) -{ - if (r < 0) - error("Read error: %s", strerror(errno)); - FD_CLR(fd, &active_fdset); - close(fd); - sdp_svcdb_collect_all(fd); - if (fd == active_maxfd) - active_maxfd--; -} - -static void check_active(fd_set *mask, int num) +static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer data) { sdp_pdu_hdr_t hdr; - int size, fd, count, r; uint8_t *buf; + int sk, len, size; - for (fd = 0, count = 0; fd <= active_maxfd && count < num; fd++) { - if (fd == l2cap_sock || fd == unix_sock || !FD_ISSET(fd, mask)) - continue; + if (cond & (G_IO_HUP | G_IO_ERR)) { + g_io_channel_unref(chan); + return FALSE; + } - count++; + sk = g_io_channel_unix_get_fd(chan); - r = recv(fd, (void *)&hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK); - if (r <= 0) { - close_sock(fd, r); - continue; - } + len = recv(sk, &hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK); + if (len <= 0) { + sdp_svcdb_collect_all(sk); + return FALSE; + } - size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen); - buf = malloc(size); - if (!buf) - continue; + size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen); + buf = malloc(size); + if (!buf) + return TRUE; - r = recv(fd, buf, size, 0); - if (r <= 0) - close_sock(fd, r); - else - handle_request(fd, buf, r); + len = recv(sk, buf, size, 0); + if (len <= 0) { + sdp_svcdb_collect_all(sk); + return FALSE; } + + handle_request(sk, buf, len); + + return TRUE; +} + +static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + GIOChannel *io; + int nsk; + + if (data == &l2cap_sock) { + struct sockaddr_l2 addr; + socklen_t len = sizeof(addr); + + nsk = accept(l2cap_sock, (struct sockaddr *) &addr, &len); + } else if (data == &unix_sock) { + struct sockaddr_un addr; + socklen_t len = sizeof(addr); + + nsk = accept(unix_sock, (struct sockaddr *) &addr, &len); + } else + return FALSE; + + io = g_io_channel_unix_new(nsk); + g_io_channel_set_close_on_unref(io, TRUE); + + g_io_add_watch(io, G_IO_IN, io_session_event, data); + + return TRUE; +} + +static void sig_term(int sig) +{ + g_main_quit(event_loop); +} + +static void sig_hup(int sig) +{ } static void usage(void) @@ -409,10 +430,10 @@ static struct option main_options[] = { int main(int argc, char *argv[]) { - sigset_t sigs; + struct sigaction sa; + GIOChannel *l2cap_io, *unix_io; uint16_t mtu = 0; - int daemonize = 1, public = 0, master = 0; - int opt; + int opt, daemonize = 1, public = 0, master = 0; while ((opt = getopt_long(argc, argv, "nm:pM", main_options, NULL)) != -1) { switch (opt) { @@ -443,8 +464,22 @@ int main(int argc, char *argv[]) exit(1); } + umask(0077); + start_logging("sdpd", "Bluetooth SDP daemon"); + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + #ifdef SDP_DEBUG enable_debug(); #endif @@ -454,60 +489,32 @@ int main(int argc, char *argv[]) exit(1); } - signal(SIGINT, sig_term); - signal(SIGTERM, sig_term); - signal(SIGABRT, sig_term); - signal(SIGQUIT, sig_term); - signal(SIGPIPE, SIG_IGN); - - sigfillset(&sigs); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGABRT); - sigdelset(&sigs, SIGQUIT); - sigdelset(&sigs, SIGPIPE); - - for (;;) { - int num, nfd; - fd_set mask; - - FD_ZERO(&mask); - mask = active_fdset; - - num = pselect(active_maxfd + 1, &mask, NULL, NULL, NULL, &sigs); - if (num <= 0) { - debug("Select error:%s", strerror(errno)); - break; - } + /* Create event loop */ + event_loop = g_main_new(FALSE); - if (FD_ISSET(l2cap_sock, &mask)) { - /* New L2CAP connection */ - struct sockaddr_l2 caddr; - socklen_t len = sizeof(caddr); - - nfd = accept(l2cap_sock, (struct sockaddr *)&caddr, &len); - if (nfd >= 0) { - if (nfd > active_maxfd) - active_maxfd = nfd; - FD_SET(nfd, &active_fdset); - } - } else if (FD_ISSET(unix_sock, &mask)) { - /* New unix connection */ - struct sockaddr_un caddr; - socklen_t len = sizeof(caddr); - - nfd = accept(unix_sock, (struct sockaddr *)&caddr, &len); - if (nfd != -1) { - if (nfd > active_maxfd) - active_maxfd = nfd; - FD_SET(nfd, &active_fdset); - } - } else - check_active(&mask, num); - } + l2cap_io = g_io_channel_unix_new(l2cap_sock); + g_io_channel_set_close_on_unref(l2cap_io, TRUE); + + g_io_add_watch(l2cap_io, G_IO_IN, io_accept_event, &l2cap_sock); + + unix_io = g_io_channel_unix_new(unix_sock); + g_io_channel_set_close_on_unref(unix_io, TRUE); + + g_io_add_watch(unix_io, G_IO_IN, io_accept_event, &unix_sock); + + /* Start event processor */ + g_main_run(event_loop); sdp_svcdb_reset(); + g_main_unref(event_loop); + + g_io_channel_unref(unix_io); + + g_io_channel_unref(l2cap_io); + + info("Exit"); + stop_logging(); return 0; -- cgit From 1e33e3190f1545cf23c03dd2a13e5cf439add265 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 22:58:54 +0000 Subject: Change linking order --- sdpd/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index a520ac46..d29932da 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -7,7 +7,7 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c -sdpd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a libsdpserver.a +sdpd_LDADD = @BLUEZ_LIBS@ libsdpserver.a $(top_builddir)/common/libhelper.a AM_CFLAGS = @BLUEZ_CFLAGS@ -- cgit From 4cfded0ce163301d9723b36340254070b3ab5d7a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 23:04:48 +0000 Subject: Include the SDP prototypes --- sdpd/sdpd.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sdpd') diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 67ba4e78..ed33c681 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -24,6 +24,8 @@ * */ +#include + typedef struct request { bdaddr_t device; bdaddr_t bdaddr; -- cgit From 9ce11bb84c54444560d2fc548c9caf4e9ad96aa4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 18 Nov 2006 20:07:37 +0000 Subject: Check for errors on listening socket --- sdpd/main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 3a663218..0dde76fb 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -382,6 +382,11 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da GIOChannel *io; int nsk; + if (cond & (G_IO_HUP | G_IO_ERR)) { + g_io_channel_unref(chan); + return FALSE; + } + if (data == &l2cap_sock) { struct sockaddr_l2 addr; socklen_t len = sizeof(addr); -- cgit From 2a97c2f0298379e903aac404b1f4cfd69c8cdcd2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 18 Nov 2006 20:13:09 +0000 Subject: Check if the accept() call fails --- sdpd/main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 0dde76fb..e64d805b 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -400,6 +400,11 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da } else return FALSE; + if (nsk < 0) { + error("Can't accept connection: %s", strerror(errno)); + return TRUE; + } + io = g_io_channel_unix_new(nsk); g_io_channel_set_close_on_unref(io, TRUE); -- cgit From c97480f11bdfdc3cbb867b8127074bcb6b047024 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 12 Jan 2007 00:37:42 +0000 Subject: Allow compilation against GLib --- sdpd/Makefile.am | 12 ++++++++++-- sdpd/main.c | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index d29932da..e87b03a9 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -1,4 +1,12 @@ +if GLIB +glib_cflags = @GLIB_CFLAGS@ +glib_ldadd = @GLIB_LIBS@ +else +glib_cflags = +glib_ldadd = +endif + noinst_LIBRARIES = libsdpserver.a libsdpserver_a_SOURCES = sdpd.h cstate.c request.c service.c servicedb.c @@ -7,9 +15,9 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c -sdpd_LDADD = @BLUEZ_LIBS@ libsdpserver.a $(top_builddir)/common/libhelper.a +sdpd_LDADD = $(glib_ldadd) @BLUEZ_LIBS@ libsdpserver.a $(top_builddir)/common/libhelper.a -AM_CFLAGS = @BLUEZ_CFLAGS@ +AM_CFLAGS = @BLUEZ_CFLAGS@ $(glib_cflags) INCLUDES = -I$(top_srcdir)/common diff --git a/sdpd/main.c b/sdpd/main.c index e64d805b..ab258e93 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -500,7 +500,7 @@ int main(int argc, char *argv[]) } /* Create event loop */ - event_loop = g_main_new(FALSE); + event_loop = g_main_loop_new(NULL, FALSE); l2cap_io = g_io_channel_unix_new(l2cap_sock); g_io_channel_set_close_on_unref(l2cap_io, TRUE); @@ -517,7 +517,7 @@ int main(int argc, char *argv[]) sdp_svcdb_reset(); - g_main_unref(event_loop); + g_main_loop_unref(event_loop); g_io_channel_unref(unix_io); -- cgit From 607695ed109340f4b7a5628420e0a8e8aee34f4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 17:48:12 +0000 Subject: Update copyright information --- sdpd/cstate.c | 2 +- sdpd/main.c | 2 +- sdpd/request.c | 2 +- sdpd/sdpd.h | 2 +- sdpd/service.c | 2 +- sdpd/servicedb.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index ad23f4ec..f1d84498 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/main.c b/sdpd/main.c index ab258e93..56370dd8 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/request.c b/sdpd/request.c index 471871d7..2fc4b8b6 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index ed33c681..97637125 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/service.c b/sdpd/service.c index ce292292..bea82930 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 0ae62e99..decc2e65 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * -- cgit From 3f5e2295dd6b747609ad3a893a76af5ba2146c93 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 18:02:10 +0000 Subject: Better integration into a SDP server library --- sdpd/main.c | 203 +-------------------------------------------------------- sdpd/request.c | 40 +++++++++++- sdpd/sdpd.h | 5 +- sdpd/service.c | 166 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 209 insertions(+), 205 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 56370dd8..60d477ec 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -54,171 +54,6 @@ static GMainLoop *event_loop; static int l2cap_sock, unix_sock; -static sdp_record_t *server; - -/* - * List of version numbers supported by the SDP server. - * Add to this list when newer versions are supported. - */ -static sdp_version_t sdpVnumArray[1] = { - { 1, 0 } -}; -static const int sdpServerVnumEntries = 1; - -/* - * The service database state is an attribute of the service record - * of the SDP server itself. This attribute is guaranteed to - * change if any of the contents of the service repository - * changes. This function updates the timestamp of value of - * the svcDBState attribute - * Set the SDP server DB. Simply a timestamp which is the marker - * when the DB was modified. - */ -void update_db_timestamp(void) -{ - uint32_t dbts = sdp_get_time(); - sdp_data_t *d = sdp_data_alloc(SDP_UINT32, &dbts); - sdp_attr_replace(server, SDP_ATTR_SVCDB_STATE, d); -} - -static void add_lang_attr(sdp_record_t *r) -{ - sdp_lang_attr_t base_lang; - sdp_list_t *langs = 0; - - base_lang.code_ISO639 = (0x65 << 8) | 0x6e; - // UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) - base_lang.encoding = 106; - base_lang.base_offset = SDP_PRIMARY_LANG_BASE; - langs = sdp_list_append(0, &base_lang); - sdp_set_lang_attr(r, langs); - sdp_list_free(langs, 0); -} - -static void register_public_browse_group(int public) -{ - sdp_list_t *browselist; - uuid_t bgscid, pbgid; - sdp_data_t *sdpdata; - sdp_record_t *browse = sdp_record_alloc(); - - if (public) { - browse->handle = sdp_next_handle(); - if (browse->handle < 0x10000) - return; - } else - browse->handle = SDP_SERVER_RECORD_HANDLE + 1; - - sdp_record_add(BDADDR_ANY, browse); - sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); - sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); - - add_lang_attr(browse); - sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", "Root of public browse hierarchy"); - - sdp_uuid16_create(&bgscid, BROWSE_GRP_DESC_SVCLASS_ID); - browselist = sdp_list_append(0, &bgscid); - sdp_set_service_classes(browse, browselist); - sdp_list_free(browselist, 0); - - if (public) { - sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); - sdp_set_group_id(browse, pbgid); - } -} - -/* - * The SDP server must present its own service record to - * the service repository. This can be accessed by service - * discovery clients. This method constructs a service record - * and stores it in the repository - */ -static void register_server_service(int public) -{ - int i; - sdp_list_t *classIDList, *browseList; - sdp_list_t *access_proto = 0; - uuid_t l2cap, classID, browseGroupId, sdpSrvUUID; - void **versions, **versionDTDs; - uint8_t dtd; - uint16_t version, port; - sdp_data_t *pData, *port_data, *version_data; - sdp_list_t *pd, *seq; - - server = sdp_record_alloc(); - server->pattern = NULL; - - /* Force the record to be SDP_SERVER_RECORD_HANDLE */ - server->handle = SDP_SERVER_RECORD_HANDLE; - - sdp_record_add(BDADDR_ANY, server); - sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); - - /* - * Add all attributes to service record. (No need to commit since we - * are the server and this record is already in the database.) - */ - add_lang_attr(server); - sdp_set_info_attr(server, "SDP Server", "BlueZ", "Bluetooth service discovery server"); - - sdp_uuid16_create(&classID, SDP_SERVER_SVCLASS_ID); - classIDList = sdp_list_append(0, &classID); - sdp_set_service_classes(server, classIDList); - sdp_list_free(classIDList, 0); - - /* - * Set the version numbers supported, these are passed as arguments - * to the server on command line. Now defaults to 1.0 - * Build the version number sequence first - */ - versions = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); - versionDTDs = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); - dtd = SDP_UINT16; - for (i = 0; i < sdpServerVnumEntries; i++) { - uint16_t *version = malloc(sizeof(uint16_t)); - *version = sdpVnumArray[i].major; - *version = (*version << 8); - *version |= sdpVnumArray[i].minor; - versions[i] = version; - versionDTDs[i] = &dtd; - } - pData = sdp_seq_alloc(versionDTDs, versions, sdpServerVnumEntries); - for (i = 0; i < sdpServerVnumEntries; i++) - free(versions[i]); - free(versions); - free(versionDTDs); - sdp_attr_add(server, SDP_ATTR_VERSION_NUM_LIST, pData); - - sdp_uuid16_create(&sdpSrvUUID, SDP_UUID); - sdp_set_service_id(server, sdpSrvUUID); - - sdp_uuid16_create(&l2cap, L2CAP_UUID); - pd = sdp_list_append(0, &l2cap); - port = SDP_PSM; - port_data = sdp_data_alloc(SDP_UINT16, &port); - pd = sdp_list_append(pd, port_data); - version = 1; - version_data = sdp_data_alloc(SDP_UINT16, &version); - pd = sdp_list_append(pd, version_data); - seq = sdp_list_append(0, pd); - - access_proto = sdp_list_append(0, seq); - sdp_set_access_protos(server, access_proto); - sdp_list_free(access_proto, free); - sdp_data_free(port_data); - sdp_data_free(version_data); - sdp_list_free(pd, 0); - - if (public) { - sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); - browseList = sdp_list_append(0, &browseGroupId); - sdp_set_browse_groups(server, browseList); - sdp_list_free(browseList, 0); - } - - update_db_timestamp(); -} - /* * SDP server initialization on startup includes creating the * l2cap and unix sockets over which discovery and registration clients @@ -306,42 +141,6 @@ static int init_server(uint16_t mtu, int master, int public) return 0; } -static inline void handle_request(int sk, uint8_t *data, int len) -{ - struct sockaddr_l2 sa; - socklen_t size; - sdp_req_t req; - - size = sizeof(sa); - if (getpeername(sk, (struct sockaddr *) &sa, &size) < 0) - return; - - if (sa.l2_family == AF_BLUETOOTH) { - struct l2cap_options lo; - memset(&lo, 0, sizeof(lo)); - size = sizeof(lo); - getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); - bacpy(&req.bdaddr, &sa.l2_bdaddr); - req.mtu = lo.omtu; - req.local = 0; - memset(&sa, 0, sizeof(sa)); - size = sizeof(sa); - getsockname(sk, (struct sockaddr *) &sa, &size); - bacpy(&req.device, &sa.l2_bdaddr); - } else { - bacpy(&req.device, BDADDR_ANY); - bacpy(&req.bdaddr, BDADDR_LOCAL); - req.mtu = 2048; - req.local = 1; - } - - req.sock = sk; - req.buf = data; - req.len = len; - - process_request(&req); -} - static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer data) { sdp_pdu_hdr_t hdr; @@ -523,7 +322,7 @@ int main(int argc, char *argv[]) g_io_channel_unref(l2cap_io); - info("Exit"); + info("Exit"); stop_logging(); diff --git a/sdpd/request.c b/sdpd/request.c index 2fc4b8b6..2b052863 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -30,10 +30,12 @@ #include #include +#include #include #include #include +#include #include #include @@ -765,7 +767,7 @@ done: * function based on request type. Handles service registration * client requests also. */ -void process_request(sdp_req_t *req) +static void process_request(sdp_req_t *req) { sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)req->buf; sdp_pdu_hdr_t *rsphdr; @@ -852,3 +854,39 @@ send_rsp: free(rsp.data); free(req->buf); } + +void handle_request(int sk, uint8_t *data, int len) +{ + struct sockaddr_l2 sa; + socklen_t size; + sdp_req_t req; + + size = sizeof(sa); + if (getpeername(sk, (struct sockaddr *) &sa, &size) < 0) + return; + + if (sa.l2_family == AF_BLUETOOTH) { + struct l2cap_options lo; + memset(&lo, 0, sizeof(lo)); + size = sizeof(lo); + getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); + bacpy(&req.bdaddr, &sa.l2_bdaddr); + req.mtu = lo.omtu; + req.local = 0; + memset(&sa, 0, sizeof(sa)); + size = sizeof(sa); + getsockname(sk, (struct sockaddr *) &sa, &size); + bacpy(&req.device, &sa.l2_bdaddr); + } else { + bacpy(&req.device, BDADDR_ANY); + bacpy(&req.bdaddr, BDADDR_LOCAL); + req.mtu = 2048; + req.local = 1; + } + + req.sock = sk; + req.buf = data; + req.len = len; + + process_request(&req); +} diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 97637125..a22096d6 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -37,12 +37,15 @@ typedef struct request { int len; } sdp_req_t; -void process_request(sdp_req_t *req); +void handle_request(int sk, uint8_t *data, int len); int service_register_req(sdp_req_t *req, sdp_buf_t *rsp); int service_update_req(sdp_req_t *req, sdp_buf_t *rsp); int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp); +void register_public_browse_group(int public); +void register_server_service(int public); + typedef struct { uint32_t timestamp; union { diff --git a/sdpd/service.c b/sdpd/service.c index bea82930..ae4a7c10 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -41,7 +42,170 @@ #include "sdpd.h" #include "logging.h" -extern void update_db_timestamp(void); +static sdp_record_t *server; + +/* + * List of version numbers supported by the SDP server. + * Add to this list when newer versions are supported. + */ +static sdp_version_t sdpVnumArray[1] = { + { 1, 0 } +}; +static const int sdpServerVnumEntries = 1; + +/* + * The service database state is an attribute of the service record + * of the SDP server itself. This attribute is guaranteed to + * change if any of the contents of the service repository + * changes. This function updates the timestamp of value of + * the svcDBState attribute + * Set the SDP server DB. Simply a timestamp which is the marker + * when the DB was modified. + */ +static void update_db_timestamp(void) +{ + uint32_t dbts = sdp_get_time(); + sdp_data_t *d = sdp_data_alloc(SDP_UINT32, &dbts); + sdp_attr_replace(server, SDP_ATTR_SVCDB_STATE, d); +} + +static void add_lang_attr(sdp_record_t *r) +{ + sdp_lang_attr_t base_lang; + sdp_list_t *langs = 0; + + base_lang.code_ISO639 = (0x65 << 8) | 0x6e; + // UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) + base_lang.encoding = 106; + base_lang.base_offset = SDP_PRIMARY_LANG_BASE; + langs = sdp_list_append(0, &base_lang); + sdp_set_lang_attr(r, langs); + sdp_list_free(langs, 0); +} + +void register_public_browse_group(int public) +{ + sdp_list_t *browselist; + uuid_t bgscid, pbgid; + sdp_data_t *sdpdata; + sdp_record_t *browse = sdp_record_alloc(); + + if (public) { + browse->handle = sdp_next_handle(); + if (browse->handle < 0x10000) + return; + } else + browse->handle = SDP_SERVER_RECORD_HANDLE + 1; + + sdp_record_add(BDADDR_ANY, browse); + sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); + sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); + + add_lang_attr(browse); + sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", "Root of public browse hierarchy"); + + sdp_uuid16_create(&bgscid, BROWSE_GRP_DESC_SVCLASS_ID); + browselist = sdp_list_append(0, &bgscid); + sdp_set_service_classes(browse, browselist); + sdp_list_free(browselist, 0); + + if (public) { + sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); + sdp_set_group_id(browse, pbgid); + } +} + +/* + * The SDP server must present its own service record to + * the service repository. This can be accessed by service + * discovery clients. This method constructs a service record + * and stores it in the repository + */ +void register_server_service(int public) +{ + int i; + sdp_list_t *classIDList, *browseList; + sdp_list_t *access_proto = 0; + uuid_t l2cap, classID, browseGroupId, sdpSrvUUID; + void **versions, **versionDTDs; + uint8_t dtd; + uint16_t version, port; + sdp_data_t *pData, *port_data, *version_data; + sdp_list_t *pd, *seq; + + server = sdp_record_alloc(); + server->pattern = NULL; + + /* Force the record to be SDP_SERVER_RECORD_HANDLE */ + server->handle = SDP_SERVER_RECORD_HANDLE; + + sdp_record_add(BDADDR_ANY, server); + sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); + + /* + * Add all attributes to service record. (No need to commit since we + * are the server and this record is already in the database.) + */ + add_lang_attr(server); + sdp_set_info_attr(server, "SDP Server", "BlueZ", "Bluetooth service discovery server"); + + sdp_uuid16_create(&classID, SDP_SERVER_SVCLASS_ID); + classIDList = sdp_list_append(0, &classID); + sdp_set_service_classes(server, classIDList); + sdp_list_free(classIDList, 0); + + /* + * Set the version numbers supported, these are passed as arguments + * to the server on command line. Now defaults to 1.0 + * Build the version number sequence first + */ + versions = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); + versionDTDs = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); + dtd = SDP_UINT16; + for (i = 0; i < sdpServerVnumEntries; i++) { + uint16_t *version = malloc(sizeof(uint16_t)); + *version = sdpVnumArray[i].major; + *version = (*version << 8); + *version |= sdpVnumArray[i].minor; + versions[i] = version; + versionDTDs[i] = &dtd; + } + pData = sdp_seq_alloc(versionDTDs, versions, sdpServerVnumEntries); + for (i = 0; i < sdpServerVnumEntries; i++) + free(versions[i]); + free(versions); + free(versionDTDs); + sdp_attr_add(server, SDP_ATTR_VERSION_NUM_LIST, pData); + + sdp_uuid16_create(&sdpSrvUUID, SDP_UUID); + sdp_set_service_id(server, sdpSrvUUID); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + pd = sdp_list_append(0, &l2cap); + port = SDP_PSM; + port_data = sdp_data_alloc(SDP_UINT16, &port); + pd = sdp_list_append(pd, port_data); + version = 1; + version_data = sdp_data_alloc(SDP_UINT16, &version); + pd = sdp_list_append(pd, version_data); + seq = sdp_list_append(0, pd); + + access_proto = sdp_list_append(0, seq); + sdp_set_access_protos(server, access_proto); + sdp_list_free(access_proto, free); + sdp_data_free(port_data); + sdp_data_free(version_data); + sdp_list_free(pd, 0); + + if (public) { + sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); + browseList = sdp_list_append(0, &browseGroupId); + sdp_set_browse_groups(server, browseList); + sdp_list_free(browseList, 0); + } + + update_db_timestamp(); +} // FIXME: refactor for server-side static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t handleExpected, int *scanned) -- cgit From c6e4778e9cbc61e77ef9d8721bc04343af11d7e9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 23:30:30 +0000 Subject: Turn it into a full SDP server library --- sdpd/Makefile.am | 2 +- sdpd/main.c | 210 +++-------------------------------------------- sdpd/sdpd.h | 8 ++ sdpd/server.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 264 insertions(+), 201 deletions(-) create mode 100644 sdpd/server.c (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index e87b03a9..f1f01ecb 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -9,7 +9,7 @@ endif noinst_LIBRARIES = libsdpserver.a -libsdpserver_a_SOURCES = sdpd.h cstate.c request.c service.c servicedb.c +libsdpserver_a_SOURCES = sdpd.h server.c cstate.c request.c service.c servicedb.c sbin_PROGRAMS = sdpd diff --git a/sdpd/main.c b/sdpd/main.c index 60d477ec..7e97d3f9 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -32,186 +32,16 @@ #include #include #include -#include #include +#include #include -#include - -#include -#include -#include -#include - -#include -#include #include "glib-ectomy.h" - -#include "sdpd.h" #include "logging.h" +#include "sdpd.h" static GMainLoop *event_loop; -static int l2cap_sock, unix_sock; - -/* - * SDP server initialization on startup includes creating the - * l2cap and unix sockets over which discovery and registration clients - * access us respectively - */ -static int init_server(uint16_t mtu, int master, int public) -{ - struct l2cap_options opts; - struct sockaddr_l2 l2addr; - struct sockaddr_un unaddr; - socklen_t optlen; - - /* Register the public browse group root */ - register_public_browse_group(public); - - /* Register the SDP server's service record */ - register_server_service(public); - - /* Create L2CAP socket */ - l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (l2cap_sock < 0) { - error("opening L2CAP socket: %s", strerror(errno)); - return -1; - } - - memset(&l2addr, 0, sizeof(l2addr)); - l2addr.l2_family = AF_BLUETOOTH; - bacpy(&l2addr.l2_bdaddr, BDADDR_ANY); - l2addr.l2_psm = htobs(SDP_PSM); - - if (bind(l2cap_sock, (struct sockaddr *) &l2addr, sizeof(l2addr)) < 0) { - error("binding L2CAP socket: %s", strerror(errno)); - return -1; - } - - if (master) { - int opt = L2CAP_LM_MASTER; - if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - error("setsockopt: %s", strerror(errno)); - return -1; - } - } - - if (mtu > 0) { - memset(&opts, 0, sizeof(opts)); - optlen = sizeof(opts); - - if (getsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { - error("getsockopt: %s", strerror(errno)); - return -1; - } - - opts.imtu = mtu; - - if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { - error("setsockopt: %s", strerror(errno)); - return -1; - } - } - - listen(l2cap_sock, 5); - - /* Create local Unix socket */ - unix_sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (unix_sock < 0) { - error("opening UNIX socket: %s", strerror(errno)); - return -1; - } - - memset(&unaddr, 0, sizeof(unaddr)); - unaddr.sun_family = AF_UNIX; - strcpy(unaddr.sun_path, SDP_UNIX_PATH); - - unlink(unaddr.sun_path); - - if (bind(unix_sock, (struct sockaddr *) &unaddr, sizeof(unaddr)) < 0) { - error("binding UNIX socket: %s", strerror(errno)); - return -1; - } - - listen(unix_sock, 5); - - chmod(SDP_UNIX_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - - return 0; -} - -static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer data) -{ - sdp_pdu_hdr_t hdr; - uint8_t *buf; - int sk, len, size; - - if (cond & (G_IO_HUP | G_IO_ERR)) { - g_io_channel_unref(chan); - return FALSE; - } - - sk = g_io_channel_unix_get_fd(chan); - - len = recv(sk, &hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK); - if (len <= 0) { - sdp_svcdb_collect_all(sk); - return FALSE; - } - - size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen); - buf = malloc(size); - if (!buf) - return TRUE; - - len = recv(sk, buf, size, 0); - if (len <= 0) { - sdp_svcdb_collect_all(sk); - return FALSE; - } - - handle_request(sk, buf, len); - - return TRUE; -} - -static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer data) -{ - GIOChannel *io; - int nsk; - - if (cond & (G_IO_HUP | G_IO_ERR)) { - g_io_channel_unref(chan); - return FALSE; - } - - if (data == &l2cap_sock) { - struct sockaddr_l2 addr; - socklen_t len = sizeof(addr); - - nsk = accept(l2cap_sock, (struct sockaddr *) &addr, &len); - } else if (data == &unix_sock) { - struct sockaddr_un addr; - socklen_t len = sizeof(addr); - - nsk = accept(unix_sock, (struct sockaddr *) &addr, &len); - } else - return FALSE; - - if (nsk < 0) { - error("Can't accept connection: %s", strerror(errno)); - return TRUE; - } - - io = g_io_channel_unix_new(nsk); - g_io_channel_set_close_on_unref(io, TRUE); - - g_io_add_watch(io, G_IO_IN, io_session_event, data); - - return TRUE; -} - static void sig_term(int sig) { g_main_quit(event_loop); @@ -240,9 +70,9 @@ static struct option main_options[] = { int main(int argc, char *argv[]) { struct sigaction sa; - GIOChannel *l2cap_io, *unix_io; uint16_t mtu = 0; - int opt, daemonize = 1, public = 0, master = 0; + uint32_t flags = SDP_SERVER_COMPAT; + int opt, daemonize = 1; while ((opt = getopt_long(argc, argv, "nm:pM", main_options, NULL)) != -1) { switch (opt) { @@ -255,11 +85,11 @@ int main(int argc, char *argv[]) break; case 'p': - public = 1; + flags |= SDP_SERVER_PUBLIC; break; case 'M': - master = 1; + flags |= SDP_SERVER_MASTER; break; default: @@ -289,39 +119,19 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); -#ifdef SDP_DEBUG - enable_debug(); -#endif + event_loop = g_main_loop_new(NULL, FALSE); - if (init_server(mtu, master, public) < 0) { - error("Server initialization failed"); + if (start_sdp_server(mtu, flags) < 0) { + g_main_loop_unref(event_loop); exit(1); } - /* Create event loop */ - event_loop = g_main_loop_new(NULL, FALSE); - - l2cap_io = g_io_channel_unix_new(l2cap_sock); - g_io_channel_set_close_on_unref(l2cap_io, TRUE); - - g_io_add_watch(l2cap_io, G_IO_IN, io_accept_event, &l2cap_sock); - - unix_io = g_io_channel_unix_new(unix_sock); - g_io_channel_set_close_on_unref(unix_io, TRUE); - - g_io_add_watch(unix_io, G_IO_IN, io_accept_event, &unix_sock); - - /* Start event processor */ g_main_run(event_loop); - sdp_svcdb_reset(); + stop_sdp_server(); g_main_loop_unref(event_loop); - g_io_channel_unref(unix_io); - - g_io_channel_unref(l2cap_io); - info("Exit"); stop_logging(); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index a22096d6..ccdd9653 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -24,6 +24,7 @@ * */ +#include #include typedef struct request { @@ -74,3 +75,10 @@ int sdp_check_access(uint32_t handle, bdaddr_t *device); uint32_t sdp_next_handle(void); uint32_t sdp_get_time(); + +#define SDP_SERVER_COMPAT (1 << 0) +#define SDP_SERVER_MASTER (1 << 1) +#define SDP_SERVER_PUBLIC (1 << 2) + +int start_sdp_server(uint16_t mtu, uint32_t flags); +void stop_sdp_server(void); diff --git a/sdpd/server.c b/sdpd/server.c new file mode 100644 index 00000000..67622e60 --- /dev/null +++ b/sdpd/server.c @@ -0,0 +1,245 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "glib-ectomy.h" +#include "logging.h" +#include "sdpd.h" + +static GIOChannel *l2cap_io, *unix_io; + +static int l2cap_sock, unix_sock; + +/* + * SDP server initialization on startup includes creating the + * l2cap and unix sockets over which discovery and registration clients + * access us respectively + */ +static int init_server(uint16_t mtu, int master, int public) +{ + struct l2cap_options opts; + struct sockaddr_l2 l2addr; + struct sockaddr_un unaddr; + socklen_t optlen; + + /* Register the public browse group root */ + register_public_browse_group(public); + + /* Register the SDP server's service record */ + register_server_service(public); + + /* Create L2CAP socket */ + l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (l2cap_sock < 0) { + error("opening L2CAP socket: %s", strerror(errno)); + return -1; + } + + memset(&l2addr, 0, sizeof(l2addr)); + l2addr.l2_family = AF_BLUETOOTH; + bacpy(&l2addr.l2_bdaddr, BDADDR_ANY); + l2addr.l2_psm = htobs(SDP_PSM); + + if (bind(l2cap_sock, (struct sockaddr *) &l2addr, sizeof(l2addr)) < 0) { + error("binding L2CAP socket: %s", strerror(errno)); + return -1; + } + + if (master) { + int opt = L2CAP_LM_MASTER; + if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + error("setsockopt: %s", strerror(errno)); + return -1; + } + } + + if (mtu > 0) { + memset(&opts, 0, sizeof(opts)); + optlen = sizeof(opts); + + if (getsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + error("getsockopt: %s", strerror(errno)); + return -1; + } + + opts.imtu = mtu; + + if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { + error("setsockopt: %s", strerror(errno)); + return -1; + } + } + + listen(l2cap_sock, 5); + + /* Create local Unix socket */ + unix_sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (unix_sock < 0) { + error("opening UNIX socket: %s", strerror(errno)); + return -1; + } + + memset(&unaddr, 0, sizeof(unaddr)); + unaddr.sun_family = AF_UNIX; + strcpy(unaddr.sun_path, SDP_UNIX_PATH); + + unlink(unaddr.sun_path); + + if (bind(unix_sock, (struct sockaddr *) &unaddr, sizeof(unaddr)) < 0) { + error("binding UNIX socket: %s", strerror(errno)); + return -1; + } + + listen(unix_sock, 5); + + chmod(SDP_UNIX_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + + return 0; +} + +static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + sdp_pdu_hdr_t hdr; + uint8_t *buf; + int sk, len, size; + + if (cond & (G_IO_HUP | G_IO_ERR)) { + g_io_channel_unref(chan); + return FALSE; + } + + sk = g_io_channel_unix_get_fd(chan); + + len = recv(sk, &hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK); + if (len <= 0) { + sdp_svcdb_collect_all(sk); + return FALSE; + } + + size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen); + buf = malloc(size); + if (!buf) + return TRUE; + + len = recv(sk, buf, size, 0); + if (len <= 0) { + sdp_svcdb_collect_all(sk); + return FALSE; + } + + handle_request(sk, buf, len); + + return TRUE; +} + +static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + GIOChannel *io; + int nsk; + + if (cond & (G_IO_HUP | G_IO_ERR)) { + g_io_channel_unref(chan); + return FALSE; + } + + if (data == &l2cap_sock) { + struct sockaddr_l2 addr; + socklen_t len = sizeof(addr); + + nsk = accept(l2cap_sock, (struct sockaddr *) &addr, &len); + } else if (data == &unix_sock) { + struct sockaddr_un addr; + socklen_t len = sizeof(addr); + + nsk = accept(unix_sock, (struct sockaddr *) &addr, &len); + } else + return FALSE; + + if (nsk < 0) { + error("Can't accept connection: %s", strerror(errno)); + return TRUE; + } + + io = g_io_channel_unix_new(nsk); + g_io_channel_set_close_on_unref(io, TRUE); + + g_io_add_watch(io, G_IO_IN, io_session_event, data); + + return TRUE; +} + +int start_sdp_server(uint16_t mtu, uint32_t flags) +{ + int master = flags & SDP_SERVER_MASTER; + int public = flags & SDP_SERVER_PUBLIC; + + info("Starting SDP server"); + + if (init_server(mtu, master, public) < 0) { + error("Server initialization failed"); + return -1; + } + + l2cap_io = g_io_channel_unix_new(l2cap_sock); + g_io_channel_set_close_on_unref(l2cap_io, TRUE); + + g_io_add_watch(l2cap_io, G_IO_IN, io_accept_event, &l2cap_sock); + + unix_io = g_io_channel_unix_new(unix_sock); + g_io_channel_set_close_on_unref(unix_io, TRUE); + + g_io_add_watch(unix_io, G_IO_IN, io_accept_event, &unix_sock); + + return 0; +} + +void stop_sdp_server(void) +{ + info("Stopping SDP server"); + + sdp_svcdb_reset(); + + g_io_channel_unref(unix_io); + + g_io_channel_unref(l2cap_io); +} -- cgit From 54b33571eb8833f86d17957ff5a3309512aab57b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 23:53:00 +0000 Subject: Make installation of hcid and sdpd conditional --- sdpd/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index f1f01ecb..0a425f74 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -11,11 +11,13 @@ noinst_LIBRARIES = libsdpserver.a libsdpserver_a_SOURCES = sdpd.h server.c cstate.c request.c service.c servicedb.c +if SDPD sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c sdpd_LDADD = $(glib_ldadd) @BLUEZ_LIBS@ libsdpserver.a $(top_builddir)/common/libhelper.a +endif AM_CFLAGS = @BLUEZ_CFLAGS@ $(glib_cflags) -- cgit From 70fcd297bce634b8a1b117c3b27784995a8c652a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 14 Jan 2007 00:04:48 +0000 Subject: Make debug information optional --- sdpd/main.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 7e97d3f9..1154547b 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -51,6 +51,11 @@ static void sig_hup(int sig) { } +static void sig_debug(int sig) +{ + toggle_debug(); +} + static void usage(void) { printf("sdpd - SDP daemon ver %s\n", VERSION); @@ -72,14 +77,18 @@ int main(int argc, char *argv[]) struct sigaction sa; uint16_t mtu = 0; uint32_t flags = SDP_SERVER_COMPAT; - int opt, daemonize = 1; + int opt, daemonize = 1, debug = 0; - while ((opt = getopt_long(argc, argv, "nm:pM", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "ndm:pM", main_options, NULL)) != -1) { switch (opt) { case 'n': daemonize = 0; break; + case 'd': + debug = 1; + break; + case 'm': mtu = atoi(optarg); break; @@ -115,10 +124,18 @@ int main(int argc, char *argv[]) sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); + sa.sa_handler = sig_debug; + sigaction(SIGUSR2, &sa, NULL); + sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); + if (debug) { + info("Enabling debug information"); + enable_debug(); + } + event_loop = g_main_loop_new(NULL, FALSE); if (start_sdp_server(mtu, flags) < 0) { -- cgit From fa70fc6dfb0912b116aabdd39436a8b0be55123e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 14 Jan 2007 00:33:09 +0000 Subject: Implement compat mode for the Unix socket access --- sdpd/server.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index 67622e60..65d36996 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -55,7 +55,7 @@ static int l2cap_sock, unix_sock; * l2cap and unix sockets over which discovery and registration clients * access us respectively */ -static int init_server(uint16_t mtu, int master, int public) +static int init_server(uint16_t mtu, int master, int public, int compat) { struct l2cap_options opts; struct sockaddr_l2 l2addr; @@ -112,6 +112,11 @@ static int init_server(uint16_t mtu, int master, int public) listen(l2cap_sock, 5); + if (!compat) { + unix_sock = -1; + return 0; + } + /* Create local Unix socket */ unix_sock = socket(PF_UNIX, SOCK_STREAM, 0); if (unix_sock < 0) { @@ -210,12 +215,13 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da int start_sdp_server(uint16_t mtu, uint32_t flags) { + int compat = flags & SDP_SERVER_COMPAT; int master = flags & SDP_SERVER_MASTER; int public = flags & SDP_SERVER_PUBLIC; info("Starting SDP server"); - if (init_server(mtu, master, public) < 0) { + if (init_server(mtu, master, public, compat) < 0) { error("Server initialization failed"); return -1; } @@ -225,10 +231,13 @@ int start_sdp_server(uint16_t mtu, uint32_t flags) g_io_add_watch(l2cap_io, G_IO_IN, io_accept_event, &l2cap_sock); - unix_io = g_io_channel_unix_new(unix_sock); - g_io_channel_set_close_on_unref(unix_io, TRUE); + if (compat) { + unix_io = g_io_channel_unix_new(unix_sock); + g_io_channel_set_close_on_unref(unix_io, TRUE); - g_io_add_watch(unix_io, G_IO_IN, io_accept_event, &unix_sock); + g_io_add_watch(unix_io, G_IO_IN, io_accept_event, &unix_sock); + } else + unix_io = NULL; return 0; } @@ -239,7 +248,8 @@ void stop_sdp_server(void) sdp_svcdb_reset(); - g_io_channel_unref(unix_io); + if (unix_io) + g_io_channel_unref(unix_io); g_io_channel_unref(l2cap_io); } -- cgit From 2006d2ff671751d0ced48827ae8a58887c404a48 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Jan 2007 00:58:23 +0000 Subject: Modify the server database directly --- sdpd/sdpd.h | 3 +++ sdpd/service.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) (limited to 'sdpd') diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index ccdd9653..8ec47b1a 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -82,3 +82,6 @@ uint32_t sdp_get_time(); int start_sdp_server(uint16_t mtu, uint32_t flags); void stop_sdp_server(void); + +int add_record_to_server(sdp_record_t *rec); +void remove_record_from_server(uint32_t handle); diff --git a/sdpd/service.c b/sdpd/service.c index ae4a7c10..0b4b0d8e 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -207,6 +207,52 @@ void register_server_service(int public) update_db_timestamp(); } +int add_record_to_server(sdp_record_t *rec) +{ + sdp_data_t *data; + + if (rec->handle == 0xffffffff) { + rec->handle = sdp_next_handle(); + if (rec->handle < 0x10000) + return -1; + } else { + if (sdp_record_find(rec->handle)) + return -1; + } + + debug("Adding record with handle 0x%05x", rec->handle); + + sdp_record_add(BDADDR_ANY, rec); + + data = sdp_data_alloc(SDP_UINT32, &rec->handle); + sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); + + if (sdp_data_get(rec, SDP_ATTR_BROWSE_GRP_LIST) == NULL) { + uuid_t uuid; + sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); + sdp_pattern_add_uuid(rec, &uuid); + } + + update_db_timestamp(); + + return 0; +} + +void remove_record_from_server(uint32_t handle) +{ + sdp_record_t *rec; + + debug("Removing record with handle 0x%05x", handle); + + rec = sdp_record_find(handle); + if (rec) { + if (sdp_record_remove(handle) == 0) + update_db_timestamp(); + + sdp_record_free(rec); + } +} + // FIXME: refactor for server-side static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t handleExpected, int *scanned) { -- cgit From 8cc5595d9091b484b9a4abe314c0f3ec055e0581 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 20 Jan 2007 05:26:15 +0000 Subject: Make it possible to support an embedded GLib --- sdpd/Makefile.am | 14 ++++---------- sdpd/main.c | 7 ++++--- sdpd/server.c | 3 ++- 3 files changed, 10 insertions(+), 14 deletions(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 0a425f74..12740584 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -1,12 +1,4 @@ -if GLIB -glib_cflags = @GLIB_CFLAGS@ -glib_ldadd = @GLIB_LIBS@ -else -glib_cflags = -glib_ldadd = -endif - noinst_LIBRARIES = libsdpserver.a libsdpserver_a_SOURCES = sdpd.h server.c cstate.c request.c service.c servicedb.c @@ -16,10 +8,12 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c -sdpd_LDADD = $(glib_ldadd) @BLUEZ_LIBS@ libsdpserver.a $(top_builddir)/common/libhelper.a +sdpd_LDADD = libsdpserver.a \ + $(top_builddir)/common/libhelper.a \ + @GLIB_LIBS@ @BLUEZ_LIBS@ endif -AM_CFLAGS = @BLUEZ_CFLAGS@ $(glib_cflags) +AM_CFLAGS = @BLUEZ_CFLAGS@ @GLIB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common diff --git a/sdpd/main.c b/sdpd/main.c index 1154547b..d29c8c16 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -36,7 +36,8 @@ #include #include -#include "glib-ectomy.h" +#include + #include "logging.h" #include "sdpd.h" @@ -44,7 +45,7 @@ static GMainLoop *event_loop; static void sig_term(int sig) { - g_main_quit(event_loop); + g_main_loop_quit(event_loop); } static void sig_hup(int sig) @@ -143,7 +144,7 @@ int main(int argc, char *argv[]) exit(1); } - g_main_run(event_loop); + g_main_loop_run(event_loop); stop_sdp_server(); diff --git a/sdpd/server.c b/sdpd/server.c index 65d36996..c5458aac 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -42,7 +42,8 @@ #include #include -#include "glib-ectomy.h" +#include + #include "logging.h" #include "sdpd.h" -- cgit From 7899df370a9395fe016f54a311e58487be04c66c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 20 Jan 2007 20:42:27 +0000 Subject: Fix memory leaks --- sdpd/server.c | 2 ++ sdpd/service.c | 8 ++++++-- sdpd/servicedb.c | 8 ++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index c5458aac..4316746b 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -211,6 +211,8 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da g_io_add_watch(io, G_IO_IN, io_session_event, data); + g_io_channel_unref(io); + return TRUE; } diff --git a/sdpd/service.c b/sdpd/service.c index 0b4b0d8e..83844d68 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -353,11 +353,15 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) if (rec->handle == 0xffffffff) { rec->handle = sdp_next_handle(); - if (rec->handle < 0x10000) + if (rec->handle < 0x10000) { + sdp_record_free(rec); goto invalid; + } } else { - if (sdp_record_find(rec->handle)) + if (sdp_record_find(rec->handle)) { + sdp_record_free(rec); goto invalid; + } } sdp_record_add(&req->device, rec); diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index decc2e65..8f5ff810 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -244,14 +244,18 @@ int sdp_record_remove(uint32_t handle) } r = (sdp_record_t *) p->data; - if (r) + if (r) { service_db = sdp_list_remove(service_db, r); + sdp_record_free(r); + } p = access_locate(handle); if (p) { a = (sdp_access_t *) p->data; - if (a) + if (a) { access_db = sdp_list_remove(access_db, a); + access_free(a); + } } return 0; -- cgit From f8987b921efb679a03279e52328dee0a6dbdfe15 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 20 Jan 2007 20:49:45 +0000 Subject: Remove double free action --- sdpd/servicedb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sdpd') diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 8f5ff810..edf255ac 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -244,10 +244,8 @@ int sdp_record_remove(uint32_t handle) } r = (sdp_record_t *) p->data; - if (r) { + if (r) service_db = sdp_list_remove(service_db, r); - sdp_record_free(r); - } p = access_locate(handle); if (p) { -- cgit From f64b45ffc0f9b1a0c202946c15ab35c681a7a3a2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 20 Jan 2007 21:04:59 +0000 Subject: Don't forget to free the record when session terminates --- sdpd/servicedb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sdpd') diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index edf255ac..0eeb4060 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -113,6 +113,7 @@ void sdp_svcdb_collect_all(int sock) if (item->sock == sock) { sdp_list_t *next = p->next; sdp_record_remove(item->record->handle); + sdp_record_free(item->record); free(item); if (q) q->next = next; -- cgit From 5d3f7702c50861f7f7f5ebeb160ef0073a5470f5 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 20 Jan 2007 21:09:28 +0000 Subject: Fix GIOChannel refcounting for io_session_event --- sdpd/server.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index 4316746b..eeda8a86 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -149,10 +149,8 @@ static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer d uint8_t *buf; int sk, len, size; - if (cond & (G_IO_HUP | G_IO_ERR)) { - g_io_channel_unref(chan); + if (cond & (G_IO_HUP | G_IO_ERR)) return FALSE; - } sk = g_io_channel_unix_get_fd(chan); -- cgit From 84dc067ee69533534a9e79359f17ab337f2a37e1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Jan 2007 18:52:46 +0000 Subject: Only create watch if Unix socket can be created --- sdpd/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index eeda8a86..6e632237 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -232,7 +232,7 @@ int start_sdp_server(uint16_t mtu, uint32_t flags) g_io_add_watch(l2cap_io, G_IO_IN, io_accept_event, &l2cap_sock); - if (compat) { + if (compat && unix_sock > fileno(stderr)) { unix_io = g_io_channel_unix_new(unix_sock); g_io_channel_set_close_on_unref(unix_io, TRUE); -- cgit From f274c01bde0e88ee7aa86f0197ad59b125930ad4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Jan 2007 18:57:15 +0000 Subject: Fix cleanup in case the SDP server startup fails --- sdpd/server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index 6e632237..3f29bbef 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -47,7 +47,7 @@ #include "logging.h" #include "sdpd.h" -static GIOChannel *l2cap_io, *unix_io; +static GIOChannel *l2cap_io = NULL, *unix_io = NULL; static int l2cap_sock, unix_sock; @@ -237,8 +237,7 @@ int start_sdp_server(uint16_t mtu, uint32_t flags) g_io_channel_set_close_on_unref(unix_io, TRUE); g_io_add_watch(unix_io, G_IO_IN, io_accept_event, &unix_sock); - } else - unix_io = NULL; + } return 0; } @@ -252,5 +251,6 @@ void stop_sdp_server(void) if (unix_io) g_io_channel_unref(unix_io); - g_io_channel_unref(l2cap_io); + if (l2cap_io) + g_io_channel_unref(l2cap_io); } -- cgit From 2c9cbad68a808567201f01d3f29f49611d59b690 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 23 Jan 2007 09:50:22 +0000 Subject: Allow removal of previously-set attributes --- sdpd/service.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index 83844d68..69c5242b 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -289,6 +289,9 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h rec->handle = handleExpected; sdp_record_add(device, rec); } + } else { + sdp_list_free(rec->attrlist, (sdp_free_func_t) sdp_data_free); + rec->attrlist = NULL; } while (localExtractedLength < seqlen) { -- cgit From cb50607d568c96fb15dd435249868818d923c847 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 24 Jan 2007 06:11:43 +0000 Subject: Update option references --- sdpd/main.c | 2 +- sdpd/sdpd.8 | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index d29c8c16..4027ae96 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -61,7 +61,7 @@ static void usage(void) { printf("sdpd - SDP daemon ver %s\n", VERSION); printf("Usage: \n"); - printf("\tsdpd [-n]\n"); + printf("\tsdpd [-n] [-d] [-m mtu] [-p]\n"); } static struct option main_options[] = { diff --git a/sdpd/sdpd.8 b/sdpd/sdpd.8 index c2e90837..3b69430d 100644 --- a/sdpd/sdpd.8 +++ b/sdpd/sdpd.8 @@ -66,6 +66,12 @@ available. .SH "OPTIONS" .IP "\fB-n\fP" 10 Don't detach from the controlling terminal. +.IP "\fB-d\fP" 10 +Enable debugging output. +.IP "\fB-m \fP" 10 +Set maximum MTU to use on the L2CAP channel. +.IP "\fB-p\fP" 10 +Register server record in public browse group. .SH "BUGS" .PP -- cgit From 559a9a2ef363a2d9e81581f5846c59b0209c3575 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 16 Feb 2007 20:18:37 +0000 Subject: Add missing flags to g_io_add_watch calls --- sdpd/server.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index 3f29bbef..8f13a051 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -207,7 +207,8 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da io = g_io_channel_unix_new(nsk); g_io_channel_set_close_on_unref(io, TRUE); - g_io_add_watch(io, G_IO_IN, io_session_event, data); + g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP, io_session_event, + data); g_io_channel_unref(io); @@ -230,13 +231,15 @@ int start_sdp_server(uint16_t mtu, uint32_t flags) l2cap_io = g_io_channel_unix_new(l2cap_sock); g_io_channel_set_close_on_unref(l2cap_io, TRUE); - g_io_add_watch(l2cap_io, G_IO_IN, io_accept_event, &l2cap_sock); + g_io_add_watch(l2cap_io, G_IO_IN | G_IO_ERR | G_IO_HUP, + io_accept_event, &l2cap_sock); if (compat && unix_sock > fileno(stderr)) { unix_io = g_io_channel_unix_new(unix_sock); g_io_channel_set_close_on_unref(unix_io, TRUE); - g_io_add_watch(unix_io, G_IO_IN, io_accept_event, &unix_sock); + g_io_add_watch(unix_io, G_IO_IN | G_IO_ERR | G_IO_HUP, + io_accept_event, &unix_sock); } return 0; -- cgit From 652fc04d9039e9e6805f9bc08126416bbf0b3559 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Mar 2007 09:26:15 +0000 Subject: Don't install manual pages if daemon has been disabled --- sdpd/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 12740584..46989209 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -17,8 +17,10 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @GLIB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common +if SDPD man_MANS = sdpd.8 +endif -EXTRA_DIST = $(man_MANS) +EXTRA_DIST = sdpd.8 MAINTAINERCLEANFILES = Makefile.in -- cgit From a36be2a103e95b04d5b348c83b41dc8c06439990 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 4 Apr 2007 07:30:14 +0000 Subject: Fix missing G_IO_NVAL handling --- sdpd/server.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index 8f13a051..2abcc6bc 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -149,7 +149,7 @@ static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer d uint8_t *buf; int sk, len, size; - if (cond & (G_IO_HUP | G_IO_ERR)) + if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) return FALSE; sk = g_io_channel_unix_get_fd(chan); @@ -181,7 +181,7 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da GIOChannel *io; int nsk; - if (cond & (G_IO_HUP | G_IO_ERR)) { + if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { g_io_channel_unref(chan); return FALSE; } @@ -207,8 +207,8 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da io = g_io_channel_unix_new(nsk); g_io_channel_set_close_on_unref(io, TRUE); - g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP, io_session_event, - data); + g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + io_session_event, data); g_io_channel_unref(io); @@ -231,15 +231,15 @@ int start_sdp_server(uint16_t mtu, uint32_t flags) l2cap_io = g_io_channel_unix_new(l2cap_sock); g_io_channel_set_close_on_unref(l2cap_io, TRUE); - g_io_add_watch(l2cap_io, G_IO_IN | G_IO_ERR | G_IO_HUP, - io_accept_event, &l2cap_sock); + g_io_add_watch(l2cap_io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + io_accept_event, &l2cap_sock); if (compat && unix_sock > fileno(stderr)) { unix_io = g_io_channel_unix_new(unix_sock); g_io_channel_set_close_on_unref(unix_io, TRUE); - g_io_add_watch(unix_io, G_IO_IN | G_IO_ERR | G_IO_HUP, - io_accept_event, &unix_sock); + g_io_add_watch(unix_io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + io_accept_event, &unix_sock); } return 0; -- cgit From eefb64d927b48d2de2e100b1f7ee715bf86bbb57 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 25 Apr 2007 18:59:55 +0000 Subject: Add device ID support --- sdpd/main.c | 2 +- sdpd/sdpd.h | 4 +++- sdpd/server.c | 18 ++++++++++++++++- sdpd/service.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 82 insertions(+), 5 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 4027ae96..856c6cb3 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -139,7 +139,7 @@ int main(int argc, char *argv[]) event_loop = g_main_loop_new(NULL, FALSE); - if (start_sdp_server(mtu, flags) < 0) { + if (start_sdp_server(mtu, NULL, flags) < 0) { g_main_loop_unref(event_loop); exit(1); } diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 8ec47b1a..13aa2c74 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -46,6 +46,8 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp); void register_public_browse_group(int public); void register_server_service(int public); +void register_device_id(const uint16_t vendor, const uint16_t product, + const uint16_t version); typedef struct { uint32_t timestamp; @@ -80,7 +82,7 @@ uint32_t sdp_get_time(); #define SDP_SERVER_MASTER (1 << 1) #define SDP_SERVER_PUBLIC (1 << 2) -int start_sdp_server(uint16_t mtu, uint32_t flags); +int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags); void stop_sdp_server(void); int add_record_to_server(sdp_record_t *rec); diff --git a/sdpd/server.c b/sdpd/server.c index 2abcc6bc..fab17f00 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -215,7 +216,7 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da return TRUE; } -int start_sdp_server(uint16_t mtu, uint32_t flags) +int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags) { int compat = flags & SDP_SERVER_COMPAT; int master = flags & SDP_SERVER_MASTER; @@ -228,6 +229,21 @@ int start_sdp_server(uint16_t mtu, uint32_t flags) return -1; } + if (did && strlen(did) > 0) { + const char *ptr = did; + uint16_t vid = 0x0000, pid = 0x0000, ver = 0x0000; + + vid = (uint16_t) strtol(ptr, NULL, 16); + ptr = strchr(ptr, ':'); + if (ptr) { + pid = (uint16_t) strtol(ptr + 1, NULL, 16); + ptr = strchr(ptr + 1, ':'); + if (ptr) + ver = (uint16_t) strtol(ptr + 1, NULL, 16); + register_device_id(vid, pid, ver); + } + } + l2cap_io = g_io_channel_unix_new(l2cap_sock); g_io_channel_set_close_on_unref(l2cap_io, TRUE); diff --git a/sdpd/service.c b/sdpd/service.c index 69c5242b..8c8c3a73 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -102,7 +102,8 @@ void register_public_browse_group(int public) sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); add_lang_attr(browse); - sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", "Root of public browse hierarchy"); + sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", + "Root of public browse hierarchy"); sdp_uuid16_create(&bgscid, BROWSE_GRP_DESC_SVCLASS_ID); browselist = sdp_list_append(0, &bgscid); @@ -140,7 +141,8 @@ void register_server_service(int public) server->handle = SDP_SERVER_RECORD_HANDLE; sdp_record_add(BDADDR_ANY, server); - sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); + sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, + sdp_data_alloc(SDP_UINT32, &server->handle)); /* * Add all attributes to service record. (No need to commit since we @@ -207,6 +209,63 @@ void register_server_service(int public) update_db_timestamp(); } +void register_device_id(const uint16_t vendor, const uint16_t product, + const uint16_t version) +{ + const uint16_t spec = 0x0102, source = 0x0002; + const uint8_t primary = 1; + sdp_list_t *class_list, *group_list, *profile_list; + uuid_t class_uuid, group_uuid; + sdp_data_t *sdp_data, *primary_data, *source_data; + sdp_data_t *spec_data, *vendor_data, *product_data, *version_data; + sdp_profile_desc_t profile; + sdp_record_t *record = sdp_record_alloc(); + + info("Adding device id record for %04x:%04x", vendor, product); + + record->handle = sdp_next_handle(); + + sdp_record_add(BDADDR_ANY, record); + sdp_data = sdp_data_alloc(SDP_UINT32, &record->handle); + sdp_attr_add(record, SDP_ATTR_RECORD_HANDLE, sdp_data); + + sdp_uuid16_create(&class_uuid, PNP_INFO_SVCLASS_ID); + class_list = sdp_list_append(0, &class_uuid); + sdp_set_service_classes(record, class_list); + sdp_list_free(class_list, NULL); + + sdp_uuid16_create(&group_uuid, PUBLIC_BROWSE_GROUP); + group_list = sdp_list_append(NULL, &group_uuid); + sdp_set_browse_groups(record, group_list); + sdp_list_free(group_list, NULL); + + sdp_uuid16_create(&profile.uuid, PNP_INFO_PROFILE_ID); + profile.version = spec; + profile_list = sdp_list_append(NULL, &profile); + sdp_set_profile_descs(record, profile_list); + sdp_list_free(profile_list, NULL); + + spec_data = sdp_data_alloc(SDP_UINT16, &spec); + sdp_attr_add(record, 0x0200, spec_data); + + vendor_data = sdp_data_alloc(SDP_UINT16, &vendor); + sdp_attr_add(record, 0x0201, vendor_data); + + product_data = sdp_data_alloc(SDP_UINT16, &product); + sdp_attr_add(record, 0x0202, product_data); + + version_data = sdp_data_alloc(SDP_UINT16, &version); + sdp_attr_add(record, 0x0203, version_data); + + primary_data = sdp_data_alloc(SDP_BOOL, &primary); + sdp_attr_add(record, 0x0204, primary_data); + + source_data = sdp_data_alloc(SDP_UINT16, &source); + sdp_attr_add(record, 0x0205, source_data); + + update_db_timestamp(); +} + int add_record_to_server(sdp_record_t *rec) { sdp_data_t *data; -- cgit From 44847d5dfc0eebba1cebad1fbc89895901bfe09b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 25 Apr 2007 22:14:22 +0000 Subject: Added UpdateServiceRecord --- sdpd/sdpd.h | 2 +- sdpd/service.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'sdpd') diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 13aa2c74..31f3b645 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -86,4 +86,4 @@ int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags); void stop_sdp_server(void); int add_record_to_server(sdp_record_t *rec); -void remove_record_from_server(uint32_t handle); +int remove_record_from_server(uint32_t handle); diff --git a/sdpd/service.c b/sdpd/service.c index 8c8c3a73..e469d841 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -297,19 +297,22 @@ int add_record_to_server(sdp_record_t *rec) return 0; } -void remove_record_from_server(uint32_t handle) +int remove_record_from_server(uint32_t handle) { sdp_record_t *rec; debug("Removing record with handle 0x%05x", handle); rec = sdp_record_find(handle); - if (rec) { - if (sdp_record_remove(handle) == 0) - update_db_timestamp(); + if (!rec) + return -ENOENT; - sdp_record_free(rec); - } + if (sdp_record_remove(handle) == 0) + update_db_timestamp(); + + sdp_record_free(rec); + + return 0; } // FIXME: refactor for server-side -- cgit From 68dc1b1a461792897e7be1cafb97b1f80e6aa304 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 May 2007 10:47:49 +0000 Subject: Make it possible to disable installation of manual pages --- sdpd/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 46989209..a7efa56f 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -18,8 +18,10 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @GLIB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common if SDPD +if MANPAGES man_MANS = sdpd.8 endif +endif EXTRA_DIST = sdpd.8 -- cgit From dd438cd1ffaeeba1840a8badcd03bd0313cbbee0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 May 2007 09:56:09 +0000 Subject: Use server root if browse group is not public --- sdpd/service.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index e469d841..8af2933f 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -110,10 +110,12 @@ void register_public_browse_group(int public) sdp_set_service_classes(browse, browselist); sdp_list_free(browselist, 0); - if (public) { + if (public) sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); - sdp_set_group_id(browse, pbgid); - } + else + sdp_uuid16_create(&pbgid, SDP_SERVER_SVCLASS_ID); + + sdp_set_group_id(browse, pbgid); } /* -- cgit From 646f2140653faca517ecd55863e15e4d9dffc4af Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 May 2007 10:32:21 +0000 Subject: Use browse group descriptor list --- sdpd/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index 8af2933f..50df26e8 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -113,7 +113,7 @@ void register_public_browse_group(int public) if (public) sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); else - sdp_uuid16_create(&pbgid, SDP_SERVER_SVCLASS_ID); + sdp_uuid16_create(&pbgid, BROWSE_GRP_DESC_SVCLASS_ID); sdp_set_group_id(browse, pbgid); } -- cgit From 09e129d5ef90ad61775517e752b8b9918f1a7c3e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 May 2007 11:43:30 +0000 Subject: Minimize SDP root records and browse groups --- sdpd/main.c | 7 +---- sdpd/sdpd.8 | 2 -- sdpd/sdpd.h | 5 ++-- sdpd/server.c | 9 +++---- sdpd/service.c | 83 +++++++--------------------------------------------------- 5 files changed, 17 insertions(+), 89 deletions(-) (limited to 'sdpd') diff --git a/sdpd/main.c b/sdpd/main.c index 856c6cb3..0abc8088 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -68,7 +68,6 @@ static struct option main_options[] = { { "help", 0, 0, 'h' }, { "nodaemon", 0, 0, 'n' }, { "mtu", 1, 0, 'm' }, - { "public", 0, 0, 'p' }, { "master", 0, 0, 'M' }, { 0, 0, 0, 0} }; @@ -80,7 +79,7 @@ int main(int argc, char *argv[]) uint32_t flags = SDP_SERVER_COMPAT; int opt, daemonize = 1, debug = 0; - while ((opt = getopt_long(argc, argv, "ndm:pM", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "ndm:M", main_options, NULL)) != -1) { switch (opt) { case 'n': daemonize = 0; @@ -94,10 +93,6 @@ int main(int argc, char *argv[]) mtu = atoi(optarg); break; - case 'p': - flags |= SDP_SERVER_PUBLIC; - break; - case 'M': flags |= SDP_SERVER_MASTER; break; diff --git a/sdpd/sdpd.8 b/sdpd/sdpd.8 index 3b69430d..e23c6ffc 100644 --- a/sdpd/sdpd.8 +++ b/sdpd/sdpd.8 @@ -70,8 +70,6 @@ Don't detach from the controlling terminal. Enable debugging output. .IP "\fB-m \fP" 10 Set maximum MTU to use on the L2CAP channel. -.IP "\fB-p\fP" 10 -Register server record in public browse group. .SH "BUGS" .PP diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 31f3b645..d3d45b85 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -44,8 +44,8 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp); int service_update_req(sdp_req_t *req, sdp_buf_t *rsp); int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp); -void register_public_browse_group(int public); -void register_server_service(int public); +void register_public_browse_group(void); +void register_server_service(void); void register_device_id(const uint16_t vendor, const uint16_t product, const uint16_t version); @@ -80,7 +80,6 @@ uint32_t sdp_get_time(); #define SDP_SERVER_COMPAT (1 << 0) #define SDP_SERVER_MASTER (1 << 1) -#define SDP_SERVER_PUBLIC (1 << 2) int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags); void stop_sdp_server(void); diff --git a/sdpd/server.c b/sdpd/server.c index fab17f00..2750dec2 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -57,7 +57,7 @@ static int l2cap_sock, unix_sock; * l2cap and unix sockets over which discovery and registration clients * access us respectively */ -static int init_server(uint16_t mtu, int master, int public, int compat) +static int init_server(uint16_t mtu, int master, int compat) { struct l2cap_options opts; struct sockaddr_l2 l2addr; @@ -65,10 +65,10 @@ static int init_server(uint16_t mtu, int master, int public, int compat) socklen_t optlen; /* Register the public browse group root */ - register_public_browse_group(public); + register_public_browse_group(); /* Register the SDP server's service record */ - register_server_service(public); + register_server_service(); /* Create L2CAP socket */ l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); @@ -220,11 +220,10 @@ int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags) { int compat = flags & SDP_SERVER_COMPAT; int master = flags & SDP_SERVER_MASTER; - int public = flags & SDP_SERVER_PUBLIC; info("Starting SDP server"); - if (init_server(mtu, master, public, compat) < 0) { + if (init_server(mtu, master, compat) < 0) { error("Server initialization failed"); return -1; } diff --git a/sdpd/service.c b/sdpd/service.c index 50df26e8..8c48555b 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -69,53 +69,27 @@ static void update_db_timestamp(void) sdp_attr_replace(server, SDP_ATTR_SVCDB_STATE, d); } -static void add_lang_attr(sdp_record_t *r) -{ - sdp_lang_attr_t base_lang; - sdp_list_t *langs = 0; - - base_lang.code_ISO639 = (0x65 << 8) | 0x6e; - // UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) - base_lang.encoding = 106; - base_lang.base_offset = SDP_PRIMARY_LANG_BASE; - langs = sdp_list_append(0, &base_lang); - sdp_set_lang_attr(r, langs); - sdp_list_free(langs, 0); -} - -void register_public_browse_group(int public) +void register_public_browse_group(void) { sdp_list_t *browselist; uuid_t bgscid, pbgid; sdp_data_t *sdpdata; sdp_record_t *browse = sdp_record_alloc(); - if (public) { - browse->handle = sdp_next_handle(); - if (browse->handle < 0x10000) - return; - } else - browse->handle = SDP_SERVER_RECORD_HANDLE + 1; + browse->handle = SDP_SERVER_RECORD_HANDLE + 1; sdp_record_add(BDADDR_ANY, browse); sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); - add_lang_attr(browse); - sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", - "Root of public browse hierarchy"); - sdp_uuid16_create(&bgscid, BROWSE_GRP_DESC_SVCLASS_ID); browselist = sdp_list_append(0, &bgscid); sdp_set_service_classes(browse, browselist); sdp_list_free(browselist, 0); - if (public) - sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); - else - sdp_uuid16_create(&pbgid, BROWSE_GRP_DESC_SVCLASS_ID); - - sdp_set_group_id(browse, pbgid); + sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); + sdp_attr_add_new(browse, SDP_ATTR_GROUP_ID, + SDP_UUID16, &pbgid.value.uuid16); } /* @@ -124,17 +98,14 @@ void register_public_browse_group(int public) * discovery clients. This method constructs a service record * and stores it in the repository */ -void register_server_service(int public) +void register_server_service(void) { - int i; - sdp_list_t *classIDList, *browseList; - sdp_list_t *access_proto = 0; - uuid_t l2cap, classID, browseGroupId, sdpSrvUUID; + sdp_list_t *classIDList; + uuid_t classID; void **versions, **versionDTDs; uint8_t dtd; - uint16_t version, port; - sdp_data_t *pData, *port_data, *version_data; - sdp_list_t *pd, *seq; + sdp_data_t *pData; + int i; server = sdp_record_alloc(); server->pattern = NULL; @@ -146,13 +117,6 @@ void register_server_service(int public) sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); - /* - * Add all attributes to service record. (No need to commit since we - * are the server and this record is already in the database.) - */ - add_lang_attr(server); - sdp_set_info_attr(server, "SDP Server", "BlueZ", "Bluetooth service discovery server"); - sdp_uuid16_create(&classID, SDP_SERVER_SVCLASS_ID); classIDList = sdp_list_append(0, &classID); sdp_set_service_classes(server, classIDList); @@ -181,33 +145,6 @@ void register_server_service(int public) free(versionDTDs); sdp_attr_add(server, SDP_ATTR_VERSION_NUM_LIST, pData); - sdp_uuid16_create(&sdpSrvUUID, SDP_UUID); - sdp_set_service_id(server, sdpSrvUUID); - - sdp_uuid16_create(&l2cap, L2CAP_UUID); - pd = sdp_list_append(0, &l2cap); - port = SDP_PSM; - port_data = sdp_data_alloc(SDP_UINT16, &port); - pd = sdp_list_append(pd, port_data); - version = 1; - version_data = sdp_data_alloc(SDP_UINT16, &version); - pd = sdp_list_append(pd, version_data); - seq = sdp_list_append(0, pd); - - access_proto = sdp_list_append(0, seq); - sdp_set_access_protos(server, access_proto); - sdp_list_free(access_proto, free); - sdp_data_free(port_data); - sdp_data_free(version_data); - sdp_list_free(pd, 0); - - if (public) { - sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); - browseList = sdp_list_append(0, &browseGroupId); - sdp_set_browse_groups(server, browseList); - sdp_list_free(browseList, 0); - } - update_db_timestamp(); } -- cgit From 7cc971c79cd88798c5c40f9cdf85532a7aeab8a9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 May 2007 14:31:02 +0000 Subject: Set input and output MTU when requested --- sdpd/server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index 2750dec2..baac03d0 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -104,6 +104,7 @@ static int init_server(uint16_t mtu, int master, int compat) return -1; } + opts.omtu = mtu; opts.imtu = mtu; if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { -- cgit From 145dfdd4b2e09f6b5b9e0be03d134c0242261b81 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Aug 2007 01:06:26 +0000 Subject: Calculate service classes value for class of device --- sdpd/service.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 4 deletions(-) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index 8c48555b..e37a0c38 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -69,6 +69,56 @@ static void update_db_timestamp(void) sdp_attr_replace(server, SDP_ATTR_SVCDB_STATE, d); } +static void update_svclass_list(void) +{ + sdp_list_t *list = sdp_get_record_list(); + uint8_t val = 0; + + for (; list; list = list->next) { + sdp_record_t *rec = (sdp_record_t *) list->data; + + if (rec->svclass.type != SDP_UUID16) + continue; + + switch (rec->svclass.value.uuid16) { + case DIALUP_NET_SVCLASS_ID: + val |= 0x42; /* Telephony & Networking */ + break; + case IRMC_SYNC_SVCLASS_ID: + case OBEX_OBJPUSH_SVCLASS_ID: + case OBEX_FILETRANS_SVCLASS_ID: + case IRMC_SYNC_CMD_SVCLASS_ID: + val |= 0x10; /* Object Transfer */ + break; + case HEADSET_SVCLASS_ID: + case HANDSFREE_SVCLASS_ID: + val |= 0x20; /* Audio */ + break; + case CORDLESS_TELEPHONY_SVCLASS_ID: + case INTERCOM_SVCLASS_ID: + case FAX_SVCLASS_ID: + case SAP_SVCLASS_ID: + val |= 0x40; /* Telephony */ + break; + case AUDIO_SOURCE_SVCLASS_ID: + case VIDEO_SOURCE_SVCLASS_ID: + val |= 0x08; /* Capturing */ + break; + case AUDIO_SINK_SVCLASS_ID: + case VIDEO_SINK_SVCLASS_ID: + val |= 0x04; /* Rendering */ + break; + case PANU_SVCLASS_ID: + case NAP_SVCLASS_ID: + case GN_SVCLASS_ID: + val |= 0x02; /* Networking */ + break; + } + } + + debug("Service classes 0x%02x", val); +} + void register_public_browse_group(void) { sdp_list_t *browselist; @@ -146,6 +196,7 @@ void register_server_service(void) sdp_attr_add(server, SDP_ATTR_VERSION_NUM_LIST, pData); update_db_timestamp(); + update_svclass_list(); } void register_device_id(const uint16_t vendor, const uint16_t product, @@ -203,6 +254,7 @@ void register_device_id(const uint16_t vendor, const uint16_t product, sdp_attr_add(record, 0x0205, source_data); update_db_timestamp(); + update_svclass_list(); } int add_record_to_server(sdp_record_t *rec) @@ -232,6 +284,7 @@ int add_record_to_server(sdp_record_t *rec) } update_db_timestamp(); + update_svclass_list(); return 0; } @@ -246,8 +299,10 @@ int remove_record_from_server(uint32_t handle) if (!rec) return -ENOENT; - if (sdp_record_remove(handle) == 0) + if (sdp_record_remove(handle) == 0) { update_db_timestamp(); + update_svclass_list(); + } sdp_record_free(rec); @@ -386,6 +441,7 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) } update_db_timestamp(); + update_svclass_list(); /* Build a rsp buffer */ bt_put_unaligned(htonl(rec->handle), (uint32_t *) rsp->data); @@ -420,9 +476,10 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) if (orec) { sdp_record_t *nrec = extract_pdu_server(BDADDR_ANY, p, handle, &scanned); - if (nrec && handle == nrec->handle) + if (nrec && handle == nrec->handle) { update_db_timestamp(); - else { + update_svclass_list(); + } else { debug("SvcRecHandle : 0x%x", handle); debug("SvcRecHandleNew : 0x%x", nrec->handle); debug("SvcRecNew : %p", nrec); @@ -460,8 +517,10 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_svcdb_collect(rec); status = sdp_record_remove(handle); sdp_record_free(rec); - if (status == 0) + if (status == 0) { update_db_timestamp(); + update_svclass_list(); + } } else { status = SDP_INVALID_RECORD_HANDLE; debug("Could not find record : 0x%x", handle); -- cgit From b22d297c0c679b400d7825367e31fed46c552a49 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Aug 2007 01:50:41 +0000 Subject: First attempt for automatic setting of service classes value --- sdpd/sdpd.h | 2 ++ sdpd/service.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index d3d45b85..dbb1ee09 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -86,3 +86,5 @@ void stop_sdp_server(void); int add_record_to_server(sdp_record_t *rec); int remove_record_from_server(uint32_t handle); + +uint8_t get_service_classes(void); diff --git a/sdpd/service.c b/sdpd/service.c index e37a0c38..f84ddc9a 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -42,7 +42,9 @@ #include "sdpd.h" #include "logging.h" -static sdp_record_t *server; +static sdp_record_t *server = NULL; + +static uint8_t service_classes = 0x00; /* * List of version numbers supported by the SDP server. @@ -117,6 +119,13 @@ static void update_svclass_list(void) } debug("Service classes 0x%02x", val); + + service_classes = val; +} + +uint8_t get_service_classes(void) +{ + return service_classes; } void register_public_browse_group(void) -- cgit From 81960de41b9c34897769fb7eb404bdcad9afd4ae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Aug 2007 11:32:02 +0000 Subject: Handle Common ISDN Access profile --- sdpd/service.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index f84ddc9a..29170941 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -84,6 +84,7 @@ static void update_svclass_list(void) switch (rec->svclass.value.uuid16) { case DIALUP_NET_SVCLASS_ID: + case CIP_SVCLASS_ID: val |= 0x42; /* Telephony & Networking */ break; case IRMC_SYNC_SVCLASS_ID: -- cgit From c2cd5eed70f1108529432fb8e0b868c1d5ea6922 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Aug 2007 11:42:38 +0000 Subject: Handle phonebook access server --- sdpd/service.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index 29170941..a75c0ed7 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -91,6 +91,7 @@ static void update_svclass_list(void) case OBEX_OBJPUSH_SVCLASS_ID: case OBEX_FILETRANS_SVCLASS_ID: case IRMC_SYNC_CMD_SVCLASS_ID: + case PBAP_PSE_SVCLASS_ID: val |= 0x10; /* Object Transfer */ break; case HEADSET_SVCLASS_ID: -- cgit From f205cd06dc4e9da2c1d5109e570008d7d80b8380 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Aug 2007 09:48:14 +0000 Subject: Update service classes on all adapters --- sdpd/sdpd.h | 2 +- sdpd/service.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index dbb1ee09..6fc60e85 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -87,4 +87,4 @@ void stop_sdp_server(void); int add_record_to_server(sdp_record_t *rec); int remove_record_from_server(uint32_t handle); -uint8_t get_service_classes(void); +uint8_t get_service_classes(const bdaddr_t *bdaddr); diff --git a/sdpd/service.c b/sdpd/service.c index a75c0ed7..851c1459 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -125,7 +125,7 @@ static void update_svclass_list(void) service_classes = val; } -uint8_t get_service_classes(void) +uint8_t get_service_classes(const bdaddr_t *bdaddr) { return service_classes; } -- cgit From 8af5664021b471e769b93a345f451f9a20b08ca8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Aug 2007 10:12:37 +0000 Subject: Trigger the service classes update through a callback --- sdpd/sdpd.h | 3 +++ sdpd/service.c | 9 +++++++++ 2 files changed, 12 insertions(+) (limited to 'sdpd') diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 6fc60e85..ad7a2d4f 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -87,4 +87,7 @@ void stop_sdp_server(void); int add_record_to_server(sdp_record_t *rec); int remove_record_from_server(uint32_t handle); +typedef void (*service_classes_callback_t) (const bdaddr_t *bdaddr, uint8_t value); + uint8_t get_service_classes(const bdaddr_t *bdaddr); +void set_service_classes_callback(service_classes_callback_t callback); diff --git a/sdpd/service.c b/sdpd/service.c index 851c1459..7f8296f4 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -45,6 +45,7 @@ static sdp_record_t *server = NULL; static uint8_t service_classes = 0x00; +static service_classes_callback_t service_classes_callback = NULL; /* * List of version numbers supported by the SDP server. @@ -123,6 +124,9 @@ static void update_svclass_list(void) debug("Service classes 0x%02x", val); service_classes = val; + + if (service_classes_callback) + service_classes_callback(BDADDR_ANY, val); } uint8_t get_service_classes(const bdaddr_t *bdaddr) @@ -130,6 +134,11 @@ uint8_t get_service_classes(const bdaddr_t *bdaddr) return service_classes; } +void set_service_classes_callback(service_classes_callback_t callback) +{ + service_classes_callback = callback; +} + void register_public_browse_group(void) { sdp_list_t *browselist; -- cgit From eb4d49890ca8a4d8f567e81fdf82b6903d30f326 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Aug 2007 01:21:33 +0000 Subject: Move the extended inquiry response creation into the SDP code --- sdpd/sdpd.h | 1 + sdpd/service.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'sdpd') diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index ad7a2d4f..0a2bccf4 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -91,3 +91,4 @@ typedef void (*service_classes_callback_t) (const bdaddr_t *bdaddr, uint8_t valu uint8_t get_service_classes(const bdaddr_t *bdaddr); void set_service_classes_callback(service_classes_callback_t callback); +void create_ext_inquiry_response(const char *name, uint8_t *data); diff --git a/sdpd/service.c b/sdpd/service.c index 7f8296f4..bbc7fcc8 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -139,6 +139,23 @@ void set_service_classes_callback(service_classes_callback_t callback) service_classes_callback = callback; } +void create_ext_inquiry_response(const char *name, uint8_t *data) +{ + if (name) { + int len = strlen(name); + + if (len > 48) { + len = 48; + data[1] = 0x08; + } else + data[1] = 0x09; + + data[0] = len + 1; + + memcpy(data + 2, name, len); + } +} + void register_public_browse_group(void) { sdp_list_t *browselist; -- cgit From 466452630ca4b126bdd54e46b1da28604d0968f2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Aug 2007 01:58:19 +0000 Subject: Include all UUID-16 values in the extended inquiry response --- sdpd/service.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index bbc7fcc8..e51f4aed 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -141,18 +141,61 @@ void set_service_classes_callback(service_classes_callback_t callback) void create_ext_inquiry_response(const char *name, uint8_t *data) { + sdp_list_t *list = sdp_get_record_list(); + uint8_t *ptr = data; + uint16_t uuid[24]; + int i, index = 0; + if (name) { int len = strlen(name); if (len > 48) { len = 48; - data[1] = 0x08; + ptr[1] = 0x08; } else - data[1] = 0x09; + ptr[1] = 0x09; + + ptr[0] = len + 1; + + memcpy(ptr + 2, name, len); + + ptr += len + 2; + } + + ptr[1] = 0x03; + + for (; list; list = list->next) { + sdp_record_t *rec = (sdp_record_t *) list->data; + + if (rec->svclass.type != SDP_UUID16) + continue; + + if (rec->svclass.value.uuid16 < 0x1100) + continue; + + if (index > 23) { + ptr[1] = 0x02; + break; + } - data[0] = len + 1; + for (i = 0; i < index; i++) + if (uuid[i] == rec->svclass.value.uuid16) + break; - memcpy(data + 2, name, len); + if (i == index - 1) + continue; + + uuid[index++] = rec->svclass.value.uuid16; + } + + if (index > 0) { + ptr[0] = (index * 2) + 1; + ptr += 2; + + for (i = 0; i < index; i++) { + *ptr++ = (uuid[i] & 0x00ff); + *ptr++ = (uuid[i] & 0xff00) >> 8; + } } } -- cgit From 997f32ca18683a57c1e0ca83cf17214335b5f4c3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 10 Oct 2007 16:37:19 +0000 Subject: Publish device id information through EIR --- sdpd/service.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index e51f4aed..eb8d304f 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -47,6 +47,10 @@ static sdp_record_t *server = NULL; static uint8_t service_classes = 0x00; static service_classes_callback_t service_classes_callback = NULL; +static uint16_t did_vendor = 0x0000; +static uint16_t did_product = 0x0000; +static uint16_t did_version = 0x0000; + /* * List of version numbers supported by the SDP server. * Add to this list when newer versions are supported. @@ -162,6 +166,20 @@ void create_ext_inquiry_response(const char *name, uint8_t *data) ptr += len + 2; } + if (did_vendor != 0x0000) { + uint16_t source = 0x0002; + *ptr++ = 9; + *ptr++ = 0x10; + *ptr++ = (source & 0x00ff); + *ptr++ = (source & 0xff00) >> 8; + *ptr++ = (did_vendor & 0x00ff); + *ptr++ = (did_vendor & 0xff00) >> 8; + *ptr++ = (did_product & 0x00ff); + *ptr++ = (did_product & 0xff00) >> 8; + *ptr++ = (did_version & 0x00ff); + *ptr++ = (did_version & 0xff00) >> 8; + } + ptr[1] = 0x03; for (; list; list = list->next) { @@ -293,6 +311,10 @@ void register_device_id(const uint16_t vendor, const uint16_t product, info("Adding device id record for %04x:%04x", vendor, product); + did_vendor = vendor; + did_product = product; + did_version = version; + record->handle = sdp_next_handle(); sdp_record_add(BDADDR_ANY, record); -- cgit From e7613df411ab21a28af57347f37cc3c0283bb10e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 17 Oct 2007 12:59:39 +0000 Subject: Fix EIR tag number for device id record --- sdpd/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index eb8d304f..2ad701f8 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -169,7 +169,7 @@ void create_ext_inquiry_response(const char *name, uint8_t *data) if (did_vendor != 0x0000) { uint16_t source = 0x0002; *ptr++ = 9; - *ptr++ = 0x10; + *ptr++ = 11; *ptr++ = (source & 0x00ff); *ptr++ = (source & 0xff00) >> 8; *ptr++ = (did_vendor & 0x00ff); -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- sdpd/cstate.c | 2 +- sdpd/main.c | 2 +- sdpd/request.c | 2 +- sdpd/sdpd.h | 2 +- sdpd/server.c | 2 +- sdpd/service.c | 2 +- sdpd/servicedb.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index f1d84498..bb422ce4 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/main.c b/sdpd/main.c index 0abc8088..51c66f0f 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/request.c b/sdpd/request.c index 2b052863..c338bd7d 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 0a2bccf4..ae1245d8 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/server.c b/sdpd/server.c index baac03d0..fcdbf49f 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/service.c b/sdpd/service.c index 2ad701f8..e156cdc4 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 0eeb4060..b5ea17ca 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * -- cgit From a1ddddc934657aa734ceb4bf581423647cc68060 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 15:06:45 +0000 Subject: Fix compilation issues with UCHAR_MAX, USHRT_MAX and UINT_MAX --- sdpd/request.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index c338bd7d..20e68b62 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include -- cgit From 51862bbe2eefb797734e495f1d6190dfeb1ef31e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 5 Mar 2008 18:10:39 +0000 Subject: Avoid potential allignment trap --- sdpd/request.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index 20e68b62..5e3c715f 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -179,7 +179,10 @@ static sdp_cont_state_t *sdp_cstate_get(uint8_t *buffer) pdata += sizeof(uint8_t); if (cStateSize != 0) { - sdp_cont_state_t *cstate = (sdp_cont_state_t *)pdata; + sdp_cont_state_t *cstate = malloc(sizeof(sdp_cont_state_t)); + if (!cstate) + return NULL; + memcpy(cstate, (sdp_cont_state_t *)pdata, sizeof(sdp_cont_state_t)); debug("Cstate TS : 0x%lx", cstate->timestamp); debug("Bytes sent : %d", cstate->cStateValue.maxBytesSent); return cstate; @@ -408,6 +411,8 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) } done: + if (cstate) + free(cstate); if (pattern) sdp_list_free(pattern, free); @@ -593,6 +598,8 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) buf->buf_size += sizeof(uint16_t); done: + if (cstate) + free(cstate); if (seq) sdp_list_free(seq, free); if (status) @@ -754,6 +761,8 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) } done: + if (cstate) + free(cstate); if (tmpbuf.data) free(tmpbuf.data); if (pattern) -- cgit From d504a0767e08b04f2af78c10db79d8e35f0c3e92 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 20 Mar 2008 20:10:49 +0000 Subject: Add records based on the adapter address --- sdpd/sdpd.h | 2 +- sdpd/service.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sdpd') diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index ae1245d8..30f05df4 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -84,7 +84,7 @@ uint32_t sdp_get_time(); int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags); void stop_sdp_server(void); -int add_record_to_server(sdp_record_t *rec); +int add_record_to_server(bdaddr_t *src, sdp_record_t *rec); int remove_record_from_server(uint32_t handle); typedef void (*service_classes_callback_t) (const bdaddr_t *bdaddr, uint8_t value); diff --git a/sdpd/service.c b/sdpd/service.c index e156cdc4..57a272db 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -359,7 +359,7 @@ void register_device_id(const uint16_t vendor, const uint16_t product, update_svclass_list(); } -int add_record_to_server(sdp_record_t *rec) +int add_record_to_server(bdaddr_t *src, sdp_record_t *rec) { sdp_data_t *data; @@ -374,7 +374,7 @@ int add_record_to_server(sdp_record_t *rec) debug("Adding record with handle 0x%05x", rec->handle); - sdp_record_add(BDADDR_ANY, rec); + sdp_record_add(src, rec); data = sdp_data_alloc(SDP_UINT32, &rec->handle); sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); -- cgit From 797ca808e5cd54f173754c979bbfd110ea79cd9d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Apr 2008 20:10:39 +0000 Subject: Don't built the standalone SDP server --- sdpd/Makefile.am | 21 +------- sdpd/main.c | 153 ------------------------------------------------------- sdpd/sdpd.8 | 92 --------------------------------- 3 files changed, 2 insertions(+), 264 deletions(-) delete mode 100644 sdpd/main.c delete mode 100644 sdpd/sdpd.8 (limited to 'sdpd') diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index a7efa56f..6ce2f85b 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -1,28 +1,11 @@ noinst_LIBRARIES = libsdpserver.a -libsdpserver_a_SOURCES = sdpd.h server.c cstate.c request.c service.c servicedb.c - -if SDPD -sbin_PROGRAMS = sdpd - -sdpd_SOURCES = main.c - -sdpd_LDADD = libsdpserver.a \ - $(top_builddir)/common/libhelper.a \ - @GLIB_LIBS@ @BLUEZ_LIBS@ -endif +libsdpserver_a_SOURCES = \ + sdpd.h server.c cstate.c request.c service.c servicedb.c AM_CFLAGS = @BLUEZ_CFLAGS@ @GLIB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common -if SDPD -if MANPAGES -man_MANS = sdpd.8 -endif -endif - -EXTRA_DIST = sdpd.8 - MAINTAINERCLEANFILES = Makefile.in diff --git a/sdpd/main.c b/sdpd/main.c deleted file mode 100644 index 51c66f0f..00000000 --- a/sdpd/main.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2001-2002 Nokia Corporation - * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2008 Marcel Holtmann - * Copyright (C) 2002-2003 Stephen Crane - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "logging.h" -#include "sdpd.h" - -static GMainLoop *event_loop; - -static void sig_term(int sig) -{ - g_main_loop_quit(event_loop); -} - -static void sig_hup(int sig) -{ -} - -static void sig_debug(int sig) -{ - toggle_debug(); -} - -static void usage(void) -{ - printf("sdpd - SDP daemon ver %s\n", VERSION); - printf("Usage: \n"); - printf("\tsdpd [-n] [-d] [-m mtu] [-p]\n"); -} - -static struct option main_options[] = { - { "help", 0, 0, 'h' }, - { "nodaemon", 0, 0, 'n' }, - { "mtu", 1, 0, 'm' }, - { "master", 0, 0, 'M' }, - { 0, 0, 0, 0} -}; - -int main(int argc, char *argv[]) -{ - struct sigaction sa; - uint16_t mtu = 0; - uint32_t flags = SDP_SERVER_COMPAT; - int opt, daemonize = 1, debug = 0; - - while ((opt = getopt_long(argc, argv, "ndm:M", main_options, NULL)) != -1) { - switch (opt) { - case 'n': - daemonize = 0; - break; - - case 'd': - debug = 1; - break; - - case 'm': - mtu = atoi(optarg); - break; - - case 'M': - flags |= SDP_SERVER_MASTER; - break; - - default: - usage(); - exit(1); - } - } - - if (daemonize && daemon(0, 0)) { - error("Server startup failed: %s (%d)", strerror(errno), errno); - exit(1); - } - - umask(0077); - - start_logging("sdpd", "Bluetooth SDP daemon"); - - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_NOCLDSTOP; - sa.sa_handler = sig_term; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sa.sa_handler = sig_hup; - sigaction(SIGHUP, &sa, NULL); - - sa.sa_handler = sig_debug; - sigaction(SIGUSR2, &sa, NULL); - - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - - if (debug) { - info("Enabling debug information"); - enable_debug(); - } - - event_loop = g_main_loop_new(NULL, FALSE); - - if (start_sdp_server(mtu, NULL, flags) < 0) { - g_main_loop_unref(event_loop); - exit(1); - } - - g_main_loop_run(event_loop); - - stop_sdp_server(); - - g_main_loop_unref(event_loop); - - info("Exit"); - - stop_logging(); - - return 0; -} diff --git a/sdpd/sdpd.8 b/sdpd/sdpd.8 deleted file mode 100644 index e23c6ffc..00000000 --- a/sdpd/sdpd.8 +++ /dev/null @@ -1,92 +0,0 @@ -.\" $Header$ -.\" -.\" transcript compatibility for postscript use. -.\" -.\" synopsis: .P! -.\" -.de P! -.fl -\!!1 setgray -.fl -\\&.\" -.fl -\!!0 setgray -.fl \" force out current output buffer -\!!save /psv exch def currentpoint translate 0 0 moveto -\!!/showpage{}def -.fl \" prolog -.sy sed -e 's/^/!/' \\$1\" bring in postscript file -\!!psv restore -. -.de pF -.ie \\*(f1 .ds f1 \\n(.f -.el .ie \\*(f2 .ds f2 \\n(.f -.el .ie \\*(f3 .ds f3 \\n(.f -.el .ie \\*(f4 .ds f4 \\n(.f -.el .tm ? font overflow -.ft \\$1 -.. -.de fP -.ie !\\*(f4 \{\ -. ft \\*(f4 -. ds f4\" -' br \} -.el .ie !\\*(f3 \{\ -. ft \\*(f3 -. ds f3\" -' br \} -.el .ie !\\*(f2 \{\ -. ft \\*(f2 -. ds f2\" -' br \} -.el .ie !\\*(f1 \{\ -. ft \\*(f1 -. ds f1\" -' br \} -.el .tm ? font underflow -.. -.ds f1\" -.ds f2\" -.ds f3\" -.ds f4\" -'\" t -.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n -.TH "sdpd" "8" -.SH "NAME" -sdpd \(em Bluetooth SDP daemon -.SH "SYNOPSIS" -.PP -\fBsdpd\fR [\fIoptions\fR] -.SH "DESCRIPTION" -.PP -\fBsdpd\fR allows Bluetooth devices -connected to the host to advertise via SDP the Bluetooth services -available. - -.SH "OPTIONS" -.IP "\fB-n\fP" 10 -Don't detach from the controlling terminal. -.IP "\fB-d\fP" 10 -Enable debugging output. -.IP "\fB-m \fP" 10 -Set maximum MTU to use on the L2CAP channel. - -.SH "BUGS" -.PP -None yet known. -.SH "AUTHOR" -.PP -Maxim Krasnyansky , -Stephen Crane . Man page written -by Edd Dumbill . - -.PP -Based on work done by Guruprasad Krishnamurthy -, Dmitry Kasatkin - and Manel Guerrero Zapata -. - -.SH "SEE ALSO" -.PP -sdptool(1) -.\" created by instant / docbook-to-man, Thu 15 Jan 2004, 21:01 -- cgit From 788878d89291688a06d2bb067fa9d5c82c4ad050 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 May 2008 01:10:52 +0000 Subject: Fix failure when MaximumServiceRecordCount is 0xFFFF --- sdpd/request.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index 5e3c715f..757c5ad9 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -238,13 +238,12 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) { int status = 0, i, plen, mlen, mtu, scanned; sdp_list_t *pattern = NULL; - uint16_t expected, actual; + uint16_t expected, actual, rsp_count = 0; uint8_t dtd; sdp_cont_state_t *cstate = NULL; uint8_t *pCacheBuffer = NULL; int handleSize = 0; uint32_t cStateId = 0; - short rsp_count = 0; short *pTotalRecordCount, *pCurrentRecordCount; uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); -- cgit From 45c36dbd276501aa76d9798a8fafe6c202db7276 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 11 Jun 2008 13:20:50 +0000 Subject: Avoid direct inclusion of malloc.h --- sdpd/cstate.c | 2 +- sdpd/request.c | 2 +- sdpd/servicedb.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sdpd') diff --git a/sdpd/cstate.c b/sdpd/cstate.c index bb422ce4..d0adf08a 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/sdpd/request.c b/sdpd/request.c index 757c5ad9..44b65f69 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index b5ea17ca..6cc34bd3 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include -- cgit From f65077489960f0dda7f02461de9cedc89ef347a5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jun 2008 01:10:06 +0000 Subject: Fix collect for non-persistent service records --- sdpd/server.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'sdpd') diff --git a/sdpd/server.c b/sdpd/server.c index fcdbf49f..1524d1c0 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -151,11 +151,16 @@ static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer d uint8_t *buf; int sk, len, size; - if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) + if (cond & G_IO_NVAL) return FALSE; sk = g_io_channel_unix_get_fd(chan); + if (cond & (G_IO_HUP | G_IO_ERR)) { + sdp_svcdb_collect_all(sk); + return FALSE; + } + len = recv(sk, &hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK); if (len <= 0) { sdp_svcdb_collect_all(sk); -- cgit From f39c79a261bf19109234df386959fc855d84d202 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 24 Jun 2008 00:26:47 +0000 Subject: Use safe functions for the server PDU extraction --- sdpd/request.c | 26 ++++++++++++++++++++++++-- sdpd/service.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 7 deletions(-) (limited to 'sdpd') diff --git a/sdpd/request.c b/sdpd/request.c index 44b65f69..9020dd38 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -67,8 +67,9 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p uint8_t dataType; int status = 0; const uint8_t *p; + int bufsize; - scanned = sdp_extract_seqtype(buf, &seqType, &data_size); + scanned = sdp_extract_seqtype_safe(buf, len, &seqType, &data_size); debug("Seq type : %d", seqType); if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) { @@ -76,6 +77,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p return -1; } p = buf + scanned; + bufsize = len - scanned; debug("Data size : %d", data_size); @@ -83,6 +85,11 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p char *pElem = NULL; int localSeqLength = 0; + if (bufsize < sizeof(uint8_t)) { + debug("->Unexpected end of buffer"); + return -1; + } + dataType = *(uint8_t *)p; debug("Data type: 0x%02x", dataType); @@ -100,27 +107,42 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p case SDP_UINT16: p += sizeof(uint8_t); seqlen += sizeof(uint8_t); + bufsize -= sizeof(uint8_t); + if (bufsize < sizeof(uint16_t)) { + debug("->Unexpected end of buffer"); + return -1; + } + pElem = malloc(sizeof(uint16_t)); bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)pElem); p += sizeof(uint16_t); seqlen += sizeof(uint16_t); + bufsize -= sizeof(uint16_t); break; case SDP_UINT32: p += sizeof(uint8_t); seqlen += sizeof(uint8_t); + bufsize -= sizeof(uint8_t); + if (bufsize < (int)sizeof(uint32_t)) { + debug("->Unexpected end of buffer"); + return -1; + } + pElem = malloc(sizeof(uint32_t)); bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)pElem); p += sizeof(uint32_t); seqlen += sizeof(uint32_t); + bufsize -= sizeof(uint32_t); break; case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: pElem = malloc(sizeof(uuid_t)); - status = sdp_uuid_extract(p, (uuid_t *)pElem, &localSeqLength); + status = sdp_uuid_extract_safe(p, bufsize, (uuid_t *) pElem, &localSeqLength); if (status == 0) { seqlen += localSeqLength; p += localSeqLength; + bufsize -= localSeqLength; } break; default: diff --git a/sdpd/service.c b/sdpd/service.c index 57a272db..a1072cd6 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -412,7 +412,7 @@ int remove_record_from_server(uint32_t handle) } // FIXME: refactor for server-side -static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t handleExpected, int *scanned) +static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, int bufsize, uint32_t handleExpected, int *scanned) { int extractStatus = -1, localExtractedLength = 0; uint8_t dtd; @@ -422,13 +422,24 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h sdp_data_t *pAttr = NULL; uint32_t handle = 0xffffffff; - *scanned = sdp_extract_seqtype(p, &dtd, &seqlen); + *scanned = sdp_extract_seqtype_safe(p, bufsize, &dtd, &seqlen); p += *scanned; + bufsize -= *scanned; + + if (bufsize < sizeof(uint8_t) + sizeof(uint8_t)) { + debug("Unexpected end of packet"); + return NULL; + } + lookAheadAttrId = ntohs(bt_get_unaligned((uint16_t *) (p + sizeof(uint8_t)))); debug("Look ahead attr id : %d", lookAheadAttrId); if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { + if (bufsize < (sizeof(uint8_t) * 2) + sizeof(uint16_t) + sizeof(uint32_t)) { + debug("Unexpected end of packet"); + return NULL; + } handle = ntohl(bt_get_unaligned((uint32_t *) (p + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t)))); @@ -456,6 +467,11 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h int attrSize = sizeof(uint8_t); int attrValueLength = 0; + if (bufsize < attrSize + sizeof(uint16_t)) { + debug("Unexpected end of packet: Terminating extraction of attributes"); + break; + } + debug("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength); dtd = *(uint8_t *) p; @@ -464,7 +480,8 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h debug("DTD of attrId : %d Attr id : 0x%x", dtd, attrId); - pAttr = sdp_extract_attr(p + attrSize, &attrValueLength, rec); + pAttr = sdp_extract_attr_safe(p + attrSize, bufsize - attrSize, + &attrValueLength, rec); debug("Attr id : 0x%x attrValueLength : %d", attrId, attrValueLength); @@ -475,6 +492,7 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h } localExtractedLength += attrSize; p += attrSize; + bufsize -= attrSize; sdp_attr_replace(rec, attrId, pAttr); extractStatus = 0; debug("Extract PDU, seqLength: %d localExtractedLength: %d", @@ -499,16 +517,18 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) int scanned = 0; sdp_data_t *handle; uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); + int bufsize = req->len - sizeof(sdp_pdu_hdr_t); sdp_record_t *rec; req->flags = *p++; if (req->flags & SDP_DEVICE_RECORD) { bacpy(&req->device, (bdaddr_t *) p); p += sizeof(bdaddr_t); + bufsize -= sizeof(bdaddr_t); } // save image of PDU: we need it when clients request this attribute - rec = extract_pdu_server(&req->device, p, 0xffffffff, &scanned); + rec = extract_pdu_server(&req->device, p, bufsize, 0xffffffff, &scanned); if (!rec) goto invalid; @@ -566,18 +586,20 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_record_t *orec; int status = 0, scanned = 0; uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); + int bufsize = req->len - sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p)); debug("Svc Rec Handle: 0x%x", handle); p += sizeof(uint32_t); + bufsize -= sizeof(uint32_t); orec = sdp_record_find(handle); debug("SvcRecOld: %p", orec); if (orec) { - sdp_record_t *nrec = extract_pdu_server(BDADDR_ANY, p, handle, &scanned); + sdp_record_t *nrec = extract_pdu_server(BDADDR_ANY, p, bufsize, handle, &scanned); if (nrec && handle == nrec->handle) { update_db_timestamp(); update_svclass_list(); -- cgit From 50ef5513db1ddcfa1e0bf704fe79cc8e30964cd2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 02:58:49 +0000 Subject: Fix SDP record registration with specific record handles --- sdpd/service.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'sdpd') diff --git a/sdpd/service.c b/sdpd/service.c index a1072cd6..002efc85 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -540,8 +540,10 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) } } else { if (sdp_record_find(rec->handle)) { - sdp_record_free(rec); - goto invalid; + /* extract_pdu_server will add the record handle + * if it is missing. So instead of failing, skip + * the record adding to avoid duplication. */ + goto success; } } @@ -552,10 +554,9 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) handle = sdp_data_alloc(SDP_UINT32, &rec->handle); sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, handle); - /* - * if the browse group descriptor is NULL, - * ensure that the record belongs to the ROOT group - */ +success: + /* if the browse group descriptor is NULL, + * ensure that the record belongs to the ROOT group */ if (sdp_data_get(rec, SDP_ATTR_BROWSE_GRP_LIST) == NULL) { uuid_t uuid; sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); -- cgit