Support multi trunks
This commit is contained in:
@@ -7,6 +7,7 @@ use serde::{Serialize};
|
||||
use diesel_derive_enum::DbEnum;
|
||||
use std::str::FromStr;
|
||||
use strum_macros::EnumString;
|
||||
use crate::schema::dids;
|
||||
|
||||
#[derive(Debug, PartialEq, DbEnum, Serialize, EnumString)]
|
||||
#[db_enum(existing_type_path = "crate::schema::sql_types::DidTargetType")]
|
||||
@@ -26,23 +27,25 @@ pub enum DidTargetType {
|
||||
}
|
||||
|
||||
#[derive(Debug, Queryable, Selectable, Serialize, AsChangeset)]
|
||||
#[diesel(table_name = crate::schema::dids)]
|
||||
#[diesel(table_name = dids)]
|
||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||
pub struct Did {
|
||||
pub id: i32,
|
||||
pub did_number: String,
|
||||
pub target_type: DidTargetType,
|
||||
pub target: Option<String>,
|
||||
pub active: bool
|
||||
pub active: bool,
|
||||
pub trunk: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable)]
|
||||
#[diesel(table_name = crate::schema::dids)]
|
||||
#[diesel(table_name = dids)]
|
||||
pub struct NewDid<'a> {
|
||||
pub did_number: &'a str,
|
||||
pub target_type: DidTargetType,
|
||||
pub target: Option<&'a str>,
|
||||
pub active: bool
|
||||
pub active: bool,
|
||||
pub trunk: &'a str,
|
||||
}
|
||||
|
||||
pub fn connect() -> PgConnection {
|
||||
@@ -98,24 +101,22 @@ pub fn update_did(d: Did)-> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_did(did_number: &str, target_type: &str, target: &str, active: bool)
|
||||
-> Result<Did, Error> {
|
||||
use crate::schema::dids;
|
||||
|
||||
pub fn add_did(did_number: &str, target_type: &str, target: &str, active: bool, trunk: &str)
|
||||
-> Result<(), Error> {
|
||||
let mut conn = connect();
|
||||
let new_did = NewDid {
|
||||
did_number: did_number,
|
||||
target_type: DidTargetType::from_str(target_type).unwrap(),
|
||||
target: Some(target),
|
||||
active: active
|
||||
active: active,
|
||||
trunk: trunk,
|
||||
};
|
||||
|
||||
let did = diesel::insert_into(dids::table)
|
||||
diesel::insert_into(dids::table)
|
||||
.values(&new_did)
|
||||
.returning(Did::as_returning())
|
||||
.get_result(&mut conn)?;
|
||||
.execute(&mut conn)?;
|
||||
|
||||
Ok(did)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn list_did() ->Result<Vec<Did>, Error> {
|
||||
@@ -123,6 +124,7 @@ pub fn list_did() ->Result<Vec<Did>, Error> {
|
||||
let mut conn = connect();
|
||||
|
||||
let res = dids
|
||||
.order_by(id.asc())
|
||||
.load(&mut conn)?;
|
||||
|
||||
Ok(res)
|
||||
|
||||
@@ -30,10 +30,11 @@ pub fn moh(_did: Did) -> XMLElement {
|
||||
pub fn external_number(did: Did) -> XMLElement {
|
||||
let mut work = XMLElement::new("work");
|
||||
let mut bridge = XMLElement::new("execute");
|
||||
let target = did.target.unwrap();
|
||||
let callee_number = did.target.unwrap();
|
||||
let ds = build_dial_string(&callee_number, &did.did_number);
|
||||
|
||||
bridge.add_attribute("application", "bridge");
|
||||
bridge.add_attribute("data", format!("sofia/gateway/powernet_1/{}", target).as_str());
|
||||
bridge.add_attribute("data", &ds);
|
||||
|
||||
work.add_child(bridge).unwrap();
|
||||
|
||||
@@ -68,12 +69,36 @@ pub fn custom_message(_did: Did) -> XMLElement {
|
||||
work
|
||||
}
|
||||
|
||||
pub fn outbound(d: &str) -> XMLElement {
|
||||
fn build_dial_string(callee_number: &str, caller_number: &str) -> String {
|
||||
let ds = match db::get_did_by(&caller_number) {
|
||||
Ok(d) => {
|
||||
if d.trunk == "3229" || d.trunk == "3401" {
|
||||
format!("{{origination_caller_id_number={} }}sofia/gateway/powernet_1/{}",
|
||||
caller_number,
|
||||
callee_number)
|
||||
} else {
|
||||
format!("{{origination_caller_id_number={} }}sofia/gateway/powernet_2/{}",
|
||||
caller_number,
|
||||
callee_number)
|
||||
}
|
||||
},
|
||||
Err(..) =>{
|
||||
format!("{{origination_caller_id_number={} }}sofia/gateway/powernet_1/{}",
|
||||
caller_number,
|
||||
callee_number)
|
||||
}
|
||||
};
|
||||
|
||||
ds
|
||||
}
|
||||
|
||||
pub fn outbound(did: &str, caller_number: &str) -> XMLElement {
|
||||
let mut work = XMLElement::new("work");
|
||||
let mut bridge = XMLElement::new("execute");
|
||||
let ds = build_dial_string(did, caller_number);
|
||||
|
||||
bridge.add_attribute("application", "bridge");
|
||||
bridge.add_attribute("data", format!("sofia/gateway/powernet_1/{}", d).as_str());
|
||||
bridge.add_attribute("data", &ds);
|
||||
|
||||
work.add_child(bridge).unwrap();
|
||||
|
||||
@@ -90,9 +115,9 @@ pub fn add_playback_element(work: &mut XMLElement ,file_path: &str) {
|
||||
work.add_child(playback).unwrap();
|
||||
}
|
||||
|
||||
pub fn build_work_element(did: &str, caller_ipaddr: &str) -> XMLElement {
|
||||
pub fn build_work_element(did: &str, caller_number: &str, caller_ipaddr: &str) -> XMLElement {
|
||||
if db::from_pbx(&caller_ipaddr).unwrap() == true {
|
||||
outbound(did)
|
||||
outbound(did, caller_number)
|
||||
} else {
|
||||
let d = db::get_did_by(&did).unwrap();
|
||||
let work = match d.target_type {
|
||||
@@ -120,7 +145,7 @@ pub fn build_work_element(did: &str, caller_ipaddr: &str) -> XMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn route_call(did: String, caller_ipaddr: String) -> Vec<u8> {
|
||||
pub fn route_call(did: String, caller_number: String,caller_ipaddr: String) -> Vec<u8> {
|
||||
let mut xml = XMLBuilder::new()
|
||||
.version(XMLVersion::XML1_1)
|
||||
.encoding("UTF-8".into())
|
||||
@@ -130,7 +155,7 @@ pub fn route_call(did: String, caller_ipaddr: String) -> Vec<u8> {
|
||||
doc.add_attribute("type", "xml/freeswitch-httapi");
|
||||
|
||||
let params = XMLElement::new("params");
|
||||
let mut work = build_work_element(&did, &caller_ipaddr);
|
||||
let mut work = build_work_element(&did, &caller_number, &caller_ipaddr);
|
||||
|
||||
let mut hangup = XMLElement::new("execute");
|
||||
hangup.add_attribute("application", "hangup");
|
||||
|
||||
@@ -10,14 +10,17 @@ use actix_web::{web, App,
|
||||
http::header::ContentType,
|
||||
Responder,
|
||||
};
|
||||
use actix_cors::Cors;
|
||||
use serde::Deserialize;
|
||||
use database as db;
|
||||
use database::DidTargetType;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct RouteData {
|
||||
struct RouteRequest {
|
||||
#[serde(rename = "Caller-Destination-Number")]
|
||||
dest_did: String,
|
||||
callee_number: String,
|
||||
#[serde(rename = "Caller-Caller-ID-Number")]
|
||||
caller_number: String,
|
||||
#[serde(rename = "Caller-Network-Addr")]
|
||||
caller_ipaddr: String
|
||||
}
|
||||
@@ -27,13 +30,15 @@ struct JsonDid {
|
||||
did_number: String,
|
||||
target_type: String,
|
||||
target: String,
|
||||
trunk: String,
|
||||
active: bool
|
||||
}
|
||||
|
||||
async fn route_did(form_data: web::Form<RouteData>) -> impl Responder {
|
||||
let did = form_data.dest_did.clone();
|
||||
let caller_ipaddr = form_data.caller_ipaddr.clone();
|
||||
let xml = httapi::route_call(did, caller_ipaddr);
|
||||
async fn route_did(request: web::Form<RouteRequest>) -> impl Responder {
|
||||
let callee_number = request.callee_number.clone();
|
||||
let caller_number = request.caller_number.clone();
|
||||
let caller_ipaddr = request.caller_ipaddr.clone();
|
||||
let xml = httapi::route_call(callee_number, caller_number,caller_ipaddr);
|
||||
HttpResponse::Ok()
|
||||
.content_type(ContentType::xml())
|
||||
.body(xml)
|
||||
@@ -42,7 +47,8 @@ async fn route_did(form_data: web::Form<RouteData>) -> impl Responder {
|
||||
async fn did_post(d: web::Json<JsonDid>) -> impl Responder {
|
||||
let did = d.deref();
|
||||
|
||||
db::add_did(&did.did_number, &did.target_type, &did.target, did.active).unwrap();
|
||||
println!("{:?}", did);
|
||||
db::add_did(&did.did_number, &did.target_type, &did.target, did.active ,&did.trunk).unwrap();
|
||||
HttpResponse::Ok().body("DID added.")
|
||||
}
|
||||
|
||||
@@ -66,6 +72,7 @@ async fn did_patch(d: web::Json<JsonDid>, path: web::Path<i32>) -> impl Responde
|
||||
did_number: d.did_number.clone(),
|
||||
target_type: DidTargetType::from_str(&d.target_type).unwrap(),
|
||||
target: Some(d.target.clone()),
|
||||
trunk: d.trunk.clone(),
|
||||
active: d.active
|
||||
};
|
||||
|
||||
@@ -103,7 +110,9 @@ fn api_config(cfg: &mut web::ServiceConfig) {
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
HttpServer::new(|| {
|
||||
let cors = Cors::permissive();
|
||||
App::new()
|
||||
.wrap(cors)
|
||||
.service(
|
||||
web::scope("/api").configure(api_config))
|
||||
})
|
||||
|
||||
@@ -18,5 +18,7 @@ diesel::table! {
|
||||
#[max_length = 512]
|
||||
target -> Nullable<Varchar>,
|
||||
active -> Bool,
|
||||
#[max_length = 32]
|
||||
trunk -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user