serialize_dlg.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*
  2. * Copyright (C) 2005 iptelorg GmbH
  3. *
  4. * This file is part of ser, a free SIP server.
  5. *
  6. * ser is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. * For a license to use the ser software under conditions
  12. * other than those described here, or to purchase support for this
  13. * software, please contact iptel.org by e-mail at the following addresses:
  14. * [email protected]
  15. *
  16. * ser is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. */
  25. #include "dlg_mod_internal.h"
  26. #include "serialize_dlg.h"
  27. #include <cds/logger.h>
  28. #include <cds/memory.h>
  29. #include <cds/rr_serialize.h>
  30. static int serialize_dlg_state(sstream_t *ss, dlg_state_t *state)
  31. {
  32. int i = -1;
  33. if (is_input_sstream(ss)) { /* read state */
  34. if (serialize_int(ss, &i) != 0) return -1;
  35. switch (i) {
  36. case 0: *state = DLG_NEW; break;
  37. case 1: *state = DLG_EARLY; break;
  38. case 2: *state = DLG_CONFIRMED; break;
  39. case 3: *state = DLG_DESTROYED; break;
  40. default:
  41. ERROR_LOG("deserializing unknow dialog state (%d)!\n", i);
  42. return -1; /* unknown dialog state */
  43. }
  44. }
  45. else { /* store state */
  46. switch (*state) {
  47. case DLG_NEW: i = 0; break;
  48. case DLG_EARLY: i = 1; break;
  49. case DLG_CONFIRMED: i = 2; break;
  50. case DLG_DESTROYED: i = 3; break;
  51. }
  52. if (i == -1) {
  53. WARN_LOG("serializing unknow dialog state (probably unloadable!)\n");
  54. }
  55. serialize_int(ss, &i);
  56. }
  57. return 0;
  58. }
  59. #if 0
  60. static int serialize_ptype(sstream_t *ss, ptype_t *type)
  61. {
  62. int i = -1;
  63. if (is_input_sstream(ss)) { /* read ptype */
  64. if (serialize_int(ss, &i) != 0) return -1;
  65. switch (i) {
  66. case 0: *type = P_OTHER; break;
  67. case 1: *type = P_Q; break;
  68. case 2: *type = P_EXPIRES; break;
  69. case 3: *type = P_METHOD; break;
  70. case 4: *type = P_RECEIVED; break;
  71. case 5: *type = P_TRANSPORT; break;
  72. case 6: *type = P_LR; break;
  73. case 7: *type = P_R2; break;
  74. case 8: *type = P_MADDR; break;
  75. case 9: *type = P_TTL; break;
  76. case 10: *type = P_DSTIP; break;
  77. case 11: *type = P_DSTPORT; break;
  78. case 12: *type = P_INSTANCE; break;
  79. default:
  80. ERROR_LOG("deserializing unknow ptype (%d)!\n", i);
  81. return -1;
  82. }
  83. }
  84. else { /* store ptype */
  85. switch (*type) {
  86. case P_OTHER: i = 0; break;
  87. case P_Q: i = 1; break;
  88. case P_EXPIRES: i = 2; break;
  89. case P_METHOD: i = 3; break;
  90. case P_RECEIVED: i = 4; break;
  91. case P_TRANSPORT: i = 5; break;
  92. case P_LR: i = 6; break;
  93. case P_R2: i = 7; break;
  94. case P_MADDR: i = 8; break;
  95. case P_TTL: i = 9; break;
  96. case P_DSTIP: i = 10; break;
  97. case P_DSTPORT: i = 11; break;
  98. case P_INSTANCE: i = 12; break;
  99. }
  100. if (i == -1) {
  101. WARN_LOG("serializing unknow ptype (probably unloadable!)\n");
  102. }
  103. serialize_int(ss, &i);
  104. }
  105. return 0;
  106. }
  107. /*static int serialize_param(sstream_t *ss, rr_t **_r)
  108. {
  109. int do_it = 0;
  110. int res = 0;
  111. if (is_input_sstream(ss)) { / * read route * /
  112. if (serialize_int(ss, &do_it) != 0) return -1;
  113. if (!do_it) *_r = NULL;
  114. else {
  115. *_r = (rr_t*)cds_malloc(sizeof(rr_t));
  116. if (!*_r) {
  117. ERROR_LOG("serialize_route(): can't allocate memory\n");
  118. return -1;
  119. }
  120. (*_r)->r2 = NULL;
  121. (*_r)->params = NULL;
  122. (*_r)->next = NULL;
  123. }
  124. }
  125. else { / * store route * /
  126. if (*_r) do_it = 1;
  127. else do_it = 0;
  128. if (serialize_int(ss, &do_it) != 0) return -1;
  129. }
  130. if (do_it) {
  131. rr_t *r = *_r;
  132. res = serialize_str(ss, &r->nameaddr.name) | res;
  133. res = serialize_str(ss, &r->nameaddr.uri) | res;
  134. res = serialize_int(ss, &r->nameaddr.len) | res;
  135. res = serialize_params(ss, &r->nameaddr.params) | res;
  136. res = serialize_int(ss, &r->nameaddr.len) | res;
  137. }
  138. return res;
  139. }*/
  140. static int serialize_param(sstream_t *ss, param_t *p)
  141. {
  142. int res = 0;
  143. res = serialize_ptype(ss, &p->type) | res;
  144. res = serialize_str(ss, &p->name) | res;
  145. res = serialize_str(ss, &p->body) | res;
  146. res = serialize_int(ss, &p->len) | res;
  147. return res;
  148. }
  149. static int serialize_params(sstream_t *ss, param_t **params)
  150. {
  151. if (is_input_sstream(ss)) { /* read */
  152. int i = 0;
  153. param_t *p, *last = NULL;
  154. *params = NULL;
  155. if (serialize_int(ss, &i) != 0) return -1; /* can't read "terminator" */
  156. while (i) {
  157. p = (param_t *)cds_malloc(sizeof(param_t));
  158. if (!p) {
  159. ERROR_LOG("serialize_params(): can't allocate memory\n");
  160. return -1;
  161. }
  162. p->next = NULL;
  163. if (last) last->next = p;
  164. else *params = p;
  165. last = p;
  166. if (serialize_param(ss, p) != 0) return -1;
  167. if (serialize_int(ss, &i) != 0) return -1; /* can't read "terminator" */
  168. }
  169. }
  170. else { /* store */
  171. param_t *p = *params;
  172. int i = 1;
  173. while (p) {
  174. if (serialize_int(ss, &i) != 0) return -1; /* params terminator ! */
  175. if (serialize_param(ss, p) != 0) return -1;
  176. p = p->next;
  177. }
  178. i = 0;
  179. if (serialize_int(ss, &i) != 0) return -1; /* params terminator ! */
  180. }
  181. return 0;
  182. }
  183. static int serialize_route_ex(sstream_t *ss, rr_t **_r)
  184. {
  185. int do_it = 0;
  186. int res = 0;
  187. if (is_input_sstream(ss)) { /* read route */
  188. if (serialize_int(ss, &do_it) != 0) return -1;
  189. if (!do_it) *_r = NULL;
  190. else {
  191. *_r = (rr_t*)cds_malloc(sizeof(rr_t));
  192. if (!*_r) {
  193. ERROR_LOG("serialize_route(): can't allocate memory\n");
  194. return -1;
  195. }
  196. (*_r)->r2 = NULL;
  197. (*_r)->params = NULL;
  198. (*_r)->next = NULL;
  199. }
  200. }
  201. else { /* store route */
  202. if (*_r) do_it = 1;
  203. else do_it = 0;
  204. if (serialize_int(ss, &do_it) != 0) return -1;
  205. }
  206. if (do_it) {
  207. rr_t *r = *_r;
  208. str s = { r->nameaddr.name.s, r->len };
  209. int delta = r->nameaddr.uri.s - r->nameaddr.name.s;
  210. res = serialize_str(ss, &s) | res;
  211. res = serialize_int(ss, &r->nameaddr.name.len) | res;
  212. res = serialize_int(ss, &r->nameaddr.uri.len) | res;
  213. res = serialize_int(ss, &r->nameaddr.len) | res;
  214. res = serialize_int(ss, &delta) | res;
  215. if (is_input_sstream(ss)) {
  216. r->nameaddr.name.s = s.s;
  217. r->nameaddr.uri.s = s.s + delta;
  218. }
  219. /* !!! optimalized strings - use carefuly !!! */
  220. /*res = serialize_str(ss, &r->nameaddr.name) | res;
  221. res = serialize_str(ss, &r->nameaddr.uri) | res;
  222. res = serialize_int(ss, &r->nameaddr.len) | res;*/
  223. /* ??? res = serialize_r2(ss, &r->nameaddr.params) | res; ??? */
  224. res = serialize_params(ss, &r->params) | res;
  225. res = serialize_int(ss, &r->len) | res;
  226. TRACE_LOG("ROUTE: rlen=%d name=%.*s, uri=%.*s\n len=%d WHOLE=%.*s\n",
  227. r->len,
  228. FMT_STR(r->nameaddr.name),
  229. FMT_STR(r->nameaddr.uri),
  230. r->nameaddr.len,
  231. r->nameaddr.len, r->nameaddr.name.s
  232. );
  233. }
  234. return res;
  235. }
  236. #endif
  237. /*static void trace_dlg(const char *s, dlg_t *d)
  238. {
  239. rr_t *r;
  240. TRACE_LOG("%s: callid = %.*s \nrem tag = %.*s \nloc tag = %.*s\n"
  241. "loc uri = %.*s\n rem uri = %.*s\n rem target = %.*s\n"
  242. "loc_cseq = %d rem_cseq = %d\n",
  243. s,
  244. FMT_STR(d->id.call_id),
  245. FMT_STR(d->id.rem_tag),
  246. FMT_STR(d->id.loc_tag),
  247. FMT_STR(d->loc_uri),
  248. FMT_STR(d->rem_uri),
  249. FMT_STR(d->rem_target),
  250. d->loc_seq.value,
  251. d->rem_seq.value
  252. );
  253. r = d->route_set;
  254. while (r) {
  255. TRACE_LOG(" ... name = %.*s\n uri = %.*s",
  256. FMT_STR(r->nameaddr.name),
  257. FMT_STR(r->nameaddr.uri));
  258. r = r->next;
  259. }
  260. }*/
  261. int serialize_dlg(sstream_t *ss, dlg_t *dlg)
  262. {
  263. int res = 0;
  264. if (is_input_sstream(ss)) {
  265. memset(dlg, 0, sizeof(*dlg));
  266. }
  267. res = serialize_str(ss, &dlg->id.call_id) | res;
  268. res = serialize_str(ss, &dlg->id.rem_tag) | res;
  269. res = serialize_str(ss, &dlg->id.loc_tag) | res;
  270. res = serialize_uint(ss, &dlg->loc_seq.value) | res;
  271. res = serialize_uchar(ss, &dlg->loc_seq.is_set) | res;
  272. res = serialize_uint(ss, &dlg->rem_seq.value) | res;
  273. res = serialize_uchar(ss, &dlg->rem_seq.is_set) | res;
  274. res = serialize_str(ss, &dlg->loc_uri) | res;
  275. res = serialize_str(ss, &dlg->rem_uri) | res;
  276. res = serialize_str(ss, &dlg->rem_target) | res;
  277. res = serialize_uchar(ss, &dlg->secure) | res;
  278. res = serialize_dlg_state(ss, &dlg->state) | res;
  279. res = serialize_route_set(ss, &dlg->route_set) | res;
  280. if ((res == 0) && (is_input_sstream(ss))) {
  281. /* tmb.w_calculate_hooks(dlg); */
  282. res = tmb.calculate_hooks(dlg);
  283. if (res < 0) {
  284. ERROR_LOG("error during calculate_hooks (%d)!\n", res);
  285. }
  286. }
  287. return res;
  288. }
  289. int dlg2str(dlg_t *dlg, str *dst_str)
  290. {
  291. int res = 0;
  292. sstream_t store;
  293. init_output_sstream(&store, 256);
  294. if (serialize_dlg(&store, dlg) != 0) {
  295. ERROR_LOG("can't serialize dialog\n");
  296. res = -1;
  297. }
  298. else {
  299. if (get_serialized_sstream(&store, dst_str) != 0) {
  300. ERROR_LOG("can't get serialized dialog data\n");
  301. res = -1;
  302. }
  303. }
  304. destroy_sstream(&store);
  305. return res;
  306. }
  307. int str2dlg(const str *s, dlg_t *dst_dlg)
  308. {
  309. int res = 0;
  310. sstream_t store;
  311. if (!s) return -1;
  312. init_input_sstream(&store, s->s, s->len);
  313. if (serialize_dlg(&store, dst_dlg) != 0) {
  314. ERROR_LOG("can't de-serialize dialog\n");
  315. res = -1;
  316. }
  317. destroy_sstream(&store);
  318. return res;
  319. }