Skip to content

Instantly share code, notes, and snippets.

@cyanide-burnout
Last active October 12, 2024 17:29
Show Gist options
  • Save cyanide-burnout/a7dadea75b18a3c8edc00106ad4f0cca to your computer and use it in GitHub Desktop.
Save cyanide-burnout/a7dadea75b18a3c8edc00106ad4f0cca to your computer and use it in GitHub Desktop.
Retreive VoIP configuration from SFP ONU and MikroTik, then apply to Asterisk (triggered by dhcp-voip.rsc)
<?php
define('PJSIP_PEER_NAME', 'mgts');
define('PJSIP_PEER_FILE', '/etc/asterisk/pjsip-mgts.conf');
define('ONU_ADDRESS', '192.168.1.1');
define('ONU_USER', 'admin');
define('ONU_PASSWORD', 'admin');
define('ONU_COMMAND', '/sbin/omcicli mib get 00148');
define('AMI_PORT', '5038');
define('AMI_UESR', 'admin');
define('AMI_PASSWORD', 'admin');
$data = file_get_contents('php://input');
$lock = fopen('/tmp/onu.lock', 'w');
if (is_string($data) &&
(strlen($data) > 0) &&
flock($lock, LOCK_EX))
{
// Parse server list received by MikroTik via DHCP option 120
$address = explode(',', $data)[0];
$network = preg_replace('/\.\d+$/', '.0/24', $address);
// Retreive and parse settings from XPON ONU
$connection = ssh2_connect(ONU_ADDRESS, 22);
ssh2_auth_password($connection, ONU_USER, ONU_PASSWORD);
$stream = ssh2_exec($connection, ONU_COMMAND);
sleep(2);
while (($line = fgets($stream, 2048)) !== false)
{
$line = trim($line);
if (preg_match('/(\w+): (.+)/', $line, $matches))
{
switch ($matches[1])
{
case 'Username1': $name = $matches[2]; break;
case 'Username2': $name .= hex2bin(preg_replace('/^0x|(00)+$/', '', $matches[2])); break;
case 'Password': $password = hex2bin(preg_replace('/^0x|(00)+$/', '', $matches[2])); break;
}
}
if (isset($name) &&
isset($password) &&
($line == '================================='))
{
// Entity reading complete
break;
}
}
fclose($stream);
ssh2_disconnect($connection);
// Build configuration
$section = PJSIP_PEER_NAME;
$data = <<<EOD
[$section]
type=auth
auth_type=userpass
username=$name
password=$password
[$section]
type=registration
outbound_auth=$section
server_uri=sip:$address
client_uri=sip:$name
retry_interval=60
line=yes
endpoint=$section
[$section]
type=identify
endpoint=$section
match=$network
[$section]
type=aor
contact=sip:$name
EOD;
// Verify and apply changes
if ($data != file_get_contents(PJSIP_PEER_FILE))
{
file_put_contents(PJSIP_PEER_FILE, $data);
$socket = fsockopen('127.0.0.1', AMI_PORT);
fputs($socket, "Action: Login\r\n");
fputs($socket, "UserName: " . AMI_UESR . "\r\n");
fputs($socket, "Secret: " . AMI_PASSWORD . "\r\n\r\n");
fputs($socket, "Action: Command\r\n");
fputs($socket, "Command: module reload res_pjsip.so\r\n\r\n");
fgets($socket, 256);
fclose($socket);
}
flock($lock, LOCK_UN);
}
fclose($lock);
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment