/* * Presence Agent, XPIDF document support * * $Id: xpidf.c 455 2005-12-08 10:58:56Z bogdan_iancu $ * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of openser, a free SIP server. * * openser 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 * * openser 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 #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 "" #define XML_VERSION_L (sizeof(XML_VERSION) - 1) #define PRESENCE_STAG "" #define PRESENCE_STAG_L (sizeof(PRESENCE_STAG) - 1) #define PRESENCE_ETAG "" #define PRESENCE_ETAG_L (sizeof(PRESENCE_ETAG) - 1) #define ADDRESS_ETAG "" #define ADDRESS_ETAG_L (sizeof(ADDRESS_ETAG) - 1) #define ATOM_ETAG "" #define ATOM_ETAG_L (sizeof(ATOM_ETAG) - 1) #define XPIDF_DTD "xpidf.dtd" #define XPIDF_DTD_L (sizeof(XPDIF_DTD) - 1) #define DOCTYPE "" #define DOCTYPE_L (sizeof(DOCTYPE) - 1) #define PRESENTITY_START "" #define PRESENTITY_END_L (sizeof(PRESENTITY_END) - 1) #define ATOM_STAG "" #define ATOM_STAG_L (sizeof(ATOM_STAG) - 1) #define ADDRESS_START "
" #define ADDRESS_END_L (sizeof(ADDRESS_END) - 1) #define STATUS_OPEN "" #define STATUS_OPEN_L (sizeof(STATUS_OPEN) - 1) #define STATUS_CLOSED "" #define STATUS_CLOSED_L (sizeof(STATUS_CLOSED) - 1) #define MSNSUBSTATUS_ONLINE "\r\n" #define MSNSUBSTATUS_ONLINE_L (sizeof(MSNSUBSTATUS_ONLINE)-1) #define MSNSUBSTATUS_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; #ifdef WITH_MSN int len_available = 0; char * available; #endif switch(_st) { case XPIDF_ST_OPEN: p = STATUS_OPEN; len = STATUS_OPEN_L; #ifdef WITH_MSN available = MSNSUBSTATUS_ONLINE; len_available = MSNSUBSTATUS_ONLINE_L; #endif 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; #ifdef WITH_MSN available = MSNSUBSTATUS_OFFLINE; len_available = MSNSUBSTATUS_OFFLINE_L; #endif 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 + #ifdef WITH_MSN len_available + #endif 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); #ifdef WITH_MSN str_append(_b,available, len_available); #endif 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; }