/*
* Presence Agent, XPIDF document support
*
* $Id: xpidf.c,v 1.11 2004/08/24 09:00:33 janakj Exp $
*
* Copyright (C) 2001-2003 FhG Fokus
*
* This file is part of ser, a free SIP server.
*
* ser 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
*
* For a license to use the ser software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info@iptel.org
*
* ser 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include "../../dprint.h"
#include "paerrno.h"
#include "common.h"
#include "xpidf.h"
#define CRLF "\r\n"
#define CRLF_L (sizeof(CRLF) - 1)
#define PUBLIC_ID "//IETF//DTD RFCxxxx XPIDF 1.0//EN"
#define PUBLIC_ID_L (sizeof(PUBLIC_ID) - 1)
#define MIME_TYPE "application/xpidf+xml"
#define MIME_TYPE_L (sizeof(MIME_TYPE) - 1)
#define XML_VERSION "<?xml version=\"1.0\"?>"
#define XML_VERSION_L (sizeof(XML_VERSION) - 1)
#define PRESENCE_STAG "<presence>"
#define PRESENCE_STAG_L (sizeof(PRESENCE_STAG) - 1)
#define PRESENCE_ETAG "</presence>"
#define PRESENCE_ETAG_L (sizeof(PRESENCE_ETAG) - 1)
#define ADDRESS_ETAG "</address>"
#define ADDRESS_ETAG_L (sizeof(ADDRESS_ETAG) - 1)
#define ATOM_ETAG "</atom>"
#define ATOM_ETAG_L (sizeof(ATOM_ETAG) - 1)
#define XPIDF_DTD "xpidf.dtd"
#define XPIDF_DTD_L (sizeof(XPDIF_DTD) - 1)
#define DOCTYPE "<!DOCTYPE presence PUBLIC \"" PUBLIC_ID "\" \"" XPIDF_DTD "\">"
#define DOCTYPE_L (sizeof(DOCTYPE) - 1)
#define PRESENTITY_START "<presentity uri=\"sip:"
#define PRESENTITY_START_L (sizeof(PRESENTITY_START) - 1)
#define PRESENTITY_END ";method=SUBSCRIBE\"/>"
#define PRESENTITY_END_L (sizeof(PRESENTITY_END) - 1)
#define ATOM_STAG "<atom id=\"9r28r49\">"
#define ATOM_STAG_L (sizeof(ATOM_STAG) - 1)
#define ADDRESS_START "<address uri=\"sip:"
#define ADDRESS_START_L (sizeof(ADDRESS_START) - 1)
#define ADDRESS_END ";user=ip\" priority=\"0,800000\">"
#define ADDRESS_END_L (sizeof(ADDRESS_END) - 1)
#define STATUS_OPEN "<status status=\"open\"/>"
#define STATUS_OPEN_L (sizeof(STATUS_OPEN) - 1)
#define STATUS_CLOSED "<status status=\"closed\"/>"
#define STATUS_CLOSED_L (sizeof(STATUS_CLOSED) - 1)
#define MSNSUBSTATUS_ONLINE "<msnsubstatus substatus=\"online\"/>\r\n"
#define MSNSUBSTATUS_ONLINE_L (sizeof(MSNSUBSTATUS_ONLINE)-1)
#define MSNSUBSTATUS_OFFLINE "<msnsubstatus substatus=\"offline\"/>\r\n"
#define MSNSUBSTATUS_OFFLINE_L (sizeof(MSNSUBSTATUS_OFFLINE)-1)
/*
* Create start of pidf document
*/
int start_xpidf_doc(str* _b, int _l)
{
if (!_b || !_b->s) {
LOG(L_ERR, "start_xpidf_doc: Invalid parameter value\n");
paerrno = PA_INTERNAL_ERROR;
return -1;
}
if ((XML_VERSION_L +
CRLF_L +
DOCTYPE_L +
CRLF_L +
PRESENCE_STAG_L +
CRLF_L
) > _l) {
paerrno = PA_SMALL_BUFFER;
LOG(L_ERR, "start_xpidf_doc(): Buffer too small\n");
return -1;
}
str_append(_b, XML_VERSION CRLF DOCTYPE CRLF PRESENCE_STAG CRLF,
XML_VERSION_L + CRLF_L + DOCTYPE_L + CRLF_L + PRESENCE_STAG_L + CRLF_L);
return 0;
}
/*
* Add a presentity information
*/
int xpidf_add_presentity(str* _b, int _l, str* _uri)
{
if (!_b || !_b->s || !_uri || !_uri->s) {
LOG(L_ERR, "xpidf_add_presentity: Invalid parameter value\n");
paerrno = PA_INTERNAL_ERROR;
return -1;
}
if (_l < PRESENTITY_START_L + _uri->len + PRESENTITY_END_L + CRLF_L) {
paerrno = PA_SMALL_BUFFER;
LOG(L_ERR, "xpidf_add_presentity(): Buffer too small\n");
return -1;
}
str_append(_b, PRESENTITY_START, PRESENTITY_START_L);
str_append(_b, _uri->s, _uri->len);
str_append(_b, PRESENTITY_END CRLF, PRESENTITY_END_L + CRLF_L);
return 0;
}
/*
* Add a contact address with given status
*/
int xpidf_add_address(str* _b, int _l, str* _addr, xpidf_status_t _st)
{
int len = 0;
char* p;
int len_available = 0;
char * available;
switch(_st) {
case XPIDF_ST_OPEN:
p = STATUS_OPEN;
len = STATUS_OPEN_L;
available = MSNSUBSTATUS_ONLINE;
len_available = MSNSUBSTATUS_ONLINE_L;
break;
#if 0
case XPIDF_ST_INUSE:
p = STATUS_INUSE;
len = STATUS_INUSE_L;
available = MSNSUBSTATUS_OFFLINE;
len_available = MSNSUBSTATUS_OFFLINE_L;
break;
#endif
default:
case XPIDF_ST_CLOSED:
p = STATUS_CLOSED;
len = STATUS_CLOSED_L;
available = MSNSUBSTATUS_OFFLINE;
len_available = MSNSUBSTATUS_OFFLINE_L;
break;
}
if (!_b || !_b->s || !_addr || !_addr->s) {
LOG(L_ERR, "xpidf_add_address: Invalid parameter value\n");
paerrno = PA_INTERNAL_ERROR;
return -1;
}
if (_l < (ATOM_STAG_L +
CRLF_L +
ADDRESS_START_L +
_addr->len +
ADDRESS_END_L +
CRLF_L +
len +
len_available +
CRLF_L +
ADDRESS_ETAG_L +
CRLF_L +
ATOM_ETAG_L +
CRLF_L
)
) {
paerrno = PA_SMALL_BUFFER;
LOG(L_ERR, "xpidf_add_address(): Buffer too small\n");
return -1;
}
str_append(_b, ATOM_STAG CRLF ADDRESS_START, ATOM_STAG_L + CRLF_L + ADDRESS_START_L);
str_append(_b, _addr->s, _addr->len);
str_append(_b, ADDRESS_END CRLF, ADDRESS_END_L + CRLF_L);
str_append(_b, p, len);
str_append(_b,available, len_available);
str_append(_b, CRLF ADDRESS_ETAG CRLF ATOM_ETAG CRLF,
CRLF_L + ADDRESS_ETAG_L + CRLF_L + ATOM_ETAG_L + CRLF_L);
return 0;
}
/*
* End the document
*/
int end_xpidf_doc(str* _b, int _l)
{
if (_l < (PRESENCE_ETAG_L + CRLF_L)) {
paerrno = PA_SMALL_BUFFER;
LOG(L_ERR, "end_xpidf_doc(): Buffer too small\n");
return -1;
}
str_append(_b, PRESENCE_ETAG CRLF, PRESENCE_ETAG_L + CRLF_L);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1