Asterisco: Cómo gestionar un multidominio en tiempo real sin llamar la atención de los enfermeros

¿De qué se trata realmente?

Trabajando en una gran empresa, y en una mediana empresa con un número reducido de sucursales, cada vez más piensas en optimizar recursos, simplificar la administración y estandarizar todo y a todos.





Tenemos, por ejemplo, varias (bueno, no pocas) del mismo tipo de sucursales para 10-100 empleados. La telefonía se puede organizar de diferentes formas:





  • Tome una solución lista para usar en la nube del proveedor





  • Instale su propio miniservidor y asterisco en cada rama





  • Haz un solo asterisco en el centro





Las 2 primeras opciones, por supuesto, tienen lugar, pero tienen suficientes desventajas. Esta no es la conveniencia de mantener varias instancias pequeñas, esto es un problema financiero y algunos otros puntos.





, , , , . , , . , , 3 , 6 . - 6 ("6 ! !"), 6 .





, - SIP . , -, .





, . , - , -. . ? , - , , - .





18.1 PJSIP .





? , . - . , " ".





(Numbers), . , ?





  • , (Number)





  • - ? (Secret)





  • - , , (domain)





  • CID -





  • : , DTMF, -





  • Flags - -, . , , .





, . ? , , . - , , VIEW. , , . 3 :





  • Endpoints (ps_endpoints)





  • (ps_auths)





  • Aors (ps_aors)





, , "" PJSIP. SQL:





/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

CREATE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW `ps_aors` AS select concat(`Numbers`.`Number`,if(`Numbers`.`domain` is not null,concat('@',`Numbers`.`domain`),'')) AS `id`,180 AS `default_expiration`,2 AS `max_contacts`,30 AS `minimum_expiration`,'yes' AS `remove_existing`,'' AS `contact` from `Numbers`;
CREATE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW `ps_auths` AS select concat(`Numbers`.`Number`,if(`Numbers`.`domain` is not null,concat('@',`Numbers`.`domain`),'')) AS `id`,'userpass' AS `auth_type`,3600 AS `nonce_lifetime`,`Numbers`.`Secret` AS `password`,`Numbers`.`Number` AS `username`,`Numbers`.`domain` AS `realm` from `Numbers` where `Numbers`.`Secret` <> '';
CREATE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW `ps_endpoints` AS select concat(`Numbers`.`Number`,if(`Numbers`.`domain` is not null,concat('@',`Numbers`.`domain`),'')) AS `id`,concat('transport-',lcase(`Numbers`.`Protocol`)) AS `transport`,concat(`Numbers`.`Number`,if(`Numbers`.`domain` is not null,concat('@',`Numbers`.`domain`),'')) AS `aors`,if(`Numbers`.`Secret` <> '',concat(`Numbers`.`Number`,if(`Numbers`.`domain` is not null,concat('@',`Numbers`.`domain`),'')),NULL) AS `auth`,'SIP' AS `context`,'all' AS `disallow`,concat('ulaw,alaw,opus',if(find_in_set('Video',`Numbers`.`Flags`),',h263,h261,h263p,h264','')) AS `allow`,concat(`Numbers`.`Number`,if(`Numbers`.`domain` is not null,concat('@',`Numbers`.`domain`),'')) AS `outbound_auth`,concat(`Numbers`.`CID`,' <',`Numbers`.`Number`,'>') AS `callerid`,if(`Numbers`.`Protocol` = 'TLS','sdes','no') AS `media_encryption`,`Numbers`.`PickupGroup` AS `named_pickup_group`,2 AS `device_state_busy_at`,concat('vRecord=',if(find_in_set('Record',`Numbers`.`Flags`) > 0,'yes','no'),';','vRussia=',if(find_in_set('Russia',`Numbers`.`Flags`) > 0,'yes','no'),';','vAbroad=',if(find_in_set('Abroad',`Numbers`.`Flags`) > 0,'yes','no'),';','vVoicemail=',if(find_in_set('Voicemail',`Numbers`.`Flags`) > 0,'yes','no'),';','vFilterCID=no') AS `set_var`,`Numbers`.`NumberID` AS `callerid_tag`,'username,auth_username,ip' AS `identify_by` from `Numbers`;

/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

      
      



. - - "" "":





  • , 5 . , . , .





  • , 3 , , , , , 101, 102, "" 007 ..





, Numbers .





Numbers:





, " " , , .





ps_endpoints





, - Numbers.





ps_auth





ps_aors





, . , Numbers, .





, . - id. 5 , - . 3 @ . , , - .





. , . AOR endpointa , .. @, . , (id) , AOR . . - AOR , . , .





, , .





pjsip.conf

, .





disable multi domain





, no. , . - . , , yes. 2 . .





endpoint identifier order





, , . = ip,username. , , .. IP . , username, endpoint .





, .





res config mysql.conf





, - :





extconfig.conf





, .





ps_contacts , astdb.





Spoiler

CDR. , . , GitHub









sorcery.conf





. , , .





.





, ?

, endpoint :









, . " " . " " .





, . .., 5 :





Dial(PJSIP/19960)





3





Dial(PJSIP/123@test3)





, , .





?

Microsip, :









101 . ?





PS:

- .





- , , . , .





domains:





domain (VARCHAR) | code (VARCHAR)





Rellenamos, por ejemplo, así:





test2 | 01





test3 | 02





Por supuesto, puede tomar cualquier código de sucursal, incluso 1 carácter. Estamos determinados con el acceso a las sucursales. Por ejemplo, yo tengo acceso a la "ciudad" después de las 9, y llevaré a las sucursales el 8. Tú tomas lo que te conviene. Al menos * (asterisco).





Vincula la tabla de dominios con el identificador de dominios en extconfig.conf . Escribimos un plan de marcado:





exten => _8XXXXX,1,NoOp(Call from ${CALLERID(all)} to filial ${EXTEN:1:2})
same => n, Set(domain=${REALTIME_FIELD(domains,code,${EXTEN:1:2},domain)})
same => n, GotoIF($[ "${domain}" = "" ]?GotoError) ;     
same => n, Dial(PJSIP/${EXTEN:3}@${domain})
same => n, Hangip
      
      



En total, marcamos 801123 en el teléfono y llegamos a la sucursal de test2 en 123.





Para facilitar la administración, puede agregar otra restricción clave:





Números .dominio - LLAVE EXTRANJERA -> dominios .dominio





Esto evitará que pierda dominios mientras edita.








All Articles