Soporte & Consultoria

Soporte Remoto y Consultoria skype : ambiorixg12.
Nota no se brinda ningun tipo de consulta o soporte fuera del blog de forma gratuita

martes, 30 de diciembre de 2025

click to call

 <?php
//https://pbxncom/asterisk_api/click_to_call.php?key=A7f9K2bX4qP1Lz7a&src=100&dst=13052341212&cid=11302846&trunk=1

//error_reporting(E_ALL & ~E_USER_WARNING & ~E_USER_NOTICE);


//ini_set('display_errors', 1);

header('Content-Type: application/json');
$key="kA7f9Mze";

if($_GET['key']!="$key"){


echo json_encode(["Auth"=>401],JSON_PRETTY_PRINT);
exit();
}

print_r(json_encode($_REQUEST, JSON_PRETTY_PRINT));

$timeout=100;

$host="127.0.0.1";

$port=5038;



$src = preg_replace('/\D/', '', $_GET['src']); // remove non-digits
$dst = preg_replace('/\D/', '', $_GET['dst']); // remove non-digits

$trunkId = preg_replace('/\D/', '', $_GET['trunk']); // remove non-digits


$trunks=[1=>"Twilio",2=>"Telnyx",3=>"Didlogic"];

$trunk=$trunks[$trunkId]??$trunks[1];  // set  a default trunk if none is selected



$cid = preg_replace('/\s+/', '', $_GET['cid']);

$id = preg_replace('/\s+/', '', $_GET['id']);


$socket = fsockopen("$host","$port", $errno, $errstr, 10);

      if (!$socket){

      //If network connection fails; 
      print_r(json_encode([$errstr=>$errno],JSON_PRETTY_PRINT));

        }else{

            fputs($socket, "Action: Login\r\n");

            fputs($socket, "UserName: admin\r\n");

            fputs($socket, "Secret: L29481uKCU\r\n\r\n");



          $wrets=fgets($socket,128);

                
              fputs($socket, "Action: Originate\r\n" );

              fputs($socket, "Channel: Local/$src@click_to_call_api_src\r\n" );

              fputs($socket, "Exten: $dst\r\n" );

               fputs($socket, "Context: click_to_call_api_dst\r\n" );

               fputs($socket, "Priority: 1\r\n" );

               fputs($socket, "CallerID: $cid\r\n" );

                fputs($socket, "Variable: __src=$src\r\n" );

               fputs($socket, "Variable: __dst=$dst\r\n" );

               fputs($socket, "Variable: __cid=$cid\r\n" );

                fputs($socket, "Variable: __trunk=$trunk\r\n" );

             fputs($socket, "Async: yes\r\n\r\n" );   

        fputs($socket, "Action: Logoff\r\n\r\n");

           while (!feof($socket)){
  $result=fgets($socket);

                   print_r(json_encode(["API"=>"$wrets","MSG"=>$result],JSON_PRETTY_PRINT));




}



fclose($socket);

 }



?>


-------------

 [click_to_call_api_src]

exten=>_x.,1,Noop("DST : ${src}, DST : ${dst}, CID : ${CID} , TRUNK : ${trunk}");

same=>n,Set(CALLERID(num)=${dst})

same=>n,Dial(PJSIP/${src})

same=>n,hangup()


[click_to_call_api_dst]

exten=>_x.,1,Noop("DST : ${src}, DST : ${dst}, CID : ${CID} , TRUNK : ${trunk}");

same=>n,Set(CALLERID(num)=+${cid})


same => n,GotoIf($["${trunk}"="Telnyx"]?Telnyx)

same=>n,Dial(PJSIP/+${dst}@${trunk})

same=>n,hangup()


same => n(Telnyx),Set(dst=9817+${dst})  ;;add a prefix if trunk is Telnyx

same=>n,Dial(PJSIP/${dst}@${trunk})

same=>n,hangup()

-----------------

lunes, 29 de diciembre de 2025

Configuring res_pjsip to work through NAT

Overview

Here we can show some examples of working configuration for Asterisk's SIP channel driver when Asterisk is behind NAT (Network Address Translation).

If you are migrating from chan_sip to chan_pjsip, then also read the NAT section in Migrating from chan_sip to res_pjsip for helpful tips.

Asterisk and Phones Connecting Through NAT to an ITSP

This example should apply for most simple NAT scenarios that meet the following criteria:

  • Asterisk and the phones are on a private network.
  • There is a router interfacing the private and public networks. Where the public network is the Internet.
  • The router is performing Network Address Translation and Firewall functions.
  • The router is configured for port-forwarding, where it is mapping the necessary ranges of SIP and RTP traffic to your internal Asterisk server.
    In this example the router is port-forwarding WAN inbound TCP/UDP 5060 and UDP 10000-20000 to LAN 192.0.2.10

This example was based on a configuration for the ITSP SIP.US and assuming you swap out the addresses and credentials for real ones, it should work for a SIP.US SIP account.

Devices Involved in the Example

Using RFC5737 documentation addresses

Device IP in example
VOIP Phone(6001) 192.0.2.20
PC/Asterisk 192.0.2.10
Router LAN: 192.0.2.1
WAN: 198.51.100.5
ITSP SIP gateway 203.0.113.1 (gw1.example.com)
203.0.113.2 (gw2.example.com)

For the sake of a complete example and clarity, in this example we use the following fake details:

ITSP Account number: 1112223333

DID number provided by ITSP: 19998887777

pjsip.conf Configuration

We are assuming you have already read the Configuring res_pjsip page and have a basic understanding of Asterisk. For this NAT example, the important config options to note are local_net, external_media_address and external_signaling_address in the transport type section and direct_media in the endpoint section. The rest of the options may depend on your particular configuration, phone model, network settings, ITSP, etc. The key is to make sure you have those three options set appropriately.

local_net

This is the IP network that we want to consider our local network. For communication to addresses within this range, we won't apply any NAT-related settings, such as the external* options below.

external_media_address

This is the external IP address to use in RTP handling. When a request or response is sent out from Asterisk, if the destination of the message is outside the IP network defined in the option 'local_net', and the media address in the SDP is within the localnet network, then the media address in the SDP will be rewritten to the value defined for 'external_media_address'.

external_signaling_address

This is much like the external_media_address setting, but for SIP signaling instead of RTP media. The two external* options mentioned here should be set to the same address unless you separate your signaling and media to different addresses or servers.

direct_media

Determines whether media may flow directly between endpoints

Together these options make sure the far end knows where to send back SIP and RTP packets, and direct_media ensures Asterisk stays in the media path. This is important, because our Asterisk system has a private IP address that the ITSP cannot route to. We want to make sure the SIP and RTP traffic comes back to the WAN/Public internet address of our router. The sections prefixed with "sipus" are all configuration needed for inbound and outbound connectivity of the SIP trunk, and the sections named 6001 are all for the VOIP phone.

[transport-udp-nat]
type=transport
protocol=udp
bind=0.0.0.0
local_net=192.0.2.0/24
local_net=127.0.0.1/32
external_media_address=198.51.100.5
external_signaling_address=198.51.100.5

[sipus_reg]
type=registration
transport=transport-udp-nat
outbound_auth=sipus_auth
server_uri=sip:gw1.example.com
client_uri=sip:1112223333@gw1.example.com
contact_user=19998887777
retry_interval=60

[sipus_auth]
type=auth
auth_type=userpass
password=************
username=1112223333
realm=gw1.example.com

[sipus_endpoint]
type=endpoint
transport=transport-udp-nat
context=from-external
disallow=all
allow=ulaw
outbound_auth=sipus_auth
aors=sipus_aor
direct_media=no
from_domain=gw1.example.com

[sipus_aor]
type=aor
contact=sip:gw1.example.com
contact=sip:gw2.example.com

[sipus_identify]
type=identify
endpoint=sipus_endpoint
match=203.0.113.1
match=203.0.113.2

[6001]
type=endpoint
context=from-internal
disallow=all
allow=ulaw
transport=transport-udp-nat
auth=6001
aors=6001
direct_media=no

[6001]
type=auth
auth_type=userpass
password=************
username=6001

[6001]
type=aor
max_contacts=2

For Remote Phones Behind NAT

In the above example we assumed the phone was on the same local network as Asterisk. Now, perhaps Asterisk is exposed on a public address, and instead your phones are remote and behind NAT, or maybe you have a double NAT scenario?

In these cases you will want to consider the below settings for the remote endpoints.

media_address

IP address used in SDP for media handling

At the time of SDP creation, the IP address defined here will be used as

rtp_symmetric

Enforce that RTP must be symmetric. Send RTP back to the same address/port we received it from.

force_rport

Force RFC3581 compliant behavior even when no rport parameter exists. Basically always send SIP responses back to the same port we received SIP requests from.

direct_media

Determines whether media may flow directly between endpoints.

rewrite_contact

Determine whether SIP requests will be sent to the source IP address and port, instead of the address provided by the endpoint.

Clients Supporting ICE,STUN,TURN

This is really relevant to media, so look to the section here for basic information on enabling this support and we'll add relevant examples later.

https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Configuring-res_pjsip-to-work-through-NAT/#overview

martes, 15 de abril de 2025

sox convertion

 sox tarotgama.wav -t ul -r 8000 -c 1 tarotgama.ulaw


sox tarotgama.wav -r 8000 -c 1 -e signed -b 16 -t wav tarotgama_asterisk.wav

sábado, 12 de abril de 2025

while endwhile

 exten => 100,1,Answer()

 same => n,Set(i=1)   ; counter

 same => n,AGI(getTotal.php,${userID})  ; sets vmtotal, body, mdate, recipient, etc.


 same => n,While($[${i} <= ${vmtotal}])

   same => n,Playback(message-number)

   same => n,SayDigits(${i})

   same => n,Playback(from)

   same => n,Playback(${recipient})

   same => n,Playback(at)

   same => n,SayTime(${mtime})

   same => n,Playback(${body})

   same => n,Set(i=$[${i} + 1])

 same => n,EndWhile()


 same => n,Playback(no-more-msg)

 same => n,Hangup()


miércoles, 2 de abril de 2025

 same => n,ExecIf($["${isyou}" != "1" || "${isyou}"!="2"]?Playback(${audio_path_general}/no-valid-option))



same=>n,ExecIf($["${LEN(${userPin})}" < "4" && "${userPin}"!="#"]?Playback(${audio_path_general}/4-digits-required))



same => n,GotoIf($[${action}=9]?user-menu,100,1)

same=>n,ExecIf($[${LEN(${opt})} ="0"]?playback(${audio_path_general}/no-valid-option))

