📄 notify.c
字号:
/* * Presence Agent, notifications * * $Id: notify.c,v 1.21 2004/08/24 22:11:43 jamey 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 * * History: * -------- * 2003-02-28 protocolization of t_uac_dlg completed (jiri) */#include "../../str.h"#include "../../dprint.h"#include "../../trim.h"#include "../../parser/parse_event.h"#include "pa_mod.h"#include "lpidf.h"#include "xpidf.h"#include "presentity.h"#include "pidf.h"#include "common.h"#include "paerrno.h"#include "notify.h"#include "watcher.h"#include "location.h"#define CONTENT_TYPE "Content-Type: "#define CONTENT_TYPE_L (sizeof(CONTENT_TYPE) - 1)#define EVENT "Event: "#define EVENT_L (sizeof(EVENT) - 1)#define PRESENCE_TEXT "presence"#define PRESENCE_TEXT_L (sizeof(PRESENCE_TEXT) - 1)#define WINFO_TEXT "presence.winfo"#define WINFO_TEXT_L (sizeof(WINFO_TEXT) - 1)#define XCAP_CHANGE_TEXT "xcap-change"#define XCAP_CHANGE_TEXT_L (sizeof(XCAP_CHANGE_TEXT) - 1)#define CONT_TYPE_XPIDF "application/xpidf+xml"#define CONT_TYPE_XPIDF_L (sizeof(CONT_TYPE_XPIDF) - 1)#define CONT_TYPE_LPIDF "text/lpidf"#define CONT_TYPE_LPIDF_L (sizeof(CONT_TYPE_LPIDF) - 1)#define CONT_TYPE_PIDF "application/pidf+xml"#define CONT_TYPE_PIDF_L (sizeof(CONT_TYPE_PIDF) - 1)#define CONT_TYPE_WINFO "application/watcherinfo+xml"#define CONT_TYPE_WINFO_L (sizeof(CONT_TYPE_WINFO) - 1)#define CONT_TYPE_XCAP_CHANGE "application/xcap-change+xml"#define CONT_TYPE_XCAP_CHANGE_L (sizeof(CONT_TYPE_XCAP_CHANGE) - 1)#define SUBSCRIPTION_STATE "Subscription-State: "#define SUBSCRIPTION_STATE_L (sizeof(SUBSCRIPTION_STATE) - 1)#define SS_EXPIRES ";expires="#define SS_EXPIRES_L (sizeof(SS_EXPIRES) - 1)#define SS_REASON ";reason="#define SS_REASON_L (sizeof(SS_REASON) - 1)#define CRLF "\r\n"#define CRLF_L (sizeof(CRLF) - 1)#define ST_ACTIVE "active"#define ST_ACTIVE_L (sizeof(ST_ACTIVE) - 1)#define ST_TERMINATED "terminated"#define ST_TERMINATED_L (sizeof(ST_TERMINATED) - 1)#define ST_PENDING "pending"#define ST_PENDING_L (sizeof(ST_PENDING) - 1)#define REASON_DEACTIVATED "deactivated"#define REASON_DEACTIVATED_L (sizeof(REASON_DEACTIVATED) - 1)#define REASON_NORESOURCE "noresource"#define REASON_NORESOURCE_L (sizeof(REASON_NORESOURCE) - 1)#define REASON_PROBATION "probation"#define REASON_PROBATION_L (sizeof(REASON_PROBATION) - 1)#define REASON_REJECTED "rejected"#define REASON_REJECTED_L (sizeof(REASON_REJECTED) - 1)#define REASON_TIMEOUT "timeout"#define REASON_TIMEOUT_L (sizeof(REASON_TIMEOUT) - 1)#define REASON_GIVEUP "giveup"#define REASON_GIVEUP_L (sizeof(REASON_GIVEUP) - 1)#define METHOD_NOTIFY "NOTIFY"#define METHOD_NOTIFY_L (sizeof(METHOD_NOTIFY) - 1)/* * Subscription-State values */static str subs_states[] = { {ST_ACTIVE, ST_ACTIVE_L }, {ST_TERMINATED, ST_TERMINATED_L}, {ST_PENDING, ST_PENDING_L }};/* * Subscription-State reason parameter values */static str reason[] = { {REASON_DEACTIVATED, REASON_DEACTIVATED_L}, {REASON_NORESOURCE, REASON_NORESOURCE_L }, {REASON_PROBATION, REASON_PROBATION_L }, {REASON_REJECTED, REASON_REJECTED_L }, {REASON_TIMEOUT, REASON_TIMEOUT_L }, {REASON_GIVEUP, REASON_GIVEUP_L }};static str method = {METHOD_NOTIFY, METHOD_NOTIFY_L};#define BUF_LEN 4096static char headers_buf[BUF_LEN];static char buffer[BUF_LEN];static str headers = {headers_buf, 0};static str body = {buffer, 0};static inline int add_event_hf(str* _h, int _l, int accept){ int event_l; char *event; if (accept == DOC_WINFO) { event = WINFO_TEXT; event_l = WINFO_TEXT_L; } else if (accept == DOC_XCAP_CHANGE) { event = XCAP_CHANGE_TEXT; event_l = XCAP_CHANGE_TEXT_L; } else { event = PRESENCE_TEXT; event_l = PRESENCE_TEXT_L; } if (_l < EVENT_L + event_l + CRLF_L) { paerrno = PA_SMALL_BUFFER; LOG(L_ERR, "add_event_hf(): Buffer too small\n"); return -1; } str_append(_h, EVENT, EVENT_L); str_append(_h, event, event_l); str_append(_h, CRLF, CRLF_L); return 0;}static inline int add_cont_type_hf(str* _h, int _l, doctype_t _d){ switch(_d) { case DOC_XPIDF: if (_l < CONTENT_TYPE_L + CONT_TYPE_XPIDF_L + CRLF_L) { paerrno = PA_SMALL_BUFFER; LOG(L_ERR, "add_cont_type_hf(): Buffer too small\n"); return -1; } str_append(_h, CONTENT_TYPE CONT_TYPE_XPIDF CRLF, CONTENT_TYPE_L + CONT_TYPE_XPIDF_L + CRLF_L); return 0; case DOC_LPIDF: if (_l < CONTENT_TYPE_L + CONT_TYPE_LPIDF_L + CRLF_L) { paerrno = PA_SMALL_BUFFER; LOG(L_ERR, "add_cont_type_hf(): Buffer too small\n"); return -2; } str_append(_h, CONTENT_TYPE CONT_TYPE_LPIDF CRLF, CONTENT_TYPE_L + CONT_TYPE_LPIDF_L + CRLF_L); return 0; case DOC_PIDF: if (_l < CONTENT_TYPE_L + CONT_TYPE_PIDF_L + CRLF_L) { paerrno = PA_SMALL_BUFFER; LOG(L_ERR, "add_cont_type_hf(): Buffer too small\n"); return -2; } str_append(_h, CONTENT_TYPE CONT_TYPE_PIDF CRLF, CONTENT_TYPE_L + CONT_TYPE_PIDF_L + CRLF_L); return 0; case DOC_WINFO: if (_l < CONTENT_TYPE_L + CONT_TYPE_WINFO_L + CRLF_L) { paerrno = PA_SMALL_BUFFER; LOG(L_ERR, "add_cont_type_hf(): Buffer too small\n"); return -2; } str_append(_h, CONTENT_TYPE CONT_TYPE_WINFO CRLF, CONTENT_TYPE_L + CONT_TYPE_WINFO_L + CRLF_L); return 0; case DOC_XCAP_CHANGE: if (_l < CONTENT_TYPE_L + CONT_TYPE_XCAP_CHANGE_L + CRLF_L) { paerrno = PA_SMALL_BUFFER; LOG(L_ERR, "add_cont_type_hf(): Buffer too small\n"); return -2; } str_append(_h, CONTENT_TYPE CONT_TYPE_XCAP_CHANGE CRLF, CONTENT_TYPE_L + CONT_TYPE_XCAP_CHANGE_L + CRLF_L); return 0; default: paerrno = PA_UNSUPP_DOC; LOG(L_ERR, "add_cont_type_hf(): Unsupported document type\n"); return -3; }}static inline int add_subs_state_hf(str* _h, int _l, subs_state_t _s, ss_reason_t _r, time_t _e){ char* num; int len; if (_l < SUBSCRIPTION_STATE_L + subs_states[_s].len + SS_EXPIRES_L + SS_REASON_L + reason[_r].len + CRLF_L) { paerrno = PA_SMALL_BUFFER; LOG(L_ERR, "add_subs_state_hf(): Buffer too small\n"); return -1; } str_append(_h, SUBSCRIPTION_STATE, SUBSCRIPTION_STATE_L); str_append(_h, subs_states[_s].s, subs_states[_s].len); switch(_s) { case SS_ACTIVE: str_append(_h, SS_EXPIRES, SS_EXPIRES_L); num = int2str((unsigned int)_e, &len); str_append(_h, num, len); break; case SS_TERMINATED: str_append(_h, SS_REASON, SS_REASON_L); str_append(_h, reason[_r].s, reason[_r].len); break; case SS_PENDING: break; } str_append(_h, CRLF, CRLF_L); return 0;}static inline int create_headers(struct watcher* _w){ time_t t; subs_state_t s; headers.len = 0; if (add_event_hf(&headers, BUF_LEN, _w->accept) < 0) { LOG(L_ERR, "create_headers(): Error while adding Event header field\n"); return -1; } if (add_cont_type_hf(&headers, BUF_LEN - headers.len, _w->accept) < 0) { LOG(L_ERR, "create_headers(): Error while adding Content-Type header field\n"); return -2; } if (_w && _w->expires) t = _w->expires - time(0); else t = 0; if (t == 0) { s = SS_TERMINATED; } else { s = SS_ACTIVE; } if (add_subs_state_hf(&headers, BUF_LEN - headers.len, s, SR_TIMEOUT, t) < 0) { LOG(L_ERR, "create_headers(): Error while adding Subscription-State\n"); return -3; } return 0;}static int send_xpidf_notify(struct presentity* _p, struct watcher* _w){ xpidf_status_t st; presence_tuple_t *tuple = _p->tuples; /* Send a notify, saved Contact will be put in * Request-URI, To will be put in from and new tag * will be generated, callid will be callid, * from will be put in to including tag */ if (start_xpidf_doc(&body, BUF_LEN) < 0) { LOG(L_ERR, "send_xpidf_notify(): start_xpidf_doc failed\n"); return -1; } if (xpidf_add_presentity(&body, BUF_LEN - body.len, &_p->uri) < 0) { LOG(L_ERR, "send_xpidf_notify(): xpidf_add_presentity failed\n"); return -3; } while (tuple) { switch(tuple->state) { case PS_ONLINE: st = XPIDF_ST_OPEN; break; default: st = XPIDF_ST_CLOSED; break; } if (xpidf_add_address(&body, BUF_LEN - body.len, &_p->uri, st) < 0) { LOG(L_ERR, "send_xpidf_notify(): xpidf_add_address failed\n"); return -3; } tuple = tuple->next; } if (end_xpidf_doc(&body, BUF_LEN - body.len) < 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -