diff --git a/core/AmSession.cpp b/core/AmSession.cpp index 7963453c..cb92abf6 100644 --- a/core/AmSession.cpp +++ b/core/AmSession.cpp @@ -1216,16 +1216,23 @@ void AmSession::onFailure(AmSipDialogEventHandler::FailureCause cause, const AmSipRequest *req, const AmSipReply *rpl) { switch (cause) { - case FAIL_REL100: + case FAIL_REL100_421: + case FAIL_REL100_420: if (rpl) { dlg.cancel(); if (dlg.getStatus() < AmSipDialog::Connected) setStopped(); } else if (req) { - dlg.reply(*req, 421, "Extension Required", "", "", + if (cause == FAIL_REL100_421) { + dlg.reply(*req, 421, SIP_REPLY_EXTENSION_REQUIRED, "", "", SIP_HDR_COLSP(SIP_HDR_REQUIRE) SIP_EXT_100REL CRLF); - if (dlg.getStatus() < AmSipDialog::Connected) - setStopped(); + } else { + dlg.reply(*req, 420, SIP_REPLY_BAD_EXTENSION, "", "", + SIP_HDR_COLSP(SIP_HDR_UNSUPPORTED) SIP_EXT_100REL CRLF); + } + /* finally, stop session if running */ + if (dlg.getStatus() < AmSipDialog::Connected) + setStopped(); } break; default: diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp index 3a79d3ac..fa73dc1a 100644 --- a/core/AmSipDialog.cpp +++ b/core/AmSipDialog.cpp @@ -173,19 +173,17 @@ int AmSipDialog::rel100OnRequestIn(const AmSipRequest& req) SIP_EXT_100REL))) { ERROR("'" SIP_EXT_100REL "' extension required, but not advertised" " by peer.\n"); - if (hdl) hdl->onFailure(FAIL_REL100, &req, 0); + if (hdl) hdl->onFailure(FAIL_REL100_421, &req, 0); return 0; // has been replied } break; // 100rel required case REL100_DISABLED: // TODO: shouldn't this be part of a more general check in SEMS? - if (key_in_list(getHeader(req.hdrs,SIP_HDR_REQUIRE),SIP_EXT_100REL)) - reply_error(req, 420, SIP_REPLY_BAD_EXTENSION, - SIP_HDR_COLSP(SIP_HDR_UNSUPPORTED) SIP_EXT_100REL CRLF, - next_hop_for_replies ? next_hop_ip : "", - next_hop_for_replies ? next_hop_port : 0); - return 0; + if (key_in_list(getHeader(req.hdrs,SIP_HDR_REQUIRE),SIP_EXT_100REL)) { + if (hdl) hdl->onFailure(FAIL_REL100_420, &req, 0); + return 0; // has been replied + } break; default: @@ -416,7 +414,7 @@ int AmSipDialog::rel100OnReplyIn(const AmSipReply &reply) !reply.rseq) { ERROR(SIP_EXT_100REL " not supported or no positive RSeq value in " "(reliable) 1xx.\n"); - if (hdl) hdl->onFailure(FAIL_REL100, 0, &reply); + if (hdl) hdl->onFailure(FAIL_REL100_421, 0, &reply); } else { DBG(SIP_EXT_100REL " now active.\n"); if (hdl) hdl->onInvite1xxRel(reply); @@ -436,7 +434,7 @@ int AmSipDialog::rel100OnReplyIn(const AmSipReply &reply) } else if (reliable_1xx && reply.method==SIP_METH_PRACK) { if (300 <= reply.code) { // if PRACK fails, tear down session - if (hdl) hdl->onFailure(FAIL_REL100, 0, &reply); + if (hdl) hdl->onFailure(FAIL_REL100_421, 0, &reply); } else if (200 <= reply.code) { if (hdl) hdl->onPrack2xx(reply); } else { diff --git a/core/AmSipDialog.h b/core/AmSipDialog.h index 52f2a362..baceb2ca 100644 --- a/core/AmSipDialog.h +++ b/core/AmSipDialog.h @@ -110,8 +110,10 @@ class AmSipDialogEventHandler virtual void onPrack2xx(const AmSipReply &)=0; enum FailureCause { - FAIL_REL100, -#define FAIL_REL100 AmSipDialogEventHandler::FAIL_REL100 + FAIL_REL100_421, +#define FAIL_REL100_421 AmSipDialogEventHandler::FAIL_REL100_421 + FAIL_REL100_420, +#define FAIL_REL100_420 AmSipDialogEventHandler::FAIL_REL100_420 }; virtual void onFailure(FailureCause cause, const AmSipRequest*, const AmSipReply*)=0; diff --git a/core/AmSipHeaders.h b/core/AmSipHeaders.h index 28ac91a0..cb8543cc 100644 --- a/core/AmSipHeaders.h +++ b/core/AmSipHeaders.h @@ -52,4 +52,5 @@ #define SIP_REPLY_SERVER_INTERNAL_ERROR "Server Internal Error" #define SIP_REPLY_BAD_EXTENSION "Bad Extension" +#define SIP_REPLY_EXTENSION_REQUIRED "Extension Required" #endif /* __AMSIPHEADERS_H__ */