same => n,GotoIf($[${LEN(${opt})}="0]"?update-lang)

same => n,GotoIf($[${opt}>3]?update-lang)

same=>n,goto(personal-menu)


same=>n,ExecIf($["${opt}" = "1" || "${opt}" = "2" || "${opt}" = "3" ]?Playback(${audio_path_general}/lang-updated&${audio_path_general}/sent-prev-menu):Playback(${audio_path_general}/no-valid-option))

viernes, 28 de marzo de 2025

connection files

database connection file


db_con.php

<?php

// Enable error reporting

//error_reporting(E_ALL);  // Report all errors

error_reporting(E_ERROR | E_PARSE);  // Show only errors and parse errors

ini_set('display_errors', 1);  // Display errors on the web page

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

// Database connection parameters


$host = "172.18.0.3";

$user = "root";

$password = "7133";

$database = "fm";


$mysqli = new mysqli("$host", "$user", "$password", "$database");

// Check for connection errors


if ($mysqli->connect_error) {


    die("Connection failed: " . $mysqli->connect_error);


}


?>






=============select function example=============

 #!/usr/bin/php -q

<?php

require(__DIR__."/getInfo.php");


$PhoneNum="$argv[1]";


$query_val_phone = "SELECT count(phoneNumber) as phoneNumber_num FROM users where phoneNumber='$PhoneNum'";


$registered=select($query_val_phone)[0]['phoneNumber_num'];


if($registered>0){


echo "EXEC Verbose \"User PhoneNum already registered\"\n";



echo "EXEC Goto \"music,100,1\"";

}


else {


echo "EXEC Verbose \"Phone number  $PhoneNum is not registered\"\n";


echo "EXEC Goto \"singup-en,sign-1,1\"";



?>

-----------------

Function for  select.


 <?php

function select($query){
require(__DIR__."/db_con.php");

$result = $mysqli->query($query); 

if (!$result) {  // Check if the query failed

    printf("Error message: %s\n", $mysqli->error);

    exit();

}



$mysqli->close();  

 return $rows = $result->fetch_all(MYSQLI_ASSOC);  
}

?>



================
------------------------

Function for insert


function db_insert($query){

require(__DIR__."/db_con.php");

$result = $mysqli->query($query); 

if (!$result) {  // Check if the query failed

    printf("Error message: %s\n", $mysqli->error);

    exit();

}



$mysqli->close();  
 
}

$query="insert into bla bla";

db_insert($query); 
echo "EXEC Verbose \"$query\"\n";

// php cr_user.php "8297143421" "1982" "5001" "en" "cid"

?>

domingo, 9 de febrero de 2025

Debian Asterisk Realtime

1  apt update &&  o apt update

apt-get install unixodbc odbcinst


apt-get install alembic


Install MariaDB

4  apt install mariadb-server -y

5 systemctl enable mariadb.service

6 systemctl status mariadb.service
Change root mysql pass
1. mysqladmin -u root -p password 'asterisk'
create the asterisk db
2. mysqladmin -u root -pasterisk create asterisk
3 check the db
mysql -u root -p -D asterisk
First, install Alembic: and the  mysql module
 apt-get install python3-mysqldb

 apt-get install alembic
Then, move to the Asterisk source directory containing the Alembic scripts:
# cd contrib/ast-db-manage/
Next, edit the config.ini.sample file and change the sqlalchemy.url option, e.g.
sqlalchemy.url = mysql://root:asterisk@localhost/asterisk
such that the URL matches the username and password required to access your database.
Then rename the config.ini.sample file to config.ini
# cp config.ini.sample config.ini
Finally, use Alembic to setup the database tables:
# alembic -c config.ini upgrade head
You'll see something similar to:
# alembic -c config.ini upgrade head
INFO  [alembic.migration] Context impl MySQLImpl.
INFO  [alembic.migration] Will assume non-transactional DDL.
INFO  [alembic.migration] Running upgrade None -> 4da0c5f79a9c, Create tables
INFO  [alembic.migration] Running upgrade 4da0c5f79a9c -> 43956d550a44, Add tables for pjsip
#

 mysql -u root -p -D asterisk

mysql> show tables;
+--------------------+
| Tables_in_asterisk |
+--------------------+
| alembic_version    |
| iaxfriends         |
| meetme             |
| musiconhold        |
| ps_aors            |
| ps_auths           |
| ps_contacts        |
| ps_domain_aliases  |
| ps_endpoint_id_ips |
| ps_endpoints       |
| sippeers           |
| voicemail          |
+--------------------+
12 rows in set (0.00 sec)
mysql> quit

 https://www.asterisk.org/configuring-realtime-voicemail-on-debian/


Initial ODBC Setup


apt-get install odbc-mariadb

8   dpkg -L odbc-mariadb

9   nano  /etc/odbc.ini

[asterisk]
Description = MySQL Server
Driver = MySQL ODBC Driver
Database = asterisk
Server = localhost
User = root
Password = asterisk
Port = 3306
Socket = /var/run/mysqld/mysqld.sock


10   nano  /etc/odbcinst.ini 

[MariaDB Unicode]
Driver=libmaodbc.so
Description=MariaDB Connector/ODBC(Unicode)
Threading=0
UsageCount=1


[MySQL ODBC Driver]
Description = MySQL Connector/ODBC
Driver = /usr/lib/x86_64-linux-gnu/odbc/libmaodbc.so



11  test connection
odbcinst -q -d
echo “select 1” | isql -v asterisk

Install Asterisk


 1  wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-22-current.tar.gz
 

2 tar zxvf asterisk*


3 rm *.gz

4 cd asterisk*

 5 contrib/scripts/install_prereq install

6 ./configure --libdir=/usr/lib64 --with-pjproject-bundled --with-jansson-bundled && make menuselect && make && make install

   7 make samples

  8  make config

   9 ldconfig

    10 /etc/init.d/asterisk start

   11 asterisk -rvvvvvvvv
 
 if shared library error 
     ldd /usr/sbin/asterisk
  
    find / -name 'libasteriskssl.so.1'
     ln -s /usr/lib64/libasteriskssl.so.1 /lib/x86_64-linux-gnu
     ln -s /usr/lib64/libasteriskpj.so.2 /lib/x86_64-linux-gnu
    ldconfig
     systemctl start asterisk

     asterisk -rvvvvvvvv



Configure asterisk ODBC files


/etc/asterisk/res_odbc.conf
[asterisk]
enabled => yes
dsn => asterisk
username => root
password => asterisk
pre-connect => yes


/etc/asterisk/cdr_adaptive_odbc.conf

[asterisk]
connection=asterisk
table=cdr
alias start => calldate




module reload res_odbc.so

Check connection

asterisk_realtime*CLI> odbc show all

ODBC DSN Settings
-----------------

  Name:   asterisk
  DSN:    asterisk
    Number of active connections: 1 (out of 1)
    Logging: Disabled

Asterisk relatime configuration 
/etc/asterisk/sorcery.conf
[res_pjsip] ; Realtime PJSIP configuration wizard
endpoint=realtime,ps_endpoints
auth=realtime,ps_auths
aor=realtime,ps_aors
domain_alias=realtime,ps_domain_aliases
contact=realtime,ps_contacts

[res_pjsip_endpoint_identifier_ip]
identify=realtime,ps_endpoint_id_ips

[res_pjsip_outbound_registration]
registration=realtime,ps_registrations




/etc/asterisk/extconfig.conf
ps_endpoints => odbc,asterisk
ps_auths => odbc,asterisk
ps_aors => odbc,asterisk
ps_domain_aliases => odbc,asterisk
ps_endpoint_id_ips => odbc,asterisk
ps_contacts => odbc,asterisk
ps_registrations = odbc,asterisk


etc/asterisk/modules.conf
preload => res_odbc.so
preload => res_config_odbc.so
noload => chan_sip.so 


/etc/asterisk/pjsip.conf
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0


/etc/asterisk/extensions.conf
[testing]
exten=>_x.,1,Dial(PJSIP/${EXTEN},120)
same=>n,hangup()

RESTART the asterisk service after add the transport


core restart now


ALTER TABLE ps_contacts

ADD COLUMN qualify_2xx_only VARCHAR(255) AFTER qualify_timeout;


https://hotkey404.com/fix-missing-asterisk-library-error-libasteriskssl-so-1-libasteriskpj-so-2-not-found/



https://docs.vultr.com/how-to-install-mariadb-on-debian-12


https://asterisk-rd.blogspot.com/search?q=rocky


sudo apt install apache2

sudo apt install php php-mysql php-cli

sudo systemctl status apache2

sudo systemctl enable apache2

sudo systemctl restart apache2


1. Disable UFW (Temporarily)

sudo ufw disable

2. Check UFW Status
sudo ufw status


3. Remove UFW (Optional)
sudo apt remove --purge ufw