📄 driver.cpp
字号:
char *p; char *uri; long mult = 60000; osip_message_t *msg = NULL; if(!ScriptChecks::useKeywords(line, "=uri=timeout=server=proxy=userid=secret=type=realm=dtmf=public=encoding=framing")) return "invalid keywords for sip, use uri, timeout, proxy, userid, secret, port"; reg->active = false; reg->protocol = "sip"; reg->iface = getLast("interface"); reg->uri = ScriptChecks::findKeyword(line, "uri"); reg->address = ScriptChecks::findKeyword(line, "public"); reg->hostid = ScriptChecks::findKeyword(line, "proxy"); reg->userid = ScriptChecks::findKeyword(line, "userid"); reg->secret = ScriptChecks::findKeyword(line, "secret"); reg->realm = ScriptChecks::findKeyword(line, "realm"); reg->type = ScriptChecks::findKeyword(line, "type"); reg->dtmf = ScriptChecks::findKeyword(line, "dtmf"); reg->encoding = ScriptChecks::findKeyword(line, "encoding"); cp = ScriptChecks::findKeyword(line, "framing"); if(!cp || !reg->encoding) cp = "0"; reg->framing = atol(cp); reg->add(img); if(!reg->dtmf) reg->dtmf = getLast("dtmf"); if(!reg->dtmf) reg->dtmf = "auto"; if(!reg->type) reg->type = getLast("peering"); if(!reg->hostid || !*reg->hostid) reg->hostid = ScriptChecks::findKeyword(line, "server"); if(!reg->hostid || !*reg->hostid) reg->hostid = getLast("proxy"); if(!reg->hostid || !*reg->hostid) reg->hostid = server->getLast("proxy"); if(!reg->hostid || !*reg->hostid) reg->hostid = server->getLast("server"); if(!reg->hostid || !*reg->hostid) reg->hostid = "localhost"; if(!reg->userid) reg->userid = getLast("userid"); if(!reg->userid) reg->userid = server->getLast("userid"); if(!*reg->userid) reg->userid = NULL; if(!reg->secret) reg->secret = getLast("secret"); if(!reg->secret) reg->secret = server->getLast("secret"); if(!*reg->secret) reg->secret = NULL; if(!cp) cp = getLast("duration"); lcp = cp + strlen(cp) - 1; switch(*lcp) { case 'm': case 'M': mult = 60000; break; case 's': case 'S': mult = 1000; break; case 'h': case 'H': mult = 360000; break; } reg->duration = mult * atol(cp); reg->line = line; reg->scr = scr; // min 3 minutes, as automatic resend is minute prior if(reg->duration < 180000) reg->duration = 180000; cp = scr->name; if(!strnicmp(cp, "sip::", 5)) cp += 5; snprintf(buf, sizeof(buf) - 2, "sip:%s", cp); p = strchr(buf + 4, ':'); if(p) { *(p++) = '.'; cp = strrchr(scr->name, ':'); strcpy(p, cp + 1); } len = strlen(buf) - 3; reg->localid = (const char *)img->getMemory(len); strcpy((char *)reg->localid, buf + 4); if(!reg->userid) reg->userid = reg->localid; len = strlen(buf); buf[len++] = '@'; buf[len] = 0; pos = len; if(reg->address) { cp = strrchr(reg->iface, ':'); if(!cp) cp = ""; snprintf(buf + pos, sizeof(buf) - pos, "%s%s", reg->address, cp); } else setString(buf + pos, sizeof(buf) - pos, reg->iface); len = strlen(buf) + 1; reg->contact = (const char *)img->getMemory(len); strcpy((char *)reg->contact, buf); setString(buf + pos, sizeof(buf) - pos, reg->hostid); p = strrchr(buf + 5, ':'); if(p) *p = 0; len = 8 + strlen(reg->userid) + strlen(reg->hostid); uri = (char *)img->getMemory(len); snprintf(uri, len, "sip:%s@%s", reg->userid, reg->hostid); snprintf(buf, sizeof(buf), "sip:%s", reg->hostid); len = strlen(buf) + 1; reg->proxy = (const char *)img->getMemory(len); strcpy((char *)reg->proxy, buf); if(!reg->uri) reg->uri = uri; slog.debug("register %s as %s on %s", reg->localid, reg->userid, reg->proxy); if(!registry) registry = true; eXosip_lock(); reg->regid = eXosip_register_build_initial_register((char *)reg->uri, (char *)reg->proxy, (char *)reg->contact, reg->duration / 1000, &msg); eXosip_unlock(); if(reg->regid < 0) return "cannot create sip registration"; if(reg->secret) setAuthentication(reg);// osip_message_set_supported(msg, "path"); osip_message_set_header(msg, "Event", "Registration"); osip_message_set_header(msg, "Allow-Events", "presence");/* cp = getLast("transport"); if(cp && !stricmp(cp, "tcp")) eXosip_transport_set(msg, "TCP"); else if(cp && !stricmp(cp, "tls")) eXosip_transport_set(msg, "TLS"); reg->route = ScriptChecks::findKeyword(line, "route"); if(reg->route && reg->route[0]) { char *hdr = osip_strdup(reg->route); osip_message_set_multiple_header(msg, hdr, reg->route); osip_free(hdr); }*/ eXosip_lock(); eXosip_register_send_register(reg->regid, msg); eXosip_unlock(); if(!strnicmp(reg->proxy, "sip:", 4)) snprintf(buf, sizeof(buf), "sip.%s", reg->proxy + 4); else snprintf(buf, sizeof(buf), "sip.%s", reg->proxy); p = strrchr(buf, ':'); if(p && !stricmp(p, ":5060")) *p = 0; img->setPointer(buf, reg); snprintf(buf, sizeof(buf), "sipreg.%d", reg->regid); img->setPointer(buf, reg); snprintf(buf, sizeof(buf), "uri.%s", reg->localid); img->setPointer(buf, reg); img->addRegistration(line); line->scr.registry = reg; return "";}Session *Driver::getCall(int callid){ timeslot_t ts = 0; Session *session; BayonneSession *bs; while(ts < count) { bs = getTimeslot(ts++); if(!bs) continue; session = (Session *)bs; if(session->cid == callid && session->offhook) return session; } return NULL;}void Driver::run(void){ eXosip_event_t *sevent; Event event; char buf[1024]; char cbuf[256]; Registry *reg, *peer, *proxy; Name *scr; ScriptImage *img; const char *cp; const char *caller = NULL; const char *dialed = NULL; const char *display = NULL; BayonneSession *s; Session *session; char *k, *v, *l, *p, *line; osip_from_t *from; osip_to_t *to; char digit[10]; char duration[10]; osip_body_t *mbody; const char *auth = "anon"; timeout_t event_timer = atoi(getLast("timer")); osip_message_t *msg = NULL; char *remote_uri = NULL; char *local_uri = NULL; sdp_message_t *remote_sdp, *local_sdp; sdp_connection_t *conn; osip_content_type_t *ct; sdp_media_t *remote_media, *local_media, *audio_media; char *tmp, *audio_payload, *adp; const char *data_rtpmap = NULL; int pos, mpos, rtn; sdp_attribute_t *attr; char *sdp; bool reg_inband; uint8 reg_payload; Bayonne::waitLoaded(); for(;;) { sevent = eXosip_event_wait(0, event_timer); eXosip_lock(); eXosip_automatic_action(); eXosip_unlock(); Thread::yield(); if(exiting) Thread::sync(); if(!sevent) continue; slog.debug("sip: event %04x; cid=%d, did=%d, rid=%d", sevent->type, sevent->cid, sevent->did, sevent->rid); switch(sevent->type) { case EXOSIP_REGISTRATION_NEW: slog.info("sip: new registration"); break; case EXOSIP_REGISTRATION_SUCCESS: snprintf(buf, sizeof(buf), "sipreg.%d", sevent->rid); server->enter(); img = server->getActive(); reg = (Registry *)img->getPointer(buf); if(reg) { reg->active = true; reg->setTimer(reg->duration); slog.debug("registration for %s confirmed", reg->contact); } else slog.warn("unknown sip registration confirmed; rid=%s", sevent->rid); server->leave(); break; case EXOSIP_REGISTRATION_FAILURE: if(sevent->response && sevent->response->status_code == 401) break; snprintf(buf, sizeof(buf), "sipreg.%d", sevent->rid); server->enter(); img = server->getActive(); reg = (Registry *)img->getPointer(buf); if(reg) { reg->setTimer(0); reg->active = false; slog.info("registration for %s failed", reg->contact); } else slog.warn("unknown sip registration failed; rid=%s", sevent->rid); server->leave(); break; case EXOSIP_REGISTRATION_REFRESHED: slog.info("sip registration refreshed"); break; case EXOSIP_REGISTRATION_TERMINATED: slog.info("sip registration terminated"); break; case EXOSIP_CALL_RELEASED: session = getCall(sevent->cid); if(session) goto exitcall; break; case EXOSIP_CALL_MESSAGE_NEW: if(!sevent->request) break; if(!MSG_IS_INFO(sevent->request)) break; session = getCall(sevent->cid); if(!session) { slog.warn("sip: got info for non-existant call"); goto killit; } ct = sevent->request->content_type; if(!ct || !ct->type || !ct->subtype) break; if(stricmp(ct->type, "application") || stricmp(ct->subtype, "dtmf-relay")) break; mbody = NULL; osip_message_get_body(sevent->request, 0, &mbody); line=mbody->body; digit[0] = 0; duration[0] = 0; while(line && *line) { k = v = line; while(*v && *v != '=' && *v != '\r' && *v != '\n') ++v; if(*v != '=') break; ++v; while(*v == ' ' || *v == '\b') ++v; if(!*v || *v == '\r' || *v == '\n') break; l = v; while(*l && *l != ' ' && *l != '\r' && *l != '\n') ++l; if(!*l) break; if(!strnicmp(k, "signal", 6)) strncpy(digit, v, l-v); else if(!strnicmp(k, "duration", 8)) strncpy(duration, v, l-v); ++l; while(*l == ' ' || *l == '\n' || *l == '\r') ++l; line = l; if(!*line) break; } msg = NULL; eXosip_lock(); eXosip_call_build_answer(sevent->tid, 200, &msg); eXosip_call_send_answer(sevent->tid, 200, msg); eXosip_unlock(); if(!digit[0] || !duration[0]) break; memset(&event, 0, sizeof(event)); event.id = DTMF_KEYUP; session->dtmf_inband = false; switch(*digit) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': event.dtmf.digit = *digit - '0'; event.dtmf.duration = atoi(duration); session->postEvent(&event); break; case '*': event.dtmf.digit = 10; event.dtmf.duration = atoi(duration); session->postEvent(&event); break; case '#': event.dtmf.digit = 11; event.dtmf.duration = atoi(duration); session->postEvent(&event); break; } break; case EXOSIP_CALL_CLOSED: case EXOSIP_CALL_CANCELLED: session = getCall(sevent->cid); if(!session) { slog.warn("sip: got bye for non-existant call"); break; }exitcall: memset(&event, 0, sizeof(event)); event.id = STOP_DISCONNECT; session->did = 0; session->postEvent(&event); break; case EXOSIP_CALL_PROCEEDING: session = getCall(sevent->cid); if(!session) break; memset(&event, 0, sizeof(event)); event.id = CALL_PROCEEDING; session->postEvent(&event); break; case EXOSIP_CALL_RINGING: session = getCall(sevent->cid); if(!session) break; memset(&event, 0, sizeof(event)); event.id = CALL_RINGING; session->postEvent(&event); break; case EXOSIP_CALL_ANSWERED: session = getCall(sevent->cid); if(!session) break; msg = NULL; sdp = NULL; local_sdp = NULL; remote_sdp = NULL; conn = NULL; eXosip_lock(); eXosip_call_build_ack(sevent->did, &msg); if(sevent->request && sevent->response) { local_sdp = eXosip_get_sdp_info(sevent->request); remote_sdp = eXosip_get_sdp_info(sevent->response); } eXosip_unlock(); data_rtpmap = session->getSymbol("session.rtpmap"); cp = session->getSymbol("session.ip_public"); if(local_sdp && remote_sdp && session->dtmf_payload) snprintf(buf, sizeof(buf), "v=0\r\n" "o=bayonne 0 0 IN IP4 %s\r\n" "s=call\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP %d %d\r\n" "%s\r\n" "a=rtpmap:%d telephone-events/8000\r\n", cp, cp, session->getLocalPort(), session->data_payload, session->dtmf_payload, data_rtpmap, session->dtmf_payload); else if(local_sdp && remote_sdp) snprintf(buf, sizeof(buf), "v=0\r\n" "o=bayonne 0 0 IN IP4 %s\r\n" "s=call\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP %d\r\n" "%s\r\n", cp, cp, session->getLocalPort(), session->data_payload, data_rtpmap); // we should verify sdp stuff... if(remote_sdp) { conn = eXosip_get_audio_connection(remote_sdp); remote_media = eXosip_get_audio_media(remote_sdp); } if(conn && remote_media) { session->remote_address = conn->c_addr; session->remote_port = atoi(remote_media->m_port); snprintf(cbuf, sizeof(cbuf), "%s:%d", inet_ntoa(session->remote_address.getAddress()), session->remote_port); session->setConst("session.rtp_remote", cbuf); snprintf(cbuf, sizeof(cbuf), "%s:%d", getLast("localip"), session->getLocalPort()); session->setConst("session.rtp_local", cbuf); } eXosip_lock(); osip_message_set_body(msg, buf, strlen(buf)); osip_message_set_content_type(msg, "application/sdp"); eXosip_unlock(); memset(&event, 0, sizeof(event)); event.id = CALL_ANSWERED; if(session->postEvent(&event)) { eXosip_lock(); rtn = eXosip_call_send_ack(sevent->did, msg); eXosip_unlock(); msg = NULL; memset(&event, 0, sizeof(event)); if(rtn) event.id = CALL_FAILURE; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -