/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2001-2002  Nokia Corporation
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2002-2004  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2002-2003  Stephen Crane <steve.crane@rococosoft.com>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation;
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
 *  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
 *  CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *  ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
 *  COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
 *  SOFTWARE IS DISCLAIMED.
 *
 *
 *  $Id$
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <netinet/in.h>
#include <sys/socket.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

#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;
}
