ht4-dialog.dox 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /**
  2. * @ingroup libosip2 The GNU oSIP stack
  3. * @defgroup howto_dialog How-To manage dialogs.
  4. * @section howto_dialog1 Description.
  5. Full API is there:
  6. ~~~~~~~{.c}
  7. #include <osip2/osip_dialog.h>
  8. ~~~~~~~
  9. Dialog management is a powerful facility given by oSIP. This feature is
  10. needed by SIP end point who has the capability to answer calls. (i.e.
  11. answering 200 OK to an INVITE).
  12. A Dialog is a context for a call establishment in oSIP. It's not useless
  13. to say that ONE invite request can lead to several call establishment.
  14. This can happen if your call has been forked by a proxy and several
  15. user agent was contacted and replied at the same time. It is true that
  16. this case won't probably happen several times a month...
  17. There is two ways of creating a dialog. In one case, you are the CALLER
  18. and in the other case, you will be the CALLEE.
  19. * @section howto_dialog2 Creating a dialog as a CALLER.
  20. In this case, you have to create a dialog each time you receive
  21. an answer with a code between 101 and 299. The best place in oSIP to
  22. actually create a dialog is of course in the callback that announce
  23. such SIP messages. Of course, each time you receive a response, you have
  24. to check for an existing dialog associated to this INVITE that can have
  25. been created by earlier SIP answer coming from the same User Agent. The
  26. code in the callback will look like the following:
  27. ~~~~~~~{.c}
  28. void cb_rcv1xx(osip_transaction_t *tr,osip_message_t *sip)
  29. {
  30. osip_dialog_t *dialog;
  31. if (MSG_IS_RESPONSEFOR(sip, "INVITE")&&!MSG_TEST_CODE(sip, 100))
  32. {
  33. dialog = my_application_search_existing_dialog(sip);
  34. if (dialog==NULL) //NO EXISTING DIALOG
  35. {
  36. i = osip_dialog_init_as_uac(&dialog, sip);
  37. my_application_add_existing_dialog(dialog);
  38. }
  39. }
  40. else
  41. {
  42. //no dialog establishment for other REQUEST
  43. }
  44. }
  45. ~~~~~~~
  46. * @section howto_dialog3 Creating a dialog as a CALLEE
  47. In this case, you will have to create a dialog upon receiving the first
  48. transmission of the INVITE request. The correct place to do that is inside
  49. the callback previously registered to announce new INVITE. First, you will
  50. build a SIP answer like 180 or 200 and you'll be able to create a dialog
  51. by calling the following code:
  52. ~~~~~~~{.c}
  53. osip_dialog_t *dialog;
  54. osip_dialog_init_as_uas(&dialog, original_invite, response_that_you_build);
  55. ~~~~~~~
  56. To make things working, you MUST create a VALID response: do not
  57. forget to create a new tag and put it in the 'To' header. The dialog
  58. management heavily depends on this tag.
  59. * @section howto_dialog4 Matching REQUEST against existing dialog.
  60. ~~~~~~~{.c}
  61. if (osip_dialog_match_as_uas (jd->d_dialog, evt->sip) == 0)
  62. break;
  63. ~~~~~~~
  64. * @section howto_dialog5 Matching cancel against an INVITE.
  65. Here is code that I use in eXosip2 to match incoming CANCEL against
  66. previous received INVITE. This is a bit different than dialog because
  67. CANCEL match a specific INVITE transaction, not a dialog:
  68. ~~~~~~~{.c}
  69. static int
  70. _cancel_match_invite (osip_transaction_t * invite, osip_message_t * cancel)
  71. {
  72. osip_generic_param_t *br;
  73. osip_generic_param_t *br2;
  74. osip_via_t *via;
  75. osip_via_param_get_byname (invite->topvia, "branch", &br);
  76. via = osip_list_get (&cancel->vias, 0);
  77. if (via == NULL)
  78. return OSIP_SYNTAXERROR; // request without via?
  79. osip_via_param_get_byname (via, "branch", &br2);
  80. if (br != NULL && br2 == NULL)
  81. return OSIP_UNDEFINED_ERROR;
  82. if (br2 != NULL && br == NULL)
  83. return OSIP_UNDEFINED_ERROR;
  84. if (br2 != NULL && br != NULL) { // compliant UA :)
  85. if (br->gvalue != NULL && br2->gvalue != NULL && 0 == strcmp (br->gvalue, br2->gvalue))
  86. return OSIP_SUCCESS;
  87. return OSIP_UNDEFINED_ERROR;
  88. }
  89. /old backward compatibility mechanism
  90. if (0 != osip_call_id_match (invite->callid, cancel->call_id))
  91. return OSIP_UNDEFINED_ERROR;
  92. if (0 != osip_to_tag_match (invite->to, cancel->to))
  93. return OSIP_UNDEFINED_ERROR;
  94. if (0 != osip_from_tag_match (invite->from, cancel->from))
  95. return OSIP_UNDEFINED_ERROR;
  96. if (0 != osip_via_match (invite->topvia, via))
  97. return OSIP_UNDEFINED_ERROR;
  98. return OSIP_SUCCESS;
  99. }
  100. ~~~~~~~
  101. */