function processAMIresponse($aResponse) { global $szAMIusername, $szAMIsecret, $lStartTime, $lEndTime, $szPacketTerminator, $szCRLF; //print_r($aResponse); // if( isset($aResponse["Event"])) //// if(strtolower($aResponse["Event"])=="configentry") // {// print "\nDetected (configentry) ".print_r($aResponse,true);// } if (isset($aResponse["Response"])) { switch ($aResponse["Response"]) { case "_AMIQueues": // if(isset($aResponse["QUEUESResponse"])) // { //dPrint("QUEUES RESPONSE HERE!!!!!!!!!!!!!!!!".print_r($aResponse,TRUE),iCare_dPrint_always); // vectorEvent($aResponse); // return; // } // return; break; case "Authenticate": // Remap the authentication request to look like an event. //dPrint("Authenticate REQUEST",iCare_dPrint_always); $aResponse["Event"] = "_AMIauthenticate"; break; case "Success": // Remap success packets to pseudo events. // Provide special handling for the huge list // returned by the "listcommands" command. if (isset($aResponse["WaitEvent"])) { if (isset($aResponse["MeetmeList"])) { if (isset($aResponse["DAHDIRestart"])) { handleAMI_ListCommands($aResponse); return; } } } if (isset($aResponse["Message"])) { switch ($aResponse["Message"]) { case "Authentication accepted": //Remap to look like event $oSHM = new shm(); $oSHM->bAuthenticated = TRUE; // Flag indicating if we have been // Authenticated by AMI. // Get a copy of the AsterClick.conf user logins and pass it back // to code in class.wSockets.inc to reflect the list into that // process's thread. AMIaction("getconfig", array("ORIGIN" => "SYSTEM_ASTERCLICK", "filename" => "AsterClick.conf")); $aPendingLogin = $oSHM->aPendingLogin; dPrint("AMI AUTHENTICATION ACCEPTED (" . count($aPendingLogin) . ")", 3); for (; count($aPendingLogin);) { $value = array_shift($aPendingLogin); AMIaction($value["szAction"], $value["aParams"], $value["bStack"]); } $oSHM->aPendingLogin = array(); $aResponse["Event"] = "_AMIauthenticateAccepted"; break; case "Meetme user list will follow": $aResponse["Event"] = "MeetmeListStarts"; break; default: $aResponse["Event"] = "_AMIsuccess"; break; } // /switch(Message) } else { // Reporting of events setting ("On","Off") . if (isset($aResponse["Events"])) { $aResponse["Event"] = "Events"; break; } // print "\nAMIresponse (success ) now test for config stuff ".print_r($aResponse,TRUE); if (isset($aResponse["Category-000000"])) { if (isset($aResponse["Line-000000-000000"])) { $aResponse["Event"] = "_AMIConfigFile"; break; } else { $aResponse["Event"] = "_AMIConfigFileCategories"; break; } } $aResponse["Event"] = "_AMIpayload"; dPrint("\nprocessAMIresponse(" . count($aResponse) . ")[" . $aResponse["Response"] . "|||" . $aResponse["Event"] . "]"); } break; case "Failure": // Remap Failure packets to pseudo Event $aResponse["Event"] = "_AMIfailure"; break; case "Error": // Remap error packets to pseudo Event $aResponse["Event"] = "_AMIerror"; break; case "Follows": // Remap follows packets to pseudo Event $aResponse["Event"] = "_AMIfollows"; if (isset($aResponse["CLIResponse"])) { handleAMI_CLIresponse($aResponse); // parses CLI text blob responses into structured data, // divides them up into nice sized chunks // and sends them to vectorEvent(). return; } break; default: dPrint("switch(Response) ERROR , unhanded response (" . $aResponse["Response"] . ")"); break; } // /switch(Response) } else { // if(!isset($aResponse["Event"])) // dPrint("\nDAH , No Response ".print_r($aResponse,TRUE)); } // end big if if (isset($aResponse["Event"])) { // require_once("caseEvent.php"); vectorEvent($aResponse); } $lEndTime = mktime(); }
function vectorEvent($aResponse) { global $oMSGqueue; $oSHM = new shm(); $bMustPrint = FALSE; if (!isset($aResponse["Event"])) { $aResponse["Event"] = "NonEvent"; } $szResponseText = $aResponse["Event"]; switch ($aResponse["Event"]) { // RTCP/RTP events have an extremely high frequency and so are suppressed here. case "RTPReceiverStat": return; case "RTCPReceived": return; case "RTCPSent": return; case "hold": break; case "Shutdown": // $oSHM = new shm(); $oSHM->bLoggedIn = 0; print "Asterisk SHUTDOWN DETECTED"; global $szPacketTerminator, $szCRLF, $szBufferIn, $szAMIusername, $szAMIsecret; // set in /etc/asterisk/AsterClick/AsterClickServer.conf $szBufferIn = ""; $szPacketTerminator = $szCRLF . $szCRLF; usleep(5000); AMIsocket_create(); AMIaction("Login", array("Username" => $szAMIusername, "Secret" => $szAMIsecret)); break; case "_AMIQueues": //dPrint("VECTOREVENT _AMIQueues",iCare_dPrint_always); break; // AUTHENTICATE // There really is NO SUCH EVENT, but because I like transactions to travel // in an orderly fashion , the processAMIresponse() function in AsterClick.php // remaps the message to look like an event so that it will arrive here. // AUTHENTICATE // There really is NO SUCH EVENT, but because I like transactions to travel // in an orderly fashion , the processAMIresponse() function in AsterClick.php // remaps the message to look like an event so that it will arrive here. case "_AMIauthenticate": global $szPacketTerminator, $szCRLF, $szAMIusername, $szAMIsecret; // set /etc/asterisk/AsterClick/AsterClickServer.conf([ami]secret) $szPacketTerminator = $szCRLF . $szCRLF; AMIaction("Login", array("Username" => $szAMIusername, "Secret" => $szAMIsecret)); break; case "_AMIauthenticateAccepted": $oSHM->bLoggedIn = 1; // AMIaction("EVENTS",Array("EVENTMASK" =>"system,call,log,verbose,command,agent,user" )); // AMIaction("EVENTS",Array("EVENTMASK" =>"all,system,call,log,verbose,command,agent,user,config,dtmf,reporting")); AMIaction("EVENTS", array("EVENTMASK" => "all,system,call,log,verbose,command,agent,user,config,dtmf")); break; case "_AMIsuccess": break; case "_AMIConfigFile": case "_AMIConfigFileCategories": $szACTION_ID = $aResponse["ActionID"]; unset($aResponse["ActionID"]); unset($aResponse["Response"]); unset($aResponse["Event"]); // CHECK for breadcrumbs $aStackBreadCrumbs = $oSHM->aStackBreadCrumbs; if (isset($aStackBreadCrumbs[$szACTION_ID])) { $szCategory = "_None_"; if (isset($aStackBreadCrumbs[$szACTION_ID]["category"])) { $szCategory = $aStackBreadCrumbs[$szACTION_ID]["category"]; } $szFilename = ""; if (isset($aStackBreadCrumbs[$szACTION_ID])) { if (isset($aStackBreadCrumbs[$szACTION_ID]["filename"])) { $szFilename = $aStackBreadCrumbs[$szACTION_ID]["filename"]; } } $aStart = array("Event" => "ConfigListStarts", "filename" => $szFilename, "category" => $szCategory, "ActionID" => $szACTION_ID, "Count" => count($aResponse)); vectorEventSend($aStart); unset($aStackBreadCrumbs[$szACTION_ID]); } $oSHM->aStackBreadCrumbs = $aStackBreadCrumbs; // /CHECK for breadcrumbs $aSend = array(); foreach ($aResponse as $key => $value) { if (strpos($key, "Category") !== FALSE) { if (count($aSend) > 0) { vectorEventSend($aSend); } $aCatNo = explode("-", $key); $aSend = array("Event" => "ConfigEntry", "id" => $aCatNo[1], "name" => $value, "ActionID" => $szACTION_ID); } else { $aLine = explode("-", $key); $aSend = array_merge($aSend, array("Line" . $aLine[2] => $value)); } } if (count($aSend) > 0) { vectorEventSend($aSend); } $aEnd = array("Event" => "ConfigListComplete", "ActionID" => $szACTION_ID); vectorEventSend($aEnd); // print "Break up config file here".print_r($aResponse,TRUE); return; case "_AMIfollows": break; case "_AMIfailure": break; // $aFailure=Array(0 =>"No Such extension or number" , // 1 =>"No Answer" , // 4 =>"Answered" , // 8 =>"Congested or not available" ); // print "Response (Failure)(".$aFailure[$aResponse["Reason"]].")".print_r($aResponse,TRUE)."\n"; break; // $aFailure=Array(0 =>"No Such extension or number" , // 1 =>"No Answer" , // 4 =>"Answered" , // 8 =>"Congested or not available" ); // print "Response (Failure)(".$aFailure[$aResponse["Reason"]].")".print_r($aResponse,TRUE)."\n"; break; case "_AMIerror": //print "_AMIerror\n"; // print_r($aResponse); //print "_AMIerror\n"; // print_r($aResponse); case "_AMIpayload": break; break; //AGENTS //AGENTS case "Agentcallbacklogin": break; case "Agentcallbacklogoff": break; case "AgentCalled": break; case "AgentsComplete": break; case "AgentConnect": break; case "AgentDump": break; case "Agentlogin": break; case "Agentlogoff": break; case "Events": break; case "CoreShowChannel": break; case "CoreShowChannelsComplete": break; case "DAHDIShowChannelsComplete": break; case "ListDialplan": break; //Parked Calls //Parked Calls case "ParkedCallsComplete": case "ParkedCall": case "UnParkedCall": break; case "PeerEntry": break; case "PeerlistComplete": break; case "RegistrationsComplete": break; case "Registry": break; // QUEUES // QUEUES case "QueueStatusComplete": break; case "QueueStatusEnd": break; case "QueueParams": break; case "QueueMember": break; case "QueueMemberAdded": break; case "QueueMemberPaused": break; case "QueueMemberRemoved": break; case "QueueMemberStatus": break; case "Newchannel": break; case "ChannelUpdate": break; case "Newstate": break; case "NewAccountCode": break; case "Dial": break; case "OriginateResponse": break; case "Newexten": break; case "VoicemailUserEntry": break; case "VoicemailUserEntryComplete": break; case "Hangup": break; case "NewCallerid": break; case "Bridge": break; case "Unlink": break; // Monitor /var/spool/asterisk/monitor/ // Monitor /var/spool/asterisk/monitor/ case "MonitorStart": break; case "MonitorStop": break; // Status // Status case "Status": break; case "PeerStatus": break; case "StatusComplete": break; // Cdr // Cdr case "Cdr": break; case "SetCDRUserField": break; case "ExtensionStatus": break; case "MusicOnHold": break; case "Join": break; case "Leave": break; case "Link": break; case "MeetmeListStarts": break; case "MeetmeList": break; case "MeetmeJoin": break; case "MeetmeLeave": break; case "MeetmeStopTalking": break; case "MessageWaiting": break; case "NewCallerid": break; case "NewExtension": break; case "Rename": break; //System Status Events //System Status Events case "RTPSenderStat": return; case "VarSet": if ($aResponse["Channel"] != "none") { return; } if ($aResponse["Variable"] != "CONSOLE") { return; } $aResponse["Event"] = "DialplanReload"; unset($aResponse["Channel"]); unset($aResponse["Variable"]); unset($aResponse["Value"]); dynamicDialplanEntries(); break; case "Alarm": break; case "AlarmClear": break; case "DNDState": break; case "Reload": break; //print "\nSAW RELOAD"; //print "\nSAW RELOAD"; case "Shutdown": break; case "UserEvent": //print "\nDecode USEREVENT ".print_r($aResponse,TRUE); break; case "ZapShowChannels": break; case "ZapShowChannelsComplete": break; /* The ListCommandXXXXXXX pseudo events are generated in ** AsterClick.php, by function handleAMI_ListCommands() ** The AMI command "Listcommands", tends to produce some majorly ** bulky output, so these events break up the output into ** event sized pieces. ********/ /* The ListCommandXXXXXXX pseudo events are generated in ** AsterClick.php, by function handleAMI_ListCommands() ** The AMI command "Listcommands", tends to produce some majorly ** bulky output, so these events break up the output into ** event sized pieces. ********/ case "_ListCommandsStart": // Beginning of command list // Beginning of command list case "_ListCommandEntry": // Entry in the command list // Entry in the command list case "_ListCommandsComplete": break; // No more commands to list. /* The _CLIXXXXXXXXX pseudo events are generated in ** AsterClick.php, by function handleAMI_Command() ** ** These events are generated as AsterClick parses CLI response text blobs ** returned from an AMI "command" action. The basic reason we do this is that ** some CLI responses can be very bulky, so AsterClick chunks the result into ** logical event sized pieces that easily pass through the System V messaging ** ** AsterClick also attempts to parse these text blobs into structured ** data in a generic way. See /etc/asterisk/AsterClick/class.cliParser.inc if ** your really curious. */ // No more commands to list. /* The _CLIXXXXXXXXX pseudo events are generated in ** AsterClick.php, by function handleAMI_Command() ** ** These events are generated as AsterClick parses CLI response text blobs ** returned from an AMI "command" action. The basic reason we do this is that ** some CLI responses can be very bulky, so AsterClick chunks the result into ** logical event sized pieces that easily pass through the System V messaging ** ** AsterClick also attempts to parse these text blobs into structured ** data in a generic way. See /etc/asterisk/AsterClick/class.cliParser.inc if ** your really curious. */ case "_CLIresponse": // Single line CLI response // Single line CLI response case "_CLIList": // Announce the beginning of a CLI response list. // Announce the beginning of a CLI response list. case "_CLIRow": // Row of parsed CLI response data. // Row of parsed CLI response data. case "_CLIFooter": // Row of parsed CLI response data (footer of tabular response) // Row of parsed CLI response data (footer of tabular response) case "_CLIComplete": break; // Announce the ending of a CLI response list. // Announce the ending of a CLI response list. case "DBGetResponse": //dPrint("SAW DBGetResponse ".print_r($aResponse,TRUE) ,iCare_dPrint_AMIevent); break; // If we have arrived here , then we have neglected to define the // event in one of the case statements , so we make an announcement about that and bail. // If we have arrived here , then we have neglected to define the // event in one of the case statements , so we make an announcement about that and bail. default: $szResponseText = "Unvectored event(" . $aResponse["Event"] . ")\n" . print_r($aResponse, TRUE); $bMustPrint = TRUE; vectorEventPrint($szResponseText, $bMustPrint); return; } // end switch vectorEventPrint($szResponseText, $bMustPrint); // $bMustPrint defaults to FALSE at the beginning // of this function but any of the case: statements // can turn $bMustPrint TRUE and the response // text representing by defat the event name // will be printed vectorEventSend($aResponse); // send the event to the browser System V message queue. }