?? watcher.c
字號:
/* * Presence Agent, watcher structure and related functions * * $Id: watcher.c,v 1.17.2.1 2005/06/06 16:27:32 andrei 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 "paerrno.h"#include "../../db/db.h"#include "../../dprint.h"#include "../../parser/parse_event.h"#include "../../mem/shm_mem.h"#include "../../trim.h"#include "../../ut.h"#include "pa_mod.h"#include "common.h"#include "watcher.h"#include "presentity.h"char *doctype_name[] = { [DOC_XPIDF] = "DOC_XPIDF", [DOC_LPIDF] = "DOC_LPIDF", [DOC_PIDF] = "DOC_PIDF", [DOC_WINFO] = "DOC_WINFO", [DOC_XCAP_CHANGE] = "DOC_XCAP_CHANGE", [DOC_LOCATION] = "DOC_LOCATION"};char *event_package_name[] = { [EVENT_OTHER] = "unknown", [EVENT_PRESENCE] = "presence", [EVENT_PRESENCE_WINFO] = "presence.winfo", [EVENT_XCAP_CHANGE] = "xcap-change", [EVENT_LOCATION] = "location", NULL};static str watcher_status_names[] = { [WS_PENDING] = { "pending", 7 }, [WS_ACTIVE] = { "active", 6 }, [WS_WAITING] = { "waiting", 7 }, [WS_TERMINATED] = { "terminated", 10 }, { 0, 0 }};static str watcher_event_names[] = { [WE_SUBSCRIBE] = { "subscribe", 9 }, [WE_APPROVED] = { "approved", 8 }, [WE_DEACTIVATED] = { "deactivated", 11 }, [WE_PROBATION] = { "probation", 9 }, [WE_REJECTED] = { "rejected", 8 }, [WE_TIMEOUT] = { "timeout", 7 }, [WE_GIVEUP] = { "giveup", 6 }, [WE_NORESOURCE] = { "noresource", 10 }, { 0, 0 }};int event_package_from_string(str *epname) { int i; for (i = 0; event_package_name[i]; i++) { if (strcasecmp(epname->s, event_package_name[i]) == 0) { return i; } } return 0;}watcher_status_t watcher_status_from_string(str *wsname) { int i; for (i = 0; watcher_status_names[i].len; i++) { if (str_strcasecmp(wsname, &watcher_status_names[i]) == 0) { return i; } } return 0;}watcher_event_t watcher_event_from_string(str *wename) { int i; for (i = 0; watcher_event_names[i].len; i++) { if (str_strcasecmp(wename, &watcher_event_names[i]) == 0) { return i; } } return 0;}#define S_ID_LEN 64/* be sure s!=NULL *//* compute a hash value for a string */unsigned int compute_hash(unsigned int _h, char* s, int len){ #define h_inc h+=v^(v>>3); char* p; register unsigned v; register unsigned h = _h; for(p=s; p<=(s+len-4); p+=4) { v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3]; h_inc; } v=0; for(;p<(s+len); p++) { v<<=8; v+=*p; } h_inc; return h;}static char hbuf[2048];static int watcher_assign_statement_id(presentity_t *presentity, watcher_t *watcher){ unsigned int h = 0; char *dn = doctype_name[watcher->accept]; if (1) { int len = 0; strncpy(hbuf+len, presentity->uri.s, presentity->uri.len); len += presentity->uri.len; strncpy(hbuf+len, dn, strlen(dn)); len += strlen(dn); strncpy(hbuf+len, watcher->uri.s, watcher->uri.len); len += watcher->uri.len; h = compute_hash(0, hbuf, len); } else { h = compute_hash(0, presentity->uri.s, presentity->uri.len); h = compute_hash(h, dn, strlen(dn)); h = compute_hash(h, watcher->uri.s, watcher->uri.len); } watcher->s_id.len = sprintf(watcher->s_id.s, "SID%08x", h); return 0;}/* * Create a new watcher structure but do not write to database */int new_watcher_no_wb(presentity_t *_p, str* _uri, time_t _e, int event_package, doctype_t _a, dlg_t* _dlg, str *_dn, watcher_t** _w){ watcher_t* watcher; /* Check parameters */ if (!_uri && !_dlg && !_w) { LOG(L_ERR, "new_watcher(): Invalid parameter value\n"); return -1; } /* Allocate memory buffer for watcher_t structure and uri string */ watcher = (watcher_t*)shm_malloc(sizeof(watcher_t) + _uri->len + _dn->len + S_ID_LEN); if (!watcher) { paerrno = PA_NO_MEMORY; LOG(L_ERR, "new_watcher(): No memory left\n"); return -1; } memset(watcher, 0, sizeof(watcher_t)); /* Copy uri string */ watcher->uri.s = (char*)watcher + S_ID_LEN + sizeof(watcher_t); watcher->uri.len = _uri->len; memcpy(watcher->uri.s, _uri->s, _uri->len); /* Copy display_name string */ watcher->display_name.s = (char*)watcher + S_ID_LEN + sizeof(watcher_t) + _uri->len; watcher->display_name.len = _dn->len; memcpy(watcher->display_name.s, _dn->s, _dn->len); watcher->s_id.s = (char*)watcher + sizeof(watcher_t); watcher->s_id.len = 0; watcher->event_package = event_package; watcher->expires = _e; /* Expires value */ watcher->accept = _a; /* Accepted document type */ watcher->dialog = _dlg; /* Dialog handle */ watcher->event = WE_SUBSCRIBE; *_w = watcher; return 0;}/* * Create a new watcher structure */int new_watcher(presentity_t *_p, str* _uri, time_t _e, int event_package, doctype_t _a, dlg_t* _dlg, str *_dn, watcher_t** _w){ int rc; watcher_t* watcher; /* Check parameters */ if (!_uri && !_dlg && !_w) { LOG(L_ERR, "new_watcher(): Invalid parameter value\n"); return -1; } rc = new_watcher_no_wb(_p, _uri, _e, event_package, _a, _dlg, _dn, _w); if (rc < 0) { return rc; } else { watcher = *_w; } if (use_db) { db_key_t query_cols[11]; db_op_t query_ops[11]; db_val_t query_vals[11]; db_key_t result_cols[5]; db_res_t *res; int n_query_cols = 0; int n_result_cols = 0; int s_id_col, status_col, display_name_col, event_col; char *package = event_package_name[watcher->event_package]; LOG(L_ERR, "new_watcher starting\n"); query_cols[n_query_cols] = "r_uri"; query_ops[n_query_cols] = OP_EQ; query_vals[n_query_cols].type = DB_STR; query_vals[n_query_cols].nul = n_query_cols; query_vals[n_query_cols].val.str_val.s = _p->uri.s; query_vals[n_query_cols].val.str_val.len = _p->uri.len; n_query_cols++; LOG(L_ERR, "new_watcher: _p->uri=%.*s\n", _p->uri.len, _p->uri.s); query_cols[n_query_cols] = "w_uri"; query_ops[n_query_cols] = OP_EQ; query_vals[n_query_cols].type = DB_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val.s = watcher->uri.s; query_vals[n_query_cols].val.str_val.len = watcher->uri.len; n_query_cols++; LOG(L_ERR, "db_new_watcher: watcher->uri=%.*s\n", watcher->uri.len, watcher->uri.s); query_cols[n_query_cols] = "package"; query_ops[n_query_cols] = OP_EQ; query_vals[n_query_cols].type = DB_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val.s = package; query_vals[n_query_cols].val.str_val.len = strlen(package); n_query_cols++; LOG(L_ERR, "new_watcher: watcher->package=%s\n", package); result_cols[s_id_col = n_result_cols++] = "s_id"; result_cols[status_col = n_result_cols++] = "status"; result_cols[event_col = n_result_cols++] = "event"; result_cols[display_name_col = n_result_cols++] = "display_name"; if (pa_dbf.use_table(pa_db, watcherinfo_table) < 0) { LOG(L_ERR, "new_watcher: Error in use_table\n"); return -1; } if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals, result_cols, n_query_cols, n_result_cols, 0, &res) < 0) { LOG(L_ERR, "new_watcher: Error while querying tuple\n"); return -1; } LOG(L_INFO, "new_watcher: getting values: res=%p res->n=%d\n", res, (res ? res->n : 0)); if (res && res->n > 0) { /* fill in tuple structure from database query result */ db_row_t *row = &res->rows[0]; db_val_t *row_vals = ROW_VALUES(row); str s_id = { 0, 0 }; str status = { 0, 0 }; str event_str = { 0, 0 }; watcher_event_t watcher_event = WE_SUBSCRIBE; if (!row_vals[s_id_col].nul) { s_id.s = (char*)row_vals[s_id_col].val.string_val; s_id.len = strlen(s_id.s); } if (!row_vals[status_col].nul) { status.s = (char*)row_vals[status_col].val.string_val; status.len = strlen(status.s); } if (!row_vals[event_col].nul) { event_str.s = (char*)row_vals[event_col].val.string_val; event_str.len = strlen(event_str.s); watcher_event = watcher_event_from_string(&event_str); } watcher->event = watcher_event; LOG(L_ERR, "new_watcher: status=%.*s\n", status.len, status.s); if (status.len) { watcher->status = watcher_status_from_string(&status); } else { watcher->status = WS_ACTIVE; } if (s_id.s) { strncpy(watcher->s_id.s, s_id.s, S_ID_LEN); watcher->s_id.len = strlen(s_id.s); } } else { watcher_assign_statement_id(_p, watcher); query_cols[n_query_cols] = "s_id"; query_vals[n_query_cols].type = DB_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val.s = watcher->s_id.s; query_vals[n_query_cols].val.str_val.len = watcher->s_id.len; n_query_cols++; query_cols[n_query_cols] = "status"; query_vals[n_query_cols].type = DB_STR; query_vals[n_query_cols].nul = 0; if (new_watcher_pending) { query_vals[n_query_cols].val.str_val.s = "pending"; query_vals[n_query_cols].val.str_val.len = strlen("pending"); } else { query_vals[n_query_cols].val.str_val.s = "active"; query_vals[n_query_cols].val.str_val.len = strlen("active"); } n_query_cols++; query_cols[n_query_cols] = "event"; query_vals[n_query_cols].type = DB_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val = watcher_event_names[watcher->event]; n_query_cols++; query_cols[n_query_cols] = "display_name"; query_vals[n_query_cols].type = DB_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val.s = watcher->display_name.s; query_vals[n_query_cols].val.str_val.len = watcher->display_name.len; n_query_cols++; query_cols[n_query_cols] = "accepts"; query_vals[n_query_cols].type = DB_INT; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.int_val = watcher->accept; n_query_cols++;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -