├── Aastra_Button_Functions └── show_ring_group_membership.php ├── AsteriskDB_to_Yealink_AddressBook └── yldump.py ├── Backup_Yealink_Local_Contacts ├── README.md ├── put.yealink └── yealink.conf ├── ContactManager_to_Digium_AddressBook └── cm_to_digum_aseries.php ├── ContactManager_to_Fanvil_AddressBook └── cm_to_fv_ab.php ├── ContactManager_to_Yealink_AddressBook └── cm_to_yl_ab.php ├── Example_Yealink_XML_Menu ├── shared_contacts.xml └── ylmenu.xml ├── Extension_Status ├── README.md ├── extensionstatus.php └── extensionstatus_header.php ├── Extensions_to_Grandstream_Phonebook └── generate_gs_phonebook.php ├── Extensions_to_Yealink_AddressBook └── ylab.php ├── George1421_Yealink_AddressBook └── yl.php ├── InitialSetup ├── README.md ├── root_setup.sh ├── setup.sh └── update.sh ├── LICENSE ├── Monitor_Trunk_Failure └── trunkalert.agi ├── README.md ├── Reload_Reboot_Yealink ├── AstMan.php ├── TODO ├── ami_test.php ├── ext_test.php ├── ext_test.txt ├── func_test.php ├── reboot_confirm.php ├── reboot_phones.php └── reboot_process.php └── aastra_login.php /Aastra_Button_Functions/show_ring_group_membership.php: -------------------------------------------------------------------------------- 1 | 26 | Phone Services 27 | 28 | Traffic Reports 29 | rss_to_xml.pl 30 | 31 | 32 | Employee List 33 | employees.xml 34 | 35 | 36 | Weather 37 | http://10.50.10.52/weather.pl 38 | 39 | 40 | 41 | */ 42 | // Show or don't show user extension 43 | // 0 = do not show 1 = show 44 | $show_user_extension = 0; 45 | 46 | // Load FreePBX bootstrap environment 47 | require_once('/etc/freepbx.conf'); 48 | 49 | // Get the extension that was passed on the URL. 50 | $extension = $_GET["ext"]; 51 | // $extension = $argv[1]; // for testing from CLI 52 | // echo var_dump($extension)."\n"; 53 | 54 | // Initialize a database connection 55 | global $db; 56 | 57 | if ($show_user_extension == 1) { 58 | // Check to see if extension is valid and return the user name 59 | $sql = "SELECT `id`,`description` FROM `devices` WHERE `id` = $extension;"; 60 | // Execute the SQL statement 61 | $res = $db->prepare($sql); 62 | $res->execute(); 63 | // Check that something is returned 64 | if (DB::IsError($res)) { 65 | // Potentially clean this up so that it outputs pretty if not valid 66 | error_log( "Error attempting to get the name associated to the extension
($sql)
\n" . $res->getMessage() . "\n
\n"); 67 | } else { 68 | $row = $res->fetchAll(PDO::FETCH_ASSOC); 69 | // ensure there is only one row returned. Should be impossible to do anything else. 70 | if ( count($row) == 1 ) { 71 | $personal = "".$extension." - ".$row[0]['description']."\n"; 72 | } else { 73 | $personal = "".$extension." - Error Not Found\n"; 74 | } 75 | } 76 | } 77 | 78 | // Ring groups are only able to be queried from the MySQL database. 79 | // The `grplist` coliumn contains the list of extensions that are members. 80 | // The WHERE clause below is so specific in order to not match on a potential dupe as a substring. 81 | $sql = "SELECT `grpnum`,`description`,`grplist` FROM `ringgroups` "; 82 | $sql .= "WHERE `grplist` LIKE '$extension-%' OR `grplist` LIKE '%-$extension' OR `grplist` LIKE '%-$extension-%' OR `grplist` = '$extension' "; 83 | $sql .= "ORDER BY `description`;"; 84 | 85 | // Execute the SQL statement 86 | $res = $db->prepare($sql); 87 | $res->execute(); 88 | // Check that something is returned 89 | if (DB::IsError($res)) { 90 | // Potentially clean this up so that it outputs pretty if not valid 91 | error_log( "Error attemptig to get the list of ring groups
($sql)
\n" . $res->getMessage() . "\n
\n"); 92 | } else { 93 | $row = $res->fetchAll(PDO::FETCH_ASSOC); 94 | if ( count($row) > 0 ) { 95 | //echo "
Found ".count($row)." rows:\n";
 96 |       //echo var_dump($row);
 97 |       //echo "\n
\n"; 98 | //echo $row[0]['description']; 99 | $my_ringgroups = ""; 100 | foreach ($row as $line) { 101 | $my_ringgroups .= "".$line['grpnum']." - ".$line['description']."\n"; 102 | } 103 | } else { 104 | $my_ringgroups = "No ring groups found\n"; 105 | } 106 | } 107 | 108 | // Variable to hold non breaking space 109 | $nbsp = " "; 110 | // Output 111 | $xmlout = ""; 112 | $xmlout .= "\n"; 113 | if ($show_user_extension == 1) { 114 | $xmlout .= "Your Line\n"; 115 | $xmlout .= $personal; 116 | } 117 | $xmlout .= "".$nbsp.$nbsp."Your Ring Groups\n"; 118 | $xmlout .= $my_ringgroups; 119 | $xmlout .= "\n"; 120 | 121 | print $xmlout; 122 | 123 | 124 | ?> 125 | -------------------------------------------------------------------------------- /AsteriskDB_to_Yealink_AddressBook/yldump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import subprocess 3 | extension = {} 4 | output = [] 5 | output.append('') 6 | output.append('') 7 | p = subprocess.Popen(["asterisk", "-rx", "database show"], stdout=subprocess.PIPE) 8 | out = p.communicate() 9 | out = out[0].splitlines() 10 | for line in out: 11 | if line.startswith('/AMPUSER'): 12 | if line.find('/cidname') > 1: 13 | key,value = line.split(':') 14 | key = key.strip() 15 | key = key.split('/')[2] 16 | value = value.strip() 17 | extension[key] = value 18 | output.append(' ') 19 | output.append(' ' + value + '') 20 | output.append(' ' + key + '') 21 | output.append(' ') 22 | output.append('') 23 | 24 | contactfile = open('/var/www/html/contacts.xml', 'w') 25 | for item in output: 26 | contactfile.write("%s\n" % item) 27 | -------------------------------------------------------------------------------- /Backup_Yealink_Local_Contacts/README.md: -------------------------------------------------------------------------------- 1 | Simple script that handles PUT requests from Yealink phones in order to let you backup the local contact directory to the FreePBX `/tftpboot` via HTTP(S). 2 | 3 | 1. Download and copy the `put.yealink` file to the `/tftfpboot` directory 4 | 2. Give Asterisk ownership of the file `chown asterisk:asterisk /tftpboot/put.yealink` 5 | 3. Download and copy the `yealink.conf` file to the `/etc/httpd/conf.d` directory 6 | 1. If you are on FreePBX 15 or older, you need to edit this file to use php5. See the comments in the file. 7 | 5. Restart Apache `systemctl restart httpd` 8 | 6. Edit your provisioning file to enable the remote backup `static.auto_provision.local_contact.backup.enable= 1` 9 | 7. Edit your provisioning file with the URL `static.auto_provision.local_contact.backup.path = ` 10 | 1. HTTPS: `https://pbx.domain.com:1443` 11 | 2. HTTP: `http://pbx.domain.com:84` 12 | 3. Or it could include a username and password `https://123456:0987654321@pbx.domain.com:1443` 13 | 4. Or if you have the Commerical EPM use this in basfile edit: `__provisionAddress__` 14 | 8. Reprovision or reboot your phone to pick up the change 15 | 9. Edit your local address once to force it to upload the file 16 | 17 | For troubleshooting, errors will log the variable contents to the the apache error_log. 18 | 19 | This has been expanded to also allow the mac-local.cfg to be pushed back up. 20 | 21 | To start, follow steps 1-4 above if you have not already done it for the contact backup. 22 | 5. Edit your common.cfg provisioning file (the "y" file) to enable the remote backup 23 | 1. `static.auto_provision.custom.protect = 1` 24 | 2. `static.auto_provision.custom.sync = 1` 25 | 3. `static.auto_provision.custom.upload_method = 0` 26 | 6. Edit your provisioning file with the URL `static.auto_provision.custom.sync.path = ` 27 | 1. HTTPS: `https://pbx.domain.com:1443` 28 | 2. HTTP: `http://pbx.domain.com:84` 29 | 3. Or it could include a username and password 30 | 1. Inline `https://123456:0987654321@pbx.domain.com:1443` 31 | 2. As its own parameters 32 | 1. `static.auto_provision.server.username = USERNAME` 33 | 2. `static.auto_provision.server.password = PASSWORD` 34 | 4. Or if you have the Commerical EPM use this in basfile edit: `__provisionAddress__` 35 | 36 | 37 | Discussion: 38 | https://www.mangolassi.it/topic/19086/how-to-backup-your-yealink-local-contacts-to-the-freepbx-provisioning-directory 39 | https://www.mangolassi.it/topic/19865/how-to-tell-yealink-phones-to-upload-user-changes-to-the-freepbx-provisioning-directory 40 | 41 | -------------------------------------------------------------------------------- /Backup_Yealink_Local_Contacts/put.yealink: -------------------------------------------------------------------------------- 1 | 2 | # if you are on FreePBX 15 or lower, change the handler to 3 | # php5-script 4 | AddHandler php7-script .yealink 5 | AddType text/html .yealink 6 | RewriteEngine On 7 | RewriteCond %{REQUEST_METHOD} =PUT 8 | RewriteRule ^(.*)$ put.yealink?url=$1 9 | 10 | -------------------------------------------------------------------------------- /ContactManager_to_Digium_AddressBook/cm_to_digum_aseries.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 70 | $res->execute(); 71 | // Check that something is returned 72 | if (DB::IsError($res)) { 73 | // Potentially clean this up so that it outputs pretty if not valid 74 | error_log( "There was an error attempting to query contactmanager
($sql)
\n" . $res->getMessage() . "\n
\n"); 75 | } else { 76 | $contacts = $res->fetchAll(PDO::FETCH_ASSOC); 77 | 78 | // output the XML header info 79 | echo "\n"; 80 | // Output the XML root. This tag must be in the format XXXIPPhoneDirectory 81 | // You may change the word Company below, but no other part of the root tag. 82 | echo "\n"; 83 | 84 | // Loop through the results and output them correctly. 85 | // Spacing is setup below in case you wish to look at the result in a browser. 86 | $previousname = ""; 87 | $firstloop = true; 88 | foreach ($contacts as $contact) { 89 | if ($contact['displayname'] != $previousname) { 90 | if ($firstloop){ 91 | // flip the bit 92 | $firstloop = false; 93 | } else { 94 | // close the previous entry 95 | echo " " . $ringtype . "\n"; 96 | echo " \n"; 97 | } 98 | // Start the entry 99 | echo " \n"; 100 | echo " " . htmlspecialchars($contact['displayname']) . "\n"; 101 | // set the current name to the previous name 102 | $previousname = $contact['displayname']; 103 | } 104 | // Output the numbers as mapped above 105 | if ($contact['type'] == $telephone) { 106 | echo " "; 107 | // use the number or E164 field is specified, unless it is an internal extension 108 | if ($use_e164 == 0 || ($use_e164 == 1 && $contact['type'] == $ctype['internal'])) { echo $contact['number']; } else { echo $contact['E164']; } 109 | echo "\n"; 110 | } elseif ($contact['type'] == $mobile) { 111 | echo " "; 112 | // use the number or E164 field is specified, unless it is an internal extension 113 | if ($use_e164 == 0 || ($use_e164 == 1 && $contact['type'] == $ctype['internal'])) { echo $contact['number']; } else { echo $contact['E164']; } 114 | echo "\n"; 115 | } elseif ($contact['type'] == $other) { 116 | echo " "; 117 | // use the number or E164 field is specified, unless it is an internal extension 118 | if ($use_e164 == 0 || ($use_e164 == 1 && $contact['type'] == $ctype['internal'])) { echo $contact['number']; } else { echo $contact['E164']; } 119 | echo "\n"; 120 | } 121 | } 122 | // Close the last entry. 123 | echo " " . $ringtype . "\n"; 124 | echo " \n"; 125 | // Output the closing tag of the root. If you changed it above, make sure you change it here. 126 | echo "\n"; 127 | } 128 | 129 | ?> 130 | -------------------------------------------------------------------------------- /ContactManager_to_Fanvil_AddressBook/cm_to_fv_ab.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 59 | $res->execute(); 60 | // Check that something is returned 61 | if (DB::IsError($res)) { 62 | // Potentially clean this up so that it outputs pretty if not valid 63 | error_log( "There was an error attempting to query contactmanager
($sql)
\n" . $res->getMessage() . "\n
\n"); 64 | } else { 65 | $contacts = $res->fetchAll(PDO::FETCH_ASSOC); 66 | 67 | foreach ($contacts as $i => $contact){ 68 | // The if staements provide the ability to re-lable the phone number type as you wish. 69 | // It also allows for setting the number display order to be changed for multi-number contacts. 70 | // $contact['type'] will be used as the label 71 | // $contact['sortorder'] will be used as the sort order 72 | if ($contact['type'] == "cell") { 73 | $contact['type'] = $ctype['cell']; 74 | $contact['sortorder'] = 3; 75 | } 76 | if ($contact['type'] == "internal") { 77 | $contact['type'] = $ctype['internal']; 78 | $contact['sortorder'] = 1; 79 | } 80 | if ($contact['type'] == "work") { 81 | $contact['type'] = $ctype['work']; 82 | $contact['sortorder'] = 2; 83 | } 84 | if ($contact['type'] == "other") { 85 | $contact['type'] = $ctype['other']; 86 | $contact['sortorder'] = 4; 87 | } 88 | if ($contact['type'] == "home") { 89 | $contact['type'] = $ctype['home']; 90 | $contact['sortorder'] = 5; 91 | } 92 | $contact['displayname'] = htmlspecialchars($contact['displayname']); 93 | // put the changes back into $contacts 94 | $contacts[$i] = $contact; 95 | } 96 | 97 | // output the XML header info 98 | echo "\n"; 99 | // Output the XML root. This tag must be in the format XXXIPPhoneDirectory 100 | // You may change the word Company below, but no other part of the root tag. 101 | echo "\n"; 102 | 103 | // Loop through the results and output them correctly. 104 | // Spacing is setup below in case you wish to look at the result in a browser. 105 | $previousname = ""; 106 | $firstloop = true; 107 | foreach ($contacts as $contact) { 108 | if ($contact['displayname'] != $previousname) { 109 | if ($firstloop){ 110 | // flip the bit 111 | $firstloop = false; 112 | } else { 113 | // close the previous entry 114 | echo " \n"; 115 | } 116 | // Start the entry 117 | echo " \n"; 118 | echo " " . $contact['displayname'] . "\n"; 119 | // set the current name to the previous name 120 | $previousname = $contact['displayname']; 121 | } 122 | if ($use_e164 == 0 || ($use_e164 == 1 && $contact['type'] == $ctype['internal'])) { 123 | // not using E164 or it is an internal extnsion 124 | echo " <" . $contact['type'] . ">" . $contact['number'] . "\n"; 125 | } else { 126 | // using E164s 127 | echo " <" . $contact['type'] . ">" . $contact['E164'] . "\n"; 128 | } 129 | } 130 | // Close the last entry. 131 | echo " \n"; 132 | // Output the closing tag of the root. If you changed it above, make sure you change it here. 133 | echo "\n"; 134 | } 135 | 136 | ?> 137 | -------------------------------------------------------------------------------- /ContactManager_to_Yealink_AddressBook/cm_to_yl_ab.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 59 | $res->execute(); 60 | // Check that something is returned 61 | if (DB::IsError($res)) { 62 | // Potentially clean this up so that it outputs pretty if not valid 63 | error_log( "There was an error attempting to query contactmanager
($sql)
\n" . $res->getMessage() . "\n
\n"); 64 | } else { 65 | $contacts = $res->fetchAll(PDO::FETCH_ASSOC); 66 | 67 | foreach ($contacts as $i => $contact){ 68 | // The if staements provide the ability to re-lable the phone number type as you wish. 69 | // It also allows for setting the number display order to be changed for multi-number contacts. 70 | // $contact['type'] will be used as the label 71 | // $contact['sortorder'] will be used as the sort order 72 | if ($contact['type'] == "cell") { 73 | $contact['type'] = $ctype['cell']; 74 | $contact['sortorder'] = 3; 75 | } 76 | if ($contact['type'] == "internal") { 77 | $contact['type'] = $ctype['internal']; 78 | $contact['sortorder'] = 1; 79 | } 80 | if ($contact['type'] == "work") { 81 | $contact['type'] = $ctype['work']; 82 | $contact['sortorder'] = 2; 83 | } 84 | if ($contact['type'] == "other") { 85 | $contact['type'] = $ctype['other']; 86 | $contact['sortorder'] = 4; 87 | } 88 | if ($contact['type'] == "home") { 89 | $contact['type'] = $ctype['home']; 90 | $contact['sortorder'] = 5; 91 | } 92 | $contact['displayname'] = htmlspecialchars($contact['displayname']); 93 | // put the changes back into $contacts 94 | $contacts[$i] = $contact; 95 | } 96 | /* 97 | // This sorts the extensions array by two fields, the display name and then the sort order field 98 | // To change the sort order of the labels, change the sort order number in the if statements above.. 99 | $dname = array(); 100 | $order = array(); 101 | for ($i = 0; $i < count($contacts); $i++) { 102 | $dname[] = $contacts[$i]['displayname']; 103 | $sorder[] = $contacts[$i]['sortorder']; 104 | } 105 | // now apply sort 106 | array_multisort($dname, SORT_ASC, 107 | $sorder, SORT_ASC, SORT_NUMERIC, 108 | $contacts); 109 | */ 110 | // output the XML header info 111 | echo "\n"; 112 | // Output the XML root. This tag must be in the format XXXIPPhoneDirectory 113 | // You may change the word Company below, but no other part of the root tag. 114 | echo "\n"; 115 | 116 | // Loop through the results and output them correctly. 117 | // Spacing is setup below in case you wish to look at the result in a browser. 118 | $previousname = ""; 119 | foreach ($contacts as $contact) { 120 | if ($contact['displayname'] != $previousname) { 121 | // Start the entry 122 | echo " \n"; 123 | echo " " . $contact['displayname'] . "\n"; 124 | if ($use_e164 == 0 || ($use_e164 == 1 && $contact['type'] == $ctype['internal'])) { 125 | // not using E164 or it is an internal extension 126 | echo " " . $contact['number'] . "\n"; 127 | } else { 128 | // using E164 129 | echo " " . $contact['E164'] . "\n"; 130 | } 131 | echo " \n"; 132 | // set the current name to the previous name 133 | $previousname = $contact['displayname']; 134 | } 135 | } 136 | // Output the closing tag of the root. If you changed it above, make sure you change it here. 137 | echo "\n"; 138 | } 139 | 140 | ?> 141 | -------------------------------------------------------------------------------- /Example_Yealink_XML_Menu/shared_contacts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | John Doe 9 | 10 | 11 | 5555551212 12 | 13 | 14 | Jenny 15 | 5558675309 16 | 17 | 18 | -------------------------------------------------------------------------------- /Example_Yealink_XML_Menu/ylmenu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Company Contacts 5 | 6 | 7 | Employees 8 | https://pbx.domain.com/ylab.php 9 | 10 | 11 | Shared Contacts 12 | https://pbx.domain.com/shared_contacts.xml 13 | 14 | 15 | -------------------------------------------------------------------------------- /Extension_Status/README.md: -------------------------------------------------------------------------------- 1 | To "install" this, you simply need to copy the files to a directory on your FreePBX system. 2 | 3 | I like to use `/var/ww/html/custom` for anything I add to FreepBX. 4 | 5 | Here are the commands to run to pull it down from here. 6 | 7 | ``` 8 | sudo mkdir -p /var/www/html/custom 9 | cd /var/www/html/custom 10 | sudo wget https://github.com/sorvani/freepbx-helper-scripts/raw/master/Extension_Status/extensionstatus.php 11 | sudo wget https://github.com/sorvani/freepbx-helper-scripts/raw/master/Extension_Status/extensionstatus_header.php 12 | sudo chown -R asterisk:asterisk /var/www/html/custom 13 | cd ~ 14 | ``` 15 | -------------------------------------------------------------------------------- /Extension_Status/extensionstatus.php: -------------------------------------------------------------------------------- 1 | PJSIPShowRegistrationInboundContactStatuses(); 22 | 23 | include './extensionstatus_header.php'; 24 | 25 | 26 | foreach ($results as $data) { 27 | echo ' ' . "\n"; 28 | 29 | // The extension 30 | echo ' ' . $data['AOR'] . '' . "\n"; 31 | 32 | // Extension Display Name 33 | // Use this on FreePBX <=15 aka PHP 5 34 | // if ((substr($data['AOR'],0,2) === '90') || (substr($data['AOR'],0,2) === '98')) { 35 | // Use this on FreePBX 16 aka PHP 7+ 36 | if (str_starts_with($data['AOR'],'90') || str_starts_with($data['AOR'],'98')) { 37 | $user=$fcore->getUser(substr($data['AOR'],2)); 38 | } else { 39 | $user=$fcore->getUser($data['AOR']); 40 | } 41 | echo ' ' . $user['name'] . '' . "\n"; 42 | 43 | // The URI is the AOR that we will send commands back to eventually 44 | // Eventual notify syntax to replicate 45 | // rasterisk -c 'pjsip send notify reload-yealink uri sip:103@64.53.207.74:12682' 46 | // rasterisk -x 'pjsip send notify default-yealink uri sip:5120@64.53.207.74:1073;x-ast-orig-host=10.254.103.215:5060' 47 | if ($showuri) { echo ' ' . $data['URI'] . '' . "\n"; } 48 | 49 | // The user agent contains information about the device. 50 | // Break it into pieces as Brand/Model/Firmware 51 | /********** Examples 52 | ["UserAgent"]=> string(31) "Yealink SIP VP-T49G 51.80.0.100" 53 | ["UserAgent"]=> string(26) "Yealink SIP-T54W 96.85.0.5" 54 | ["UserAgent"]=> string(17) "Zoiper rv2.10.8.2" 55 | ["UserAgent"]=> string(26) "Grandstream HT802 1.0.17.5" 56 | ["UserAgent"]=> string(16) "snomPA1/8.7.3.19" 57 | ["UserAgent"]=> string(54) "LinphoneiOS/4.3.0 (Bob's iPhone) LinphoneSDK/4.4.0" 58 | ["UserAgent"]=> string(24) "OBIHAI/OBi202-3.2.2.5921" 59 | ["UserAgent"]=> string(15) "MicroSIP/3.20.5" 60 | ["UserAgent"]=> string(14) "Acrobits SIPIS" // Sangoma Connect push service 61 | ["UserAgent"]=> string(15) "Telephone 1.5.2" // macOS app "Telephone" 62 | ["UserAgent"]=> string(67) "Linphone Desktop/4.2.5 (macOS 10.15, Qt 5.15.2) LinphoneCore/4.4.19" 63 | ["UserAgent"]=> string(21) "Sangoma Connect/1.0.1" 64 | ["UserAgent"]=> string(4) "Zulu" 65 | ["UserAgent"]=> string(47) "PolycomRealPresenceTrio-Trio_8500-UA/5.9.2.7727" 66 | ["UserAgent"]=> string(43) "PolycomSoundPointIP-SPIP_450-UA/4.0.15.1047" 67 | ["UserAgent"]=> string(24) "Jitsi2.10.5550Windows 10" 68 | ["UserAgent"]=> string(18) "Z 5.5.5 v2.10.15.2" //potentially Jitsi on macOS. 69 | ["UserAgent"]=> string(13) "Algo-8201/5.2" // Algo door intercom 70 | **********/ 71 | $ret_info = get_device_info($data['UserAgent']); 72 | echo ' ' . $ret_info['brand'] . '' . "\n"; 73 | echo ' ' . $ret_info['model'] . '' . "\n"; 74 | echo ' ' . $ret_info['firmware'] . '' . "\n"; 75 | 76 | // show the Status 77 | echo ' ' . $data['Status'] . '' . "\n"; 78 | 79 | // Show RTT times in milliseconds 80 | if (is_numeric($data['RoundtripUsec'])) { 81 | echo ' ' . $data['RoundtripUsec'] / 1000 . ' ms' . "\n"; 82 | } else { 83 | echo ' -' . "\n"; 84 | } 85 | 86 | 87 | // Pull out the various IP addresses known to Asterisk. 88 | /********* Examples 89 | // Yealink phones (all) 90 | ["CallID"] => string(28) "0_1362581122@192.168.101.161" 91 | ["URI"] => string(61) "sip:417@1X.2X.1X.1X:1025;x-ast-orig-host=10.1.17.130:5060" 92 | ["ViaAddress"] => string(17) "10.202.40.37:5060" 93 | 94 | // Grandstream HT802 95 | ["CallID"] => string(32) "1893618396-5060-2@BJC.BGI.BAC.HA" 96 | ["ViaAddress"] => string(18) "10.202.40.121:5062" 97 | 98 | // Zoiper 99 | ["CallID"] => string(24) "5nw8H9tLIoXbkewN-pn_1w.." 100 | 101 | //MicroSIP 102 | ["CallID"] => string(32) "341cec212e1747b692e5663b2023b123" 103 | ["URI"] => string(64) "sip:4272@6X.9X.2X.1X:33980;ob;x-ast-orig-host=10.0.1.131:57017" 104 | ["ViaAddress"] => string(16) "10.0.1.131:57017" 105 | 106 | //Snom PA1 107 | ["CallID"] => string(25) "386d43a45de1-l88ln518lzf9" 108 | ["ViaAddress"] => string(17) "10.202.40.33:5060" 109 | 110 | //LinphoneiOS 111 | ["CallID"] => string(10) "Ar-U8i4THj" 112 | ["ViaAddress"] => string(20) "10.254.103.179:65310" // on wifi 113 | ["ViaAddress"] => string(45) "2607:fb90:e120:b95f:c91c:ebd4:e11f:f45e:53362" // on cellular 114 | 115 | //OBiHAI 116 | ["CallID"] => string(29) "65844919897ccd8f@10.101.5.131" 117 | ["URI"] => string(25) "sip:416@6X.6X.2X.2X:5060" 118 | ["ViaAddress"] => string(17) "10.101.5.131:5060" 119 | 120 | // Polycom 121 | ["CallID"]=> string(39) "affc1078-ed6cde77-f19623f6@192.168.7.50" 122 | ["URI"]=> string(57) "sip:301@6X.5X.2X.2X:5060;x-ast-orig-host=192.168.7.50:0" 123 | ["ViaAddress"]=> string(12) "192.168.7.50" 124 | *********/ 125 | $callid = end(explode('@',$data['CallID'])); 126 | $viaaddress = explode(':',$data['ViaAddress']); 127 | $uri = explode(':',end(explode('@',$data['URI']))); 128 | echo ' ' . "\n"; 129 | if (!filter_var($uri[0], FILTER_VALIDATE_IP)) { $uri[0] = 'Not an IP'; } 130 | if (!filter_var($viaaddress[0], FILTER_VALIDATE_IP)) { $viaaddress[0] = 'Not an IP'; } 131 | if (!filter_var($callid, FILTER_VALIDATE_IP)) { $callid = 'Not an IP'; } 132 | echo ' URI: ' . $uri[0] . '
' . "\n"; 133 | echo ' Via: ' . $viaaddress[0] . '
' . "\n"; 134 | echo ' CallID: ' . $callid . '
' . "\n"; 135 | echo ' ' . "\n"; 136 | 137 | // Make RegExpire human readable 138 | $regexpire = $data['RegExpire']; 139 | $regexpire = new DateTime("@$regexpire", new DateTimeZone("UTC")); 140 | $regexpire->setTimezone(new DateTimeZone(date_default_timezone_get())); 141 | echo ' ' . $regexpire->format('Y/m/d H:i:s') . '' . "\n"; 142 | echo ' ' . "\n"; 143 | } 144 | 145 | // close out table and div. likely change to include eventually 146 | echo ' ' . "\n"; 147 | echo '' . "\n"; 148 | echo '' . "\n"; 149 | 150 | 151 | function get_device_info($ua) { 152 | $ua_arr = preg_split("/[\s\/]/", $ua, 2); 153 | switch ($ua_arr[0]) { 154 | case "Yealink": 155 | case "Zulu": 156 | case "Z": 157 | $mod_firm_arr = preg_split("/[\s]/", preg_replace("/^SIP[\s-]/","",$ua_arr[1])); 158 | $device_info = ["brand" => $ua_arr[0], "model" => $mod_firm_arr[0], "firmware" => $mod_firm_arr[1]]; 159 | break; 160 | case "Grandstream": 161 | case "OBIHAI": 162 | case "Fanvil": 163 | case "Acrobits": 164 | case "Cisco": 165 | $mod_firm_arr = preg_split("/[\s-]/", $ua_arr[1]); 166 | $device_info = ["brand" => $ua_arr[0], "model" => $mod_firm_arr[0], "firmware" => $mod_firm_arr[1]]; 167 | break; 168 | case "Sangoma": 169 | $mod_firm_arr = preg_split("/[\/]/", $ua_arr[1]); 170 | $device_info = ["brand" => $ua_arr[0], "model" => $mod_firm_arr[0], "firmware" => $mod_firm_arr[1]]; 171 | break; 172 | case "Zoiper": 173 | case "MicroSIP": 174 | case "Telephone": 175 | $device_info = ["brand" => $ua_arr[0], "model" => "", "firmware" => $ua_arr[1]]; 176 | break; 177 | case "snomPA1": 178 | $device_info = ["brand" => "Snom", "model" => "PA1", "firmware" => $ua_arr[1]]; 179 | break; 180 | case "LinphoneiOS": 181 | $mod_firm_arr = preg_split("/[\s]/", $ua_arr[1]); 182 | $device_info = ["brand" => $ua_arr[0], "model" => "", "firmware" => $mod_firm_arr[0]]; 183 | break; 184 | case "Linphone": //Linphone Desktop 185 | $mod_firm_arr = preg_split("/[\s\/]/", preg_replace('/\(|\)/','',$ua_arr[1])); 186 | $device_info = ["brand" => $ua_arr[0] . " " . $mod_firm_arr[0], "model" => $mod_firm_arr[2], "firmware" => $mod_firm_arr[1]]; 187 | break; 188 | default: 189 | // Messy, will look into it after more Poly devices are tested 190 | if (substr($ua_arr[0],0,7) == "Polycom") { 191 | $mod_firm_arr = preg_split("/[-]/", $ua_arr[0]); 192 | $device_info = ["brand" => "Polycom", "model" => preg_replace('/_/',' ',$mod_firm_arr[1]), "firmware" => $ua_arr[1]]; 193 | // Algo is Algo-NNNN/firmware 194 | } elseif (substr($ua_arr[0],0,4) == "Algo" ) { 195 | $mod_arr = preg_split("/[-]/", $ua_arr[0]); 196 | $device_info = ["brand" => $mod_arr[0], "model" => $mod_arr[1], "firmware" => $ua_arr[1]]; 197 | // Jitsi on Windows does not have a split character. 198 | } elseif (substr($ua_arr[0],0,5) == "Jitsi" ) { 199 | $regexp='/(\D+)([\d\.]+)(\D+.*)/'; 200 | preg_match($regexp, $ua, $ua_jitsi); 201 | $device_info = ["brand" => $ua_jitsi[1], "model" => $ua_jitsi[3], "firmware" => $ua_jitsi[2]]; 202 | } else { 203 | $device_info = ["brand" => "Unknown", "model" => "", "firmware" => ""]; 204 | } 205 | } 206 | return $device_info; 207 | } 208 | 209 | if ($showdebug) { 210 | echo "
BEGIN RESULTS DUMP
\r\n
\r\n";
211 |   var_dump($results);
212 |   echo "\r\n

\r\nEND RESULTS DUMP\r\n"; 213 | } 214 | 215 | ?> 216 | -------------------------------------------------------------------------------- /Extension_Status/extensionstatus_header.php: -------------------------------------------------------------------------------- 1 | Extension Status 2 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | URI"; } 31 | ?> 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Extensions_to_Grandstream_Phonebook/generate_gs_phonebook.php: -------------------------------------------------------------------------------- 1 | 'custom';"; 26 | // This example will pull all extensions from 1000 to 1999 27 | // $sql = "SELECT `id`,`description` FROM `devices` WHERE `id` BETWEEN 1000 and 1999;"; 28 | 29 | // Execute the SQL statement 30 | $res = $db->prepare($sql); 31 | $res->execute(); 32 | // Check that something is returned 33 | if (DB::IsError($res)) { 34 | // Potentially clean this up so that it outputs pretty if not valid 35 | error_log( "There was an error attempting to query the extensions
($sql)
\n" . $res->getMessage() . "\n
\n"); 36 | } else { 37 | $extensions = $res->fetchAll(PDO::FETCH_ASSOC); 38 | //gs_phonebook.xml for older models like GXP1200 39 | // output the XML header info 40 | echo "\n"; 41 | // Root element of XML 42 | echo "\n"; 43 | // Loop through the results and output them correctly. 44 | // Spacing is setup below in case you wish to look at the result in a browser. 45 | foreach ($extensions as $extension) { 46 | echo " \n"; 47 | echo " " . $extension['description'] . "\n"; 48 | echo " \n"; 49 | echo " " . $extension['id'] . "\n"; 50 | echo " 0\n"; 51 | echo " \n"; 52 | echo " \n"; 53 | } 54 | // Output the closing tag of the root. 55 | echo "\n"; 56 | } 57 | /* 58 | // phonebook.xml for newer models like GXP2110 59 | // output the XML header info 60 | echo "\n"; 61 | // Root element of XML 62 | echo "\n"; 63 | // Loop through the results and output them correctly. 64 | // Spacing is setup below in case you wish to look at the result in a browser. 65 | foreach ($extensions as $extension) { 66 | echo " \n"; 67 | echo " " . $extension['description'] . "\n"; 68 | echo " \n"; 69 | echo " \n"; 70 | echo " " . $extension['id'] . "\n"; 71 | echo " 1\n"; 72 | echo " \n"; 73 | echo " \n"; 74 | } 75 | // Output the closing tag of the root. 76 | echo "\n"; 77 | */ 78 | ?> 79 | -------------------------------------------------------------------------------- /Extensions_to_Yealink_AddressBook/ylab.php: -------------------------------------------------------------------------------- 1 | 'custom';"; 25 | // This example will pull all extensions from 1000 to 1999 26 | // $sql = "SELECT `id`,`description` FROM `devices` WHERE `id` BETWEEN 1000 and 1999;"; 27 | 28 | // Execute the SQL statement 29 | $res = $db->prepare($sql); 30 | $res->execute(); 31 | // Check that something is returned 32 | if (DB::IsError($res)) { 33 | // Potentially clean this up so that it outputs pretty if not valid 34 | error_log( "There was an error attempting to query the extensions
($sql)
\n" . $res->getMessage() . "\n
\n"); 35 | } else { 36 | $extensions = $res->fetchAll(PDO::FETCH_ASSOC); 37 | // output the XML header info 38 | echo "\n"; 39 | // Output the XML root. This tag must be in the format XXXIPPhoneDirectory 40 | // You may change the word Company below, but no other part of the root tag. 41 | echo "\n"; 42 | 43 | // Loop through the results and output them correctly. 44 | // Spacing is setup below in case you wish to look at the result in a browser. 45 | foreach ($extensions as $extension) { 46 | echo " \n"; 47 | echo " " . $extension['description'] . "\n"; 48 | echo " " . $extension['id'] . "\n"; 49 | echo " \n"; 50 | } 51 | // Output the closing tag of the root. If you changed it above, make sure you change it here. 52 | echo "\n"; 53 | } 54 | 55 | ?> 56 | -------------------------------------------------------------------------------- /George1421_Yealink_AddressBook/yl.php: -------------------------------------------------------------------------------- 1 | \"\']+)\s*$/",$line,$matches)) { 22 | $amp_conf[ $matches[1] ] = $matches[2]; 23 | } 24 | } 25 | } 26 | 27 | require_once('DB.php'); //PEAR must be installed 28 | $db_user = $amp_conf["AMPDBUSER"]; 29 | $db_pass = $amp_conf["AMPDBPASS"]; 30 | $db_host = $amp_conf["AMPDBHOST"]; 31 | $db_name = $amp_conf["AMPDBNAME"]; 32 | 33 | $datasource = 'mysql://'.$db_user.':'.$db_pass.'@'.$db_host.'/'.$db_name; 34 | $db = DB::connect($datasource); // attempt connection 35 | 36 | $type="getAll"; 37 | $results = $db->$type("select extension,name,voicemail from users where voicemail <> 'novm' order by name asc", null); 38 | # $results = $db->$type("SELECT extension,name,voicemail FROM users ORDER BY extension", null); 39 | foreach($results as $result){ 40 | $extensions[] = array($result[0],$result[1],$result[2]); 41 | } 42 | 43 | #$extensions = core_users_list(); 44 | echo "\n"; 45 | echo " \n"; 46 | echo "\n\tPhoneList"; 47 | echo "\n\tPrompt"; 48 | $index = 0; 49 | if (isset($extensions)) { 50 | foreach ($extensions as $key=>$extension) { 51 | $index= $index + 1; 52 | echo "\n\t"; 53 | echo "\n\t\t" . $extension[1] . ""; 54 | echo "\n\t\t" . $extension[0] . ""; 55 | echo "\n\t\n"; 56 | } 57 | } 58 | echo "\n\t"; 59 | echo "\n\t\t2"; 60 | echo "\n\t\thttp://192.168.1.16/directory/yl.php"; 61 | echo "\n\t"; 62 | 63 | echo "\n \n"; 64 | ?> 65 | -------------------------------------------------------------------------------- /InitialSetup/README.md: -------------------------------------------------------------------------------- 1 | ## Log in to a new FreePBX 15 or 16 instance as root and run the following to get started. 2 | 3 | `wget https://raw.githubusercontent.com/sorvani/freepbx-helper-scripts/master/InitialSetup/root_setup.sh` 4 | 5 | `chmod +x root_setup.sh` 6 | 7 | `./root_setup.sh` 8 | 9 | -------------------------------------------------------------------------------- /InitialSetup/root_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Prompt for a username and password 4 | # Possibly change this to a parameter 5 | read -p "Enter a new username to use for SSH access: " myUserName 6 | 7 | # Create user account with default password of ChangeMe 8 | echo "Creating the user $myUserName and assigning permissions" 9 | echo "" 10 | useradd --create-home $myUserName --password $(openssl passwd -1 ChangeMe) >> setup.log 11 | # expire the password to force reset on first login 12 | chage -d 0 $myUserName >> setup.log 13 | # Add user to wheel and asterisk groups 14 | gpasswd -a $myUserName wheel >> setup.log 15 | gpasswd -a $myUserName asterisk >> setup.log 16 | 17 | # Disable root login via ssh 18 | echo "Disabling root login to SSH." 19 | echo "" 20 | sed -i 's/^#\?\(PermitRootLogin\s*\).*$/\1no/' /etc/ssh/sshd_config >> setup.log 21 | 22 | # Restart SSH service to apply changes 23 | echo "Restarting the SSH service" 24 | echo "" 25 | systemctl restart sshd >> setup.log 26 | 27 | # Pre download the setup script into the user's home directory. 28 | echo "Downloading the main setup script" 29 | echo "" 30 | wget -O /home/$myUserName/setup.sh https://raw.githubusercontent.com/sorvani/freepbx-helper-scripts/master/InitialSetup/setup.sh >> setup.log 31 | chown $myUserName:$myUserName /home/$myUserName/setup.sh >> setup.log 32 | chmod +x /home/$myUserName/setup.sh >> setup.log 33 | 34 | # Pre download the update script into the user's home directory. 35 | echo "Downloading the update script" 36 | echo "" 37 | wget -O /home/$myUserName/update.sh https://raw.githubusercontent.com/sorvani/freepbx-helper-scripts/master/InitialSetup/update.sh >> setup.log 38 | chown $myUserName:$myUserName /home/$myUserName/update.sh >> setup.log 39 | chmod +x /home/$myUserName/update.sh >> setup.log 40 | 41 | 42 | ipaddress=`ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'` 43 | 44 | echo "Root setup complete." 45 | echo "Please log out from the root user and login, via SSH to $ipaddress or the FQDN you have setup, with username: $myUserName." 46 | echo "You will be required to change your password. It is currently set to: ChangeMe" 47 | echo "" 48 | echo "Then execute 'sudo ./setup.sh'" 49 | -------------------------------------------------------------------------------- /InitialSetup/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | logfile=setup.log 3 | printf "Beginning FreePBX 15 initial setup...\n" | tee -a $logfile 4 | if [ "$EUID" -ne 0 ] 5 | then printf "This script must be executed with sudo. Please run again: sudo ./setup.sh\n" | tee -a $logfile 6 | exit 7 | fi 8 | 9 | # Require key for ssh login 10 | printf "Disabling password login to SSH.\n" | tee -a $logfile 11 | # Ends up with duplicate PasswordAuthentication because it modifies both #PasswordAuthentication and PasswordAuthentication 12 | sed -i 's/^#\?\(PasswordAuthentication\s*\).*$/\1no/' /etc/ssh/sshd_config | tee -a $logfile 13 | systemctl restart sshd | tee -a $logfile 14 | 15 | printf "Updating operating system.\n" | tee -a $logfile 16 | printf "This can take a seemingly excessive amount of time depending on\n" | tee -a $logfile 17 | printf "how many Linux updates have been released since the ISO was created.\n" | tee -a $logfile 18 | yum update -y | tee -a $logfile 19 | printf "Installing git\n" | tee -a $logfile 20 | yum install git -y | tee -a $logfile 21 | printf "Operating system upgrades completed.\n" | tee -a $logfile 22 | printf "Removing FreePBX commerical modules, except sysadmin...\n" | tee -a $logfile 23 | printf "Removing Oracle Connector\n" | tee -a $logfile 24 | fwconsole ma delete oracle_connector >> $logfile 25 | printf "Removing Advanced Recovery\n" | tee -a $logfile 26 | fwconsole ma delete adv_recovery >> $logfile 27 | printf "Removing Appointment Reminder\n" | tee -a $logfile 28 | fwconsole ma delete areminder >> $logfile 29 | printf "Removing Broadcast\n" | tee -a $logfile 30 | fwconsole ma delete broadcast >> $logfile 31 | printf "Removing Call Accounting\n" | tee -a $logfile 32 | fwconsole ma delete callaccounting >> $logfile 33 | printf "Removing CallerID Managment\n" | tee -a $logfile 34 | fwconsole ma delete callerid >> $logfile 35 | printf "Removing Outbound Call Limit\n" | tee -a $logfile 36 | fwconsole ma delete calllimit >> $logfile 37 | printf "Removing Conference Professional\n" | tee -a $logfile 38 | fwconsole ma delete conferencespro >> $logfile 39 | printf "Removing Extension Routes\n" | tee -a $logfile 40 | fwconsole ma delete extensionroutes >> $logfile 41 | printf "Removing Fax Configuration Professional\n" | tee -a $logfile 42 | fwconsole ma delete faxpro >> $logfile 43 | printf "Removing IoT Server\n" | tee -a $logfile 44 | fwconsole ma delete iotserver >> $logfile 45 | printf "Removing Paging Professional\n" | tee -a $logfile 46 | fwconsole ma delete pagingpro >> $logfile 47 | printf "Removing Parking Professional\n" | tee -a $logfile 48 | fwconsole ma delete parkpro >> $logfile 49 | printf "Removing Pinsets Professional\n" | tee -a $logfile 50 | fwconsole ma delete pinsetspro >> $logfile 51 | printf "Removing Property Management System\n" | tee -a $logfile 52 | fwconsole ma delete pms >> $logfile 53 | printf "Removing Queue Wallboard\n" | tee -a $logfile 54 | fwconsole ma delete queuestats >> $logfile 55 | printf "Removing Queue reports\n" | tee -a $logfile 56 | fwconsole ma delete qxact_reports >> $logfile 57 | printf "Removing Call Recording Report\n" | tee -a $logfile 58 | fwconsole ma delete recording_report >> $logfile 59 | printf "Removing Rest Apps\n" | tee -a $logfile 60 | fwconsole ma delete restapps >> $logfile 61 | printf "Removing Endpoint Manager\n" | tee -a $logfile 62 | fwconsole ma delete endpoint >> $logfile 63 | printf "Removing Sangoma CRM\n" | tee -a $logfile 64 | fwconsole ma delete sangomacrm >> $logfile 65 | printf "Removing SIPSTATION\n" | tee -a $logfile 66 | fwconsole ma delete sipstation >> $logfile 67 | printf "Removing Vega\n" | tee -a $logfile 68 | fwconsole ma delete vega >> $logfile 69 | printf "Removing Voicemail Notifications\n" | tee -a $logfile 70 | fwconsole ma delete vmnotify >> $logfile 71 | printf "Removing Voicemail Reports\n" | tee -a $logfile 72 | fwconsole ma delete voicemail_report >> $logfile 73 | printf "Removing Queues Professional\n" | tee -a $logfile 74 | fwconsole ma delete vqplus >> $logfile 75 | printf "Removing Web Callback\n" | tee -a $logfile 76 | fwconsole ma delete webcallback >> $logfile 77 | printf "Removing Zulu\n" | tee -a $logfile 78 | fwconsole ma delete zulu >> $logfile 79 | printf "Removing Sangoma Connect\n" | tee -a $logfile 80 | fwconsole ma delete sangomaconnect >> $logfile 81 | printf "Removing SMS\n" | tee -a $logfile 82 | fwconsole ma delete sms >> $logfile 83 | printf "Removing Class of Service\n" | tee -a $logfile 84 | fwconsole ma delete cos >> $logfile 85 | printf "Removing rarely needed Open Source modules\n" | tee -a $logfile 86 | printf "Removing Answering Machine Detection\n" | tee -a $logfile 87 | fwconsole ma delete amd >> $logfile 88 | printf "Removing iSymphonyV3\n" | tee -a $logfile 89 | fwconsole ma delete cxpanel >> $logfile 90 | printf "Removing Digium Phones Config\n" | tee -a $logfile 91 | fwconsole ma delete digium_phones >> $logfile 92 | printf "Removing Digium Addons\n" | tee -a $logfile 93 | fwconsole ma delete digiumaddoninstaller >> $logfile 94 | printf "Removing Wake Up Calls\n" | tee -a $logfile 95 | fwconsole ma delete hotelwakeup >> $logfile 96 | printf "Removing IRC\n" | tee -a $logfile 97 | fwconsole ma delete irc >> $logfile 98 | printf "Removing DISA\n" | tee -a $logfile 99 | fwconsole ma delete disa >> $logfile 100 | printf "Removing PHP Info\n" | tee -a $logfile 101 | fwconsole ma delete phpinfo >> $logfile 102 | # printf "Removing Rest API\n" | tee -a $logfile 103 | # fwconsole ma delete restapi >> $logfile 104 | printf "Reloading FreePBX...\n" | tee -a $logfile 105 | fwconsole reload >> $logfile 106 | printf "Enabling commerical repository...\n" | tee -a $logfile 107 | fwconsole ma enablerepo commercial >> $logfile 108 | printf "Upgrading all installed modules...\n" | tee -a $logfile 109 | printf "This can also take a seemingly excessive amount of time depending on\n" | tee -a $logfile 110 | printf "how many module updates have been released since the ISO was created.\n" | tee -a $logfile 111 | fwconsole ma upgradeall 2> /dev/null >> $logfile 112 | printf "Updating all permissions...\n" | tee -a $logfile 113 | fwconsole chown 2> /dev/null | tee -a $logfile 114 | printf "Reloading FreePBX...\n" | tee -a $logfile 115 | fwconsole reload >> $logfile 116 | printf "Your initial FreePBX command line setup is complete.\n" | tee -a $logfile 117 | ipaddress=`ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'` 118 | printf "Please reboot and then navigate to https://$ipaddress or https://YOURFQDN to complete your setup.\n" | tee -a $logfile 119 | -------------------------------------------------------------------------------- /InitialSetup/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | logdate=`date +"%Y%m%d-%H%M%S"` 3 | logfile=upgrade-$logdate.log 4 | printf "Beginning update of FreePBX 15...\n" | tee -a $logfile 5 | if [ "$EUID" -ne 0 ] 6 | then printf "This script must be executed with sudo. Please run again: sudo ./update.sh\n" | tee -a $logfile 7 | exit 8 | fi 9 | 10 | printf "Updating operating system.\n" | tee -a $logfile 11 | printf "This can take a seemingly excessive amount of time depending on\n" | tee -a $logfile 12 | printf "how many Linux updates have been released since the last update.\n" | tee -a $logfile 13 | yum update -y | tee -a $logfile 14 | 15 | printf "Upgrading all installed modules...\n" | tee -a $logfile 16 | printf "This can also take a seemingly excessive amount of time depending on\n" | tee -a $logfile 17 | printf "how many module updates have been released since the update.\n" | tee -a $logfile 18 | fwconsole ma upgradeall 2> /dev/null >> $logfile 19 | 20 | printf "Updating all permissions...\n" | tee -a $logfile 21 | fwconsole chown 2> /dev/null | tee -a $logfile 22 | 23 | printf "Reloading FreePBX...\n" | tee -a $logfile 24 | fwconsole reload >> $logfile 25 | 26 | printf "Your FreePBX system has been updated.\n\n" | tee -a $logfile 27 | if grep -q "Upgrading module" $logfile 28 | then 29 | printf "The following FreePBX modules were upgraded:\n" | tee -a $logfile 30 | grep "Upgrading module" $logfile | sed 's/Upgrading module //' | tee -a $logfile 31 | printf "\n\n" | tee -a $logfile 32 | fi 33 | 34 | # Get system uptime in days (divide seconds by 86400) 35 | daysup=`awk '{print $0/86400;}' /proc/uptime`; 36 | 37 | if [ $(echo "$daysup > 30" | bc) -ne 0 ] 38 | then 39 | printf "Your system has been running for $daysup days.\n" | tee -a $logfile 40 | printf "It is strongly recommended that you schedule a reboot.\n\n" | tee -a $logfile 41 | fi 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /Monitor_Trunk_Failure/trunkalert.agi: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################## 4 | ### Setup Instructions ### 5 | ################################## 6 | # 1. Put this file on your PBX in the directory /var/lib/asterisk/agi-bin/ 7 | # sudo wget -O /var/lib/asterisk/agi-bin/trunkalert.agi https://raw.githubusercontent.com/sorvani/freepbx-helper-scripts/master/Monitor_Trunk_Failure/trunkalert.agi 8 | # 2. Edit the downloaded file to have the email addresses you need. 9 | # sudo nano /var/lib/asterisk/agi-bin/trunkalert.agi 10 | # 2. Set the file to the correct permissions 11 | # sudo fwconsole chown 12 | # 3. In the web interface, edit your trunk and put this in the "Monitor Trunk Failures" field 13 | # trunkalert.agi,YOURTRUNKNAME 14 | # 4. Change the No to Yes under the "Monitor Trunk Failures" field 15 | # 5. Submit 16 | # 6. Apply Config 17 | 18 | ################################## 19 | ### Set these values as needed ### 20 | ################################## 21 | EMAIL_FROM=yourpbxemail@domain.com 22 | EMAIL_TO=alertemail@domain.com 23 | # If the system hostname is not clear, change this to be whatever you want 24 | HOST=`hostname` 25 | 26 | ################################## 27 | ### No more editing required ### 28 | ################################## 29 | 30 | # Variable to hold the details for the log file 31 | DUMPARG=" Begin Argument dump:\n" 32 | # Create an Array to hold the results of the loop 33 | declare -a array 34 | # Loop through the AGI variables 35 | while read -e ARG && [ "$ARG" ] ; do 36 | # Dump them into an array, after removing the : 37 | array=(` echo $ARG | sed -e 's/://'`) 38 | # take the array and create a variable from the first element put the rest as the value 39 | # value must be put into a holding variable to parse correctly by the export command due the possibility of havine a space in the value 40 | val=${array[@]:1} 41 | export ${array[0]}="$val" 42 | # Dump them into a string for the log file 43 | DUMPARG="$DUMPARG $ARG\n" 44 | done 45 | 46 | DATE=`date "+%Y.%m.%d %H:%M:%S"` 47 | # Put together a human readable message 48 | MSG=" At $DATE, a call has failed to dial out.\n" 49 | MSG="$MSG The call was attempted from channel [$agi_channel] using the trunk [$agi_arg_1].\n" 50 | MSG="$MSG The number dialed was [$agi_dnid].\n" 51 | MSG="$MSG The outbound CID information was [$agi_calleridname] - [$agi_callerid].\n" 52 | 53 | # Log to file with more details and copy of the email text 54 | echo -e "$MSG" >> /var/log/asterisk/trunkfailure.log 55 | echo -e "$DUMPARG" >> /var/log/asterisk/trunkfailure.log 56 | 57 | # Send an email 58 | echo -e "$MSG" | mail -s "Failed call from system [$HOST] on trunk [$agi_arg_1] when dialing [$agi_dnid]" -r $EMAIL_FROM $EMAIL_TO 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # freepbx-helper-scripts 2 | Assorted scripts and files that work with FreePBX 3 | -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/AstMan.php: -------------------------------------------------------------------------------- 1 | socket = FALSE; 7 | $this->error = ""; 8 | } 9 | 10 | function Login() { 11 | // Open /etc/amportal.conf and get the Asterisk Manager connection information 12 | define("AMP_CONF", "/etc/amportal.conf"); 13 | $file = file(AMP_CONF); 14 | if (is_array($file)) { 15 | foreach ($file as $line) { 16 | if (preg_match("/^\s*([a-zA-Z0-9_]+)=([a-zA-Z0-9 .&-@=_!<>\"\']+)\s*$/",$line,$matches)) { 17 | $amp_conf[ $matches[1] ] = $matches[2]; 18 | } 19 | } 20 | } 21 | 22 | require_once('DB.php'); //php-pear-db must first be installed on a new FreePBX 14 system 23 | $db_user = $amp_conf["AMPMGRUSER"]; 24 | $db_pass = $amp_conf["AMPMGRPASS"]; 25 | $db_host = $amp_conf["ASTMANAGERHOST"]; 26 | $db_port = $amp_conf["ASTMANAGERPORT"]; 27 | $db_timeout = $amp_conf["ASTMGRWRITETIMEOUT"]; 28 | 29 | $this->socket = @fsockopen($db_host,$db_port, $errno, $errstr, $db_timeout); 30 | if (!$this->socket) { 31 | $this->error = "Could not connect - $errstr ($errno)"; 32 | return FALSE; 33 | } else { 34 | stream_set_timeout($this->socket, 1); 35 | $wrets = $this->Query("Action: Login\r\nUserName: $db_user\r\nSecret: $db_pass\r\nEvents: off\r\n\r\n"); 36 | if (strpos($wrets, "Message: Authentication accepted") != FALSE) { 37 | return true; 38 | } else { 39 | $this->error = "Could not login - Authentication failed"; 40 | fclose($this->socket); 41 | $this->socket = FALSE; 42 | return FALSE; 43 | } 44 | } 45 | } 46 | 47 | function Logout() { 48 | $wrets=""; 49 | if ($this->socket) { 50 | fputs($this->socket, "Action: Logoff\r\n\r\n"); 51 | while (!feof($this->socket)) { 52 | $wrets .= fread($this->socket, 8192); 53 | } 54 | fclose($this->socket); 55 | $this->socket = "FALSE"; 56 | } 57 | return; 58 | } 59 | 60 | function Query($query) { 61 | $wrets=""; 62 | if ($this->socket === FALSE) 63 | return FALSE; 64 | 65 | fputs($this->socket, $query); 66 | do { 67 | $line = fgets($this->socket, 4096); 68 | $wrets .= $line; 69 | $info = stream_get_meta_data($this->socket); 70 | } while ($line != "\r\n" && $info['timed_out'] == false ); 71 | return $wrets; 72 | } 73 | 74 | function QueryEndpoint($query) { 75 | $wrets=""; 76 | if ($this->socket === FALSE) 77 | return FALSE; 78 | 79 | fputs($this->socket, $query); 80 | do { 81 | $line = fgets($this->socket, 4096); 82 | $wrets .= $line; 83 | $info = stream_get_meta_data($this->socket); 84 | } while ($line != "Event: EndpointDetailComplete\r\n" && $info['timed_out'] == false); 85 | return $wrets; 86 | } 87 | 88 | function GetError() { 89 | return $this->error; 90 | } 91 | 92 | function GetDB($family, $key) { 93 | $wrets = $this->Query("Action: Command\r\nCommand: database get $family $key\r\n\r\n"); 94 | if ($wrets) { 95 | $value_start = strpos($wrets, "Value: ") + 7; 96 | $value_stop = strpos($wrets, "\n", $value_start); 97 | if ($value_start > 8) { 98 | $value = substr($wrets, $value_start, $value_stop - $value_start); 99 | } 100 | } 101 | return $value; 102 | } 103 | 104 | function PutDB($family, $key, $value){ 105 | $wrets = $this->Query("Action: Command\r\nCommand: database put $family $key $value\r\n\r\n"); 106 | if (strpos($wrets, "Updated database successfully") != FALSE){ 107 | return TRUE; 108 | } 109 | $this->error = "Could not updated database"; 110 | return FALSE; 111 | } 112 | 113 | function DelDB($family, $key) { 114 | $wrets = $this->Query("Action: Command\r\nCommand: database del $family $key\r\n\r\n"); 115 | if (strpos($wrets, "Database entry removed.") != FALSE) { 116 | return TRUE; 117 | } 118 | $this->error = "Database entry does not exist"; 119 | return FALSE; 120 | } 121 | 122 | function GetFamilyDB($family) { 123 | $wrets = $this->Query("Action: Command\r\nCommand: database show $family\r\n\r\n"); 124 | if ($wrets) { 125 | $value_start = strpos($wrets, "Response: Follows\r\n") + 19; 126 | $value_stop = strpos($wrets, "--END COMMAND--\r\n", $value_start); 127 | if ($value_start > 18) { 128 | $wrets = substr($wrets, $value_start, $value_stop - $value_start); 129 | } 130 | $lines = explode("\n", $wrets); 131 | foreach($lines as $line) { 132 | if (strlen($line) > 4) { 133 | $value_start = strpos($line, ": ") + 2; 134 | $value_stop = strpos($line, " ", $value_start); 135 | $key = trim(substr($line, strlen($family) + 2, strpos($line, " ") - strlen($family) + 2)); 136 | $value[$key] = trim(substr($line, $value_start)); 137 | } 138 | } 139 | return $value; 140 | } 141 | return FALSE; 142 | } 143 | 144 | function GetEndpointsPJSIP() { 145 | $wrets = $this->Query("Action: Command\r\nCommand: pjsip list endpoints\r\n\r\n"); 146 | if (strpos($wrets, "Output: Objects found: ") != FALSE){ 147 | return $wrets; 148 | } 149 | $this->error = "Failed list PJSIP endpoints"; 150 | return FALSE; 151 | } 152 | 153 | function RebootYealink($extension){ 154 | $wrets = $this->Query("Action: Command\r\nCommand: pjsip send notify reboot-yealink endpoint $extension\r\n\r\n"); 155 | if (strpos($wrets, "Output: Sending NOTIFY of type 'reboot-yealink' to '$extension'") != FALSE){ 156 | return TRUE; 157 | } 158 | $this->error = "Failed to send reboot-yealink command to $extension"; 159 | return FALSE; 160 | } 161 | 162 | function ReloadYealink($extension){ 163 | $wrets = $this->Query("Action: Command\r\nCommand: pjsip send notify reload-yealink endpoint $extension\r\n\r\n"); 164 | if (strpos($wrets, "Output: Sending NOTIFY of type 'reload-yealink' to '$extension'") != FALSE){ 165 | return TRUE; 166 | } 167 | $this->error = "Failed to send reload-yealink command to $extension"; 168 | return FALSE; 169 | } 170 | 171 | function PJSIPShowEndpoint($extension) { 172 | //$extension must only be a single extension 173 | $wrets = $this->QueryEndpoint("Action: PJSIPShowEndpoint\r\nEndpoint: $extension\r\n\r\n"); 174 | if (strpos($wrets,"Unable to retrieve endpoint") != FALSE) { 175 | $this->error = "Failed to get data for extension $extension"; 176 | return FALSE; 177 | } else { 178 | $item = ""; 179 | $getitem = 0; 180 | $lines = explode("\n", $wrets); 181 | foreach($lines as $line) { 182 | $a = explode(":", $line, 2); 183 | if (trim($a[0]) == "Event") { 184 | if (trim($a[1]) == "ContactStatusDetail") { 185 | $getitem = 1; 186 | } else { 187 | $getitem = 0; 188 | } 189 | } 190 | if ($getitem == 1 && strlen(trim($a[0]))) { 191 | $key = trim($a[0]); 192 | $item[$key] = trim($a[1]); 193 | } 194 | } 195 | return $item; 196 | } 197 | } 198 | } 199 | ?> 200 | -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/TODO: -------------------------------------------------------------------------------- 1 | Things to add that are just PHP 2 | - Select All/None to Select column 3 | - Select All/None by Manufacturer (super low priority as this is designed only for Yealink right now) 4 | - Select All/None by Model 5 | - Filter by Manufacturer 6 | - Filter by Model 7 | - Way to specify the Extension range in the GUI (and have it be persistent) 8 | - Sort columns 9 | 10 | Things to add that require changes related to Asterisk 11 | - Get public and local IP of extension and show in a column 12 | - Keep multiple registrations separate 13 | -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/ami_test.php: -------------------------------------------------------------------------------- 1 | \"\']+)\s*$/",$line,$matches)) { 16 | $amp_conf[ $matches[1] ] = $matches[2]; 17 | } 18 | } 19 | } 20 | 21 | require_once('DB.php'); //php-pear-db must first be installed on a new FreePBX 14 system 22 | $db_user = $amp_conf["AMPMGRUSER"]; 23 | $db_pass = $amp_conf["AMPMGRPASS"]; 24 | $db_host = $amp_conf["ASTMANAGERHOST"]; 25 | $db_port = $amp_conf["ASTMANAGERPORT"]; 26 | $db_timeout = $amp_conf["ASTMGRWRITETIMEOUT"]; 27 | 28 | // Connect to Asterisk Manager and run a command 29 | $socket = fsockopen($db_host, $db_port, $errno, $errstr, $db_timeout); 30 | fputs($socket, "Action: Login\r\n"); 31 | fputs($socket, "UserName: $db_user\r\n"); 32 | fputs($socket, "Secret: $db_pass\r\n\r\n"); 33 | fputs($socket, "Action: PJSIPShowEndpoint\r\n"); 34 | fputs($socket, "Endpoint: 103\r\n\r\n"); 35 | fputs($socket, "Action: Logoff\r\n\r\n"); 36 | 37 | //read the result into a srtring 38 | $wrets = ''; 39 | while (!feof($socket)) { 40 | $wrets .= fread($socket, 8192); 41 | } 42 | fclose($socket); 43 | 44 | echo "Dumping \$wrets
\r\n
\r\n";
45 |     echo var_dump($wrets);
46 |     echo "\r\n
\r\nEnd \$wrets dump
\r\n"; 47 | 48 | $getitem = 0; 49 | $lines = explode("\n", $wrets); 50 | foreach($lines as $line) { 51 | $a = explode(":", $line, 2); 52 | if (trim($a[0]) == "Event") { 53 | if (trim($a[1]) == "ContactStatusDetail") { 54 | $getitem = 1; 55 | } else { 56 | $getitem = 0; 57 | } 58 | } 59 | 60 | if ($getitem == 1 && strlen(trim($a[0])) > 0) { 61 | $key = trim($a[0]); 62 | $value[$key] = trim($a[1]); 63 | } 64 | } 65 | echo "
Begin parsed dump
\r\n
\r\n";
66 |     var_dump($value);
67 |     echo "\r\n

\r\nEnd parsed Dump\r\n"; 68 | 69 | ?> 70 | -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/ext_test.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EXT TEST 7 | 8 | 9 | 10 | 50 | 54 | 55 |
56 |
Select extension(s) to reboot or reload: 57 | 58 | 60 |
> 61 | 62 | 63 |
ExtensionNameBrandModelFirmwareStatusResponse TimeKnown Device IPsRegistration Expires
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | $value) { 78 | if($value >= $f_ext && $value <= $l_ext) { 79 | echo "\t\t\n\t\t\t\n"; 80 | echo "\t\t\t\n"; 81 | } 82 | } 83 | 84 | echo "\n"; 85 | echo "

Selected

Extension

$value
\n"; // end table 86 | echo "
\n"; 87 | echo "

"; 88 | echo "

"; 89 | echo "\n"; 90 | echo "\n"; 91 | echo "\n"; 92 | 93 | } else { 94 | ?> 95 | 96 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/ext_test.txt: -------------------------------------------------------------------------------- 1 | ASTERISK MANAGER OUTPUT: 2 | 3 | Asterisk Call Manager/4.0.3 4 | Response: Success 5 | Message: Authentication accepted 6 | 7 | Event: FullyBooted 8 | Privilege: system,all 9 | Uptime: 1069663 10 | LastReload: 452056 11 | Status: Fully Booted 12 | 13 | Response: Success 14 | Message: Command output follows 15 | Output: 16 | Output: Endpoint: 17 | Output: ========================================================================================== 18 | Output: 19 | Output: Endpoint: 101/101 Not in use 0 of inf 20 | Output: Endpoint: 102/102 Not in use 0 of inf 21 | Output: Endpoint: 103/103 Not in use 0 of inf 22 | Output: Endpoint: 104/104 Not in use 0 of inf 23 | Output: Endpoint: 105/105 Not in use 0 of inf 24 | Output: Endpoint: 108/108 Not in use 0 of inf 25 | Output: Endpoint: 110/110 Not in use 0 of inf 26 | Output: Endpoint: 99103/99103 Unavailable 0 of inf 27 | Output: Endpoint: 99108/99108 Unavailable 0 of inf 28 | Output: Endpoint: 9999103/9999103 Unavailable 0 of inf 29 | Output: Endpoint: 999999103/999999103 Unavailable 0 of inf 30 | Output: Endpoint: Bundy_VoIPms_PJSIP Not in use 0 of inf 31 | Output: Endpoint: dpma_endpoint Unavailable 0 of inf 32 | Output: 33 | Output: Objects found: 13 34 | Output: 35 | 36 | Response: Goodbye 37 | Message: Thanks for all the fish. -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/func_test.php: -------------------------------------------------------------------------------- 1 | Login(); 6 | if (strlen($astman->GetError()) > 0) { 7 | echo $astman->GetError();echo "\r\n
\r\n"; 8 | return; 9 | } else { 10 | echo "Login Successful.
\r\n"; 11 | } 12 | 13 | $endpoints=$astman->GetEndpointsPJSIP(); 14 | if (strlen($astman->GetError()) > 0) { 15 | echo $astman->GetError();echo "
\r\n"; 16 | return; 17 | } else { 18 | echo "GetEndpointsPJSIP Successful.
\r\n"; 19 | echo "Dumping \$endpoints.
\r\n"; 20 | echo "
\r\n";
21 |     var_dump($endpoints);
22 |     echo "\r\n

