📄 driver.cpp
字号:
event.id = CALL_ACCEPTED; session->queEvent(&event); } if(sdp) delString(sdp); if(msg) osip_message_free(msg); if(local_sdp) sdp_message_free(local_sdp); if(remote_sdp) sdp_message_free(remote_sdp); break; case EXOSIP_CALL_GLOBALFAILURE: case EXOSIP_CALL_SERVERFAILURE: session = getCall(sevent->cid); if(!session) break; memset(&event, 0, sizeof(event)); event.id = CALL_FAILURE; session->postEvent(&event); break; case EXOSIP_CALL_ACK: session = getCall(sevent->cid); if(!session) { slog.warn("sip: call ack for non-existant call");killit: eXosip_lock(); eXosip_call_terminate(sevent->cid, sevent->did); eXosip_unlock(); break; } memset(&event, 0, sizeof(event)); event.id = CALL_ACCEPTED; session->postEvent(&event); break; case EXOSIP_CALL_MESSAGE_REQUESTFAILURE: case EXOSIP_CALL_REQUESTFAILURE: session = getCall(sevent->cid); if(!session) break; memset(&event, 0, sizeof(event)); switch(sevent->response->status_code) { case AUTH_REQUIRED: getAuthentication(session); eXosip_lock(); eXosip_automatic_action(); eXosip_unlock(); break; case UNAUTHORIZED: getAuthentication(session); break; case BUSY_HERE: event.id = DIAL_BUSY; break; case REQ_TIMEOUT: event.id = DIAL_TIMEOUT; break; case NOT_FOUND: case NOT_ALLOWED: case NOT_ACCEPTABLE: case FORBIDDEN: case BAD_REQ: case TEMP_UNAVAILABLE: event.id = DIAL_INVALID; default: event.id = DIAL_FAILED; } if(event.id) session->postEvent(&event); break; case EXOSIP_CALL_INVITE: if(!sevent->request) break; if(sevent->cid < 1 && sevent->did < 1) break; remote_media = NULL; local_media = NULL; conn = NULL; remote_sdp = NULL; local_sdp = NULL; display = NULL; caller = NULL; dialed = NULL; local_uri = NULL; remote_uri = NULL; from = NULL; to = NULL; sdp = NULL; msg = NULL; session = NULL; osip_to_to_str(sevent->request->to, &local_uri); if(!local_uri) goto clear; osip_from_to_str(sevent->request->from, &remote_uri); if(!remote_uri) goto clear; osip_to_init(&to); osip_to_parse(to, local_uri); if(!to) goto clear; if(to->url != NULL && to->url->username != NULL) dialed = to->url->username; osip_from_init(&from); osip_from_parse(from, remote_uri); if(!from) goto clear; if(from->url != NULL && from->url->username != NULL) caller = from->url->username; display = osip_from_get_displayname(from); if(display && *display == '\"') { ++display; p = (char *)strrchr(display, '\"'); if(p) *p = 0; } else if(!display) display = caller; img = useImage(); if(to->url->port && stricmp(to->url->port, "5060")) snprintf(buf, sizeof(buf), "sip.%s:%s", to->url->host, to->url->port); else snprintf(buf, sizeof(buf), "sip.%s", to->url->host); proxy = (Registry *)img->getPointer(buf); if(proxy && !proxy->isActive()) goto sip404; if(from->url->port && stricmp(from->url->port, "5060")) snprintf(buf, sizeof(buf), "sip.%s:%s", from->url->host, from->url->port); else snprintf(buf, sizeof(buf), "sip.%s", from->url->host); peer = (Registry *)img->getPointer(buf); if(peer && !peer->isActive()) goto sip404; snprintf(buf, sizeof(buf), "uri.%s", dialed); reg = (Registry *)img->getPointer(buf); reg_inband = dtmf_inband; reg_payload = dtmf_negotiate; auth = "none"; if(peer && !reg) auth = peer->type; else if(reg) auth = reg->type; if(!strnicmp(auth, "ext", 3)) auth = "peer"; if(!stricmp(auth, "friend") && peer) auth = "peer"; else if(!stricmp(auth, "friend") && proxy) auth = "proxy"; else if(!stricmp(auth, "friend")) reg = NULL; if(proxy && !reg && !stricmp(auth, "proxy")) reg = proxy; if(peer && !reg && !stricmp(auth, "peer")) reg = peer; if(reg && !peer && !stricmp(auth, "peer")) reg = NULL; if(reg && !peer && !stricmp(auth, "user")) reg = NULL; if(reg && !proxy && !stricmp(auth, "proxy")) reg = NULL; if(reg) { if(!reg->isActive()) goto sip404; scr = img->getScript(reg->scr->name); cp = reg->dtmf; if(cp && *cp) { if(!stricmp(cp, "info") || !stricmp(cp, "sipinfo")) reg_inband = false; else if(atoi(cp) < 255 && atoi(cp) > 10) reg_payload = atoi(cp); else if(stricmp(cp, "2833") && stricmp(cp, "rfc2833")) reg_payload = 0; } } else goto sip404; if(!scr) { slog.warn("sip: unknown uri %s dialed", dialed);sip404: endImage(img); eXosip_lock(); eXosip_call_send_answer(sevent->tid, 404, NULL); eXosip_unlock(); goto clear; } s = getIdle(); if(!s) { slog.warn("sip: no timeslots available"); endImage(img); eXosip_lock(); eXosip_call_send_answer(sevent->tid, 480, NULL); eXosip_unlock(); goto clear; } session = (Session *)(s); session->dtmf_sipinfo = info_negotiate; if(reg->dtmf && !stricmp(reg->dtmf, "info")) session->dtmf_sipinfo = true; else if(reg->dtmf && !stricmp(reg->dtmf, "sipinfo")) session->dtmf_sipinfo = true; else if(reg->dtmf) session->dtmf_sipinfo = false; cp = getLast("localip"); if(reg->address) { InetAddress host(reg->address); snprintf(cbuf, sizeof(cbuf), "%s", inet_ntoa(host.getAddress())); session->setConst("session.ip_public", cbuf); } else session->setConst("session.ip_public", cp); session->setConst("session.ip_local", cp); session->cid = sevent->cid; session->did = sevent->did; session->setConst("session.info", auth); session->setConst("session.dialed", dialed); session->setConst("session.caller", caller); session->setConst("session.display", display); if(from->url->port && stricmp(from->url->port, "5060")) snprintf(buf, sizeof(buf), "sip:%s@%s:%s", from->url->username, from->url->host, from->url->port); else snprintf(buf, sizeof(buf), "sip:%s@%s", from->url->username, from->url->host); session->setConst("session.uri_remote", buf); if(reg) { snprintf(cbuf, sizeof(cbuf), "sipreg.%d", reg->regid); session->setConst("session.registry", cbuf); session->setConst("session.uri_server", reg->proxy); session->setConst("session.uri_local", reg->contact); if(reg->encoding) session->setEncoding(reg->encoding, reg->framing); } else { auth = "anon"; snprintf(buf, sizeof(buf), "sip:anon@%s", getLast("interface")); p = strrchr(buf, ':'); if(p && !stricmp(p, ":5060")) *p = 0; session->setConst("session.uri_local", buf); } session->local_address = getLast("localip"); snprintf(buf, sizeof(buf), "%s:%d", inet_ntoa(session->local_address.getAddress()), session->getLocalPort()); session->setConst("session.rtp_local", buf); memset(&event, 0, sizeof(event)); if(!stricmp(auth, "peer")) event.id = START_INCOMING; else event.id = START_DIRECT; event.start.img = img; event.start.scr = scr; eXosip_lock(); remote_sdp = eXosip_get_sdp_info(sevent->request); eXosip_unlock(); if(!remote_sdp) { eXosip_unlock(); eXosip_call_send_answer(sevent->tid, 400, NULL); eXosip_unlock(); goto clear; } eXosip_lock(); conn = eXosip_get_audio_connection(remote_sdp); remote_media = eXosip_get_audio_media(remote_sdp); eXosip_unlock(); if(!remote_media || !remote_media->m_port) {sip415: eXosip_lock(); eXosip_call_send_answer(sevent->tid, 415, NULL); eXosip_unlock(); goto clear; } session->remote_address = conn->c_addr; session->remote_port = atoi(remote_media->m_port); snprintf(buf, sizeof(buf), "%s:%d", inet_ntoa(session->remote_address.getAddress()), session->getRemotePort()); session->setConst("session.rtp_remote", buf); cp = session->getSymbol("session.ip_public"); sdp = newString("", 4096); snprintf(sdp, 4096, "v=0\r\n" "o=bayonne 0 0 IN IP4 %s\r\n" "s=conversation\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n", cp, cp); session->data_payload = data_negotiate; session->dtmf_payload = 0; mpos = 0; switch(session->info.encoding) { case mulawAudio: session->data_payload = 0; data_rtpmap = "PCMU/8000/1"; break; case alawAudio: session->data_payload = 8; data_rtpmap = "PCMA/8000/1"; break; case speexVoice: session->data_payload = 97; data_rtpmap = "SPEEX/8000/1"; break; case gsmVoice: session->data_payload = 3; data_rtpmap = "GSM/8000/1"; break; case pcm16Stereo: session->data_payload = 98; data_rtpmap = "L16/11025/2"; session->info.rate = 11025; break; case pcm16Mono: switch(session->info.rate) { case 16000: session->data_payload = 98; data_rtpmap = "L16/16000/1"; break; default: session->info.rate = 8000; session->data_payload = 97; data_rtpmap = "L16/8000/1"; } default: break; } audio_payload = NULL; while(!osip_list_eol(remote_sdp->m_medias, mpos)) { remote_media = (sdp_media_t *)osip_list_get(remote_sdp->m_medias, mpos++); if(!remote_media) continue; if(!stricmp(remote_media->m_media, "audio") && !audio_payload) audio_media = remote_media; else audio_media = NULL; audio_payload = NULL; tmp = NULL; pos = 0; while(!osip_list_eol(remote_media->a_attributes, pos)) { attr = (sdp_attribute_t *)osip_list_get(remote_media->a_attributes, pos++); if(!attr) continue; tmp = attr->a_att_value; if(!tmp) continue; if(stricmp(attr->a_att_field, "rtpmap")) continue; adp = tmp; tmp = strchr(tmp, ' '); if(!tmp) { adp = NULL; continue; } while(isspace(*tmp)) ++tmp; if(!strnicmp(tmp, "telephone-event/", 16)) { session->dtmf_payload = atoi(adp); continue; } if(!strnicmp(tmp, data_rtpmap, strlen(tmp))) { audio_payload = adp; session->data_payload = atoi(adp); } } pos = 0; while(!osip_list_eol(remote_media->m_payloads, pos) && !audio_payload) { tmp = (char *)osip_list_get(remote_media->m_payloads, pos++); if(!tmp || !*tmp) continue; if(reg_payload && atoi(tmp) == reg_payload) { session->dtmf_payload = dtmf_negotiate; reg_inband = false; } if(audio_media && atoi(tmp) == session->data_payload) audio_payload = tmp; } } session->dtmf_inband = reg_inband; if(!audio_payload) goto sip415; snprintf(cbuf, sizeof(cbuf), "a=rtpmap:%d %s", session->data_payload, data_rtpmap); session->setConst("session.rtpmap", cbuf); data_rtpmap = session->getSymbol("session.rtpmap"); if(session->dtmf_payload) snprintf(cbuf, sizeof(cbuf), "m=audio %d RTP/AVP %d %d\r\n" "%s\r\n", session->getLocalPort(), session->data_payload, session->dtmf_payload, data_rtpmap); else snprintf(cbuf, sizeof(cbuf), "m=audio %d RTP/AVP %d\r\n" "%s\r\n", session->getLocalPort(), session->data_payload, data_rtpmap); addString(sdp, 4096, cbuf); if(session->dtmf_sipinfo) session->setConst("session.dtmfmode", "info"); else if(session->dtmf_payload) session->setConst("session.dtmfmode", "2833"); else session->setConst("session.dtmfmode", "none"); if(session->dtmf_payload) { snprintf(cbuf, sizeof(cbuf), "a=rtpmap:%d telephone-events/8000\r\n", session->dtmf_payload); addString(sdp, 4096, cbuf); } if(!s->postEvent(&event)) goto sip404; eXosip_lock(); eXosip_call_send_answer(sevent->tid, 180, NULL); eXosip_unlock(); eXosip_lock(); eXosip_call_build_answer(sevent->tid, 200, &msg); if(!msg) goto sip404; osip_message_set_require(msg, "100rel"); osip_message_set_header(msg, "RSeq", "1"); osip_message_set_body(msg, sdp, strlen(sdp)); osip_message_set_content_type(msg, "application/sdp"); eXosip_call_send_answer(sevent->tid, 183, msg); eXosip_unlock(); session = NULL;clear: if(session) add(session); eXosip_lock();// if(msg)// osip_message_free(msg); if(sdp) delString(sdp); if(remote_sdp) sdp_message_free(remote_sdp); if(local_sdp) sdp_message_free(local_sdp); if(from) osip_from_free(from); if(to) osip_to_free(to); if(remote_uri) osip_free(remote_uri); if(local_uri) osip_free(local_uri); eXosip_unlock(); default: break; } eXosip_event_free(sevent); }}} // namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -