/* * Copyright (C) 2005 iptelorg GmbH * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "dlg_mod_internal.h" #include "serialize_dlg.h" #include #include #include static int serialize_dlg_state(sstream_t *ss, dlg_state_t *state) { int i = -1; if (is_input_sstream(ss)) { /* read state */ if (serialize_int(ss, &i) != 0) return -1; switch (i) { case 0: *state = DLG_NEW; break; case 1: *state = DLG_EARLY; break; case 2: *state = DLG_CONFIRMED; break; case 3: *state = DLG_DESTROYED; break; default: ERROR_LOG("deserializing unknow dialog state (%d)!\n", i); return -1; /* unknown dialog state */ } } else { /* store state */ switch (*state) { case DLG_NEW: i = 0; break; case DLG_EARLY: i = 1; break; case DLG_CONFIRMED: i = 2; break; case DLG_DESTROYED: i = 3; break; } if (i == -1) { WARN_LOG("serializing unknow dialog state (probably unloadable!)\n"); } serialize_int(ss, &i); } return 0; } #if 0 static int serialize_ptype(sstream_t *ss, ptype_t *type) { int i = -1; if (is_input_sstream(ss)) { /* read ptype */ if (serialize_int(ss, &i) != 0) return -1; switch (i) { case 0: *type = P_OTHER; break; case 1: *type = P_Q; break; case 2: *type = P_EXPIRES; break; case 3: *type = P_METHOD; break; case 4: *type = P_RECEIVED; break; case 5: *type = P_TRANSPORT; break; case 6: *type = P_LR; break; case 7: *type = P_R2; break; case 8: *type = P_MADDR; break; case 9: *type = P_TTL; break; case 10: *type = P_DSTIP; break; case 11: *type = P_DSTPORT; break; case 12: *type = P_INSTANCE; break; default: ERROR_LOG("deserializing unknow ptype (%d)!\n", i); return -1; } } else { /* store ptype */ switch (*type) { case P_OTHER: i = 0; break; case P_Q: i = 1; break; case P_EXPIRES: i = 2; break; case P_METHOD: i = 3; break; case P_RECEIVED: i = 4; break; case P_TRANSPORT: i = 5; break; case P_LR: i = 6; break; case P_R2: i = 7; break; case P_MADDR: i = 8; break; case P_TTL: i = 9; break; case P_DSTIP: i = 10; break; case P_DSTPORT: i = 11; break; case P_INSTANCE: i = 12; break; } if (i == -1) { WARN_LOG("serializing unknow ptype (probably unloadable!)\n"); } serialize_int(ss, &i); } return 0; } /*static int serialize_param(sstream_t *ss, rr_t **_r) { int do_it = 0; int res = 0; if (is_input_sstream(ss)) { / * read route * / if (serialize_int(ss, &do_it) != 0) return -1; if (!do_it) *_r = NULL; else { *_r = (rr_t*)cds_malloc(sizeof(rr_t)); if (!*_r) { ERROR_LOG("serialize_route(): can't allocate memory\n"); return -1; } (*_r)->r2 = NULL; (*_r)->params = NULL; (*_r)->next = NULL; } } else { / * store route * / if (*_r) do_it = 1; else do_it = 0; if (serialize_int(ss, &do_it) != 0) return -1; } if (do_it) { rr_t *r = *_r; res = serialize_str(ss, &r->nameaddr.name) | res; res = serialize_str(ss, &r->nameaddr.uri) | res; res = serialize_int(ss, &r->nameaddr.len) | res; res = serialize_params(ss, &r->nameaddr.params) | res; res = serialize_int(ss, &r->nameaddr.len) | res; } return res; }*/ static int serialize_param(sstream_t *ss, param_t *p) { int res = 0; res = serialize_ptype(ss, &p->type) | res; res = serialize_str(ss, &p->name) | res; res = serialize_str(ss, &p->body) | res; res = serialize_int(ss, &p->len) | res; return res; } static int serialize_params(sstream_t *ss, param_t **params) { if (is_input_sstream(ss)) { /* read */ int i = 0; param_t *p, *last = NULL; *params = NULL; if (serialize_int(ss, &i) != 0) return -1; /* can't read "terminator" */ while (i) { p = (param_t *)cds_malloc(sizeof(param_t)); if (!p) { ERROR_LOG("serialize_params(): can't allocate memory\n"); return -1; } p->next = NULL; if (last) last->next = p; else *params = p; last = p; if (serialize_param(ss, p) != 0) return -1; if (serialize_int(ss, &i) != 0) return -1; /* can't read "terminator" */ } } else { /* store */ param_t *p = *params; int i = 1; while (p) { if (serialize_int(ss, &i) != 0) return -1; /* params terminator ! */ if (serialize_param(ss, p) != 0) return -1; p = p->next; } i = 0; if (serialize_int(ss, &i) != 0) return -1; /* params terminator ! */ } return 0; } static int serialize_route_ex(sstream_t *ss, rr_t **_r) { int do_it = 0; int res = 0; if (is_input_sstream(ss)) { /* read route */ if (serialize_int(ss, &do_it) != 0) return -1; if (!do_it) *_r = NULL; else { *_r = (rr_t*)cds_malloc(sizeof(rr_t)); if (!*_r) { ERROR_LOG("serialize_route(): can't allocate memory\n"); return -1; } (*_r)->r2 = NULL; (*_r)->params = NULL; (*_r)->next = NULL; } } else { /* store route */ if (*_r) do_it = 1; else do_it = 0; if (serialize_int(ss, &do_it) != 0) return -1; } if (do_it) { rr_t *r = *_r; str s = { r->nameaddr.name.s, r->len }; int delta = r->nameaddr.uri.s - r->nameaddr.name.s; res = serialize_str(ss, &s) | res; res = serialize_int(ss, &r->nameaddr.name.len) | res; res = serialize_int(ss, &r->nameaddr.uri.len) | res; res = serialize_int(ss, &r->nameaddr.len) | res; res = serialize_int(ss, &delta) | res; if (is_input_sstream(ss)) { r->nameaddr.name.s = s.s; r->nameaddr.uri.s = s.s + delta; } /* !!! optimalized strings - use carefuly !!! */ /*res = serialize_str(ss, &r->nameaddr.name) | res; res = serialize_str(ss, &r->nameaddr.uri) | res; res = serialize_int(ss, &r->nameaddr.len) | res;*/ /* ??? res = serialize_r2(ss, &r->nameaddr.params) | res; ??? */ res = serialize_params(ss, &r->params) | res; res = serialize_int(ss, &r->len) | res; TRACE_LOG("ROUTE: rlen=%d name=%.*s, uri=%.*s\n len=%d WHOLE=%.*s\n", r->len, FMT_STR(r->nameaddr.name), FMT_STR(r->nameaddr.uri), r->nameaddr.len, r->nameaddr.len, r->nameaddr.name.s ); } return res; } #endif /*static void trace_dlg(const char *s, dlg_t *d) { rr_t *r; TRACE_LOG("%s: callid = %.*s \nrem tag = %.*s \nloc tag = %.*s\n" "loc uri = %.*s\n rem uri = %.*s\n rem target = %.*s\n" "loc_cseq = %d rem_cseq = %d\n", s, FMT_STR(d->id.call_id), FMT_STR(d->id.rem_tag), FMT_STR(d->id.loc_tag), FMT_STR(d->loc_uri), FMT_STR(d->rem_uri), FMT_STR(d->rem_target), d->loc_seq.value, d->rem_seq.value ); r = d->route_set; while (r) { TRACE_LOG(" ... name = %.*s\n uri = %.*s", FMT_STR(r->nameaddr.name), FMT_STR(r->nameaddr.uri)); r = r->next; } }*/ int serialize_dlg(sstream_t *ss, dlg_t *dlg) { int res = 0; if (is_input_sstream(ss)) { memset(dlg, 0, sizeof(*dlg)); } res = serialize_str(ss, &dlg->id.call_id) | res; res = serialize_str(ss, &dlg->id.rem_tag) | res; res = serialize_str(ss, &dlg->id.loc_tag) | res; res = serialize_uint(ss, &dlg->loc_seq.value) | res; res = serialize_uchar(ss, &dlg->loc_seq.is_set) | res; res = serialize_uint(ss, &dlg->rem_seq.value) | res; res = serialize_uchar(ss, &dlg->rem_seq.is_set) | res; res = serialize_str(ss, &dlg->loc_uri) | res; res = serialize_str(ss, &dlg->rem_uri) | res; res = serialize_str(ss, &dlg->rem_target) | res; res = serialize_uchar(ss, &dlg->secure) | res; res = serialize_dlg_state(ss, &dlg->state) | res; res = serialize_route_set(ss, &dlg->route_set) | res; if ((res == 0) && (is_input_sstream(ss))) { /* tmb.w_calculate_hooks(dlg); */ res = tmb.calculate_hooks(dlg); if (res < 0) { ERROR_LOG("error during calculate_hooks (%d)!\n", res); } } return res; } int dlg2str(dlg_t *dlg, str *dst_str) { int res = 0; sstream_t store; init_output_sstream(&store, 256); if (serialize_dlg(&store, dlg) != 0) { ERROR_LOG("can't serialize dialog\n"); res = -1; } else { if (get_serialized_sstream(&store, dst_str) != 0) { ERROR_LOG("can't get serialized dialog data\n"); res = -1; } } destroy_sstream(&store); return res; } int str2dlg(const str *s, dlg_t *dst_dlg) { int res = 0; sstream_t store; if (!s) return -1; init_input_sstream(&store, s->s, s->len); if (serialize_dlg(&store, dst_dlg) != 0) { ERROR_LOG("can't de-serialize dialog\n"); res = -1; } destroy_sstream(&store); return res; }