\r\n"; 23 | } 24 | 25 | $ext_detail=$astman->PJSIPShowEndpoint($value); 26 | if (strlen($astman->GetError()) > 0) { 27 | echo $astman->GetError();echo "\r\n
"; 28 | return; 29 | } else { 30 | echo "PJSIPShowEndpoint Successful.
\r\n"; 31 | echo "Dumping \$ext_detail.
\r\n"; 32 | echo "
\r\n";
33 |     var_dump($ext_detail);
34 |     echo "\r\n

\r\n"; 35 | } 36 | 37 | $astman->Logout(); 38 | if (strlen($astman->GetError()) > 0) { 39 | echo $astman->GetError();echo "\r\n
\r\n"; 40 | return; 41 | } else { 42 | echo "Logut Successful.
\r\n"; 43 | } 44 | 45 | ?> 46 | -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/reboot_confirm.php: -------------------------------------------------------------------------------- 1 | Login(); 9 | foreach ($extension as $extension_value) { 10 | if ($astman->ReloadYealink($extension_value)) { 11 | echo "
NOTIFY sent to $extension_value

\r\n"; 12 | } else { 13 | echo "
NOTIFY failed to $extension_value

\r\n"; 14 | } 15 | } 16 | $astman->Logout(); 17 | echo "Reload done."; 18 | echo "\n"; 19 | echo "\n"; 20 | } 21 | if (isset($_POST['confirm_reboot'])) { 22 | $astman->Login(); 23 | foreach ($extension as $extension_value) { 24 | if ($astman->RebootYealink($extension_value)) { 25 | echo "
NOTIFY sent to $extension_value

