void AmSession::process(AmEvent* ev) { CALL_EVENT_H(process,ev); DBG("AmSession::process\n"); AmSipEvent* sip_ev = dynamic_cast<AmSipEvent*>(ev); if(sip_ev){ DBG("Session received SIP Event\n"); onSipEvent(sip_ev); return; } AmAudioEvent* audio_ev = dynamic_cast<AmAudioEvent*>(ev); if(audio_ev && (audio_ev->event_id == AmAudioEvent::cleared)){ setStopped(); return; } AmDtmfEvent* dtmf_ev = dynamic_cast<AmDtmfEvent*>(ev); if (dtmf_ev) { DBG("Session received DTMF, event = %d, duration = %d\n", dtmf_ev->event(), dtmf_ev->duration()); onDtmf(dtmf_ev->event(), dtmf_ev->duration()); return; } AmRtpTimeoutEvent* timeout_ev = dynamic_cast<AmRtpTimeoutEvent*>(ev); if(timeout_ev){ onRtpTimeout(); return; } }
void DSMCallCalleeSession::onSipReply(const AmSipRequest& req, const AmSipReply& reply, AmBasicSipDialog::Status old_dlg_status) { // call event handlers where it is not done TransMap::iterator t = relayed_req.find(reply.cseq); bool fwd = t != relayed_req.end(); DBG("onSipReply: %i %s (fwd=%i)\n",reply.code,reply.reason.c_str(),fwd); DBG("onSipReply: content-type = %s\n",reply.body.getCTStr().c_str()); if(fwd) { CALL_EVENT_H(onSipReply, req, reply, old_dlg_status); } if (NULL == auth.get()) { AmB2BCalleeSession::onSipReply(req, reply, old_dlg_status); return; } unsigned int cseq_before = dlg->cseq; if (!auth->onSipReply(req, reply, old_dlg_status)) { AmB2BCalleeSession::onSipReply(req, reply, old_dlg_status); } else { if (cseq_before != dlg->cseq) { DBG("uac_auth consumed reply with cseq %d and resent with cseq %d; " "updating relayed_req map\n", reply.cseq, cseq_before); updateUACTransCSeq(reply.cseq, cseq_before); } } }
void AmSession::onSipReply(const AmSipReply& reply) { CALL_EVENT_H(onSipReply,reply); int status = dlg.getStatus(); dlg.updateStatus(reply); if (status != dlg.getStatus()) DBG("Dialog status changed %s -> %s (stopped=%s) \n", AmSipDialog::status2str[status], AmSipDialog::status2str[dlg.getStatus()], sess_stopped.get() ? "true" : "false"); else DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[status], sess_stopped.get() ? "true" : "false"); if (negotiate_onreply) { if(status < AmSipDialog::Connected){ switch(dlg.getStatus()){ case AmSipDialog::Connected: try { acceptAudio(reply.body,reply.hdrs); if(detached.get() && !getStopped()){ onSessionStart(reply); if(input || output) AmMediaProcessor::instance()->addSession(this, callgroup); else { ERROR("missing audio input and/or ouput.\n"); } } }catch(const AmSession::Exception& e){ ERROR("could not connect audio!!!\n"); ERROR("%i %s\n",e.code,e.reason.c_str()); dlg.bye(); setStopped(); break; } break; case AmSipDialog::Pending: switch(reply.code){ case 180: break;//TODO: local ring tone. case 183: break;//TODO: remote ring tone. default: break;// continue waiting. } } } } }
void AmSession::onSipRequest(const AmSipRequest& req) { CALL_EVENT_H(onSipRequest,req); DBG("onSipRequest: method = %s\n",req.method.c_str()); updateRefreshMethod(req.hdrs); if(req.method == SIP_METH_INVITE){ try { onInvite(req); } catch(const string& s) { ERROR("%s\n",s.c_str()); setStopped(); dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR); } catch(const AmSession::Exception& e) { ERROR("%i %s\n",e.code,e.reason.c_str()); setStopped(); dlg->reply(req, e.code, e.reason, NULL, e.hdrs); } } else if(req.method == SIP_METH_ACK){ return; } else if( req.method == SIP_METH_BYE ){ dlg->reply(req,200,"OK"); onBye(req); } else if( req.method == SIP_METH_CANCEL ){ onCancel(req); } else if( req.method == SIP_METH_INFO ){ const AmMimeBody* dtmf_body = req.body.hasContentType("application/dtmf-relay"); if (dtmf_body) { string dtmf_body_str((const char*)dtmf_body->getPayload(), dtmf_body->getLen()); postDtmfEvent(new AmSipDtmfEvent(dtmf_body_str)); dlg->reply(req, 200, "OK"); } else { dlg->reply(req, 415, "Unsupported Media Type"); } } else if (req.method == SIP_METH_PRACK) { // TODO: SDP dlg->reply(req, 200, "OK"); // TODO: WARN: only include latest SDP if req.rseq == dlg->rseq (latest 1xx) } else { dlg->reply(req, 501, "Not implemented"); } }
void AmSession::process(AmEvent* ev) { CALL_EVENT_H(process,ev); DBG("AmSession processing event\n"); if (ev->event_id == E_SYSTEM) { AmSystemEvent* sys_ev = dynamic_cast<AmSystemEvent*>(ev); if(sys_ev){ DBG("Session received system Event\n"); onSystemEvent(sys_ev); return; } } AmSipEvent* sip_ev = dynamic_cast<AmSipEvent*>(ev); if(sip_ev){ (*sip_ev)(dlg); return; } AmAudioEvent* audio_ev = dynamic_cast<AmAudioEvent*>(ev); if(audio_ev){ onAudioEvent(audio_ev); return; } AmDtmfEvent* dtmf_ev = dynamic_cast<AmDtmfEvent*>(ev); if (dtmf_ev) { DBG("Session received DTMF, event = %d, duration = %d\n", dtmf_ev->event(), dtmf_ev->duration()); onDtmf(dtmf_ev->event(), dtmf_ev->duration()); return; } AmRtpTimeoutEvent* timeout_ev = dynamic_cast<AmRtpTimeoutEvent*>(ev); if(timeout_ev){ onRtpTimeout(); return; } #ifdef WITH_ZRTP AmZRTPProtocolEvent* zrtp_p_ev = dynamic_cast<AmZRTPProtocolEvent*>(ev); if(zrtp_p_ev){ onZRTPProtocolEvent((zrtp_protocol_event_t)zrtp_p_ev->event_id, zrtp_p_ev->stream_ctx); return; } AmZRTPSecurityEvent* zrtp_s_ev = dynamic_cast<AmZRTPSecurityEvent*>(ev); if(zrtp_s_ev){ onZRTPSecurityEvent((zrtp_security_event_t)zrtp_s_ev->event_id, zrtp_s_ev->stream_ctx); return; } #endif }
void AmSession::onSipRequest(const AmSipRequest& req) { CALL_EVENT_H(onSipRequest,req); dlg.updateStatus(req); DBG("onSipRequest: method = %s\n",req.method.c_str()); if(req.method == "INVITE"){ onInvite(req); if(detached.get() && !getStopped()){ onSessionStart(req); if(input || output) AmMediaProcessor::instance()->addSession(this, callgroup); else { ERROR("missing audio input and/or ouput.\n"); } } } else if( req.method == "BYE" ){ dlg.reply(req,200,"OK"); onBye(req); } else if( req.method == "CANCEL" ){ dlg.reply(req,200,"OK"); onCancel(); } else if( req.method == "INFO" ){ if ((strip_header_params(getHeader(req.hdrs, "Content-Type")) =="application/dtmf-relay")|| (strip_header_params(getHeader(req.hdrs, "c")) =="application/dtmf-relay")){ postDtmfEvent(new AmSipDtmfEvent(req.body)); dlg.reply(req, 200, "OK"); } } }
void AmSession::onSipEvent(AmSipEvent* sip_ev) { CALL_EVENT_H(onSipEvent,sip_ev); AmSipRequestEvent* req_ev = dynamic_cast<AmSipRequestEvent*>(sip_ev); if(req_ev) { onSipRequest(req_ev->req); return; } AmSipReplyEvent* reply_ev = dynamic_cast<AmSipReplyEvent*>(sip_ev); if(reply_ev) { onSipReply(reply_ev->reply); return; } ERROR("Unknown SIP Event"); }
void AmSession::onSipReply(const AmSipRequest& req, const AmSipReply& reply, AmBasicSipDialog::Status old_dlg_status) { CALL_EVENT_H(onSipReply, req, reply, old_dlg_status); updateRefreshMethod(reply.hdrs); if (dlg->getStatus() < AmSipDialog::Connected && reply.code == 180) { onRinging(reply); } if (old_dlg_status != dlg->getStatus()) { DBG("Dialog status changed %s -> %s (stopped=%s) \n", AmBasicSipDialog::getStatusStr(old_dlg_status), dlg->getStatusStr(), sess_stopped.get() ? "true" : "false"); } else { DBG("Dialog status stays %s (stopped=%s)\n", AmBasicSipDialog::getStatusStr(old_dlg_status), sess_stopped.get() ? "true" : "false"); } }
void AmSession::onSendReply(const AmSipRequest& req, AmSipReply& reply, int& flags) { CALL_EVENT_H(onSendReply,req,reply,flags); }
void AmSession::onSendRequest(AmSipRequest& req, int& flags) { CALL_EVENT_H(onSendRequest,req,flags); }
void AmSession::onSendReply(const AmSipRequest& req, unsigned int code, const string& reason, const string& content_type, const string& body, string& hdrs) { CALL_EVENT_H(onSendReply,req,code,reason,content_type,body,hdrs); }
void AmSession::onSendRequest(const string& method, const string& content_type, const string& body, string& hdrs, unsigned int cseq) { CALL_EVENT_H(onSendRequest,method,content_type,body,hdrs,cseq); }