\r\n"; 26 | } else { 27 | echo "
NOTIFY failed to $extension_value

\r\n"; 28 | } 29 | } 30 | $astman->Logout(); 31 | echo "Reboot done."; 32 | echo "\n"; 33 | echo "\n"; 34 | } 35 | 36 | } 37 | 38 | ?> -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/reboot_phones.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Reboot & Reload Phones 7 | 8 | 27 | 28 | 29 | 30 | Login(); 47 | $endpoints=$astman->GetEndpointsPJSIP(); 48 | 49 | if (!$endpoints) { 50 | echo $astMan->error; 51 | return false; 52 | } 53 | 54 | // pattern and preg_match_all courtesy of https://github.com/tjgruber 55 | //regex pattern to use -- matches any number after a "/" 56 | $pattern = '/\/([0-9]+)/'; 57 | //strip out all the /### values 58 | preg_match_all($pattern,$endpoints,$matches); 59 | 60 | ?> 61 | 62 | 63 | 65 |
> 66 | 67 | 71 | 72 |
73 |
Select extension(s) to reboot or reload: 74 | 75 | 77 | > 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | $value) { 98 | if($value >= $f_ext && $value <= $l_ext) { 99 | echo "\t\t\n\t\t\t\n"; 100 | echo "\t\t\t\n"; 101 | $useragent = ""; 102 | $useragent = $astman->PJSIPShowEndpoint($value); 103 | $ext_detail = explode(" ", $useragent['UserAgent'],3); 104 | echo "\t\t\t\n"; 105 | echo "\t\t\t\n"; 106 | echo "\t\t\t\n"; 107 | echo "\t\t\n"; 108 | } 109 | } 110 | echo "\n"; 111 | echo "

Selected

Extension

Brand

Model

Firmware

$value$ext_detail[0]$ext_detail[1]$ext_detail[2]
\n"; // end table 112 | echo "
\n"; 113 | echo "

"; 114 | echo "

"; 115 | echo "\n"; 116 | echo "\n
"; 117 | echo "\n
"; 118 | 119 | $astman->Logout(); 120 | } else { 121 | ?> 122 | 123 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /Reload_Reboot_Yealink/reboot_process.php: -------------------------------------------------------------------------------- 1 | \n"; 12 | echo "
\n
Submission Results:\n"; 13 | 14 | if (isset($_POST['reload'])) { 15 | echo "

You opted to RELOAD:

\n"; 16 | if (!empty($_POST["extension"])) { 17 | $extension = $_POST['extension']; 18 | echo "\n\n\n\n\n\n\n"; 19 | foreach ($extension as $extension_value) { 20 | echo "\t\t\n\t\t\t\n\t\t\n"; 21 | } 22 | echo "\n"; 23 | echo "

Extension

$extension_value
\n\n"; 24 | ?> 25 |
> 26 | "; 29 | } 30 | echo "\n
\n

"; 31 | echo "\n
"; 32 | echo "\n
"; 33 | echo "\n"; 34 | } else { 35 | $extension = 0; 36 | $extension_value = 0; 37 | echo "

however,

\n"; 38 | echo "

you did not make selection!

"; 39 | echo "\n"; 40 | echo "\n"; 41 | } 42 | } 43 | 44 | if (isset($_POST['reboot'])) { 45 | echo "

You opted to REBOOT:

\n"; 46 | if (!empty($_POST["extension"])) { 47 | $extension = $_POST['extension']; 48 | echo "\n\n\n\n\n\n\n"; 49 | foreach ($extension as $extension_value) { 50 | echo "\t\t\n\t\t\t\n\t\t\n"; 51 | } 52 | echo "\n"; 53 | echo "

Extension

$extension_value
\n\n"; 54 | ?> 55 |
> 56 | "; 59 | } 60 | echo "\n
\n

"; 61 | echo "\n
"; 62 | echo "\n"; 63 | echo "\n"; 64 | } else { 65 | $extension = 0; 66 | $extension_value = 0; 67 | echo "

however,

\n"; 68 | echo "

you did not make selection!

"; 69 | echo "\n"; 70 | echo "\n"; 71 | } 72 | } 73 | 74 | } 75 | ?> 76 | -------------------------------------------------------------------------------- /aastra_login.php: -------------------------------------------------------------------------------- 1 | 2 | setTitle('Extension Log On'); 60 | $input->setDisplayMode('condensed'); 61 | $input->setURL('http://watson.domain.com/custom/aastra/login.php?reload=submit'); 62 | $input->setDestroyOnExit(); 63 | switch ($focus) { 64 | case "badpass": 65 | $input->setDefaultIndex(2); 66 | break; 67 | case "baddesk": 68 | $input->setDefaultIndex(2); 69 | break; 70 | default: 71 | $input->setDefaultIndex(1); 72 | } 73 | 74 | // Ask for Extension 75 | $input->addField('number'); 76 | $input->setFieldPrompt('Extension:'); 77 | $input->setFieldParameter('extension'); 78 | if ($ext != '') { 79 | $input->setFieldDefault("$ext"); 80 | } 81 | 82 | // Ask for password 83 | $input->addField('number'); 84 | $input->setFieldPassword('yes'); 85 | $input->setFieldPrompt('Password:'); 86 | $input->setFieldParameter('password'); 87 | 88 | // Desk or Guest 89 | $input->addField('number'); 90 | $input->setFieldPrompt('Desk Type?'); 91 | $input->setFieldParameter('desktype'); 92 | if ($desk != '') { 93 | $input->setFieldDefault("$desk"); 94 | } 95 | // Instruction on what to enter for Main or Guest 96 | $input->addField('string'); 97 | $input->setFieldPrompt('Main=1 or'); 98 | $input->setFieldDefault('Visitor=2'); 99 | $input->setFieldEditable('no'); 100 | 101 | // show it all 102 | $input->output(); 103 | } 104 | 105 | function ShowBadPassword($ext,$desk) { 106 | // Display bad password message and return to login script 107 | $input = new AastraIPPhoneInputScreen(); 108 | $input->setTitle('Invalid password'); 109 | $input->setDisplayMode('condensed'); 110 | $input->setURL('http://watson.domain.com/custom/aastra/login.php?extension='.$ext.'&desktype='.$desk.'&reload=badpass'); 111 | $input->setDestroyOnExit(); 112 | $input->addSoftkey('5', 'Cancel', 'SoftKey:Exit'); 113 | $input->addSoftkey('6', 'Retry', 'SoftKey:Submit'); 114 | $input->addField('empty'); 115 | $input->addField('string'); 116 | $input->setFieldPrompt('Please Try Again'); 117 | $input->setFieldDefault(''); 118 | $input->setFieldEditable('no'); 119 | // show it all 120 | $input->output(); 121 | } 122 | 123 | function ShowBadDeskType($ext) { 124 | // Display bad desktype message and return to login script 125 | $input = new AastraIPPhoneInputScreen(); 126 | $input->setTitle('Invalid Desk Type'); 127 | $input->setDisplayMode('condensed'); 128 | $input->setURL('http://watson.domain.com/custom/aastra/login.php?extension='.$ext.'&reload=baddesk'); 129 | $input->setDestroyOnExit(); 130 | $input->addSoftkey('5', 'Cancel', 'SoftKey:Exit'); 131 | $input->addSoftkey('6', 'Retry', 'SoftKey:Submit'); 132 | // Instruction on what to enter for Main or Guest 133 | $input->addField('string'); 134 | $input->setFieldPrompt('Try again'); 135 | $input->setFieldDefault('using'); 136 | $input->setFieldEditable('no'); 137 | $input->addField('empty'); 138 | $input->addField('string'); 139 | $input->setFieldPrompt('Main Desk:'); 140 | $input->setFieldDefault('1'); 141 | $input->setFieldEditable('no'); 142 | $input->addField('string'); 143 | $input->setFieldPrompt('Visitor Desk:'); 144 | $input->setFieldDefault('2'); 145 | $input->setFieldEditable('no'); 146 | // show it all 147 | $input->output(); 148 | } 149 | 150 | function ShowBadExtension() { 151 | // Display bad extension message and return to login script 152 | $input = new AastraIPPhoneInputScreen(); 153 | $input->setTitle('Invalid Extension'); 154 | $input->setDisplayMode('condensed'); 155 | $input->setURL('http://watson.domain.com/custom/aastra/login.php?&reload=badext'); 156 | $input->setDestroyOnExit(); 157 | $input->addSoftkey('5', 'Cancel', 'SoftKey:Exit'); 158 | $input->addSoftkey('6', 'Retry', 'SoftKey:Submit'); 159 | // Instruciton on what to enter for Main or Guest 160 | $input->addField('empty'); 161 | $input->addField('string'); 162 | $input->setFieldPrompt('Please Try Again'); 163 | $input->setFieldDefault(''); 164 | $input->setFieldEditable('no'); 165 | // show it all 166 | $input->output(); 167 | } 168 | 169 | function ErasePhone() { 170 | $execute = new AastraIPPhoneExecute(); 171 | $execute->addEntry('Command: Reset'); 172 | $execute->output(); 173 | } 174 | 175 | function CreateEPMEntry($header,$ext,$desk) { 176 | // Create the configuration file on the PBX. 177 | // Pull information from the HTTP header to create the command. 178 | $model = substr($header['model'],6); 179 | $mac = strtolower($header['mac']); 180 | $phoneip = $header['ip']; 181 | // set template based on IP of phone. 182 | // need to add this logic testing with chicago 183 | $template = "chicago"; 184 | 185 | // Build the fwconsole command into a string 186 | // fwconsole epm addmapping 6115-2 --brand=aastra --mac=00085d2723de --template=chicago --model=57i --account=account1 187 | $fwconsole = "fwconsole endpoint addmapping "; 188 | $fwconsole .= $ext."-".$desk." "; 189 | $fwconsole .= "--brand=aastra "; 190 | $fwconsole .= "--mac=".$mac." "; 191 | $fwconsole .= "--template=".$template." "; 192 | $fwconsole .= "--model=".$model." "; 193 | $fwconsole .= "--account=account1"; 194 | 195 | // begin manual verification of shit during development 196 | file_put_contents ("user_agent.log", "begin verification: \n", FILE_APPEND); 197 | file_put_contents ("user_agent.log", "Command: ".$fwconsole." \n", FILE_APPEND); 198 | file_put_contents ("user_agent.log", "end verification \n", FILE_APPEND); 199 | // end manual verificatoin of shit during development 200 | 201 | // execute the command and log the result 202 | $result = shell_exec($fwconsole); 203 | syslog(LOG_INFO,"Configuration file for ".str_replace("\n", "", $result)); 204 | 205 | // build the fwconsole command to to rebuild the configuration file 206 | $fwconsole = "fwconsole endpoint rebuild "; 207 | $fwconsole .= $ext."-".$desk; 208 | 209 | // execute the command an log the result 210 | $result = shell_exec($fwconsole); 211 | syslog(LOG_INFO,"Configuration file for ".str_replace("\n", "", $result)); 212 | } 213 | ?> 214 | --------------------------------------------------------------------------------