[Pkg-voip-commits] r3496 - op-panel/trunk
Santiago Ruano Rincón
santiago at alioth.debian.org
Fri Apr 27 22:57:32 UTC 2007
Author: santiago
Date: 2007-04-27 22:57:32 +0000 (Fri, 27 Apr 2007)
New Revision: 3496
Removed:
op-panel/trunk/CHANGES
op-panel/trunk/FAQ
op-panel/trunk/LICENSE
op-panel/trunk/README
op-panel/trunk/RECIPES
op-panel/trunk/TODO
op-panel/trunk/UPGRADE
op-panel/trunk/dhtml/
op-panel/trunk/extensions.conf.sample
op-panel/trunk/flash/
op-panel/trunk/init/
op-panel/trunk/ming-source/
op-panel/trunk/op_astdb.cfg
op-panel/trunk/op_buttons.cfg
op-panel/trunk/op_lang_ca.cfg
op-panel/trunk/op_lang_de.cfg
op-panel/trunk/op_lang_en.cfg
op-panel/trunk/op_lang_es.cfg
op-panel/trunk/op_lang_fr.cfg
op-panel/trunk/op_lang_it.cfg
op-panel/trunk/op_lang_se.cfg
op-panel/trunk/op_server.cfg
op-panel/trunk/op_server.pl
op-panel/trunk/op_style.cfg
Log:
removed previously injected upstream code
Deleted: op-panel/trunk/CHANGES
===================================================================
--- op-panel/trunk/CHANGES 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/CHANGES 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,750 +0,0 @@
-Version .26
-
-Tue May 9 19:24:08 ART 2006 nicolas at house.com.ar
- * New dhtml client
-
-Tue May 9 15:05:22 ART 2006 nicolas at house.com.ar
- * assorted client fixes, removed scriptable actions for now,
- add side scrolling when you have buttons that do not fit
- on the screen.
-
-Tue May 9 15:03:27 ART 2006 nicolas at house.com.ar
- * remove scriptable actions and assorted bug fixes
-
-Sat Apr 29 15:41:14 ART 2006 nicolas at house.com.ar
- * ming client updates
-
-Sat Apr 29 15:40:06 ART 2006 nicolas at house.com.ar
- * formatting fixes. Add includes to op_style.cfg
-
-Sat Apr 29 13:04:58 ART 2006 nicolas at house.com.ar
- * set clid format on link event
-
-Sat Apr 29 13:04:43 ART 2006 nicolas at house.com.ar
- * fix auto counters when using regexp butons
-
-Sat Apr 29 13:03:25 ART 2006 nicolas at house.com.ar
- * scriptable actions, tovoicemail actions, formatting fixes
-
-Sat Apr 29 12:58:54 ART 2006 nicolas at house.com.ar
- * includes style, simplify read configs, formatting fixes, removed comments
-
-Sat Apr 29 12:57:22 ART 2006 nicolas at house.com.ar
- * log fake events
-
-Sat Apr 29 12:52:48 ART 2006 nicolas at house.com.ar
- * transfer to voicemail
-
-Sat Apr 29 11:40:50 ART 2006 nicolas at house.com.ar
- * agent status updates, paused and some formatting fixes
-
-Sat Apr 29 11:13:04 ART 2006 nicolas at house.com.ar
- * clid privacy per button
-
-Sat Apr 29 11:02:16 ART 2006 nicolas at house.com.ar
- * background jpg for buttons
-
-Thu Mar 23 14:47:57 ART 2006 nicolas at house.com.ar
- * remove duplicated code
-
-Thu Mar 23 14:47:18 ART 2006 nicolas at house.com.ar
- * suse init fixes
-
-Thu Mar 23 14:46:39 ART 2006 nicolas at house.com.ar
- * configurable dimm/alpha
-
-Thu Mar 16 16:14:36 ART 2006 nicolas at house.com.ar
- tagged 0.26
-
-Version .25
-
-Mon Mar 13 17:01:23 ART 2006 nicolas at house.com.ar
- * documentation updates
-
-Mon Mar 13 16:56:00 ART 2006 nicolas at house.com.ar
- * queueagent optimizations
-
-Fri Mar 10 17:33:25 ART 2006 nicolas at house.com.ar
- * clean internal state when connecting to server
-
-Fri Mar 10 17:07:09 ART 2006 nicolas at house.com.ar
- * add_server_to_fake_events
- We need to add the server header to fake events!
-
-Fri Mar 10 17:06:44 ART 2006 nicolas at house.com.ar
- * formatting_fixes
-
-Fri Mar 10 17:05:03 ART 2006 nicolas at house.com.ar
- * update docs
-
-Mon Feb 27 19:40:37 ART 2006 nicolas at house.com.ar
- * updated docs
-
-Mon Feb 27 19:27:28 ART 2006 nicolas at house.com.ar
- * do not send settimer for nonexistant queues
-
-Mon Feb 27 19:25:36 ART 2006 nicolas at house.com.ar
- * Clear counter when there are no calls in queue
-
-Mon Feb 27 17:27:41 ART 2006 nicolas at house.com.ar
- * restrict to channel name same as mybutton
-
-Tue Feb 21 17:26:13 ART 2006 nicolas at house.com.ar
- * fix meetme sccp
-
-Tue Feb 21 16:09:02 ART 2006 nicolas at house.com.ar
- * Catalan language
-
-Mon Feb 20 16:10:40 ART 2006 nicolas at house.com.ar
- * suse_init
-
-Mon Feb 20 15:55:22 ART 2006 nicolas at house.com.ar
- * link_buttons
- Add url and target to the button definition so you can hyperlink
- to anything you want from any button.
- Also added the enable_label_background that sets the background
- color on the labels to the led colors depeding on state.
-
-Thu Feb 2 17:51:42 ART 2006 nicolas at house.com.ar
- * listen_addr
- Add listen_addr parameter to select the ip address the server will bind to
-
-Tue Jan 31 20:49:13 ART 2006 nicolas at house.com.ar
- * NewSwf
-
-Tue Jan 31 20:47:11 ART 2006 nicolas at house.com.ar
- * fontfix
- Fix several font issues on the flash client
-
-Tue Jan 31 20:41:04 ART 2006 nicolas at house.com.ar
- * Remove channel from queue hash on rename.. fix for queue buttons
-
-Tue Jan 31 20:32:40 ART 2006 nicolas at house.com.ar
- * Ignore <MASQ> & <ZOMBIE> from trunk sessions, fix TRUNK problem.
-
-Tue Dec 27 00:33:17 ART 2005 nicolas at house.com.ar
- * Fixed trunk sticky problem
-
- - Fixed choppig the last character from op_server.cfg
- when there was no end of line
-
- - Fixed text on buttons when using crypto and the text
- was empty
-
- - Changed the mute/unmute to gray out a button when muted
-
- - Fixed agentlogoff for channels with a hypen in the name
-
- - New states for sccp, thanks to Laurent Mele
-
- - New parameter to pass to operator_panel.swf: nohighligh. If set
- to 1, button highlighting when mouse over will be disabled.
-
- - New LEGEND attributes: URL, TARGET, NO_BASE64. Url for making an
- hyperlink out of the legend to that url, TARGET to use that html
- target when clicking the hyperlink, and NO_BASE64 to not convert
- the legend to base64 (it is not useful at all)
-
- - Drag&Drop channels into queues. Just drag an unused button into a
- queue button and it will be added to that queue. If dragged again,
- it will remove it from that queue.
-
- - astmanproxy support
-
- - Added Meetme participants buttons (they show each participant)
-
- - Added Queue position buttons (they show each position on a queue,
- with the corresponding timer and callerid)
-
- - Added queue_hide option in op_server.cfg. If set, queue position
- buttons won't be displayed if they are unused (so you only see
- the actual number of people waiting on the queue)
-
- - Fixed bugs for queue positions when reloading
-
- - Fixed timers when reloading
-
-.24
- Sep 12 2005:
-
- - Small bugfix, the security code is now working for everybody
-
- - Added swedish translation
-
- - Improved efficiency of regexp button matching
-
-.23
- Sep 9 2005:
-
- - FOP now tries to keep track of the number of agents logged into
- each queue, and displays that info in the queue detailed status box.
-
- - Added Mask filter for manager events. The new parameter
- is "event_mask" and should be written just below each server
- definition. View op_server.cfg for a sample.
-
- - Added Queue Position status. Just change your queue buttons to use
- more than one position. Then, instead of having a summary button for
- your queue you will have each button position occupied by the person
- waiting in that same position on your queue. You can drag them as any
- other button to transfer.
-
- - Internationalization support. 'language' configuration directive
- in op_server.cfg and op_lang_XX.cfg files and help_XX.html
-
- - Support for command line parameters, start the server with --help
- to see the list of supported options
-
- - The web_hostname and port settings in op_server.cfg are now optional
- If omited it will connect to the same host where the .swf resides and
- port 4445
-
- - Added restriction for mybutton to FOP_Popup userevent, just add the
- (optional) Button parameter with the button position (that must be
- set in the client's mybutton parameter)
-
- UserEvent(FOP_Popup|URL: page.php?e=${EXTEN}^Target: top^Button: 1)
-
- - Added font and shadow color parameters for button labels, text
- legends, clid and timer. In op_style.cfg you have 4 optional new
- parameters:
-
- label_font_color = 000000
- label_shadow_color = FFFFFF
- clid_font_color = 000000
- timer_font_color = 4000FF
-
- You have to put the hex color code for each one. To change the color of
- a legend use the parameter:
-
- font_color = FF0000
-
- - Improved debian init script. Thanks to Tzafir Cohen.
-
- - It uses a lot less CPU than previous versions on heavy asterisk boxes
-
- - Improved support for parking when using native sip transfers
-
- - Minor bugfixes
-
-.22
- Jun 9 2005:
-
- - Minor bugfixes
-
-.21
- May 29 2005:
-
- - You can use 'transparent' as a fade_color for a button in
- op_style.cfg. That button will only display its borders, with
- no background color. You can use the background.jpg in creative
- ways now.
-
- - The restrict input parameter can be set to a channel name
- instead of just the button possition. The restricted button
- will be hightlithed.
-
- - Added margintop and marginleft to the input parameters taken by
- operator_panel.swf, to set the global margins for the swf object.
- You can experiment by loading the .swf file directly like:
- operator_panel.swf?margintop=20&marginleft=40
-
- - Added voicemail_extension parameter to op_server.cfg. If set,
- FOP will originate a call to that extension when double clicking
- on the MWI icon.
-
- - Added version checking between client & server
-
- - You can disable the icon for a button by using icon=0
-
- - Added support for Zap DND state. You have to define the 'dnd'
- family in op_astdb.cfg
-
- - Added astdb checks. See op_astdb.cfg and extensions.conf.sample
- for details. You can check for day/time mode or anything that its
- stored on asterisk db.
-
- - Changed the PARKXXX buttons to PARK/XXX for consistency. The old
- syntax will still work fine.
-
- - Added monitoring for callerid instead of channel name. Use
- [CLID/XXXXXX] as the button name in op_buttons.cfg. Its experimental
- Commands like originates and others might not work. This kind
- of button will work with CVS-HEAD and without using the dial 'o'
- flag.
-
- - Added persistent security code. It remembers your last input so
- you don't have to complete it the next time you open FOP.
-
- - Added Panel_Context=* to op_buttons.cfg files, with it, that entry
- will be added to every panel context defined.
-
- - Fixed callerid on CVS-HEAD, now it works without using
- the dial 'o' flag
-
- - Added agent status. It displays Idle status an its
- timers, and refresh queue statistics after each agent
- call. Set agent_status to 1 in op_server.cfg
-
- - Added the option to change the led color from asterisk's
- dialplan:
-
- exten => 1,1,UserEvent(FOP_ledcolor|Color: 0x0000FF^State: 0)
-
- The color can be any hex value. The State is:
-
- 0 for available status (channel not in use)
- 1 for busy status (channel in use)
- 2 for agent status (channel not in use and logged in agent)
-
- - Added the option to fire screen pops from asterisk's
- dialplan:
-
- exten => 1,1,UserEvent(FOP_Popup|URL: page.php?e=${EXTEN}^Target: top)
-
- - Removed some DOWN status events that were redundant
-
- - Added callerid name in screen popups, look at the
- mypage.php sample in the html directory
-
- - Initial Status is fetched from op_server.pl memory
- instead of querying asterisk every time. Saves lots
- of asterisk resources and speeds things up
-
- - Fixed infobox bug when a button has multiple matches
-
- - Background image. Just place a background.jpg file
- in the same directory as the .swf file and it will
- be displayed as the background. The canvas size is
- 996x600
-
- - REGEXP buttons. Wildcard buttons are discarded in
- favor of the more powerful REGEXP buttons. If you
- use wildcard buttons, replace them with a REGEXP
- (Ex: if you have [SIP/*] change it to [_SIP/.*])
-
- - The security code is now optional (leave it blank
- in op_server.cfg for no security code when performing
- actions)
-
- - Added absolute timeout for transferred calls
-
- - Added the option to restart asterisk instead of reload
- the panel when hitting the reload button (enable_restart
- in op_server.cfg)
-
- - Reworked some button matching routines, now it should
- support Modem[i4l], oh323/* and mISDN
-
-.20
- Feb 22 2005:
-
- - Added support for monitoring multiple asterisk servers
-
- - Added wildcard buttons (IAX2/*)
-
- - Added Park Slot buttons (PARK701)
-
- - Barge Muted (barge_muted in op_server.cfg)
- Will start the 3rd leg muted when barging in
-
- - CallerID Privacy (clid_privacy in op_server.cfg)
- Will hide the callerid number in the buttons
-
- - Show IP address of peers (show_ip in op_server.cfg)
- Will show the ip address of peers in their buttons
-
- - Text legends (LEGEND primitive in op_buttons.cfg)
-
- - Highlight of linked buttons
-
- - Added Mailbox parameter to the button definition
-
- - You can specify a channel name in the dial parameter
- when using click-to-dial features, thus making it easier
- to implement
-
-.19
- Nov 04 2004:
-
- - Improved call details, now there is a queue/agent information
- window and last call details window.
-
- - Bugfixes and visual layout tweaks. You can set the highlight color, etc.
-
- - You can define a distinct style per panel context. See op_style.cfg
-
- - You can include files in op_buttons.cfg with the keyword 'include =>'
-
- - The swf client is compressed and much smaller.
-
- - When op_server.pl recconects, it close flash clients connections to
- force a reconnect and update on their status.
-
-.18
- Oct 29 2004:
-
- - Ming client is now the default, the new features work with
- that client only.
-
- - Led color configurable via op_style.cfg
-
- - More label renaming options
- (rename to agent name, rename queuememebers, etc)
-
- - Option to change led color for logged in agents
-
- - New click to dial feature, accesible via javascript
- (examples in the html subdir)
-
- - Ability to draw rectangles (see op_buttons.cfg for examples)
-
- - Added polling for IAX presence
-
-.17
- Oct 21 2004:
-
- - Mostly a bug fix release. Fixed the reload button in the ming client.
-
- - Added polling of agents status on connect
-
- - Initial take on showing detail info on each agent
-
-.16
- Oct 20 2004:
-
- - Bug fixes: parked channel feature works again, ringing state too.
-
- - Encryption is now optional, you can enable or disable it by changing
- enable_crypto in op_style.cfg (while is this parameter in op_style
- you may ask? well, the client has the ability to request encryption or
- not, op_style.cfg sets not only visual parameters, but any client
- parameter. I might change the configuration file name to op_client.cfg
- in the future. Without encryption the client uses less CPU.
-
- - Include the option for polling voicemail status together with sip
- peers (poll_voicemail in op_server.cfg)
-
- - New feature: ability to rename button labels when agents log in (
- rename_label_agentlogin and rename_label_callbacklogin inside
- op_server.cfg)
-
- - New Ming client included. Ming is a library for generating .swf files
- with wrappers in several languages. I used the perl wrapper to produce
- a complete client. The source is included in the ming-source directory
- The precompiled .swf file is in the html directory together with the
- native flash client. Further development might be done exclusively in
- Ming.
-
- - The Ming client treats fonts a little diferent. If you enable
- use_embed_fonts in op_style.cfg, then all the font_family values will
- be overriden by the only embedded font in the .swf. The
- embedded font looks uniform compared to system (or browser) fonts. You
- *can* use any font_family available in your platform: just disable the
- use of embed fonts and select the family for each legend in a button..
- but you might end up with chopped text depending of the type of font
- you use.
-
-
-.15
- Oct 1st 2004:
-
- - New configuration file format, there is an utility to convert
- your old configuration to the new format. See UPGRADE, and don't
- forget to backup first. Be sure to run the utility only with
- old configuration files, use it once and then remove it just in
- case.
-
- - Fixed MessageWaiting when channel was in another context
-
- - MD5 Authentication to Asterisk Manager (md5_auth in op_server.cfg)
-
- - Improved context handling in general. Now you can have a security
- code for each context, as well as meetme rooms to use for bargein.
-
- - There is no more auto_conf_exten for finding an empty meetme for
- barge-ins. You now have to specify the rooms available for that
- feature with the parameter barge_rooms in op_server.cfg
-
- - Timers are now polled from Asterisk on initial connect. (If you open
- the panel when a conversation was going, you will see the real duration
- of the call)
-
- - TEA Encryption for messages sent from server to client. MD5 used for
- hashing the password.
-
- - Many cosmetical changes to the flash movie, as well as optimizations
- and rewrites. There are new icons, animations, etc.
-
- - More information available when a call is disconnected, including
- queue status information (completed calls, average holdtime, etc)
- To get the info double click on the arrow when a call is finished.
-
- - Added ability to mute/unmute meetme participants by clicking on the
- arrow.
-
- - Supports for register/unregister/unreachable/lagged realtime events
- for SIP and IAX peers
-
- - You can restrict the drag and drop commands to one button only, see
- index-restrict.html in the html subdirectory
-
-.14
- Jul 28th 2004:
-
- - You can run the op_server.pl dettached from the console by starting it
- with the parameter '-d'. There are sample init scripts in the init
- directory for redhat and debian.
-
- - You can now drag a parked channel and transfer it to an available
- extension just like any other transfer.
-
- - Changed to work well with Asterisk RC1 (IAX2 channel names have changed
- from "IAX2[ext at context]" to IAX2/ext at context. Your IAX2 channels in
- op_buttons.cfg must be renamed if you use RC1. If you do not user RC1,
- it might work as before, but I have not tested it.
-
- - The flash side has a lot of improvements and changes. The fonts _sans
- and _serif are now embedded, so they will look consistent in different
- client computers (the tradeoff is a bigger swf file). When a channel is
- offline, the label text will also be grayed out. When dragging an icon,
- there is now visual feedback for the destination button. Added transparent
- mask to the icons to make drag easier. If the client looses connection to
- the op_server.pl, it will try to reconnect by itself (it does not work
- on linux, its a flash bug).
-
- - Also in the flash side, there are new elements. A little arrow showing
- the direction of the call. And if you double click that little arrow
- after a call is made, you can see the last call status. The new parameters
- for op_style.cfg are described in UPGRADE
-
- - There is a new parameter in op_server.cfg: clid_format
- You can choose the format for the caller id to be presented in the client
- The letter 'x' will be replaced with a number, any other text will be
- preserved.
-
-.13
- Jul 12th 2004:
-
- - Fixed an annoying bug that prevented the initial status to be displayed
- (the context for wich the panel request events was sent after the
- status events, so they were ignored by the flash client)
-
- - Fixed another annoying bug, the clid text was of an incorrect height,
- and the drag and drop was erratic because of this
-
- - Improved the parking display on the channels. Now you have a flashing
- led and a text in the button itself
-
- - Added a timer with the duration of a call to each button
-
- - Still more bugs to clean on the trunk feature, please report feedback
- on the mailing list..
-
-.12
- Jul 5th 2004:
-
- - Added a caller id display on the button itself
-
- - The status of meetme and queues is queried on initial connect
-
- - The event handling was rewriten. Now the flash client receives the
- events for its own context (in previous versions, the events were
- broadcasted to all clients)
-
- - Cleaned the debug output a bit.
-
- - You can send a USR1 signal to the server and look at some state
- variables.
-
-
-.11
- Jun 29th 2004:
-
- - Added 'trunk' buttons. You can define many buttons for just one user.
- It is not well tested, as I do not have the means to test it. It might
- introduce bugs!
-
- - Added CRM software integration. You can monitor a button, and when it
- rings, a web page is requested in the url and target you specify, with
- the clid sent as a GET variable.
-
- - The debug option in op_server.cfg has changed. See the UPGRADE file or
- the online documentation, or the comments on op_server.cfg
-
-.10
- Jun 22th 2004:
-
- - Added Contexts for the panel. You can have one server and several
- different panels.
-
- - Added 'Parked calls' as a status for a defined channel/button
-
- - Fixed important bugs (MWI with contexts not working, transfers not
- working in particular situations)
-
- - Totally new webpage, for up to date documentation, go there
-
- - You can send a HUP signal to op_server.pl and it will rewrite the
- configuration files for the flash applet.
-
- - New RELOAD button in flash, it will reread the server configuration
- and refresh the display.
-
-.09
- Jun 8th 2004:
-
- - Added Message Waiting count. When passing the mouse over the envelope
- icon the status shows the New and Old messages in that mailbox
-
- - The server sets the CallerID when originating a call.
-
- - Changed the debug parameter in op_server.cfg to a bitmap for greater
- control off debug output.
-
- - Changed the way it handles extension numbers (column number 4) in
- op_buttons.cfg. Now you can specify the context where the extension
- resides by using the syntax:
-
- extension at context
-
- If the extension is not reachable from the default context, you must
- specify its context there.
-
- - Changed the way it handles IAX2 channels. To specify an IAX channel you
- have to specify its name only, without '@context', eg:
-
- IAX2[john]
-
-
-.08
- Jun 2nd 2004:
-
- - Added "Extra Info" Input box
-
- You can write any text you want in that box. When transferring or
- originating a call, that text will be used as the callerid text for
- that call. This way you can pass usefull information to the person
- you are transferring the call. In order for this feature to work you
- need to modify your dialplan ("extensions.conf"). There is an example
- extensions.conf provided.
-
- - Configurable layout of the toolbar
-
- The bar at the top of the flash applet is now configurable. There are
- new parameters in op_style.cfg to adjust the layout:
-
- clid_label=Extra Info:
- security_label=Security Code:
- btn_help_label=Help
- btn_log_label=Debug
- show_security_code=1
- show_clid_info=2
- show_status=3
- show_btn_help=4
- show_btn_debug=5
-
- The numbers in the show_xxx varialbes indicates the position in the
- toolbar. If you do not want to display an element, set it to 0.
-
- - Added HELP button and text to the flash movie
-
- You can add a help.txt file in the same directory as the flash movie
- on your webserver. This file will be displayed inside the help window
- of the flash movie. You can use basic html tags. You *must* start the
- file with the words "text="
-
-.07
- May 19th 2004:
-
- - Added conference buttons
-
- The channel column (first one) in op_buttons.cfg must be named with
- the number of the meetme conference. Eg: you have a meetme conference
- number 901, the name of the channel must be '901'. Look at the example
- config.
-
- - Added tranfer of an empty channel to an already connected call and
- automatically conference the three parties together
-
- You have two new parameters in op_server.cfg:
-
- auto_conference_extension
- conference_context
-
- Set them up and look at op_server.cfg for an example configuration for
- asterisk in extensions.conf and meetme.conf
-
- - Added origination of calls
-
- You can drag an available button to another available button. This
- will originate a call from the first channel to the extension defined
- in the desintation button.
-
- - More readable output log for op_server.pl
-
-.06
- May 12th 2004
-
- - Added voicemail notification:
-
- There is a new parameter in op_buttons.cfg. The last column has the
- voicemail context of the extension. You can leave it blank and it will
- not check/show the voicemail status for that button (if its a queue
- button or an extension without voicemail on).
-
- You also have three new parameters in op_style.cfg:
-
- mail_margin_left
- mail_margin_top
- mail_scale
-
- to set the placement and size of the voicemail icon in the button.
-
-.05
- Apr 17th 2004
-
- - Fixed a typo that prevented the applet from working.
-
-.04
- Apr 16th 2004
-
- - Changed configuration files
-
- The configuration files are different: in version .03 the
- op_server.cfg had the button configuration and layout. In version
- .04 that information is stored in op_buttons.cfg. There are 2 new
- parameters in op_buttons.cfg, extension and icon.
-
- op_server.cfg is now used for the parameters of the op_server
- itself, like port to listent to, security code, debug level. You
- don't have to modify op_server.pl anymore. All configuration is done
- in the cfg files.
-
- There is a new configuration file: op_style.cfg with the style and
- size of the buttons.
-
- - Added Queues buttons
-
- You can display call queues on a button. Just put the name
- of the queue as the channel name.
-
- - Reconnection to Asterisk Manager port
-
- The op_server now tries to reconnect to Asterisk Manager
- port in case of disconnection. So if you restart Asterisk
- you don't need to restart the op_server.pl, it will reconnect
- by itself.
-
- - Totally redone flash movie: operator_panel3.swf
-
- The flash applet in version .04 is totally rewriten. IÏt
- has no bitmaps. All graphics are vector based, so you can
- change the style and sizes without loosing detail. There
- is no timer or status on each button in order to save space.
- You can see the status of a channel by passing the mouse
- over the red oval.
-
- The new op_server.pl is compatible with the flash applet
- of previous versions (operator_panel.swf), with fixed 24
- buttons display, timers, and scrolling info on each channel.
Deleted: op-panel/trunk/FAQ
===================================================================
--- op-panel/trunk/FAQ 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/FAQ 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,65 +0,0 @@
-Flash Operator Panel frequently asked questions:
-------------------------------------------------
-
-Q0: Do I have to run a webserver?
-
-A0: Yes, its a Flash applet, it works from a web browser. You can use apache
- or any other webserver you like. It was tested with Windows, Linux, and
- Mac browsers. Its truly multiplatform!
-
-
-Q1: Do I need to install additional Perl modules to run op_server.pl?
-
-A1: No, it works without extra modules.
-
-
-Q2: International characters are not displayed in button labels! Is it
- possible to use foreign characters?
-
-A2: Yes, its possible. The flash movie will display international
- characters if you encode the text with UTF-8. You can encode the files
- from the command line using vi:
-
- vi -c ":wq! ++enc=utf8" op_buttons.cfg
-
- There is a downside to this. If you originate calls from the panel, the
- caller id will be set with the utf8 label (ilegible characters in the
- clid)
-
-Q3: I do not want to mess with the caller id text and the asterisk database.
- Can I disable that feature?
-
-A3: Sure, just modify op_style.cfg and set the show_clid_info variable to 0
- (zero).
-
-
-Q4: When I try to open the webpage, the browser hangs. Whats wrong?
-
-A4: The flash movie tries to read a file named 'variables.txt' that is
- generated by op_server.pl in the same directory where the .swf file
- lives. If this file is corrupted or incomplete, the flash movie might
- loop forever. Make sure you have the file in place. If its not there,
- you might have permissions problems or you forgot to run op_server.pl.
-
-
-Q5: I changed the style op_style.cfg, but when I reload the page I don't
- see the changes. What's up?
-
-A5: The flash movie requests the file variables.txt when it starts. If your
- browser caches that file, you won't see the changes you made unless you
- clear your browser cache, or maybe just requesting the variables.txt
- file and hitting reload a couple of times.
-
-Q6: I do not like editing a text file to change a visual layout!
-
-A6: Me neither, I dream of a visual layout configuration. But I do not have
- the time to make it happen. Maybe in the future.
-
-Q7: Where is the .fla file?
-
-A7: The flash client is done with MING: you will find the perl source for
- generating a working .swf client under ming-source.
-
- If you want the ancient .fla for the first versions, I will trade them
- for a new apple mac mini core duo or macbook pro.
-
Deleted: op-panel/trunk/LICENSE
===================================================================
--- op-panel/trunk/LICENSE 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/LICENSE 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,341 +0,0 @@
-
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
Deleted: op-panel/trunk/README
===================================================================
--- op-panel/trunk/README 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/README 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,186 +0,0 @@
-Asterisk Flash Operator Panel
-Copyright (c) 2006 Nicolás Gudiño. All rights reserved.
-http://www.asternic.org
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-For complete and up to date documentation, please visit the web page
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-What is Flash Operator Panel?
------------------------------
-
-The Flash Operator panel is a 'switchboard' application for the Asterisk PBX
-system. It displays information about your Asterisk PBX activity in real
-time via a standard web browser with Flash plugin. The display and button
-layout is configurable, you can have more than a 100 buttons on the screen
-at once.
-
-You can see at a glance:
-
- * What extensions are busy, ringing or available
- * Who is talking and to whom (clid, context, priority)
- * SIP registration status and reachability
- * Meetme room status (number of users) in the room
- * Queue status (number of users waiting)
- * Parked extensions
- * Call duration Timers
- * Logged in Agents
-
-You can perform these actions:
-
- * Hang-up a channel (double click the colored dot on the button)
- * Transfer a call leg via drag&drop (drag the phone icon on a button to
- another button)
- * Originate calls via drag&drop
- * Drag an available extension to an ongoing conversation and conference
- the three together.
- * Change the callerid text to something meaningfull when transferring or
- originating a call
- * Mute/Unmute meetme participants
-
-Requirements
-------------
-
-* You need PERL and basic knowledge on how to use Asterisk.
-
-* You have to add a user to asterisk's manager.conf and reload asterisk for
- the changes to take effect.
-
-* For the conference buttons, message waiting indication and automatic three
- way conferences, you need asterisk CVS-HEAD as of 5/25/2004
-
-* You need flash player versions 7 and up
-
-* You also need to define in your dialplan the conferences in a proper way
- and in their own context, as explained in op_server.cfg comments.
-
-* If you plan to use the "Info" box to set the callerid text when
- transferring or originating a call, you need to modify your dialplan. See
- extensions.conf.sample
-
-* You also need to be wary, as English is not my first language.
-
-
-Install
--------
-
-1) Untar de package on a suiteable place, for example /usr/local
- (if you are reading this you probably already done that)
-
-1) Copy the files in the 'flash' or 'dhtml' subdirectory to a suitable place
- on your web server. If your web root is /var/www/html, you can create a
- subdirectory 'panel' and copy the files there.
-
- There are several ways (index files) to load the flash applet, try them
- out. You can modify the file help-xx.html files to your liking.
-
-2) Edit op_server.cfg and change the appropriate parameters for your setup.
-
- "flash_dir" parameter must be the exact location of the directory where
- the html and swf files are placed.
-
- The rest of the parameters are well commented in the cfg file
-
-3) Edit op_buttons.cfg to suit your needs. The file is commented and its
- self explanatory.
-
-4) Edit op_style.cfg to suit your needs. You can change the button size and
- colors, icon placement and size, etc. DO NOT modify the variable names,
- just the value after the equal sign and DO NOT use spaces. With proper
- adjusting, you can have more than a 100 buttons on the screen.
-
- You can change the toolbar layout by changing the number after the
- variable show_???. Each one represents a possible element in the toolbar.
- A value of 0 disables that element. A number represents the order in the
- toolbar it will be displayed, number one being the leftmost part of the
- toolbar. In the example configuration, all the toolbar elements are
- displayed in correlative order. Eg: if you do not want to display a DEBUG
- button, set the 'show_btn_debug' to 0. You can translate the text of the
- toolbar in the corresponding variables.
-
- --!! Please note !!---------------------------------------------------
- If you want to transfer an available channel to an already connected
- call, you have to configure your dialplan correctly and have the
- context properly defined, if you don't do that you will experience
- hanged channels and asterisk lockups. Thats because when you redirect
- a call within the asterisk manager with an incorrect contexts,
- asterisk does not handle the error gracefully.
- --!!-----------------------------------------------------------------
-
-
-International Characters
-------------------------
-
-If you want to display foreign characters in button labels, you have to save
-the configuration file with UTF-8 encoding. To convert the file to UTF-8
-utilizing vi and the command line just perform:
-
-vi -c ":wq! ++enc=utf8" op_buttons.cfg
-
-
-Running
--------
-
-The op_server.pl must run on the same computer as the web server
-
-When started, it writes the file 'variables.txt' to the http directory where
-the flash applet is installed with configuration data. It must have
-permissions to write to that directory.
-
-You can run it daemonized using -d as its command line argument. There are
-some example init scripts in the directory inits
-
-If you want to start the server when the machine starts, you can add a line
-similar to the following to your rc.local file (you have to replace the
-values between '*' with the ones for your system, if you do not want to run
-the op_server.pl as root, just su to that user:
-
-(cd */path/*; su *operator-user* -c */path/*op_server.pl & )
-
-Or better yet, use one of the init scripts provided.
-
-
-Security
---------
-
-Its not meant to be secure. You should take provisions yourself, like
-limiting who can connect by means of .htaccess files, firewall rules, etc.
-There is basic encryption for messages sent from the server to the client,
-and the security code is sent with MD5. It will hide sensitive information
-from the casual observer, but its not strong enough to send credit card
-information.
-
-
-How to use it
--------------
-
-Click the HELP button when running the Flash Operator Panel. Experiment.
-Drag icons, move your mouse around. Click and double click when the arrow
-turns into a hand.
-
-
-Support
--------
-
-For support or submitting bug reports, features requests, etc, please
-subscribe to the mailing list by sending an empty email to
-operator_panel-subscribe at lists.house.com.ar
-
-Donations
----------
-
-If you like the program, or have feature requests, you can contribute to the
-cause by donating via paypal. Click the donate button on the webpage. You can
-also contact me for custom works, or asterisk consultancy.
-
-Thanks!
-
-
-Credits
--------
-
-MD5 Algorithm. Copyright:
-(C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
-
-TEA Encryption algorithm:
-Copyright (c) 2000, Peter J Billam c/o P J B Computing, www.pjb.com.au
Deleted: op-panel/trunk/RECIPES
===================================================================
--- op-panel/trunk/RECIPES 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/RECIPES 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,101 +0,0 @@
-RECIPE 1
---------
-Set DND (Do not disturb) from your dialplan and
-reflect the status on FOP:
-
-# Example on setting DND state from the dialplan
-# *78 Sets DND ON
-# *79 Sets DND OFF
-#
-# This example only sets the dnd db value and
-# signals FOP to display the status on the button
-# you might have to add a check in your stdexten
-# macro to honour the DND status
-
-in extensions.conf:
-
-exten => *78,1,UserEvent(ASTDB|Family: dnd^State: On)
-exten => *78,2,SetVar(temp=${CHANNEL})
-exten => *78,3,Cut(temp=temp,,1)
-exten => *78,4,DBPut(dnd/${temp}=On)
-exten => *78,5,Hangup
-
-exten => *79,1,UserEvent(ASTDB|Family: dnd^State: ^)
-exten => *79,2,SetVar(temp=${CHANNEL})
-exten => *79,3,Cut(temp=temp,,1)
-exten => *79,4,DBDel(dnd/${temp})
-exten => *79,5,Hangup
-
-in op_astdb.cfg:
-[dnd]
-settext=DND: ${value}
-setalpha=70
-
-RECIPE 2
---------
-How to monitor rxfax. This is just a barebones sample, you can
-customize it for your needs. You have to Goto to the fax context
-from your dialplan:
-
-in extensions.conf:
-
-exten => fax,1,Goto(rxfax,s,1)
-
-[rxfax]
-exten => s,1,SetVar(FAXFILE=/var/spool/fax/fax-${TIMESTAMP}.tif)
-exten => s,2,SetVar(LOCALSTATIONID=My Company)
-exten => s,3,UserEvent(Newexten|Channel: FAX/FAX-${UNIQUEID}^State: Up^Uniqueid: 1234)
-exten => s,4,rxfax(${FAXFILE})
-exten => s,5,Hangup()
-exten => t,1,Hangup()
-exten => h,1,UserEvent(Hangup|Channel: FAX/FAX-${UNIQUEID}^State: Down^Uniqueid: 1234)
-
-in op_buttons.cfg:
-[FAX/FAX]
-Position=1
-Label="Fax"
-
-
-
-RECIPE 3
---------
-How to monitor voicemailmain (users entering the voicemail application)
-You have to define a regular extensions that performs a 'Goto' to the
-vmail context (similar to the fax case above)
-
-in extensions.conf:
-
-[vmail]
-exten => s,1,SetLanguage(es)
-exten => s,2,UserEvent(Newexten|Channel: VMAIL/VMAIL-${UNIQUEID}^State: Up^Uniqueid: 4321)
-exten => s,3,VoicemailMain(${CALLERIDNUM}@internos)
-exten => t,1,Hangup
-exten => h,1,NoOp(Hangup en voicemail)
-exten => h,2,UserEvent(Hangup|Channel: VMAIL/VMAIL-${UNIQUEID}^State: Down^Uniqueid: 4321)
-exten => h,3,Hangup
-
-in op_buttons.cfg:
-
-[VMAIL/VMAIL]
-Position=1
-Label="Voicemail"
-
-RECIPE 4
---------
-Show day/night mode based on an asterisk db value:
-
-in extensions.conf:
-
-exten => 80,1,DBPut(daymode/DAYMODE=Day);
-exten => 80,2,UserEvent(ASTDB|Family: daymode^Channel: daymode^Value: Day)
-exten => 80,3,Hangup
-;
-exten => 81,1,DBPut(daymode/DAYMODE=Night);
-exten => 81,2,UserEvent(ASTDB|Family: daymode^Channel: daymode^Value: Night)
-exten => 81,3,Hangup
-
-in op_astdb.cfg:
-
-[daymode]
-setlabel=${value}
-
Deleted: op-panel/trunk/TODO
===================================================================
--- op-panel/trunk/TODO 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/TODO 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,8 +0,0 @@
-* Clean bugs
-* A way to set astdb values from the .swf
-* A way to perform any cli or manager action from the .swf
-* Go to Astricon USA with more help
-* Change user authentication and restrictions methods
-* Get some sleep
-* Make a client in JAVA
-* Make a windows systray client
Deleted: op-panel/trunk/UPGRADE
===================================================================
--- op-panel/trunk/UPGRADE 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/UPGRADE 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,555 +0,0 @@
-Notes on upgrading from an older release
-========================================
-
-o Upgrading from version .25 to .26:
-
- New DTHML client. The directory structure on the tarball has changed
- to accommodate the new DHTML client. The former html subdirectory was
- renamed to flash, and the new client is inside the dhtml subdirectory.
-
- The new DHTLM client works in a similar way to the flash client, it has
- a couple of scripts that read the same config files than the flash
- version to draw the buttons. It is not yet complete but it mostly works.
-
- New parameter in op_style.cfg:
-
- shake_pixels
- Sets the number of pixels to shake the icon when ringing
-
- dimm_noregister_by
- Ammount of alpha dimm to apply when channel is not registred
-
- dimm_lagged_by
- Ammount of alpha dimm to apply when channel is lagged
-
- New parameters in op_buttons.cfg:
-
- VoiceMailExt
- To set the extension at context to use when transferring directly
- to voicemail
-
- Background
- To specify a jpg image to use as button background. You have to
- set No_rectangle=true on that button for the background to become
- active. The .jpg file should be of the same size as the button width
- and height as specified in op_style.cfg
-
- Privacy
- If set to true, it won't display caller id or dialed number info
- for that button.
-
-o Upgrading from version .24 to .25:
-
- Queue buttons now must be defined as:
-
- [QUEUE/SUPPORT]
-
- With this new syntax, queue names with numbers
- only as used in AMP will work without collisions.
-
- You have to rename all queue buttons in your config
- file to use the new syntax or they won't work.
-
- Added some attributes to LEGENDS in op_buttons.cfg:
-
- URL
- TARGET
- NO_BASE64
-
- If set, the legend will become an hyperlink to URL at TARGET
- If NO_BASE64 is set, the text won't be encoded
-
- Added attributes to any button in op_buttons.cfg:
-
- URL
- TARGET
-
- If set, it will add an hyperlink to the button label pointing
- to that URL and opening it inside TARGET.
-
- Added enable_label_background to op_style.cfg
-
- This parameter will set the background color to the button label
- to the same colors as the led. You can use it together with
- "no_rectangle" in the buttons and Icon=0 and a small width, height
- and font to fit hundreds of buttons on one screen. I was able to
- fit 630 buttons (but only for monitoring as you don't have the led
- or icon to transfer or hangup calls)
-
- Added dimm (alpha) for noregistered and lagged buttons to op_style.cfg
-
- dimm_noregister_by=20
- dimm_lagged_by=60
-
- Added listen_addr keyword
- If you want op_server.pl to bind to only one IP address instead of
- all avaialbe addresses.
-
- Added manager_port keyword
-
- If your manager is not running on the default port, you
- can specify the port now for each connection with this
- option. Example:
-
- manager_port = 5039
-
- Added support for astmanproxy
-
- In op_server.cfg you have to defined the astmanproxy host & port
- (the ip address where astmanproxy is listening) & server (the
- same ip or name you use in astmanproxy.conf). If you
- monitor more than one asterisk server trough astmanproxy, you
- will have to enumerate them using the astmanproxy_server keyword.
- Example:
-
- astmanproxy_host = 127.0.0.1
- astmanproxy_port = 1234
- astmanproxy_server = 192.168.10.1
- astmanproxy_server = 192.168.10.2
-
- Added buttons for MEETME participants. Just specify more
- than one position for a meetme button and they will show
- meetme participants indiviually as they join or leave the
- conference.
-
- Added [QUEUEAGENT] buttons. They will be taken by static
- or dynamic queue members automatically.
-
- Added buttons for QUEUE positions. Just specify more than
- one position for the button and they will show each queue
- position instead of a queue summary
-
-
-o Upgrading from version .23 to .24:
-
- Nothing new, just a bug fix release in op_server.pl
-
-o Upgrading from version .22 to .23:
-
- Client and server must be upgraded or it will not work well.
-
- Internationalization support:
-
- Parameter ADDED to op_server.cfg:
-
- language
-
- To set the language to use in the general section
- and optionally in every panel context defined.
-
- The language files are named op_lang_XX.cfg where XX is the
- language to use defined in the language option. Each panel
- context might have a distinct language. The default language
- is 'en' (english).
-
- You can create your own language file. If you do, please
- send it back to me so I can include it in the tarball.
- Some strings include variables, they are represented as
- $1 and $2. You can ommit the variables or use them as you
- see fit.
-
- The help file is now called help-XX.html. Be sure to add that file
- or rename the one you have. Please contribute with translations or
- beautifying them if you can.
-
- Parameters REMOVED from op_style.cfg (they were moved to the language
- configuration file):
-
- clid_label
- detail_title
- detail_from
- detail_to
- detail_duration
-
- Parameters ADDED to op_style.cfg (to set the button label color, the
- button label shadow color, and the clid text color):
-
- label_font_color = 000000
- label_shadow_color = FFFFFF
- clid_font_color = 00DD00
- timer_font_color = 200070
-
- New option for LEGENDS in op_buttons.cfg
-
- font_color = 102030
-
- Support for command line options. Run op_server.pl with --help to
- see the available options
-
-
-o Upgrading from version .21 to .22:
-
- Just replace op_server.pl that has minor bugfixes
-
-o Upgrading from version .20 to .21:
- New configuration file: op_astdb.cfg used to monitor asterisk
- db values and change states for a button based on them.
-
- New option: voicemail_extension parameter in op_server.cfg.
- If set, FOP will originate a call to that extension when
- double clicking on the MWI icon.
-
- The PARK buttons are now specified as PARK/XXX
- instead of PARKXXX to make it more consistent with
- channel naming conventions. The old name will still
- work.
-
- To enable agent_status (displays agent idle
- time and refresh queue status after each
- call). In op_server.cfg:
-
- agent_status=1
-
-
- If there is a background.jpg image in the same
- directory as the swf file, it will be used as
- the background for the panel. Resolution: 996x600
-
- The syntax for wildcard buttons has changed, if
- you have [SIP/*] change it to [_SIP/.*]
- The new matching routine allows full regexps to
- be used. To use regexps buttons start them with
- an underscore followed by your expression.
-
- To disable the security code, leave it blank. In
- op_server.cfg:
- security_code = ""
-
- To enable timeout on transfers, you have to set the
- transfer_timeout paramenter to op_server.cfg
-
- You can set the reload button to perform an asterisk
- restart if you set enable_restart to 1 in op_server.cfg
-
-o Upgrading from version .19 to .20:
-
- You can define the server number of a button in op_buttons.cfg
- using the 'server' directive. If you leave it empty, it will
- default to Server=1
-
- To monitor more than one asterisk box, just repeat the sequence of
- connection parameters in op_server.cfg
-
- ; Server 1
- manager_host=1.2.3.4
- manager_user=john
- manager_secret=doe
-
- ; Server 2
- manager_host=1.2.3.5
- manager_user=mary
- manager_secret=poppins
-
- To add text legends, the format is:
-
- [LEGEND]
- x=535
- y=50
- text=Conferences
- font_size=32
- font_family=Arial
- use_embed_fonts=1
-
- To add park slot buttons, the format is:
-
- [PARK701]
- Position=17
- Icon=3
- Extension=700
- Label="Park 701"
-
- You can specify the mailbox for a button with the mailbox parameter:
-
- [SIP/100]
- Position=1
- Mailbox=100 at default
- ...
-
- The 'old way' still works, by using the combination of Extension and
- Voicemail_Context. I recommend you to use the new format as it is more
- flexible (you can monitor a mailbox independant from the extension of
- that button).
-
-
- New directives in op_server.cfg
-
- rename_label_wildcard
- barge_muted
- clid_privacy
- show_ip
-
-o Upgrading from version .18 to .19:
-
- In op_style.cfg there is a new paramter to confgure the
- highlighting color for the buttons:
-
- btn_highlight_color=ff0000
-
-o Upgrading from version .17 to .18:
-
- The default .swf client is now the ming port. The new features
- are available only in the ming port. The flash .swf is included
- but it was not tested.
-
- In op_style.cfg there are new parameters (to configure led colors):
-
- ledcolor_ready
- ledcolor_busy
- ledcolor_agent
-
- The parameter led_color is not used anymore. (It is used by the
- flash client only, not the default ming client)
-
- In op_server.cfg there are new options too (all commented in
- op_server.cfg itsef):
-
- rename_label_agentlogin
- rename_label_callbacklogin
- rename_to_agent_name
- rename_queue_member
- change_led_agent
- clicktodial_insecure
-
- It is possible now to draw rectangles, see op_buttons.cfg for
- an example.
-
- If you use click-to-dial, the button used to originate the call
- must be specified when invoking the .swf file. The parameter used
- is 'dial'. See index-clicktodial.html for an example.
-
-o Upgrading from version .16 to .17:
-
- Just replace op_server.pl and your favorite .swf client. Its
- mostly a bug fix release. The new features do not require
- configuration changes.
-
-o Upgrading from version .15 to .16:
-
- The help window is now a browser windows that loads help.html
- (instead of being a flash window that loads the help.txt file)
- So you need to put a help.html page in the same location as the
- .swf file.
-
- There are a couple of new parameters. In op_server.cfg
-
- poll_voicemail
-
- Will check for voicemail status every poll_interval seconds.
- Remeber that poll_interval will also check for sip peers.
-
- rename_label_agentlogin
- rename_label_callbacklogin
-
- Both parameters acomplish the same goal: to rename a button
- label when an Agent logs in. One of them works with the regular
- AgentLogin application. The other one with AgentCallbackLogin.
- For the later, you need to have a button with the same extension
- and context for the callback for it to work.
-
- There is also a new parameter in op_style.cfg
-
- enable_crypto (1 for enable, 0 for disable)
-
- If you want to encrypt server to client messages, turn this on.
-
-o Upgrading from version .14 to .15:
-
- The format of the configuration file is different. You have to
- run ./convert_config_pre_14.pl in order to convert your old
- configuration files to the new format. The conversion utility
- must reside in the same directory as the old configuration files:
-
- op_server.cfg
- op_style.cfg
- op_buttons.cfg
-
- When you run the conversion routine, it will backup your old
- configuration files and do its thing. Just in case, backup the
- files yourself. The conversion program does not have extensive
- error checking.
-
- The barge-in functionality has changed also. You no longer need
- an auto_conference_extension in your dialplan. The panel will
- keep track of the conferences itself. You *do* need to add the
- conference room numbers that must be used for barge-in. The
- conversion routine adds the parameter, you have to modify it to
- suit your needs. The new parameter (in op_server.cfg) is:
-
- barge_rooms
-
- It must have at least two rooms defined, with the format:
- "minor-major". Those rooms must be defined in your extensions.conf
- under the context defined by conference_context. The extension
- number must match the meetme room number. See op_server.cfg for
- an example.
-
- To authenticate using MD5 to Asterisk Manager you can add the parameter
- auth_md5=1 in op_server.cfg. It is enabled by default.
-
- There are new parameter in op_style.cfg:
-
- enable_animation: it will animate the phone icons when ringing.
-
- use_embed_font: lets you choose between embed fonts or system fonts.
-
- (1 for enable, 0 for disable)
-
-
-o Upgrading from version .13 to .14:
-
- In Asterisk RC1, the IAX naming convention has changed. There are
- no more brackets in IAX2 channel names. If you run RC1 (try it!)
- you will have to name your IAX2 channels like:
-
- IAX2/user
-
- You will have to rename your op_buttons.cfg if you use IAX2 channels.
-
- The code for handling the previous naming convention is still there
- but I have not tested it. It might or might not work.
-
- There are new elements in op_style that affects the button style:
-
- arrow_scale
- arrow_margin_top
- arrow_margin_left
-
- The above parameters indicate the size and position of a little
- arrow that shows the 'direction' of the call.
-
- detail_title=Last call details
- detail_from=From:
- detail_to=To:
- detail_duration=Duration:
-
- These four parameters are for setting the text displayed in the
- detail box when you double click on the little arrow after a call
- is made.
-
- led_color
-
- The color scheme for the available/busy led.
- 0 for leds green/red. (default)
- 1 for leds grey/green
-
- label_shadow
-
- You can add a shadow to the text label
- 0 for disabling the shadow (default)
- 1 for enabling the shadow
-
-
- There is a new parameter in op_server.cfg:
-
- clid_format
-
- This mask will apply to the callerid field to format the
- number as you see fit. Every 'x' will be replaced by a number
- from right to left. Any other char will be preserved. Ex:
- (xxx) xxx-xxxx
-
-o Upgrading from version .12 to .13:
-
- For the timer to work, you need to add four new parameters to
- op_style.cfg
-
- timer_font_size
- timer_font_family
- timer_margin_top
- timer_margin_left
-
-o Upgrading from version .11 to .12:
-
- There are 4 new parameters in op_style.cfg for the caller id
- display on each button.
-
- clid_font_size
- clid_font_family
- clid_margin_top
- clid_margin_left
-
-o Upgrading from version .10 to .11:
-
- There are no new parameters in the configuration files. Your .10
- configuration should work fine with version .11
-
- The debug level bitmap is now different:
-
- 1 Show Manager Events Received
- 2 Show Commands set to Manager
- 4 Show Flash events Received
- 8 Show events sent to Flash Clients
- 16 1st level Debug on op_server.pl
- 32 2nd level Debug on op_server.pl
- 64 3rd level Debug on op_server.pl
-
-o Upgrading from version .09 to .10:
-
- There are 2 new parameters in op_style.cfg for a new element
- in the toolbar (a reload button)
-
- btn_reload_label
- show_btn_reload
-
-
-o Upgrading from version .08 to .09:
-
- The debug level (op_server.cfg) is now a bitmap. Now you have more
- control of the output produced by debug. The possible values are:
-
- 1 Show Manager Events Received
- 2 Show Commands set to Manager
- 4 1st level debug on op_server.pl
- 8 2nd level debug on op_server.pl
- 16 3rd level debug on op_server.pl
-
- If you want full debug, set the value to 31 in op_server.cfg
- If you want to see just the events received and sent, set it to 3 (1+2)
-
- The fade matrix for the buttons is slightly different. Its the first
- step towards a visual button layout configurator.
-
-o Upgrading from version .07 to .08:
-
- The offset and size of the icons have changed. You will need to adjust
- your op_style.cfg. Now all the icons are aproximatly the same size and
- have the same center offset, so the margins and scale parameters will
- match from icon to icon. New layout configurations should be simpler.
-
- There are several new parameters in op_style.cfg, related to the
- configurability of the toolbar. You have to add them in your current
- configuration, if you don't do it you will not see any toolbar. The
- parameters to add are:
-
- clid_label=Extra Info:
- security_label=Security Code:
- btn_help_label=Help
- btn_log_label=Debug
- show_security_code=1
- show_clid_info=2
- show_status=3
- show_btn_help=4
- show_btn_debug=5
-
- The number in show_xxx represents the order in which it is rendered. If
- you want to hide an element of the toolbar, set it to 0.
-
-o Upgrading from version .06 to .07:
-
- There are two new parameters in op_server.cfg:
-
- auto_conference_extension = 900
- conference_context = conferences
-
- Add them to your existing configuration file. In op_server.cfg there are
- also examples of asterisk configuration files to use the 3way auto
- conferences.
-
-o Upgrading from previous versions:
-
- There are three new parameters in op_sytle.cfg and a new one in
- op_buttons.cfg. See CHANGES. Just add those parameters to your current
- config files, and replace op_server.pl with the new one. The fixed 24
- buttons flash movie does not support voicemail notifications. There is a
- new index.html that scales the applet to the size of the browser window.
- Try it and use the one you like more.
Deleted: op-panel/trunk/extensions.conf.sample
===================================================================
--- op-panel/trunk/extensions.conf.sample 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/extensions.conf.sample 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,46 +0,0 @@
-#
-# Example entry for setting a callerid text comming
-# from the flash operator panel
-# You have to modify line 1 and 3 to match the channel
-# name for that extension: temp=clid should remain untouched.
-#
-# If the variable does not exist in the database
-# (if was not set by the operator panel) the line
-# 1 jumps to priority n+101, to perform a normal
-# dial without setting the CallerIDName
-
-exten => 11,1,DBget(temp=clid/SIP/11)
-exten => 11,2,SetCIDName(${temp})
-exten => 11,3,DBdel(clid/SIP/11)
-exten => 11,4,Dial(SIP/11,30,TrH)
-exten => 11,5,Hangup
-
-; gets here if there was not 'info' provided
-exten => 11,102,Dial(SIP/11,30,TrH)
-
-; busy from the dial
-exten => 11,105,Busy
-exten => 11,203,Busy
-
-
-# Example on setting DND state from the dialplan
-# *78 Sets DND ON
-# *79 Sets DND OFF
-#
-# This example only sets the dnd db value and
-# signals FOP to display the status on the button
-# you might have to add a check in your stdext
-# macro to honour the DND status
-
-exten => *78,1,UserEvent(ASTDB|Family: dnd^State: On)
-exten => *78,2,SetVar(temp=${CHANNEL})
-exten => *78,3,Cut(temp=temp,,1)
-exten => *78,4,DBPut(dnd/${temp}=On)
-exten => *78,5,Hangup
-
-exten => *79,1,UserEvent(ASTDB|Family: dnd^State: ^)
-exten => *79,2,SetVar(temp=${CHANNEL})
-exten => *79,3,Cut(temp=temp,,1)
-exten => *79,4,DBDel(dnd/${temp})
-exten => *79,5,Hangup
-
Deleted: op-panel/trunk/op_astdb.cfg
===================================================================
--- op-panel/trunk/op_astdb.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_astdb.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,30 +0,0 @@
-; FOP will ask for the value of the asterisk database families
-; specified between brackets. If the value is non empty, it will
-; send the commands to the flash client. Note that the family
-; is case sensitive!
-
-;[dnd]
-;settext=DND: ${value}
-;setalpha=70
-;flip=1
-;fopledcolor=0x001020
-
-;[cfb]
-;settext=CFB: ${value}
-;status=busy ; free, busy, ringing
-;fopledcolor=0x102030
-
-# How it works: when the panel is first started, it will check
-# for every family defined in op_astdb.cfg between brakets. The
-# key is the channel name, as defined between brackets in op_buttons.cfg
-# If a value is found and non empty it will perform the actions
-# specified in op_astdb.cfg, those actions modify the button for
-# that channel in FOP, they are:
-#
-# settext = sets the text where the callerid is displayed
-# setlabel = sets the label for the button
-# setalpha = sets the alpha blending for the whole button (0-100)
-# flip = flips the button (1)
-# state = set the state of the led to: free, busy or ringing
-# fopledcolor = sets the led color using hex values like 0x2030a0
-
Deleted: op-panel/trunk/op_buttons.cfg
===================================================================
--- op-panel/trunk/op_buttons.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_buttons.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,261 +0,0 @@
-[SIP/10] ; Channel name
-Position=1 ; Button number in the console
-Label="10 Fax" ; Text label for the button
-Extension=10 ; Extension to reach that channel
-Context=sip ; Context where that extension is defined
-Mailbox=10 at sip ; The voicemail mailbox to monitor
-Icon=1 ; There are 6 icons available
-Url=http://www.asternic.org ; Optional, add link to button label
-Target=_new ; Optional, open link in this target
-No_Rectangle=0 ; Optional: If enabled, it will not draw the button
- ; rectangle, only the icons inside
-Background=bg.jpg ; Optional: it will load that jpg as the button
- ; background. It should match the size as specified
- ; in op_style.cfg btn_width and btn_height.
-VoiceMailExt=910 at vm ; extension at context to use for transferring a call
- ; directly to voicemail
-Privacy=false ; if set to true, it will hide callerid info for
- ; the button
-
-[SIP/11]
-Position=n ; Position 'n' will be the next available
-Label="Multiline%0aLabel" ; %0a is the new line character
-Extension=11
-Context=sip
-Icon=1
-Server=1 ; If you omit the Server, it will default to 1
-
-[SIP/12]
-Position=n
-Label="12 Ernest"
-Extension=11
-Context=sip
-Icon=1
-Server=2 ; If you monitor more than one server change this
-
-[_SIP/.*] ; You can use REGEXP. Prefix the button with an
-Position=1,2 ; underscore followed by your expression
- ; (you cannot use & and = as they are reserved)
-Label="SIP Guest"
-Extension=-1 ; If set to -1 you will not be able to transfer
- ; to this button
-Context=internos
-Icon=1
-
-[PARK/701]
-Position=17
-Icon=3
-Extension=700
-Label="Park 701"
-
-[SIP/16]
-Position=6
-Label="16 Nicolás" ; you can use unicode for extended characters
-Extension=16
-Context=internos
-Icon=1
-Mailbox=16 at internos
-
-[CAPI[contr1/NNNNNNNNN]] ; where NNNN is the ISDN number. If you
-Position=22,23 ; specify more than one position, the button
- ; will be considered a 'trunk', each call will be
- ; displayed in a separate button
-Label="External CAPI"
-Extension=-1
-Context=in-extern
-Icon=4
-
-[SIP/17]
-Position=7
-Label="17 Martin"
-Extension=17
-Context=internos
-Icon=1
-Mailbox=17 at internos
-
-[IAX2/3002]
-Position=3
-Label="3002 IAX Client"
-Extension=3002
-Context=iaxcontext
-Icon=1
-
-[901] ; Meetme must be defined by its room number
-Position=8
-Label="Meetme 901"
-Extension=901
-Context=conferences
-Icon=5
-
-[902]
-Position=9
-Label="Meetme 902"
-Extension=902
-Icon=5
-
-[Zap/1]
-Position=10
-Label="External 1"
-Extension=-1
-Icon=2
-
-[Zap/2]
-Position=11
-Label="External 2"
-Extension=-1
-Icon=2
-
-[QUEUE/SALES] ; queues must be defined by its name
-Position=12
-Label="Sales Queue"
-Extension=-1 ; -1 to disable transfers to this button
-Icon=3
-
-[QUEUE/SUPPORT]
-Position=13-18 ; each position will be used by users waiting
- ; on that position number
-Label="Support Queue"
-Extension=-1 ; -1 to disable transfers to this button
-Icon=3
-
-[Local/5555555 at sip]
-Position=26
-Label="Speed Dial"
-Extension=5555555
-Context=sip
-Icon=2
-
-[IAX2/iaxtel]
-Position=15,16
-Label="Iaxtel"
-Extension=-1
-Icon=2
-
-; buttons with panel context will be displayed in their
-; own panel, you have to append ?context=NAME when loading
-; the swf file
-;
-;[IAX2/iaxtel]
-;Position=15,16
-;Label="Iaxtel"
-;Extension=-1
-;Icon=2
-;Panel_context=sip
-
-; You can draw rectangles anywhere in the screen. The canvas sixe is 996x600
-;
-
-[rectangle]
-x=748
-y=35
-width=252
-height=370
-line_width=3
-line_color=ffff10
-fade_color1=ffff10
-fade_color2=ffff3F
-rnd_border=2
-alpha=30
-layer=top ; top = above buttons
- ; bottom = below buttons
-
-[rectangle]
-x=498
-y=35
-width=252
-height=220
-line_width=3
-line_color=ff1010
-fade_color1=ff1010
-fade_color2=a01000
-rnd_border=2
-alpha=20
-layer=top
-panel_context=* ; The item will be persistant across contexts
-
-[rectangle]
-x=498
-y=255
-width=252
-height=295
-line_width=3
-line_color=10ff10
-fade_color1=10ff10
-fade_color2=10ff00
-rnd_border=2
-alpha=20
-layer=top
-
-[rectangle]
-x=-1
-y=35
-width=502
-height=515
-line_width=3
-line_color=1010ff
-fade_color1=1010ff
-fade_color2=1010ff
-rnd_border=2
-alpha=10
-layer=top
-
-; you can include configuration files
-;
-;include => more_rectangles.cfg
-
-[LEGEND]
-x=800
-y=50
-text=Zap Lines
-font_size=32
-font_color=000000
-font_family=Times New Roman ; only used when use_embed_fonts=0
-use_embed_fonts=1 ; if set to 1 it will use an embeded Arial type font
- ; that looks consistently between platforms/os
-
-[LEGEND]
-x=535
-y=50
-text=Conferences
-font_size=32
-font_color=FF0000
-font_family=Arial
-use_embed_fonts=1
-
-[LEGEND]
-x=555
-y=270
-text=Queues
-font_size=32
-font_color=000000
-font_family=Arial
-use_embed_fonts=1
-
-[LEGEND]
-x=160
-y=40
-text=Extensions
-font_color=000000
-font_size=32
-font_family=Arial
-use_embed_fonts=1
-
-[LEGEND]
-x=75
-y=75
-text=Local
-font_size=24
-font_family=Arial
-font_color=000000
-use_embed_fonts=1
-
-[LEGEND]
-x=315
-y=75
-text=Remote
-font_color=000000
-font_size=24
-font_family=Arial
-use_embed_fonts=1
-
-;include => more_legends.cfg
Deleted: op-panel/trunk/op_lang_ca.cfg
===================================================================
--- op-panel/trunk/op_lang_ca.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_lang_ca.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,31 +0,0 @@
-; Language configuration file
-dialing=Marcant
-calling=Trucant a $1
-incoming=Rebent una trucada de $1
-parked=Aparcat a $1
-registered=Registrat
-notregistered=No registrat
-reachable =Assolible $1
-unreachable=No assolible $1
-lagged=Enderrarit $1
-newold=Nous $1, Vells $2
-waitingonqueue=$1 usuari$2 a l'espera
-memberonconference=$1 participant$2
-version_mismatch=Versio incorrecte entre Client i Servidor!
-; client side
-clid_label=CLID
-detail_title=Detalls ultima trucada
-detail_from=De:
-detail_to=Per:
-detail_duration=Duracio:
-security_code_title=Introdueixi el codi de seguretat
-btn_security_text=Obrir finestra d'ingres de codi
-btn_restart_text=Reinicia Asterisk
-btn_reload_text=Recarrega la configuracio
-btn_debug_text=Obrir/Tancar finestra de Debug
-btn_help_text=Obrir ajuda
-tab_call_text=Trucada
-tab_queue_text=Cua
-calls_taken_text=Trucades ateses
-no_data_text=No hi ha dades
-debug_window_title=Finestra de Debug
Deleted: op-panel/trunk/op_lang_de.cfg
===================================================================
--- op-panel/trunk/op_lang_de.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_lang_de.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,31 +0,0 @@
-; German Language configuration file
-dialing=Waehlt
-calling=Ruft $1
-incoming=Eingehendes Gespraech von $1
-parked=Gehalten auf $1
-registered=Registriert
-notregistered=Nicht registriert
-reachable=$1 erreichbar
-unreachable=$1 nicht erreichbar
-lagged=$1 verzoegert
-newold=$1 neue, $2 alte
-waitingonqueue=$1 Nutzer warten
-memberonconference=$1 Teilnehmer
-version_mismatch=Client/Server Versionsfehler!
-; client side
-clid_label=Info
-detail_title=Letzte Anrufdetails
-detail_from=Von:
-detail_to=An:
-detail_duration=Dauer:
-security_code_title=Bitte den Sicherheitscode eingeben
-btn_security_text=Eingabe Sicherheitscode
-btn_restart_text=Asterisk-Neustart
-btn_reload_text=Konfiguration neu laden
-btn_debug_text=Debug-Fenster ein/aus
-btn_help_text=Hilfefenster oeffnen
-tab_call_text=Anruf
-tab_queue_text=Warteschlange
-calls_taken_text=Angenommene Anrufe
-no_data_text=Keine Daten vorhanden
-debug_window_title=Debug-Fenster
Deleted: op-panel/trunk/op_lang_en.cfg
===================================================================
--- op-panel/trunk/op_lang_en.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_lang_en.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,31 +0,0 @@
-; Language configuration file
-dialing=Dialing
-calling=Calling $1
-incoming=Incoming call from $1
-parked=Parked on $1
-registered=Registered
-notregistered=Not registered
-reachable=Reachable $1
-unreachable=Not reachable $1
-lagged=Lagged $1
-newold=New $1, Old $2
-waitingonqueue=$1 user$2 waiting
-memberonconference=$1 participant$2
-version_mismatch=Client/Server version mismatch!
-; client side
-clid_label=Info
-detail_title=Last call details
-detail_from=From:
-detail_to=To:
-detail_duration=Duration:
-security_code_title=Please enter the security code
-btn_security_text=Open Security Code Input Box
-btn_restart_text=Restarts Asterisk
-btn_reload_text=Reloads configuration
-btn_debug_text=Open/Close Debug Window
-btn_help_text=Open Help Window
-tab_call_text=Call
-tab_queue_text=Queue
-calls_taken_text=Calls taken
-no_data_text=No data available
-debug_window_title=Debug Window
Deleted: op-panel/trunk/op_lang_es.cfg
===================================================================
--- op-panel/trunk/op_lang_es.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_lang_es.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,31 +0,0 @@
-; Language configuration file
-dialing=Marcando
-calling=Llamando a $1
-incoming=Recibiendo llamada de $1
-parked=Aparcado en $1
-registered=Registrado
-notregistered=No registrado
-reachable =Alcanzable $1
-unreachable=No alcanzable $1
-lagged=Demorado $1
-newold=Nuevos $1, Viejos $2
-waitingonqueue=$1 usuario$2 esperando
-memberonconference=$1 participante$2
-version_mismatch=Version incorrecta entre Cliente y Servidor!
-; client side
-clid_label=CLID
-detail_title=Detalles ultimo llamado
-detail_from=De:
-detail_to=A:
-detail_duration=Duracion:
-security_code_title=Ingrese el codigo de seguridad
-btn_security_text=Abre ventana de ingreso de codigo
-btn_restart_text=Reinicia Asterisk
-btn_reload_text=Recarga la configuracion
-btn_debug_text=Abre/Cierra ventana de Debug
-btn_help_text=Abre ayuda
-tab_call_text=Llamada
-tab_queue_text=Cola
-calls_taken_text=Llamados atendidos
-no_data_text=No hay datos
-debug_window_title=Ventana de Debug
Deleted: op-panel/trunk/op_lang_fr.cfg
===================================================================
--- op-panel/trunk/op_lang_fr.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_lang_fr.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,35 +0,0 @@
-; Language configuration file
-;
-; Laurent Mele - lmele at infoclip.fr
-; 2005
-;
-dialing=Numérotation
-calling=Appel de $1
-incoming=Appel entrant du $1
-parked=Parqué au $1
-registered=Enregistré
-notregistered=Non enregistré
-reachable=Disponible. $1
-unreachable=Indisponible $1
-lagged=Lenteur $1
-newold=Nouveau $1, Ancien $2
-waitingonqueue=$1 utilisateur$2 en attente
-memberonconference=$1 participant$2
-version_mismatch=Incohérence de version Client/Serveur!
-; client side
-clid_label=Information
-detail_title=Détails du dernier appel
-detail_from=De:
-detail_to=Vers:
-detail_duration=Durée:
-security_code_title=Entrez le code de sécurité
-btn_security_text=Authentification de l'administrateur
-btn_restart_text=Redémarre Asterisk
-btn_reload_text=Recharge la configuration
-btn_debug_text=Ouvre/Ferme la fenêtre de déverminage
-btn_help_text=Ouvre la fenêtre d'aide
-tab_call_text=Appel
-tab_queue_text=File d'attente
-calls_taken_text=Appels pris
-no_data_text=Pas d'informations disponibles
-debug_window_title=Fenêtre de déverminage
Deleted: op-panel/trunk/op_lang_it.cfg
===================================================================
--- op-panel/trunk/op_lang_it.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_lang_it.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,31 +0,0 @@
-; Archivio di localizzazione nazionale
-dialing=Componendo
-calling=Chiamando $1
-incoming=Chiamata in arrivo da $1
-parked=Parcheggiata su $1
-registered=Registrato
-notregistered=Non registrato
-reachable=Raggiungibile $1
-unreachable=Non raggiungibile $1
-lagged=Trattenuto $1
-newold=Attuale $1, Precedente $2
-waitingonqueue=$1 utente$2 in attesa
-memberonconference=$1 partecipanti$2
-version_mismatch=Versione disallineata tra Client e Server!
-; client side
-clid_label=Info
-detail_title=Dettagli ultima chiamata
-detail_from=Da:
-detail_to=A:
-detail_duration=Durata:
-security_code_title=Introdurre il codice di sicurezza
-btn_security_text=Attiva richiesta Codice di sicurezza
-btn_restart_text=Riavvia Asterisk
-btn_reload_text=Ricarica la configurazione
-btn_debug_text=Apre/Chiude la finestra di debug
-btn_help_text=Attiva l'aiuto online
-tab_call_text=Chiama
-tab_queue_text=Coda
-calls_taken_text=Chiamate trattenute
-no_data_text=Non ci sono dati disponibili
-debug_window_title=Finestra di debug
Deleted: op-panel/trunk/op_lang_se.cfg
===================================================================
--- op-panel/trunk/op_lang_se.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_lang_se.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,32 +0,0 @@
-; Swedish language configuration file
-; Courtesy Daniel Nylander
-dialing=Kopplar
-calling=Ringer $1
-incoming=Inkommande samtal från $1
-parked=Parkerad på $1
-registered=Registrerad
-notregistered=Inte registrerad
-reachable=Tillgänglig $1
-unreachable=Inte tillgänglig $1
-lagged=Fördröjd $1
-newold=Nya $1, Gamla $2
-waitingonqueue=$1 användare$2 väntar
-memberonconference=$1 deltagare$2
-version_mismatch=Klient/Server ej samma version!
-; client side
-clid_label=Info
-detail_title=Detaljer om senaste samtal
-detail_from=Från:
-detail_to=Till:
-detail_duration=Längd:
-security_code_title=Vänligen tryck in säkerhetskoden
-btn_security_text=Ãppna inmatning för säkerhetskod
-btn_restart_text=Startar om Asterisk
-btn_reload_text=Läser om konfigurationen
-btn_debug_text=Ãppna/Stäng debugfönstret
-btn_help_text=Ãppna hjälpfönstret
-tab_call_text=Samtal
-tab_queue_text=Kö
-calls_taken_text=Samtal tagna
-no_data_text=Ingen data tillgänglig
-debug_window_title=Debugfönster
Deleted: op-panel/trunk/op_server.cfg
===================================================================
--- op-panel/trunk/op_server.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_server.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,207 +0,0 @@
-[general]
-; host or ip address of asterisk
-manager_host=192.168.0.1
-manager_port=5038
-; user and secret for connecting to * manager
-manager_user=user
-manager_secret=secret
-; The optional event_mask for filtering manager events.
-; Asterisk will send only the events you request
-; with this parameter. Possible values are:
-; on, off, system, call, log, verbose
-;event_mask=call
-;
-; You can specify many asterisk servers to
-; monitor. Just repeat the manager_host, manager_user
-; and manager_secret parameters in order. The first
-; one will be server number 1, and so on.
-;
-; manager_host=1.2.3.4
-; manager_user=john
-; manager_secret=doe
-
-; Enable MD5 auth to Asterisk manager
-auth_md5=1
-
-
-; you can use astmanproxy, if you enable it, all of the above
-; connections and settings will be overriden. You have to define
-; the host and port
-; astmanproxy_host = 127.0.0.1
-; astmanproxy_port = 1234
-
-; You will also have to define the servers that are monitored trough
-; astmanproxy, you have to enumerate them using the astmanproxy_server.
-; astmanproxy_server = 192.168.10.1
-; astmanproxy_server = 192.168.10.2
-; astmanproxy_server = 192.168.10.3
-;
-; ip address to listen for inbound connections, default all
-;listen_addr=127.0.0.1
-
-; port to listen for inbound flash connections, default 4445
-;listen_port=4445
-
-; hostname or ip address used to connect to the webserver where
-; the flash movie resides (just the hostname, without directories)
-; This value might be omited. In that case the flash movie will
-; try to connect to the same host as the web page.
-; web_hostname=www.myexample.com
-
-; location of the .swf file in your disk (must reside somewhere
-; inside your web root)
-flash_dir=/var/www/html/panel
-
-; secret code for performing hangups and transfers
-security_code=dkd4393kld
-
-; Frequency in second to poll for sip and iax status
-poll_interval=120
-
-; Poll for voicemail status (only necesary when you access the
-; voicemail directories outside asterisk itself - eg. web access)
-poll_voicemail=0
-
-; 1 Enable automatic hangup of zombies
-; 0 Disable
-kill_zombies=0
-
-; Debug level to stdout (bitmap)
-; 1 Manager Events Received
-; 2 Manager Commands Sent
-; 4 Show Flash events Received
-; 8 Show events sent to Flash Clients
-; 16 Server 1st Debug Level
-; 32 Server 2nd Debug Level
-; 64 Server 3rd Debug Level
-;
-; Eg: to display manager events and
-; commands sent set it to 3 (1+2)
-;
-; Maximum debug level 255
-debug=0
-
-; Default language to use (op_lang_XX.cfg file)
-language=en
-
-; Context in your diaplan where you have the conferences for barge in
-; Example:
-;
-; meetme.conf
-; [rooms]
-; conf => 900
-; conf => 901
-; conf => 902
-;
-; extensions.conf
-; [conferences]
-; exten => 900,1,MeetMe(900)
-; exten => 901,1,MeetMe(901)
-; exten => 902,1,MeetMe(902)
-conference_context=conferences
-
-; Meetme room numbers to use for barge in. The room number must match
-; the extension number (see above).
-barge_rooms=900-902
-
-; When doing barge ins, you can make the 3rd party to start
-; the meetme muted, so the other parties wont notice they are
-; now being monitored
-barge_muted=1
-
-; Formatting of the callerid field
-; where 'x' is a number
-clid_format=(xxx)xxx-xxxx
-
-; If you want not to show the callerid on the buttons, set this
-; to one
-clid_privacy=0
-
-; To display the ip address of sip or iax peer inside the button
-; set this to 1
-show_ip=0
-
-; It will hide queue position buttons and show only the active ones
-queue_hide=0
-
-; Will change the button label on AgentLogin
-rename_label_agentlogin=0
-
-; Will change the button label on Agentcallbacklogin
-rename_label_callbacklogin=0
-
-; Will rename the label for a wildcard button
-rename_label_wildcard=0
-
-; Will rename to the name specified in agents.conf
-; If disabled the renaming will be Agent/XXXX
-rename_to_agent_name=1
-
-; Will display IDLE time for agents, as well as
-; update the queue status after an agent hangs up
-; the call, so you don't need to reload to get
-; queue statistics
-agent_status=0
-
-; Will rename labels for queuemembers
-; If you use addqueuemember in your dialplan, you
-; can fake an AgengLogin event by sending it with
-; the UserEvent application. Eg:
-;
-; exten => 25,1,AddQueueMember(sales|SIP/${CALLERIDNUM}
-; exten => 25,2,UserEvent(Agentlogin|Agent: ${CALLERIDNUM});
-; exten => 25,3,Answer
-; exten => 25,4,Playback(added-to-sales-queue)
-; exten => 25,5,Hangup
-;
-; exten => 26,1,RemoveQueueMember(sales|SIP/${CALLERIDNUM})
-; exten => 26,2,UserEvent(RefreshQueue);
-; exten => 26,3,Answer
-; exten => 26,4,Playback(removed-from-sales-queue)
-; exten => 26,5,Hangup
-rename_queue_member=0
-
-; Will change the led color when the agent logs in
-; The color is configurable in op_style.cfg
-change_led_agent=1
-
-; If set to 1, you will transfer the linked channel instead
-; of the current channel when you drag the icon on a button
-reverse_transfer=0
-
-; If enabled, it will not ask forthe security code
-; when performing a click to dial
-clicktodial_insecure=1
-
-; Enable select box with absolutetimeout for the call after
-; a transfer is performed within the panel
-transfer_timeout= "0,No timeout|300,5 minutes|600,10 minutes|1200,20 minutes|2400,40 minutes|3000,50 minutes"
-
-; If set to 1, when hitting the reload button on the flash
-; client it will instead restart the 1st asterisk box
-; (For asterisk to restart you have to start it with
-; safe_asterisk, if you dont do that, asterisk will just
-; shut down)
-enable_restart = 0
-
-; If you set this parameter to your voicemailmain
-; extension at context, it will originate a call to
-; voicemailmain when double clicking on the MWI icon
-; for any button.
-voicemail_extension = 3000 at features
-
-; You can have panel contexts with their own
-; button layout and configuration. The following entry
-; will create a context called sip with a different
-; security code. In the online documentation you will
-; find how to use contexts
-;
-;[sip]
-;security_code=djdjdi43
-;web_hostname=www.virtualwebserver.com
-;flash_dir=/var/www/virtualwebserver/html/panel
-;barge_rooms=800-802
-;conference_context=otherconferences
-;transfer_timeout="0,No timeout|60,1 minute"
-;voicemail_extension=1000 at nine
-;language=es
Deleted: op-panel/trunk/op_server.pl
===================================================================
--- op-panel/trunk/op_server.pl 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_server.pl 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,9156 +0,0 @@
-#!/usr/bin/perl -w
-
-# Flash Operator Panel. http://www.asternic.org
-#
-# Copyright (c) 2004 Nicolás Gudiño. All rights reserved.
-#
-# Nicolás Gudiño <nicolas at house.com.ar>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License.
-#
-# THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-# EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-use strict;
-use integer;
-
-use constant DEBUG => 1;
-use constant BYTES_TO_READ => 256;
-
-use IO::Socket;
-use IO::Select;
-use Getopt::Long;
-use Pod::Usage;
-use Fcntl;
-use POSIX qw(setsid EWOULDBLOCK);
-
-my $FOP_VERSION = "026.001";
-my %datos = ();
-my %sesbot = ();
-my %linkbot = ();
-my %cache_hit = ();
-my %estadoboton = ();
-my %botonled = ();
-my %botonalpha = ();
-my %botonregistrado = ();
-my %boton_ip = ();
-my %botonlabel = ();
-my %botonlabelonly = ();
-my %botonsetlabel = ();
-my %botontimer = ();
-my %botontimertype = ();
-my %botonpark = ();
-my %botonmeetme = ();
-my %botonclid = ();
-my %botonqueue = ();
-my %botonqueue_count = ();
-my %botonqueuemember = ();
-my %botonvoicemail = ();
-my %botonvoicemailcount = ();
-my %botonlinked = ();
-my %parked = ();
-my %meetme_pos = ();
-my %laststatus = ();
-my %autenticado = ();
-my %auto_conference = ();
-my %buttons = ();
-my %buttons_queue = ();
-my %buttons_queue_reverse = ();
-my %buttons_preserve_case = ();
-my %button_server = ();
-my %buttons_reverse = ();
-my %textos = ();
-my %iconos = ();
-my %urls = ();
-my %targets = ();
-my %remote_callerid = ();
-my %remote_callerid_name = ();
-my %extension_transfer = ();
-my %extension_transfer_reverse = ();
-my %max_queue_waiting_time_for = ();
-my %flash_contexto = ();
-my %saved_clidnum = ();
-my %saved_clidname = ();
-my %keys_socket = ();
-my %manager_socket = ();
-my %start_muted = ();
-my %timeouts = ();
-my %no_rectangle = ();
-my %background = ();
-my %astdbcommands = ();
-my %client_queue = ();
-my %manager_queue = ();
-my %client_queue_nocrypt = ();
-my %ip_addy = ();
-my %count_queue = ();
-my %is_agent = ();
-my %agents_on_queue = ();
-my %max_lastcall = ();
-my $config = {};
-my $cola = {};
-my $language = {};
-my $global_verbose = 1;
-my $help = 0;
-my $version = 0;
-my $counter_servers = -1;
-my %bloque_completo;
-my %buferbloque;
-my $bloque_final;
-my $todo;
-my $regexp_buttons = 0;
-my $queueagent_buttons = 0;
-my $defaultlanguage;
-my @bloque;
-my @respuestas;
-my @all_flash_files;
-my @masrespuestas;
-my @fake_bloque;
-my @flash_clients;
-my @status_active;
-my @panel_contexts;
-my %mailbox;
-my %tovoicemail;
-my %instancias;
-my %agent_to_channel;
-my %agent_label;
-my %togle_action;
-my %togle_response;
-my %channel_to_agent;
-my %reverse_agents;
-my %agents_name;
-my @p;
-my $m;
-my $O;
-my @S;
-my @key;
-my @manager_host = ();
-my @manager_port = ();
-my @manager_user = ();
-my @manager_secret = ();
-my @event_mask = ();
-my @astmanproxy_servers = ();
-my @manager_conectado = ();
-my %manager_desconectado;
-my %mask_hash;
-my $web_hostname;
-my $listen_port;
-my $listen_addr;
-my $security_code;
-my $flash_dir;
-my $astmanproxy_server = "";
-my $restrict_channel = "";
-my $socketpolicy;
-my $poll_interval;
-my $poll_voicemail;
-my $kill_zombies;
-my $ren_agentlogin;
-my $ren_cbacklogin;
-my $ren_agentname;
-my $agent_status;
-my $ren_queuemember;
-my $ren_wildcard;
-my $clid_privacy;
-my %clid_private;
-my $show_ip;
-my $queue_hide;
-my $enable_restart;
-my $change_led;
-my $cdial_nosecure;
-my $barge_muted;
-my $debuglevel = -1;
-my $debuglevel_cache = "";
-my $cont_debug_cache = 0;
-my $flash_file;
-my %barge_rooms;
-my %barge_context;
-my $first_room;
-my $last_room;
-my $meetme_context;
-my $clid_format;
-my $directorio = "";
-my $auth_md5 = 1;
-my $astmanproxy_host = "";
-my $astmanproxy_port = "5038";
-my $md5challenge;
-my $reverse_transfer;
-my %shapes;
-my %legends;
-my %no_encryption = ();
-my %total_shapes;
-my %total_legends;
-my @btninclude = ();
-my @styleinclude = ();
-my $command = "";
-my $daemonized = 0;
-my $pidfile = "/var/run/op_panel.pid";
-my $logdir = "";
-my $confdir = "";
-my $tab = "";
-
-my $PADDING = join(
- '',
- map( chr,
- (
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- ) )
-);
-my %a2b = (
- A => 000,
- B => 001,
- C => 002,
- D => 003,
- E => 004,
- F => 005,
- G => 006,
- H => 007,
- I => 010,
- J => 011,
- K => 012,
- L => 013,
- M => 014,
- N => 015,
- O => 016,
- P => 017,
- Q => 020,
- R => 021,
- S => 022,
- T => 023,
- U => 024,
- V => 025,
- W => 026,
- X => 027,
- Y => 030,
- Z => 031,
- a => 032,
- b => 033,
- c => 034,
- d => 035,
- e => 036,
- f => 037,
- g => 040,
- h => 041,
- i => 042,
- j => 043,
- k => 044,
- l => 045,
- m => 046,
- n => 047,
- o => 050,
- p => 051,
- q => 052,
- r => 053,
- s => 054,
- t => 055,
- u => 056,
- v => 057,
- w => 060,
- x => 061,
- y => 062,
- z => 063,
- '0' => 064,
- '1' => 065,
- '2' => 066,
- '3' => 067,
- '4' => 070,
- '5' => 071,
- '6' => 072,
- '7' => 073,
- '8' => 074,
- '9' => 075,
- '+' => 076,
- '_' => 077,
-);
-my %b2a = reverse %a2b;
-my $rand_byte_already_called = 0;
-
-$SIG{PIPE} = 'IGNORE';
-$SIG{ALRM} = 'alarma_al_minuto';
-$SIG{INT} = 'close_all';
-$SIG{HUP} = 'generate_configs_onhup';
-$SIG{USR1} = 'dump_internal_hashes_to_stdout';
-
-GetOptions(
- 'p|pidfile=s' => \$pidfile,
- 'l|logdir=s' => \$logdir,
- 'c|confdir=s' => \$confdir,
- 'd|daemon' => \$daemonized,
- 'V|version' => \$version,
- 'x|debuglevel=i' => \$debuglevel,
- 'help|?' => \$help
-);
-
-pod2usage(1) if $help;
-
-if ( $version == 1 ) {
- print "op_server.pl version $FOP_VERSION\n";
- exit 0;
-}
-
-if ( $confdir eq "" ) {
-
- # if there is no config directory supplied at the command line
- # use the same directory where op_server.pl lives
- $directorio = $0;
- $directorio =~ s/(.*)\/(.*)/$1/g;
-}
-else {
- $directorio = $confdir;
-}
-
-if ( $logdir ne "" ) {
- open( STDOUT, ">>$logdir/output.log" )
- or die "Can't open output log $logdir/error.log";
- open( STDERR, ">>$logdir/error.log" )
- or die "Can't open output log $logdir/error.log";
-}
-
-if ( $daemonized == 1 ) {
- defined( my $pid = fork ) or die "Can't Fork: $!";
- exit if $pid;
- setsid or die "Can't start a new session: $!";
- open MYPIDFILE, ">$pidfile";
- print MYPIDFILE $$;
- close MYPIDFILE;
-
- close(STDIN);
- if ( $logdir eq "" ) {
- close STDOUT;
- close STDERR;
- }
-}
-
-sub read_language_config() {
- $/ = "\n";
-
- # tries to read and parse every language file needed
- foreach my $ctx (@panel_contexts) {
- if ( !defined( $config->{$ctx}{language} ) ) {
- $config->{"$ctx"}{language} = $defaultlanguage;
- }
-
- my $lang = $config->{$ctx}{language};
- $lang =~ tr/A-Z/a-z/;
- $lang =~ s/\W//g;
- $config->{$ctx}{language} = $lang;
-
- open( CONFIG, "<$directorio/op_lang_$lang.cfg" )
- or die("Could not open $directorio/op_lang_$lang.cfg. Aborting...");
-
- while (<CONFIG>) {
- chop;
- $_ =~ s/^\s+//g;
- $_ =~ s/([^;]*)[;](.*)/$1/g;
- $_ =~ s/\s+$//g;
- next unless $_ ne "";
- my ( $variable_name, $value ) = split( /=/, $_ );
- $variable_name =~ tr/A-Z/a-z/;
- $variable_name =~ s/\s+//g;
- $value =~ s/^\s+//g;
- $value =~ s/\s+$//g;
- $value =~ s/\"//g;
- $language->{$ctx}{$variable_name} = $value;
- }
- close(CONFIG);
- }
- $/ = "\0";
-}
-
-sub read_server_config() {
- my $context = "";
- $counter_servers = -1;
-
- $/ = "\n";
-
- open( CONFIG, "<$directorio/op_server.cfg" )
- or die("Could not open op_server.cfg. Aborting...");
-
- while (<CONFIG>) {
- chomp;
- $_ =~ s/^\s+//g;
- $_ =~ s/([^;]*)[;](.*)/$1/g;
- $_ =~ s/\s+$//g;
-
- if ( /^#/ || /^;/ || /^$/ ) {
- next;
- } # Ignores comments and empty lines
-
- if (/^\Q[\E/) {
- s/\[(.*)\]/$1/g;
- tr/a-z/A-Z/;
- $context = $_;
- }
- else {
- if ( $context ne "" ) {
- my ( $variable_name, $value ) = split( /=/, $_ );
- $variable_name =~ tr/A-Z/a-z/;
- $variable_name =~ s/\s+//g;
- $value =~ s/^\s+//g;
- $value =~ s/\s+$//g;
- $value =~ s/\"//g;
- $config->{$context}{$variable_name} = $value;
-
- if ( $variable_name eq "manager_host" ) {
- $counter_servers++;
- $manager_host[$counter_servers] = $value;
- }
-
- if ( $variable_name eq "manager_user" ) {
- $manager_user[$counter_servers] = $value;
- }
-
- if ( $variable_name eq "manager_secret" ) {
- $manager_secret[$counter_servers] = $value;
- }
-
- if ( $variable_name eq "manager_port" ) {
- $manager_port[$counter_servers] = $value;
- }
-
- if ( $variable_name eq "event_mask" ) {
- $event_mask[$counter_servers] = $value;
- }
-
- if ( $variable_name eq "astmanproxy_server" ) {
- push @astmanproxy_servers, $value;
- }
-
- }
- }
- }
- close(CONFIG);
-
- $web_hostname = $config->{GENERAL}{web_hostname};
- $listen_port = $config->{GENERAL}{listen_port};
- $listen_addr = $config->{GENERAL}{listen_addr};
- $security_code = $config->{GENERAL}{security_code};
- $flash_dir = $config->{GENERAL}{flash_dir};
- $poll_interval = $config->{GENERAL}{poll_interval};
- $poll_voicemail = $config->{GENERAL}{poll_voicemail};
- $kill_zombies = $config->{GENERAL}{kill_zombies};
- $reverse_transfer = $config->{GENERAL}{reverse_transfer};
- $auth_md5 = $config->{GENERAL}{auth_md5};
- $astmanproxy_host = $config->{GENERAL}{astmanproxy_host};
- $astmanproxy_port = $config->{GENERAL}{astmanproxy_port};
- $ren_agentlogin = $config->{GENERAL}{rename_label_agentlogin};
- $ren_cbacklogin = $config->{GENERAL}{rename_label_callbacklogin};
- $ren_wildcard = $config->{GENERAL}{rename_label_wildcard};
- $ren_agentname = $config->{GENERAL}{rename_to_agent_name};
- $agent_status = $config->{GENERAL}{agent_status};
- $ren_queuemember = $config->{GENERAL}{rename_queue_member};
- $change_led = $config->{GENERAL}{change_led_agent};
- $cdial_nosecure = $config->{GENERAL}{clicktodial_insecure};
- $barge_muted = $config->{GENERAL}{barge_muted};
- $clid_privacy = $config->{GENERAL}{clid_privacy};
- $show_ip = $config->{GENERAL}{show_ip};
- $queue_hide = $config->{GENERAL}{queue_hide};
- $enable_restart = $config->{GENERAL}{enable_restart};
- $defaultlanguage = $config->{GENERAL}{language};
-
- if ( $debuglevel == -1 ) {
- $debuglevel = $config->{GENERAL}{debug};
- }
-
- my @todos_los_rooms;
- foreach my $val ($config) {
- while ( my ( $aa, $bb ) = each( %{$val} ) ) {
- while ( my ( $cc, $dd ) = each( %{$bb} ) ) {
- if ( $cc eq "barge_rooms" ) {
- ( $first_room, $last_room ) = split( /-/, $dd );
- if ( !defined($last_room) ) {
- $last_room = $first_room;
- }
- my @arrayroom = $first_room .. $last_room;
- foreach (@arrayroom) {
- $barge_context{"$_"} = $aa;
- }
- push( @todos_los_rooms, @arrayroom );
- }
- }
- }
- }
- %barge_rooms = map { $todos_los_rooms[$_], 0 } 0 .. $#todos_los_rooms;
-
- $meetme_context = $config->{GENERAL}{conference_context};
- $clid_format = $config->{GENERAL}{clid_format};
-
- $flash_file = $flash_dir . "/variables.txt";
- push @all_flash_files, $flash_file;
-
- if ( !defined $web_hostname ) {
- $web_hostname = "";
- }
- if ( !defined $listen_port ) {
- $listen_port = 4445;
- }
- if ( !defined $listen_addr ) {
- $listen_addr = "0.0.0.0";
- }
- if ( !defined $astmanproxy_host ) {
- $astmanproxy_host = "";
- }
- else {
- @manager_host = ();
- @manager_user = ();
- @manager_secret = ();
- push @manager_host, $astmanproxy_host;
- push @manager_user, "astmanproxy";
- push @manager_secret, "astmanproxy";
- }
-
- if ( defined $astmanproxy_port ) {
- @manager_port = ();
- push @manager_port, $astmanproxy_port;
- }
-
- if ( !defined $security_code ) {
- die("Missing security_code in op_server.cfg!");
- }
-
- if ( !defined $flash_dir ) { die("Missing flash_dir in op_server.cfg!"); }
-
- if ( !defined $poll_interval ) {
- die("Missing poll_interval in op_server.cfg!");
- }
-
- if ( !defined $ren_agentlogin ) {
- $ren_agentlogin = 0;
- }
-
- if ( !defined $defaultlanguage ) {
- $defaultlanguage = "en";
- $config->{DEFAULT}{language} = "en";
- }
-
- if ( !defined $clid_privacy ) {
- $clid_privacy = 0;
- }
-
- if ( !defined $show_ip ) {
- $show_ip = 0;
- }
-
- if ( !defined $queue_hide ) {
- $queue_hide = 0;
- }
-
- if ( !defined $ren_wildcard || $ren_wildcard eq "" ) {
- $ren_wildcard = 1;
- }
-
- if ( !defined $reverse_transfer || $reverse_transfer eq "" ) {
- $reverse_transfer = 0;
- }
-
- if ( !defined $barge_muted || $barge_muted eq "" ) {
- $barge_muted = 0;
- }
-
- if ( !defined $enable_restart || $enable_restart eq "" ) {
- $enable_restart = 0;
- }
-
- if ( !defined $cdial_nosecure || $cdial_nosecure eq "" ) {
- $cdial_nosecure = 0;
- }
-
- if ( !defined $agent_status || $agent_status eq "" ) {
- $agent_status = 0;
- }
-
- if ( !defined $ren_agentname || $ren_agentname eq "" ) {
- $ren_agentname = 0;
- }
-
- if ( !defined $ren_cbacklogin || $ren_cbacklogin eq "" ) {
- $ren_cbacklogin = 0;
- }
-
- if ( !defined $ren_queuemember || $ren_queuemember eq "" ) {
- $ren_queuemember = 0;
- }
-
- if ( !defined $change_led || $change_led eq "" ) {
- $change_led = 0;
- }
-
- if ( !defined $kill_zombies || $kill_zombies eq "" ) {
- $kill_zombies = 0;
- }
-
- if ( !defined $poll_voicemail || $poll_voicemail eq "" ) {
- $poll_voicemail = 0;
- }
-
- if ( !defined $clid_format ) {
- $clid_format = "(xxx) xxx-xxxx";
- }
-
- if ( !defined $debuglevel ) {
- $debuglevel = 0;
- }
- else {
- if ( $daemonized == 1 && $logdir eq "" ) {
- $debuglevel = 0;
- }
- }
- $/ = "\0";
-}
-
-sub collect_includes {
- my $filename = shift;
- my $tipo = shift;
- my $archivo = $directorio . "/" . $filename;
-
- if ( !-r $archivo ) {
- log_debug( "** $archivo not readable... skipping", 16 ) if DEBUG;
- return;
- }
-
- if ( $tipo eq "buttons" ) {
- if ( !inArray( $filename, @btninclude ) ) {
- push( @btninclude, $filename );
- }
- else {
- log_debug( "** $filename already included", 16 ) if DEBUG;
- return;
- }
- }
- if ( $tipo eq "style" ) {
- if ( !inArray( $filename, @styleinclude ) ) {
- push( @styleinclude, $filename );
- }
- else {
- log_debug( "** $filename already included", 16 ) if DEBUG;
- return;
- }
- }
-
- open( CONFIG, "< $archivo" )
- or die("Could not open $filename. Aborting...\n\n");
-
- my @lineas = <CONFIG>;
- my $cuantos = @lineas;
- foreach my $linea (@lineas) {
- $linea =~ s/^\s+//g;
- $linea =~ s/([^;]*)[;](.*)/$1/g;
- $linea =~ s/\s+$//g;
- if ( $linea =~ /^include/ ) {
-
- # store include lines in an array so we can
- # process them later excluding duplicates
- $linea =~ s/^include//g;
- $linea =~ s/^\s+//g;
- $linea =~ s/^=>//g;
- $linea =~ s/^\s+//g;
- $linea =~ s/\s+$//g;
- collect_includes( $linea, $tipo );
- }
- }
- close CONFIG;
-}
-
-sub read_astdb_config() {
- $/ = "\n";
- if ( -e "$directorio/op_astdb.cfg" ) {
- open( ASTDB, "<$directorio/op_astdb.cfg" )
- or die("Could not open op_astdb.cfg. Aborting...");
- my $contador = 0;
- my $key = "";
- while (<ASTDB>) {
- chomp;
- $_ =~ s/^\s+//g;
- $_ =~ s/([^;]*)[;](.*)/$1/g;
- $_ =~ s/\s+$//g;
-
- if ( /^#/ || /^;/ || /^$/ ) {
- next;
- } # Ignores comments and empty lines
-
- if (/^\Q[\E/) {
- s/\[(.*)\]/$1/g;
- $key = $_;
- }
- else {
- push @{ $astdbcommands{$key} }, $_;
- }
- }
- }
- close(ASTDB);
-
- $/ = "\0";
-}
-
-sub read_buttons_config() {
- my @btn_cfg = ();
- my $contador = -1;
- my @distinct_files;
- my $no_counter = 0;
- my @contextos = ();
- my %lastposition = ();
-
- $/ = "\n";
-
- @distinct_files = unique(@btninclude);
-
- foreach my $archivo (@distinct_files) {
- open( CONFIG, "< $directorio/$archivo" )
- or die("Could not open $directorio/$archivo. Aborting...");
-
- # Read op_buttons.cfg loading it into a hash for easier processing
-
- while (<CONFIG>) {
- chomp;
- $_ =~ s/^\s+//g;
- $_ =~ s/([^;]*)[;](.*)/$1/g;
- $_ =~ s/\s+$//g;
- if ( /^#/ || /^;/ || /^$/ ) {
- next;
- } # Ignores comments and empty lines
-
- if (/^\Q[\E/) {
- $contador++;
- s/\[(.*)\]/$1/g;
- my $channel = $_;
- $btn_cfg[$contador]{'channel_preserve_case'} = $channel;
- $btn_cfg[$contador]{'channel'} = $channel;
-
- }
- else {
- next unless ( $contador >= 0 );
- my ( $key, $val ) = split( /=/, $_, 2 );
- $key =~ tr/A-Z/a-z/;
- $key =~ s/^\s+//g;
- $key =~ s/(.*)\s+/$1/g;
- if ( $key ne "label"
- && $key ne "font_family"
- && $key ne "text"
- && $key ne "mailbox"
- && $key ne "voicemail_context" )
- {
- $val =~ s/^\s+//g;
- $val =~ s/(.*)\s+/$1/g;
- }
- $btn_cfg[$contador]{$key} = $val;
- if ( $key eq "panel_context" ) {
- push @contextos, $val;
- }
- }
- }
-
- close(CONFIG);
- }
-
- my @uniq2 = unique(@contextos);
- @contextos = @uniq2;
- @uniq2 = grep { !/\*/ } @contextos;
- @contextos = @uniq2;
- push @contextos, "DEFAULT";
- push @contextos, "GENERAL";
-
- # Convert every element to uppercase
- @panel_contexts = map { uc } @contextos;
-
- # Pass to replicate panel_context=* configuration
- my @copy_cfg = ();
- @copy_cfg = @btn_cfg;
- foreach (@copy_cfg) {
- my %tmphash = %$_;
- if ( defined( $tmphash{panel_context} ) ) {
- if ( $tmphash{panel_context} eq "*" ) {
- foreach my $contextoahora (@contextos) {
- $contador++;
- while ( my ( $key, $val ) = each(%tmphash) ) {
- if ( $key eq "panel_context" ) {
- $val = $contextoahora;
- }
- $btn_cfg[$contador]{$key} = $val;
- }
- }
- }
- }
- }
-
- # We finished reading the file, now we populate our
- # structures with the relevant data
- my %rectangles_counter;
- my %legends_counter;
-
- CONFIG:
- foreach (@btn_cfg) {
- my @positions = ();
- my %tmphash = %$_;
-
- if ( defined( $tmphash{panel_context} ) ) {
- if ( $tmphash{panel_context} eq "*" ) {
-
- # We skip the * panel_context because we already
- # expand them to every context possible before
- next CONFIG;
- }
- }
- if ( $tmphash{channel} =~ /^_/ ) {
- $regexp_buttons = 1;
- }
- elsif ( $tmphash{channel} =~ /^QUEUEAGENT\//i ) {
- $queueagent_buttons = 1;
- }
- elsif ( $tmphash{channel} =~ /^legend$/i ) {
-
- # Legend config primitive
-
- if ( defined( $tmphash{panel_context} ) ) {
- $tmphash{panel_context} =~ tr/a-z/A-Z/;
- $tmphash{panel_context} =~ s/^DEFAULT$//xms;
- }
- else {
- $tmphash{panel_context} = "";
- }
- my $conttemp = $tmphash{panel_context};
- if ( $conttemp eq "" ) { $conttemp = "GENERAL"; }
-
- if ( !defined( $tmphash{text} ) ) {
- $tmphash{text} = "LEGEND";
- }
- if ( !defined( $tmphash{x} ) ) {
- $tmphash{x} = 1;
- }
- if ( !defined( $tmphash{y} ) ) {
- $tmphash{y} = 1;
- }
- if ( !defined( $tmphash{font_size} ) ) {
- $tmphash{font_size} = 16;
- }
- if ( !defined( $tmphash{font_color} ) ) {
- $tmphash{font_color} = "000000";
- }
- if ( !defined( $tmphash{use_embed_fonts} ) ) {
- $tmphash{use_embed_fonts} = 1;
- }
- if ( !defined( $tmphash{font_family} ) ) {
- $tmphash{font_family} = "Arial";
- }
- if ( !defined( $tmphash{no_base64} ) ) {
- $tmphash{no_base64} = 0;
- }
- if ( $tmphash{no_base64} == 0 ) {
- $tmphash{text} = encode_base64( $tmphash{text} );
- }
- if ( !defined( $tmphash{url} ) ) {
- $tmphash{url} = "no";
- }
- if ( !defined( $tmphash{target} ) ) {
- $tmphash{target} = "NONTARFOP";
- }
- $legends_counter{$conttemp}++;
- if ( $legends_counter{$conttemp} > 1 ) {
- $legends{$conttemp} .= "&";
- }
- $total_legends{$conttemp}++;
- $legends{$conttemp} .= "legend_$legends_counter{$conttemp}=" . $tmphash{x} . ",";
- $legends{$conttemp} .= $tmphash{y} . ",";
- $legends{$conttemp} .= $tmphash{text} . ",";
- $legends{$conttemp} .= $tmphash{font_size} . ",";
- $legends{$conttemp} .= $tmphash{font_family} . ",";
- $legends{$conttemp} .= $tmphash{font_color} . ",";
- $legends{$conttemp} .= $tmphash{use_embed_fonts} . ",";
- $legends{$conttemp} .= $tmphash{no_base64} . ",";
- $legends{$conttemp} .= $tmphash{url} . ",";
- $legends{$conttemp} .= $tmphash{target};
- next CONFIG;
- }
- elsif ( $tmphash{channel} =~ /^RECTANGLE$/i ) {
-
- # Rectangle config primitive
- if ( defined( $tmphash{panel_context} ) ) {
- $tmphash{panel_context} =~ tr/a-z/A-Z/;
- $tmphash{panel_context} =~ s/^DEFAULT$//;
- }
- else {
- $tmphash{panel_context} = "";
- }
- my $conttemp = $tmphash{panel_context};
- if ( $conttemp eq "" ) { $conttemp = "GENERAL"; }
-
- if ( !defined( $tmphash{x} ) ) {
- $tmphash{x} = 1;
- }
- if ( !defined( $tmphash{y} ) ) {
- $tmphash{y} = 1;
- }
- if ( !defined( $tmphash{width} ) ) {
- $tmphash{width} = 1;
- }
- if ( !defined( $tmphash{height} ) ) {
- $tmphash{height} = 1;
- }
- if ( !defined( $tmphash{line_width} ) ) {
- $tmphash{line_width} = 1;
- }
- if ( !defined( $tmphash{line_color} ) ) {
- $tmphash{line_color} = "0x000000";
- }
- if ( !defined( $tmphash{fade_color1} ) ) {
- $tmphash{fade_color1} = "0xd0d0d0";
- }
- if ( !defined( $tmphash{fade_color2} ) ) {
- $tmphash{fade_color2} = "0xd0d000";
- }
- if ( !defined( $tmphash{rnd_border} ) ) {
- $tmphash{rnd_border} = 3;
- }
- if ( !defined( $tmphash{alpha} ) ) {
- $tmphash{alpha} = 100;
- }
- if ( !defined( $tmphash{layer} ) ) {
- $tmphash{layer} = "bottom";
- }
-
- $rectangles_counter{$conttemp}++;
- if ( $rectangles_counter{$conttemp} > 1 ) {
- $shapes{$conttemp} .= "&";
- }
- $total_shapes{$conttemp}++;
- $shapes{$conttemp} .= "rect_$rectangles_counter{$conttemp}=" . $tmphash{x} . ",";
- $shapes{$conttemp} .= $tmphash{y} . ",";
- $shapes{$conttemp} .= $tmphash{width} . ",";
- $shapes{$conttemp} .= $tmphash{height} . ",";
- $shapes{$conttemp} .= $tmphash{line_width} . ",";
- $shapes{$conttemp} .= $tmphash{line_color} . ",";
- $shapes{$conttemp} .= $tmphash{fade_color1} . ",";
- $shapes{$conttemp} .= $tmphash{fade_color2} . ",";
- $shapes{$conttemp} .= $tmphash{rnd_border} . ",";
- $shapes{$conttemp} .= $tmphash{alpha} . ",";
- $shapes{$conttemp} .= $tmphash{layer};
- next CONFIG;
- }
-
- if ( !defined( $tmphash{position} ) ) {
- log_debug( "** Ignored button $tmphash{'channel'}, position?", 16 ) if DEBUG;
- next CONFIG;
- }
-
- if ( !defined( $tmphash{url} ) ) {
- $tmphash{url} = "0";
- }
-
- if ( !defined( $tmphash{target} ) ) {
- $tmphash{target} = "0";
- }
-
- if ( !defined( $tmphash{server} ) ) {
- $tmphash{server} = 0;
- }
- else {
- $tmphash{server} = $tmphash{server} - 1;
- }
-
- if ( !defined( $tmphash{label} ) ) {
- $tmphash{label} = $tmphash{channel};
- }
-
- if ( !defined( $tmphash{icon} ) ) {
- $tmphash{icon} = "0";
- }
-
- # Local channels are case sensitive
- my $canal_key = "";
-
- if ( $tmphash{channel} =~ m/^local/i ) {
- $canal_key = $tmphash{channel};
- }
- else {
- $canal_key = uc( $tmphash{channel} );
- }
-
- my $canal_key_case = $tmphash{channel_preserve_case};
-
- if ( $canal_key =~ m/^PARK\d/ ) {
-
- # Change the PARKXXX tu PARK/XXX
- $canal_key =~ s/PARK(.*)/PARK\/$1/g;
- $canal_key_case =~ s/PARK(.*)/PARK\/$1/gi;
- }
-
- if ( defined( $tmphash{panel_context} ) ) {
- $tmphash{panel_context} =~ tr/a-z/A-Z/;
- $tmphash{panel_context} =~ s/^DEFAULT$//;
- }
- else {
- $tmphash{panel_context} = "";
- }
-
- if ( $tmphash{panel_context} ne "" ) {
-
- # We want to add the context in case we have the same button
- # repeated in several panel_contexts. If we do not add it, then
- # only the last panel context will prevail.
- $canal_key .= "&" . $tmphash{panel_context};
- $canal_key_case .= "&" . $tmphash{panel_context};
- }
-
- if ( ( $tmphash{position} !~ /,/ )
- && ( $tmphash{position} !~ /-/ )
- && ( $canal_key =~ /^_/ ) )
- {
-
- # If it's a regexp button with just one position
- # we fake the same position number to populate
- # the array and make the button work anyways.
- my $pos = $tmphash{position};
- $pos =~ s/(\d+),(\d+)/$1/g;
- $tmphash{position} = "$pos,$pos";
- $no_counter = 1;
- }
- else {
- $no_counter = 0;
- }
-
- if ( $tmphash{position} =~ /[,-]/ ) {
-
- my $canalidx = $tmphash{server} . "^" . $tmphash{channel};
-
- if ( defined( $tmphash{panel_context} )
- && $tmphash{panel_context} ne "" )
- {
- $canalidx .= "&" . $tmphash{panel_context};
- }
- $instancias{ uc($canalidx) }{""} = 0;
-
- my @ranges = split( /,/, $tmphash{position} );
- foreach my $valu (@ranges) {
- if ( $valu !~ m/-/ ) {
- if ( $valu eq "n" ) {
- my $lastpos = $lastposition{ $tmphash{panel_context} };
- if ( is_number($lastpos) ) {
- $lastpos++;
- $lastposition{ $tmphash{panel_context} } = $lastpos;
- $valu = $lastpos;
- push @positions, $valu;
- last;
- }
- }
- push @positions, $valu;
- }
- else {
- my @range2 = split( /-/, $valu );
- my $menor = $range2[0] < $range2[1] ? $range2[0] : $range2[1];
- my $mayor = $range2[0] > $range2[1] ? $range2[0] : $range2[1];
- my @newrange = $menor .. $mayor;
- foreach my $valevale (@newrange) {
- push @positions, $valevale;
- }
- }
- }
-
- my $count = 0;
- foreach my $pos (@positions) {
- $count++;
- my $indice_contexto = $pos;
- my $chan_trunk = $tmphash{channel} . "=" . $count;
- my $chan_trunk_case = $tmphash{channel_preserve_case} . "=" . $count;
- if ( $tmphash{panel_context} ne "" ) {
- $chan_trunk .= "&" . $tmphash{panel_context};
- $chan_trunk_case .= "&" . $tmphash{panel_context};
- $indice_contexto .= "@" . $tmphash{panel_context};
- $pos .= "@" . $tmphash{panel_context};
- }
- if ( $chan_trunk =~ m/^QUEUE/i ) {
- $buttons_queue{ uc("$tmphash{server}^$chan_trunk") } = $pos;
- }
- $buttons_preserve_case{"$tmphash{server}^$chan_trunk_case"} = $pos;
- $buttons{ uc("$tmphash{server}^$chan_trunk") } = $pos;
- $textos{$indice_contexto} = $tmphash{label};
- if ( $no_counter == 0 ) {
- $textos{$indice_contexto} .= " " . $count;
- }
- $iconos{$indice_contexto} = $tmphash{icon};
- $urls{$indice_contexto} = $tmphash{url};
- $targets{$indice_contexto} = $tmphash{target};
- $button_server{$pos} = $tmphash{server};
-
- # Saves last position for the button at context
- $lastposition{ $tmphash{panel_context} } = $pos;
- log_debug( qq[** $tmphash{server}^$chan_trunk in position $pos], 16 ) if DEBUG;
- }
- }
- else {
- my $lastpos = 0;
- $lastpos = $lastposition{ $tmphash{panel_context} }
- if defined( $lastposition{ $tmphash{panel_context} } );
- if ( $tmphash{position} eq "n" ) {
- if ( is_number($lastpos) ) {
- $lastpos++;
- $lastposition{ $tmphash{panel_context} } = $lastpos;
- }
- }
- else {
- $lastpos = $tmphash{position};
- $lastposition{ $tmphash{panel_context} } = $lastpos;
- }
-
- log_debug( qq[** $tmphash{channel} in next position $lastpos], 16 ) if DEBUG;
-
- if ( $tmphash{panel_context} ne "" ) {
-
- if ( $canal_key =~ m/^QUEUE/i ) {
- $buttons_queue{ uc("$tmphash{server}^$canal_key") } = $lastpos . "\@" . $tmphash{panel_context};
- }
- $buttons{"$tmphash{server}^$canal_key"} = $lastpos . "\@" . $tmphash{panel_context};
- $buttons_preserve_case{"$tmphash{server}^$canal_key_case"} = $lastpos . "\@" . $tmphash{panel_context};
-
- $textos{"$lastpos\@$tmphash{panel_context}"} = $tmphash{label};
- $iconos{"$lastpos\@$tmphash{panel_context}"} = $tmphash{icon};
- $urls{"$lastpos\@$tmphash{panel_context}"} = $tmphash{url};
- $targets{"$lastpos\@$tmphash{panel_context}"} = $tmphash{target};
- $button_server{ $buttons{"$tmphash{server}^$canal_key"} } = $tmphash{server};
- }
- else {
- if ( $canal_key =~ /^_/ ) {
- $canal_key .= "=1";
- }
-
- if ( $canal_key =~ m/^QUEUE/i ) {
- $buttons_queue{ uc("$tmphash{server}^$canal_key") } = $lastpos;
- }
- $buttons{"$tmphash{server}^$canal_key"} = $lastpos;
- $buttons_preserve_case{"$tmphash{server}^$canal_key_case"} = $lastpos;
- $textos{$lastpos} = $tmphash{label};
- $iconos{$lastpos} = $tmphash{icon};
- $urls{$lastpos} = $tmphash{url};
- $targets{$lastpos} = $tmphash{target};
- $button_server{ $buttons{"$tmphash{server}^$canal_key"} } = $tmphash{server};
- }
- }
-
- @positions = unique(@positions);
-
- if ( defined( $tmphash{privacy} ) ) {
- my $count = @positions;
- if ( $count == 0 ) {
- push @positions, $lastposition{ $tmphash{panel_context} };
- }
- if ( $tmphash{privacy} eq "true" || $tmphash{privacy} eq "1" ) {
- my $agre_context = "";
- if ( $tmphash{panel_context} ne "" ) {
- $agre_context = "\@" . $tmphash{panel_context};
- }
- foreach my $pos (@positions) {
- $clid_private{"$pos$agre_context"} = 1;
- }
- }
- }
-
- if ( defined( $tmphash{no_rectangle} ) ) {
- my $count = @positions;
- if ( $count == 0 ) {
- push @positions, $lastposition{ $tmphash{panel_context} };
- }
-
- if ( $tmphash{no_rectangle} eq "true" || $tmphash{no_rectangle} eq "1" ) {
- my $pcont = $tmphash{panel_context};
- if ( $pcont eq "" ) { $pcont = "GENERAL"; }
- foreach my $pos (@positions) {
- $pos =~ s/\@$pcont//g;
- $no_rectangle{$pcont}{$pos} = 1;
- }
- }
- }
-
- if ( defined( $tmphash{background} ) ) {
- my $count = @positions;
- if ( $count == 0 ) {
- push @positions, $lastposition{ $tmphash{panel_context} };
- }
-
- my $pcont = $tmphash{panel_context};
- if ( $pcont eq "" ) { $pcont = "GENERAL"; }
- foreach my $pos (@positions) {
- $pos =~ s/\@$pcont//g;
- $background{$pcont} .= "&bg$pos=$tmphash{background}";
- }
- }
-
- if ( defined( $tmphash{extension} ) ) {
- if ( defined( $tmphash{context} ) ) {
-
- $extension_transfer{"$tmphash{server}^$canal_key"} = $tmphash{server} . "^" . $tmphash{extension} . "@" . $tmphash{context};
-
- }
- else {
- $extension_transfer{"$tmphash{server}^$canal_key"} = $tmphash{server} . "^" . $tmphash{extension};
- }
- if ( defined( $tmphash{voicemail_context} ) ) {
- $mailbox{"$tmphash{server}^$canal_key"} = $tmphash{extension} . "@" . $tmphash{voicemail_context};
- }
- }
- if ( defined( $tmphash{mailbox} ) ) {
- $mailbox{"$tmphash{server}^$canal_key"} = $tmphash{mailbox};
- }
- if ( defined( $tmphash{voicemailext} ) ) {
- my $indicevm = $lastposition{ $tmphash{panel_context} };
- if ( $tmphash{panel_context} ne "" ) {
- $indicevm .= "\@$tmphash{panel_context}";
- }
- $tovoicemail{$indicevm} = $tmphash{voicemailext};
- }
- $/ = "\0";
- }
- %extension_transfer_reverse = reverse %extension_transfer;
- %buttons_reverse = reverse %buttons;
- %buttons_queue_reverse = reverse %buttons_queue;
-}
-
-sub genera_config {
-
- # This sub generates the file variables.txt that is read by the
- # swf movie on load, with info about buttons, layout, etc.
-
- my @textsclients = (
- 'detail_title', 'detail_from', 'detail_to', 'security_code_title',
- 'btn_security_text', 'btn_restart_text', 'btn_reload_text', 'btn_debug_text',
- 'btn_help_text', 'tab_call_text', 'tab_queue_text', 'calls_taken_text',
- 'no_data_text', 'debug_window_title', 'detail_duration', 'clid_label',
- 'version_mismatch'
- );
-
- $/ = "\n";
- my %style_variables;
- my @contextos = ();
- my @unique_contexts = ();
- my $contextoactual = "";
- my $highest_position = 0;
- my @style_include = ();
-
- foreach my $archi (@styleinclude) {
- open( STYLE, "<$directorio/$archi" )
- or die("Could not open $archi for reading");
- while (<STYLE>) {
- chomp($_);
- $_ =~ s/^\s+//g;
- $_ =~ s/([^;]*)[;](.*)/$1/g;
- $_ =~ s/\s+$//g;
- next unless $_ ne "";
-
- if (/^\Q[\E/) {
- s/\[(.*)\]/$1/g;
- $contextoactual = $_;
- $contextoactual =~ tr/A-Z/a-z/;
- next;
- }
- if (/^include/i) {
-
- # Skip include lines
- next;
- }
- $style_variables{$contextoactual} .= $_ . "&";
- }
- close(STYLE);
- }
-
- for ( keys %textos ) {
- if ( $_ =~ /\@/ ) {
- my @partes = split(/\@/);
- if ( $partes[1] ne "*" ) {
- push( @contextos, $partes[1] );
- }
- }
- }
-
- push @contextos, "GENERAL";
- @unique_contexts = unique(@contextos);
-
- # Writes variables.txt for each context defined
- foreach my $contexto_iterate (@unique_contexts) {
-
- my $directorio = "";
- my $host_web = "";
- my $contextlower = $contexto_iterate;
- $contextlower =~ tr/A-Z/a-z/;
-
- if ( defined( $config->{$contexto_iterate}{flash_dir} ) ) {
- $directorio = $config->{$contexto_iterate}{flash_dir};
- }
- else {
- $directorio = $config->{GENERAL}{flash_dir};
- }
-
- if ( defined( $config->{$contexto_iterate}{web_hostname} ) ) {
- $host_web = $config->{$contexto_iterate}{web_hostname};
- }
- else {
- $host_web = $web_hostname;
- }
-
- my $append_filename = "";
- if ( $contexto_iterate ne "GENERAL" ) {
- $append_filename = $contexto_iterate;
- }
- my $flash_context_file = $directorio . "/variables" . $append_filename . ".txt";
- push @all_flash_files, $flash_context_file;
- open( VARIABLES, ">$flash_context_file" )
- or die("Could not write configuration data $flash_context_file.\nCheck your file permissions\n");
-
- if ( $host_web ne "" ) {
- print VARIABLES "server=$host_web&";
- }
- if ( $listen_port ne "4445" ) {
- print VARIABLES "port=$listen_port&";
- }
- print VARIABLES "restart=$enable_restart";
-
- if ( defined( $config->{$contexto_iterate}{security_code} ) ) {
- if ( $config->{"$contexto_iterate"}{security_code} eq "" ) {
- print VARIABLES "&nosecurity=1";
- }
- }
-
- if ( defined( $config->{"$contexto_iterate"}{transfer_timeout} ) ) {
- my @partes = split( /\|/, $config->{"$contexto_iterate"}{transfer_timeout} );
- my $cuantos = @partes;
- print VARIABLES "&totaltimes=$cuantos";
- my $contador = 1;
- foreach my $item_timeout (@partes) {
- print VARIABLES "&timeout_$contador=$item_timeout";
- $contador++;
- }
- }
- else {
- print VARIABLES "&totaltimes=0";
- }
-
- if ( $no_rectangle{$contexto_iterate} ) {
- my $pos_no_dibujar = "";
- while ( my ( $key, $val ) = each( %{ $no_rectangle{$contexto_iterate} } ) ) {
- $pos_no_dibujar .= "$key,";
- }
- $pos_no_dibujar = substr( $pos_no_dibujar, 0, -1 );
- print VARIABLES "&nodraw=$pos_no_dibujar";
- }
-
- if ( $background{$contexto_iterate} ) {
- my $pos_no_dibujar = $background{$contexto_iterate};
- print VARIABLES "$pos_no_dibujar";
- }
-
- while ( my ( $key, $val ) = each(%shapes) ) {
- if ( $key eq $contexto_iterate ) {
- print VARIABLES "&$val";
- }
- }
- while ( my ( $key, $val ) = each(%legends) ) {
- if ( $key eq $contexto_iterate ) {
- print VARIABLES "&$val";
- }
- }
- $highest_position = 0;
- while ( my ( $key, $val ) = each(%textos) ) {
- $val =~ s/\"(.*)\"/$1/g;
- my $contextoboton = $key;
- if ( $contextoboton =~ m/\@/ ) {
- my @parte = split( /\@/, $contextoboton, 2 );
- $contextoboton = $parte[1];
- $contextoboton =~ tr/a-z/A-Z/;
- }
- else {
- $contextoboton = "GENERAL";
- }
- if ( $contextoboton eq $contexto_iterate ) {
- $key =~ s/(\d+)\@.+/$1/g;
- print VARIABLES "&texto$key=$val";
- if ( $key > $highest_position ) { $highest_position = $key; }
- }
- }
- print VARIABLES "&highestpos=$highest_position";
- while ( my ( $key, $val ) = each(%iconos) ) {
- $val =~ s/\"(.*)\"/$1/g;
-
- my $contextoboton = $key;
- if ( $contextoboton =~ m/\@/ ) {
- my @parte = split( /\@/, $contextoboton, 2 );
- $contextoboton = $parte[1];
- $contextoboton =~ tr/a-z/A-Z/;
- }
- else {
- $contextoboton = "GENERAL";
- }
-
- if ( $contextoboton eq $contexto_iterate ) {
- $key =~ s/(\d+)\@.+/$1/g;
- print VARIABLES "&icono$key=$val";
- }
- }
- while ( my ( $key, $val ) = each(%urls) ) {
- $val =~ s/\"(.*)\"/$1/g;
- if ( $val ne "0" ) {
- my $base64_url = encode_base64($val);
- my $contextoboton = $key;
- if ( $contextoboton =~ m/\@/ ) {
- my @parte = split( /\@/, $contextoboton, 2 );
- $contextoboton = $parte[1];
- $contextoboton =~ tr/a-z/A-Z/;
- }
- else {
- $contextoboton = "GENERAL";
- }
-
- if ( $contextoboton eq $contexto_iterate ) {
- $key =~ s/(\d+)\@.+/$1/g;
- print VARIABLES "&url$key=$base64_url";
- }
- }
- }
- while ( my ( $key, $val ) = each(%targets) ) {
- $val =~ s/\"(.*)\"/$1/g;
-
- if ( $val ne "0" ) {
- my $contextoboton = $key;
- if ( $contextoboton =~ m/\@/ ) {
- my @parte = split( /\@/, $contextoboton, 2 );
- $contextoboton = $parte[1];
- $contextoboton =~ tr/a-z/A-Z/;
- }
- else {
- $contextoboton = "GENERAL";
- }
-
- if ( $contextoboton eq $contexto_iterate ) {
- $key =~ s/(\d+)\@.+/$1/g;
- print VARIABLES "&target$key=$val";
- }
- }
- }
- if ( !defined( $style_variables{$contextlower} ) ) {
- $style_variables{$contextlower} = $style_variables{"general"};
- }
- print VARIABLES "&" . $style_variables{$contextlower};
- if ( !defined( $total_shapes{$contexto_iterate} ) ) {
- $total_shapes{$contexto_iterate} = 0;
- }
- print VARIABLES "total_rectangles=" . $total_shapes{$contexto_iterate};
- if ( !defined( $total_legends{$contexto_iterate} ) ) {
- $total_legends{$contexto_iterate} = 0;
- }
- print VARIABLES "&total_legends=" . $total_legends{$contexto_iterate};
-
- foreach my $val (@textsclients) {
- if ( defined( $language->{$contexto_iterate}{$val} ) ) {
- print VARIABLES "&$val=" . $language->{$contexto_iterate}{$val};
- }
- else {
- log_debug( "Language string $val in context $contexto_iterate does not exists", 64 ) if DEBUG;
- print("Language string $val in context $contexto_iterate does not exists\n");
- }
- }
- print VARIABLES "&lang=" . $config->{$contexto_iterate}{language};
- close(VARIABLES);
- }
- $/ = "\0";
-}
-
-sub dump_internal_hashes_to_stdout {
-
- &print_botones(1);
-
- &print_instancias(1);
-
- if ( keys(%datos) ) {
- &print_datos(1);
- }
- else {
- print "No data blocks in memory\n";
- }
-
- if ( keys(%sesbot) ) {
- &print_sesbot(1);
- }
- else {
- print "No data sesiones botones\n";
- }
-
- if ( keys(%linkbot) ) {
- &print_linkbot();
- }
-
- &print_cachehit();
-
- print "\n";
- while ( my ( $key, $val ) = each(%timeouts) ) {
- print "Timer($key)=$val\n";
- }
- print "\n";
-
- &print_status();
-
- &print_clients();
-
- &print_cola_write();
-
- &print_timers();
-
-}
-
-sub generate_configs_onhup {
- %buttons = ();
- %background = ();
- %sesbot = ();
- %linkbot = ();
- %instancias = ();
- %textos = ();
- %iconos = ();
- %urls = ();
- %targets = ();
- %extension_transfer = ();
- %shapes = ();
- %legends = ();
- %total_shapes = ();
- %total_legends = ();
- @all_flash_files = ();
- %astdbcommands = ();
-
- %estadoboton = ();
- %botonled = ();
- %botonvoicemail = ();
- %botonvoicemailcount = ();
- %botonalpha = ();
- %botonqueue = ();
- %botonqueuemember = ();
- %botonpark = ();
- %botonlinked = ();
- %botonclid = ();
- %botonmeetme = ();
- %botontimer = ();
- %botontimertype = ();
- %botonlabel = ();
- %botonsetlabel = ();
- %botonregistrado = ();
- @astmanproxy_servers = ();
-
- &read_buttons_config();
- &read_server_config();
- &read_language_config();
- &read_astdb_config();
- &genera_config();
- &send_initial_status();
-}
-
-sub get_next_trunk_button {
- my $canalid = shift;
- my $contexto = shift;
- my $server = shift;
- my $canalsesion = shift;
- my $canal_tipo_fop = "";
- my $canal;
- my $sesion;
- my $return = "";
- my @uniq;
- my $trunk_pos;
- my $heading = "** GET_NEXT_TRUNK";
-
- # This routine mantains and returns the position of each channel inside
- # a trunk button.
-
- log_debug( "$heading START SUB canalid $canalid contexto $contexto server $server canalsesion $canalsesion", 16 ) if DEBUG;
-
- if ( $canalid eq "" ) {
- log_debug( "!! ERROR empty canalid ", 64 ) if DEBUG;
- return;
- }
-
- if ( $canalsesion =~ /</ ) {
-
- # We want to remove <ZOMBIE> or <MASQ>
- $canalsesion =~ s/([^<]*).*/$1/g;
- }
-
- if ( $canalid !~ /\^/ ) {
- $canal_tipo_fop = $server . "^" . $canalid;
- }
- else {
- $canal_tipo_fop = $canalid;
- $canalid =~ s/(.*)\^(.*)/$2/g;
- }
-
- if ( $canal_tipo_fop =~ /\QCAPI[\E/ ) {
- $canal_tipo_fop =~ tr/a-z/A-Z/;
- $canalid =~ tr/a-z/A-Z/;
- }
- $canal_tipo_fop =~ s/(.*)<(.*)>/$1/g;
- $canal_tipo_fop =~ s/\s+//g;
- $canal_tipo_fop =~ s/(.*)[-\/](.*)/$1/g;
- if ( defined($2) ) {
- $sesion = $2;
- }
- else {
- $sesion = "XXXX";
- }
- $sesion =~ s/(.*)\&(.*)/$1/g; # removes context if it has any
- $canal_tipo_fop =~ s/(\d+\^IAX2\/)([^@]*)(.*)/$1\U$2\E/g;
- $canal_tipo_fop =~ s/(\d+\^IAX2)\[(.*)?@?(.*)?\]?/$1\[\U$2\E\]/g;
- log_debug( "$heading canal_tipo_fop 1 $canal_tipo_fop", 64 ) if DEBUG;
-
- if ( $canalid =~ /^_.*/ ) {
- $canal_tipo_fop = $canalid;
- if ( $canal_tipo_fop =~ /=/ ) {
- $canal_tipo_fop =~ /([^=].*)(=\d+)(.*)/;
- $canal_tipo_fop = $1;
- if ( defined($3) ) {
- $contexto = $3;
- }
- }
- log_debug( "$heading contexto $contexto", 32 ) if DEBUG;
- my ( $nada, $ses ) = separate_session_from_channel($canalsesion);
- $sesion = $ses;
- }
- $canal_tipo_fop =~ tr/a-z/A-Z/;
- log_debug( "$heading canal_tipo_fop 2 $canal_tipo_fop", 64 ) if DEBUG;
-
- my $canalconcontexto = "";
- if ( $contexto ne "" ) {
- $canalconcontexto = "$canal_tipo_fop$contexto";
- }
- else {
- $canalconcontexto = $canal_tipo_fop;
- $contexto = "";
- }
-
- if ( $sesion eq "XXXX" ) {
-
- # Si la sesion es XXXX devuelve siempre el 1er boton
- log_debug( "$heading return $canal_tipo_fop=1$contexto (1st one)", 64 ) if DEBUG;
- return "$canal_tipo_fop=1$contexto";
- }
-
- my $canalconcontextosinserver = $canalconcontexto;
- $canalconcontextosinserver =~ s/(\d+)\^(.*)/$2/g;
- if ( $canalconcontexto !~ /\^/ ) {
- $canalconcontexto = $server . "^" . $canalconcontexto;
- }
- if ( exists( $instancias{"$canalconcontexto"} ) ) {
- if ( exists( $instancias{"$canalconcontexto"}{"$server^$canalsesion"} ) ) {
- log_debug(
-"$heading Found instancias($canalconcontexto)($server^$canalsesion)=$instancias{\"$canalconcontexto\"}{\"$server^$canalsesion\"}",
- 64
- )
- if DEBUG;
- $trunk_pos = $instancias{"$canalconcontexto"}{"$server^$canalsesion"};
- }
- else {
- log_debug( "$heading Not Found instancias($canalconcontexto)($server^$canalsesion)", 64 ) if DEBUG;
- my %busy_slots = ();
- foreach my $key1 ( sort ( keys(%instancias) ) ) {
- if ( $key1 eq $canalconcontexto ) {
- foreach my $key2 ( sort ( keys( %{ $instancias{$key1} } ) ) ) {
- my $indice = $instancias{$key1}{$key2};
- $busy_slots{$indice} = 1;
- }
- }
- }
- for ( $trunk_pos = 1 ; ; $trunk_pos++ ) {
- last if ( !exists( $busy_slots{$trunk_pos} ) );
- }
- $instancias{"$canalconcontexto"}{"$server^$canalsesion"} = $trunk_pos;
- }
- $return = "$canal_tipo_fop=${trunk_pos}$contexto";
- }
- return $return;
-}
-
-sub separate_session_from_channel {
- my $elemento = shift;
- my $heading = "** SEPARATE_SESSION_FROM_CHAN";
- log_debug( "$heading elemento1 $elemento", 32 ) if DEBUG;
- if ( $elemento !~ /.*[-\/].*[-\/].+$/ ) {
- if ( $elemento =~ /^OH323/ || $elemento =~ /^\QMODEM[I4l]\E/i ) {
- $elemento =~ s/(.*)\/(.*)/\U$1\E\/${2}-${2}/g;
- }
- elsif ( $elemento =~ m/^\d+/ ) {
-
- # If the channel is a meetme, do nothing;
- }
- else {
- $elemento .= "-XXXX";
- }
- }
- if ( $elemento =~ /^mISDN/i ) {
- $elemento .= "-XXXX";
-
- # $elemento =~ s/(.*)\/(.*)/\U$1\E\/${2}-${2}/g;
- }
- if ( $elemento =~ /^SRX/i ) {
- $elemento =~ s/(.*)\/(.*)/\U$1\E\/${2}-1/g;
- }
- $elemento =~ s/(.*)[-\/](.*)/$1\t$2/g;
- log_debug( "$heading elemento2 $elemento", 32 ) if DEBUG;
- my $canal = $1;
- my $sesion = $2;
- log_debug( "$heading canal $canal sesion $sesion", 32 ) if DEBUG;
-
- if ( defined($canal) && defined($sesion) ) {
- $canal =~ tr/a-z/A-Z/;
- $elemento = $canal . "\t" . $sesion;
- }
- $elemento =~ s/IAX2\[(.*)@(.*)\]\t(.*)/IAX2\[$1\]\t$3/;
- $elemento =~ s/IAX2\/(.*)@(.*)\t(.*)/IAX2\/$1\t$3/;
-
- my @partes = split( /\t/, $elemento );
- return @partes;
-}
-
-sub peerinfo {
- my $sock = shift;
- my $short = shift;
- if ( $sock eq "" ) {
- return "";
- }
- if ( defined( $sock->peeraddr ) ) {
- if ( defined($short) ) {
- return $sock->peerhost;
- }
- else {
- return sprintf( "%s:%s", $sock->peerhost, $sock->peerport );
- }
-
- }
- else {
- return "";
- }
-}
-
-sub erase_instances_for_trunk_buttons {
- my $canalid = shift;
- my $canal = shift;
- my $server = shift;
- my $canalidsinserver = "";
- my $canalglobal;
- my $valor;
- my @new = ();
- my $heading = "** ERASE_INSTANCE_TRUNK";
-
- $canalidsinserver = $canalid;
- $canalid = "$server^$canalid";
- $canalid =~ s/(.*)<(.*)>/$1/g; #discards ZOMBIE or MASQ
-
- log_debug( "$heading canalid $canalid canal $canal", 16 ) if DEBUG;
-
- $canalglobal = $canalid;
- $canalglobal =~ s/(.*)[-\/](.*)/$1/g;
- $canalglobal =~ s/IAX2\/(.*)@(.*)/IAX2\/$1/g;
- $canalglobal =~ s/IAX2\[(.*)@(.*)\]/IAX2\[$1\]/g;
-
- my ( $nada, $contexto ) = split( /\&/, $canal );
- if ( !defined($contexto) ) { $contexto = ""; }
-
- my $canalconcontexto = "";
- if ( $contexto ne "" ) {
- $canalconcontexto = "$canalglobal&$contexto";
- $contexto = "&$contexto";
- }
- else {
- $canalconcontexto = $canalglobal;
- $contexto = "";
- }
-
- my $sesiontemp = $canalid;
- if ( $canalid =~ /^Zap/i && $canal =~ /\*/ ) {
-
- # Si es un Zap y ademas wildcard, cambio el canalid para
- # que tenga la sesion modificada
- # $sesiontemp =~ s/Zap/ZAP/g;
- $sesiontemp =~ s/(.*)\/(.*)-(.*)/\U$1\/$2-${2}\E${3}/g;
- }
- if ( $canalid =~ /^MGCP/i && $canal =~ /\*/ ) {
-
- # Si es un MGCP y ademas wildcard, cambio el canalid para
- # que tenga la sesion modificada
- my $sesiontemp2 = $sesiontemp;
- $sesiontemp2 =~ s/(.*)\@(.*)-(.*)/$2/g;
- $sesiontemp2 = substr( $sesiontemp2, -3 );
- $sesiontemp =~ s/(.*)\/(.*)-(.*)/\U$1\E\/${2}-${sesiontemp2}${3}/g;
- }
-
- log_debug( "$heading looking for $canalid on instancias to erase it", 128 ) if DEBUG;
-
- foreach my $key1 ( sort ( keys(%instancias) ) ) {
- foreach my $key2 ( sort ( keys( %{ $instancias{$key1} } ) ) ) {
- if ( $key2 eq $canalid ) {
- delete $instancias{$key1}{$key2};
- log_debug( "$heading Erasing $canalid from instanacias!", 128 ) if DEBUG;
- }
- }
- }
-}
-
-sub generate_linked_buttons_list {
- my $nroboton = shift;
- my $server = shift;
- my @botonas = ();
- my $listabotones = "";
- my $heading = "** GEN_LINK_LIST ";
-
- log_debug( "$heading canal $nroboton server $server", 16 ) if DEBUG;
-
- if ( $nroboton !~ /\^/ ) {
- $nroboton = "$server^$nroboton";
- }
-
- my ( $nada1, $contexto1 ) = split( /\&/, $nroboton );
- if ( !defined($contexto1) ) { $contexto1 = ""; }
-
- if ( defined( @{ $linkbot{"$nroboton"} } ) ) {
- log_debug( "$heading Esta definido linkbot {$nroboton}", 32 ) if DEBUG;
- foreach ( @{ $linkbot{"$nroboton"} } ) {
- log_debug( "$heading y contiene $_", 32 ) if DEBUG;
- my ( $canal1, $sesion1 ) = separate_session_from_channel($_);
- log_debug( "$heading luego de separate canal1 = $canal1 y sesion1 = $sesion1", 128 ) if DEBUG;
- my $canalsesion = $_;
- if ( !defined($sesion1) ) {
- $canalsesion = $canal1 . "-XXXX";
- }
- log_debug( "$heading canal1 = $canal1 y sesion1 = $sesion1 canalsesion=$canalsesion", 128 ) if DEBUG;
- my @linkbotones = find_panel_buttons( $canal1, $canalsesion, $server );
- foreach my $cual (@linkbotones) {
- my ( $nada2, $contexto2 ) = split( /\&/, $cual );
- if ( !defined($contexto2) ) { $contexto2 = ""; }
- if ( $contexto1 eq $contexto2 ) {
- if ( defined( $buttons{"$server^$cual"} ) ) {
- my $botinro = $buttons{"$server^$cual"};
- push @botonas, $botinro;
- log_debug( "$heading Agrego $botinro", 64 ) if DEBUG;
- }
- }
- }
- }
-
- #my %seen2 = ();
- #my @uniq2 = grep { !$seen2{$_}++ } @botonas;
- #@botonas = \@uniq2;
- @botonas = unique(@botonas);
-
- foreach my $val (@botonas) {
- if ( defined($val) ) {
- $listabotones .= "$val,";
- log_debug( "$heading devuelve $val", 128 ) if DEBUG;
- }
- }
- $listabotones = substr( $listabotones, 0, -1 );
- }
- else {
- log_debug( "$heading NO ESTA DEFINIDO linkbot {$nroboton}", 32 ) if DEBUG;
- }
- return $listabotones;
-}
-
-sub erase_all_sessions_from_queues {
- my $canalid = shift;
- my $canal = shift;
- my $server = shift;
- my $canalsesion = $canalid;
- my $heading = "** ERASE SESSION QUEUE ";
- log_debug( "$heading erase queue $canalid $canal $server", 64 ) if DEBUG;
-
- for my $mnroboton ( keys %sesbot ) {
- if ( !exists( $buttons_queue_reverse{$mnroboton} ) ) {
- next;
- }
- my @final = ();
- foreach my $msesion ( @{ $sesbot{$mnroboton} } ) {
- log_debug( "$heading $msesion ne $canalsesion?", 64 ) if DEBUG;
- if ( $msesion ne $canalsesion ) {
- log_debug( "$heading sesbot es distinto dejo $msesion en sesbot($mnroboton)", 64 ) if DEBUG;
- push @final, $msesion;
- }
- }
- $sesbot{$mnroboton} = [@final];
- }
-}
-
-sub erase_all_sessions_from_channel {
- my $canalid = shift;
- my $canal = shift;
- my $server = shift;
- my $canalsesion = $canalid;
- my @final;
- my @return;
- my $heading = "** ERASE_ALL_SESS_FROM";
- log_debug( "$heading canal $canal canalid $canalid", 16 ) if DEBUG;
-
- my $indice_cache = $canalid . "-" . $canal . "-" . $server;
- log_debug( "$heading borro cache_hit($indice_cache)", 128 ) if DEBUG;
- delete $cache_hit{$indice_cache};
- if ( keys(%cache_hit) ) {
- for ( keys %cache_hit ) {
- if ( defined( @{ $cache_hit{$_} } ) ) {
- foreach my $val ( @{ $cache_hit{$_} } ) {
- if ( $val eq $canal ) {
- log_debug( "$heading borro cache $_", 128 ) if DEBUG;
- delete $cache_hit{$_};
- }
- }
- }
- }
- }
-
- if ( $canal =~ /^QUEUE/ ) {
-
- # QUEUE buttons have a special treatment with sessions (sesbot).
- # we dont want to remove a session (sesbot) from a real button when
- # the channel leaves the queue
- erase_all_sessions_from_queues( $canalid, $canal, $server );
- return;
- }
- else {
-
- if ( $canal =~ /=/ ) {
-
- # If its a trunk button, erase instances
- erase_instances_for_trunk_buttons( $canalsesion, $canal, $server );
- }
- $canalsesion =~ s/\t/-/g;
- $canalid =~ s/(.*)<(.*)>/$1/g; # Removes <zombie><masq>
-
- for my $mnroboton ( keys %sesbot ) {
- @final = ();
- foreach my $msesion ( @{ $sesbot{$mnroboton} } ) {
- log_debug( "$heading $msesion ne $canalsesion?", 64 ) if DEBUG;
- if ( $msesion ne $canalsesion ) {
- log_debug( "$heading sesbot es distinto dejo $msesion a \@final", 64 ) if DEBUG;
- push @final, $msesion;
- }
- }
- $sesbot{$mnroboton} = [@final];
- }
-
- if ( keys(%linkbot) ) {
- for ( keys %linkbot ) {
- if ( defined( @{ $linkbot{$_} } ) ) {
- my @final = ();
- foreach my $val ( @{ $linkbot{$_} } ) {
- log_debug( "$heading linkbot($_) ne $val ?", 64 ) if DEBUG;
- if ( $val ne $canalsesion ) {
- push @final, $val;
- log_debug( "$heading No es igual lo dejo $_", 64 ) if DEBUG;
- }
- else {
- push @return, $_;
- log_debug( "$heading Es igual lo AGREGO RETURN $_", 64 ) if DEBUG;
- }
- }
-
- log_debug( "$heading delete linkbot($_)", 64 ) if DEBUG;
- delete $linkbot{$_};
- $linkbot{$_} = [@final];
- }
- }
- }
-
- my $quehay = "";
- for $quehay ( keys %datos ) {
- while ( my ( $key, $val ) = each( %{ $datos{$quehay} } ) ) {
- if ( $key eq "Channel" ) {
- $val =~ s/(.*)[-\/](.*)/$1\t$2/g;
- $val =~ tr/a-z/A-Z/;
- if ( $canalid eq $val ) {
- log_debug( "** Found a match $canalid=$val ($quehay) - Cleared!", 16 ) if DEBUG;
- delete $datos{$quehay};
- }
- }
- }
- }
- for my $valores (@return) {
- log_debug( "$heading devuleve $valores", 64 ) if DEBUG;
- }
- return @return;
- }
-}
-
-sub extraer_todas_las_sesiones_de_un_canal {
- my $canal = shift;
- my $canalbase = "";
- my $sesion_numero = "";
- my $sesion = "";
- my $key = "";
- my $val = "";
- my $quehay = "";
- my @result = ();
- my $heading = "** EXTRAER_TODAS ";
- log_debug( "$heading from the channel $canal", 16 ) if DEBUG;
-
- # Removes the context if its set
-
- my @pedazos = split( /&/, $canal );
- $canal = $pedazos[0];
-
- # Checks if the channel name has an equal sign
- # (its a trunk button channel)
-
- if ( $canal =~ /(.*)=(\d+)/ ) {
- ( $canalbase, $sesion_numero ) = split( /\=/, $canal );
- log_debug( "** Its a trunk $canalbase button number $sesion_numero!", 16 ) if DEBUG;
-
- foreach my $key1 ( sort ( keys(%instancias) ) ) {
- foreach my $key2 ( sort ( keys( %{ $instancias{$key1} } ) ) ) {
- if ( $key2 eq $canalbase ) {
- push @result, $key2;
- log_debug( "$heading encontro sesion $canalbase", 16 ) if DEBUG;
- }
- }
- }
- }
-
- my $cuantos = @result;
- if ( $cuantos == 0 ) {
-
- # If there is no results for a trunk button, look into the %datos
- # hash.
-
- for $quehay ( keys %datos ) {
- while ( ( $key, $val ) = each( %{ $datos{$quehay} } ) ) {
- if ( defined($val) ) {
- my $vel = $val;
- if ( $vel =~ /^IAX2/ ) {
- $vel =~ s/IAX2\/(.*)@(.*)\/(.*)/IAX2\/$1\/$3/g;
- $vel =~ s/IAX2\[(.*)@(.*)\](.*)/IAX2\[$1\]$3/g;
- }
- if ( $vel =~ /^\Q$canal\E[-\/]/i && $key eq "Channel" ) {
- push( @result, $val );
- log_debug( "** Sesion: $val", 16 ) if DEBUG;
- }
- }
- }
- }
- }
- return @result;
-}
-
-sub extracts_exten_from_active_channel {
- my $canal = shift;
- my $quehay = "";
- my @result = ();
- my $heading = "** EXTRACT_EXTEN ";
- my $server = "";
-
- my @pedazos = split( /&/, $canal );
- $canal = $pedazos[0];
-
- if ( $canal =~ /\^/ ) {
- @pedazos = split( /\^/, $canal );
- $server = $pedazos[0];
- $canal = $pedazos[1];
- }
-
- for $quehay ( keys %datos ) {
- log_debug( "$heading turno de $quehay", 64 ) if DEBUG;
- my $canalaqui = 0;
- my $serveraqui = 0;
- my $linkeado = "";
- while ( my ( $key, $val ) = each( %{ $datos{$quehay} } ) ) {
-
- if ( $val =~ /^$canal-/i && ( $key =~ /^Chan/i || $key =~ /^Link/i ) ) {
- $canalaqui = 1;
- }
- if ( $key =~ /^Server/i && $val == $server ) {
- $serveraqui = 1;
- }
- if ( $key =~ /^Exten/i ) {
- $linkeado = $val;
- }
- }
- if ( $canalaqui == 1 && $linkeado ne "" && $serveraqui == 1 ) {
- log_debug( "$heading devuelvo $linkeado\n", 64 ) if DEBUG;
- push( @result, $linkeado );
- }
- }
- return @result;
-}
-
-sub extraer_todos_los_enlaces_de_un_canal {
- my $canal = shift;
- my $server = shift;
- my $quehay = "";
- my @result = ();
- my $heading = "** EXTRACT_LINKS_CHAN";
-
- print_datos(1);
-
- my @pedazos = split( /&/, $canal );
- $canal = $pedazos[0];
-
- if ( $canal =~ /\^/ ) {
- @pedazos = split( /\^/, $canal );
- $server = $pedazos[0];
- $canal = $pedazos[1];
- }
-
- log_debug( "$heading canal $canal server $server", 1 ) if DEBUG;
-
- for $quehay ( keys %datos ) {
- my $canalaqui = 0;
- my $serveraqui = 0;
- my $linkeado = "";
- my $todo = "";
- my $eventob = "";
-
- log_debug( "$heading turno de $quehay", 128 ) if DEBUG;
- log_debug( "", 128 ) if DEBUG;
- while ( my ( $key, $val ) = each( %{ $datos{$quehay} } ) ) {
- $todo .= "$key = $val\n";
- log_debug( "$heading buscando $canal en $key=$val", 128 ) if DEBUG;
- if ( ( $val =~ /^$canal-/i || $val =~ /^$canal$/ ) && $key =~ /^Chan/i ) {
- log_debug( "$heading canal coincide $canal = $val\n", 16 ) if DEBUG;
- $canalaqui = 1;
- }
- if ( $key =~ /^Server/i && $val eq $server ) {
- $serveraqui = 1;
- log_debug( "$heading server coincide $server = $val\n", 16 ) if DEBUG;
- }
- if ( $key =~ /^Link/i ) {
- $linkeado = $val;
- }
- if ( $key =~ /^Event/i ) {
- $eventob = $val;
- log_debug( "$heading eventob = $val\n", 16 ) if DEBUG;
- }
- }
- if ( $canalaqui == 1 && $linkeado ne "" && $serveraqui == 1 && $eventob !~ /agent/i ) {
- push( @result, $linkeado );
- log_debug( "$heading Agrego $linkeado a la lista", 16 ) if DEBUG;
- log_debug( $todo, 16 ) if DEBUG;
- }
- }
- return @result;
-}
-
-sub find_panel_buttons {
-
- # *****************************************************************
- # Based on a CHANNEL name returned by Asterisk, we try to match
- # one or more of our buttons to show status. Returns array with list
- # of channel names as set in op_buttons.cfg
-
- my $canal = shift;
- my $canalsesion = shift;
- my $server = shift;
- my $pos = 0;
- my $sesion = "";
- my @canales = ();
- my @multicanal;
- my $quehay = "";
- my $canalfinal = "";
- my $contextoindex = "";
- my $server_boton = 0;
- my $heading = "** FIND_PANEL_BUT";
- my $calleridnum = "noexiste";
- my %trunk_matched = ();
-
- $tab = $tab . "\t" if DEBUG;
- log_debug( "$heading canal $canal canalsesion $canalsesion server $server", 32 ) if DEBUG;
-
- if ( $canal eq "" ) {
- $tab = substr( $tab, 0, -1 ) if DEBUG;
- return;
- }
-
- my $uniqueid = find_uniqueid( $canalsesion, $server );
- if ( $uniqueid ne "" ) {
- if ( defined( $datos{$uniqueid}{"CallerID"} ) ) {
- $calleridnum = $datos{$uniqueid}{"CallerID"};
- }
- }
-
- # XXXXX We have to try hard to find a match for the channel
- # There are several posibilities:
- #
- # Exact match: SIP/jo (no panel context, not trunk, no wildcard)
- # Panel Ctxt match: SIP/jo&SIP (exact name, not trunk, no wildcard, panel context)
- # Trunk match: SIP/jo=1 (exact name, trunk, no wildcard, no panel context)
- # Ctxt&Trunk match: SIP/jo=1&SIP (exact name, trunk, no wildcard, panel context)
- # Wildcard SIP/*=1 (wildcard name, trunk)
- #
- # The key to match syntax is server^[chan_name|wildcard](=trunk_position)(&panel_context)
- #
- # Here I first will try to match any $buttons that might match the given channel name
-
- if ( $canalsesion =~ /</ ) {
-
- # "<" Is an invalid character for a channel name, unless its a zombie
- # or masq, in that case we should discard them
- log_debug( "$heading canalsesion $canalsesion (Se supone que no debo tratar zombies?)", 32 ) if DEBUG;
- }
-
- $canal = uc($canal);
-
- # Pass for QUEUEAGENT buttons
- # We should check it no matter the cache because we match also on queue, not only channel
- push @multicanal, $canal;
-
- if ( defined( $channel_to_agent{"$server^$canal"} ) ) {
- $canal = uc( $channel_to_agent{"$server^$canal"} );
- }
-
- if ( $queueagent_buttons == 1 ) {
-
- my $canalsindumy = $canal;
- $canalsindumy =~ s/-FOPdummy$//g;
-
- log_debug( "$heading trying with QUEUEAGENT buttons", 64 ) if DEBUG;
-
- if ( keys(%agents_on_queue) ) {
- foreach my $valor ( keys(%agents_on_queue) ) {
- my $cont = 0;
- foreach my $vvalor ( @{ $agents_on_queue{$valor} } ) {
- $cont++;
- log_debug( "$heading in queue $valor is '$vvalor' equal to '$server^$canalsindumy'?", 64 ) if DEBUG;
-
- if ( uc("$server^$canalsindumy") eq uc($vvalor) ) {
- my $queuename = $valor;
- $queuename =~ s/(\d+)\^(.*)/$2/g;
- my $fake_channel_agent = uc("QUEUEAGENT/$queuename=$cont");
-
- foreach my $ctx (@panel_contexts) {
- my $ctxp = "";
- if ( $ctx eq "DEFAULT" ) {
- $ctxp = "";
- }
- else {
- $ctxp = "&$ctx";
- }
- my $idx = "$server^$fake_channel_agent" . $ctxp;
- if ( exists( $buttons{$idx} ) ) {
-
- # We have a match! add to return canales
- push @canales, "$fake_channel_agent$ctxp";
- log_debug( "$heading we have a winner! $fake_channel_agent $ctxp", 64 ) if DEBUG;
- }
- }
- }
- }
- }
- }
- }
-
- push @multicanal, $canal;
-
- if ( $canal =~ /^AGENT/i ) {
- my $canalag = $canal;
- $canalag =~ s/^AGENT/Agent/g;
- if ( defined( $agent_to_channel{"$server^$canalag"} ) ) {
- push @multicanal, uc( $agent_to_channel{"$server^$canalag"} );
- log_debug( "$heading HAY UN AGENTE " . $agent_to_channel{"$server^$canalag"}, 32 );
- }
- else {
- if ( $canal =~ /-FOPdummy$/ ) {
- $canal =~ s/-FOPdummy$//g;
- @multicanal = ($canal);
- }
- print_agents();
- }
- }
- else {
- if ( defined( $channel_to_agent{"$server^$canal"} ) ) {
- push @multicanal, $channel_to_agent{"$server^$canal"};
- }
- }
-
- if ( $canal =~ m/^Local/i ) {
- my $canalsinlocal = $canal;
- $canalsinlocal =~ s/^LOCAL\///gi;
- $canalsinlocal =~ s/(,*)\/n$/$1/gi;
- while ( my ( $key, $val ) = each(%extension_transfer_reverse) ) {
- if ( uc($key) eq "$server^$canalsinlocal" ) {
- my $canalfin = $val;
- $canalfin =~ s/\d+\^(.*)/$1/g;
- push @multicanal, $canalfin;
- }
- }
- }
-
- my $indice_cache = "";
- @multicanal = unique(@multicanal);
-
- foreach my $canal (@multicanal) {
-
- # Attemp to match a button from cache
- $indice_cache = $canalsesion . "-" . $canal . "-" . $server;
- if ( !defined( $cache_hit{$indice_cache} ) ) {
- log_debug( "$heading CACHE MISS $indice_cache", 32 ) if DEBUG;
- for ( keys %buttons ) {
- $canalfinal = "";
- my ( $nada, $contexto ) = split( "\&", $_ );
- if ( !defined($contexto) ) { $contexto = ""; }
- if ( $contexto ne "" ) { $contexto = "&" . $contexto; }
- if ( $_ =~ /^\Q$server^$canal\E$/i ) {
-
- log_debug( "$heading exact match buttons ( $_ ) $canal $contexto", 32 ) if DEBUG;
- $canalfinal = $canal;
- }
- elsif ( $_ =~ /^\Q$server^$canal\E\&/i ) {
-
- log_debug( "$heading context match buttons ( $_ ) $canal $contexto", 32 ) if DEBUG;
- $canalfinal = $canal;
- }
- elsif ( $_ =~ /^\Q$server^$canal\E=/i ) {
- if ( !exists( $trunk_matched{"$server^$canal"} ) ) {
- $canalfinal = get_next_trunk_button( $canalsesion, $contexto, $server, $canalsesion );
- if ( $canalfinal ne "" ) {
- log_debug( "$heading trunk match ( $_ ) $canal $contexto", 32 ) if DEBUG;
- $trunk_matched{"$server^$canal"} = 1;
- $canalfinal =~ s/(.*)\^(.*)/$2/g;
- }
- }
- }
- elsif ( $_ =~ /^$server\^CLID\/\Q$calleridnum\E\&?/ ) {
-
- log_debug( "$heading clid match ( $_ ) $canal $contexto", 32 ) if DEBUG;
- $canalfinal = "CLID/$calleridnum";
- }
-
- if ( $canalfinal ne "" ) {
- my $indicefin = "";
- my $canalfinalconcontexto = $canalfinal;
-
- if ( $canalfinal =~ /\^/ ) {
- $indicefin = "${canalfinal}";
- }
- else {
- $indicefin = "$server^${canalfinal}";
- }
- if ( $indicefin !~ /(.*)\&(.*)$/ ) {
- $indicefin = "$indicefin$contexto";
- $canalfinalconcontexto = "${canalfinal}${contexto}";
- }
-
- if ( exists( $buttons{$indicefin} ) ) {
- my $posicion = $buttons{$indicefin};
- $server_boton = $button_server{$posicion};
- log_debug( "$heading server para $canalfinal = $server_boton", 64 ) if DEBUG;
- }
- push @canales, "${canalfinalconcontexto}";
- }
- }
- $canalfinal = "";
-
- my $nada1 = "";
- my $contextemp = "";
- my %contextosencontrados;
- for my $val (@canales) {
- ( $nada1, $contextemp ) = split( "&", $val );
- if ( !defined($contextemp) ) { $contextemp = ""; }
- $contextosencontrados{"&$contextemp"} = 1;
- }
-
- # Pass for REGEXP buttons
- my $canal_sin_server_ni_contexto = $canal;
- $canal_sin_server_ni_contexto =~ s/(^\d+\^)(.*)(\&.*)?(=\d+)?/$2/;
-
- if ( $regexp_buttons == 1 ) {
- for ( keys %buttons_preserve_case ) {
- my $regexp = "";
- if ( $_ =~ /^\d+\^_/ ) {
- $regexp = $_;
- $regexp =~ /^(\d+)\^_([^=&]*)(=[^&]*)?(\&.*)?/;
- my $serverb = $1;
- $regexp = $2;
- my $posicion = $3;
- my $contexto = "";
- if ( defined($4) ) {
- $contexto = $4;
- if ( defined( $contextosencontrados{$contexto} ) ) {
- next;
- }
- }
-
- if ( $canal_sin_server_ni_contexto =~ m/$regexp/i
- && !exists( $trunk_matched{"$canal_sin_server_ni_contexto^$regexp"} ) )
- {
- if ( defined($posicion) ) {
-
- # Es un trunk
- $canalfinal = get_next_trunk_button( $_, $contexto, $server, $canalsesion );
- }
- else {
-
- # No es un trunk
- $canalfinal = $_;
- }
- if ( $canalfinal ne "" ) {
- $trunk_matched{"$canal_sin_server_ni_contexto^$regexp"} = 1;
- push @canales, $canalfinal;
- }
- }
- }
- }
- }
- }
- else {
-
- # We have a cache match, retrieve the buttons from cache
- my @canales2 = @{ $cache_hit{$indice_cache} };
-
- # and add the matches from queueagents we might have
- push @canales, @canales2;
- log_debug( "$heading CACHE HIT Retrieving buttons from cache ($indice_cache)", 32 ) if DEBUG;
- }
- } # end foreach multicanal
- @canales = unique(@canales);
-
- my $cuantoscanales = @canales;
- if ( $cuantoscanales > 0 ) {
- $cache_hit{$indice_cache} = [@canales];
- }
-
- my $cuantos = $#canales + 1;
- log_debug( "$heading returns $cuantos", 16 ) if DEBUG;
- foreach (@canales) {
- log_debug( "$heading cache button $_", 32 ) if DEBUG;
- }
- $tab = substr( $tab, 0, -1 );
- return @canales;
-}
-
-sub procesa_bloque {
- my $blaque = shift;
- my $socket = shift;
- my $astmanproxy_server = shift;
- my %bloque = %$blaque if defined(%$blaque);
-
- my %hash_temporal = ();
- my $evento = "";
- my $canal = "";
- my $sesion = "";
- my $texto = "";
- my $estado_final = "";
- my $unico_id = "";
- my $exten = "";
- my $clid = "";
- my $clidnum = "";
- my $clidname = "";
- my $canalid = "";
- my $key = "";
- my $val = "";
- my @return = ();
- my $conquien = "";
- my $enlazado = "";
- my $viejo_nombre = "";
- my $nuevo_nombre = "";
- my $quehay = "";
- my $elemento = "";
- my $state = "";
- my $exists = 0;
- my $fakecounter = 1;
- my $fill_datos = 0;
- my $server = 0;
- my $timeout = 0;
- my $heading = "** PROCESA_BLOQUE";
-
- $tab = $tab . "\t";
- $hash_temporal{"Event"} = "";
-
- while ( my ( $key, $val ) = each(%bloque) ) {
- if ( defined($val) ) {
- $val =~ s/(.*)\s+$/$1/g;
- }
- else {
- $val = "";
- }
- $hash_temporal{$key} = $val;
- }
-
- if ( defined( $hash_temporal{Channel} ) ) {
- if ( $hash_temporal{Channel} =~ /^Agent/ ) {
-
- # If the channel is Agent/XXXX and we have a real channel
- # in memory, duplicate the event using the real channel
- my $uniagentid = "YYYY";
-
- my $canalcompara = $hash_temporal{"Channel"};
- $canalcompara =~ s/Agent\/(.*)/$1/g;
- for $quehay ( keys %agent_to_channel ) {
- my $conque = $quehay;
- $conque =~ s/(\d+)\^(.*)/$2/g;
- if ( $canalcompara eq $conque ) {
- while ( my ( $key, $val ) = each(%hash_temporal) ) {
- if ( $key ne "Channel" ) {
- $fake_bloque[$fakecounter]{$key} = $val;
- }
- }
- $fake_bloque[$fakecounter]{"Channel"} = $agent_to_channel{$quehay} . "-XXXX"; # We dont want to add a sesbot
- $fakecounter++;
- }
- }
- }
- }
-
- if ( $hash_temporal{"Event"} =~ /^UserEvent/ ) {
-
- # This blocks checks if we have an UserEvent
- # and splits every key value pair if it haves
- # a caret as a delimiter
- while ( my ( $key, $val ) = each(%hash_temporal) ) {
- if ( defined($val) && $val =~ /\^/ ) {
- my @partes = split( /\^/, $val, 2 );
- $hash_temporal{$key} = $partes[0];
- my $resto_de_parametros = $partes[1];
- @partes = split( /\^/, $resto_de_parametros );
- foreach my $value (@partes) {
- my @partes2 = split( /: /, $value );
- if ( !defined( $partes2[0] ) ) { next; }
- if ( !defined( $partes2[1] ) ) { $partes2[1] = ""; }
- $hash_temporal{ $partes2[0] } = $partes2[1];
- }
- }
- }
- }
-
- $canalid = "";
- $canalid = $hash_temporal{"Channel"}
- if defined( $hash_temporal{"Channel"} );
-
- $server = 0;
- $server = $hash_temporal{"Server"}
- if defined( $hash_temporal{"Server"} );
-
- if ( defined( $hash_temporal{"Uniqueid"} ) ) {
- $unico_id = $hash_temporal{"Uniqueid"};
- $fill_datos = 1;
- }
- else {
- $unico_id = "YYYY";
- }
-
- $enlazado = "";
- if ( exists( $datos{$unico_id} ) ) {
-
- if ( exists( $datos{$unico_id}{"Link"} ) ) {
- $enlazado = $datos{$unico_id}{"Link"};
- }
-
- if ( exists( $datos{$unico_id}{"Application"} ) ) {
- $enlazado .= " - " . $datos{$unico_id}{"Application"};
- }
-
- if ( exists( $datos{$unico_id}{"AppData"} ) ) {
- $enlazado .= ":" . $datos{$unico_id}{"AppData"};
- }
-
- }
-
- if ( $unico_id !~ /-\d+$/ ) {
-
- # Add the server at the end of the uniqueid
- # if its not already there
- $unico_id .= "-" . $server;
- }
-
- $evento = "";
- if ( defined( $hash_temporal{"Event"} ) ) {
- $evento = $hash_temporal{"Event"};
- }
-
- if ( defined( $hash_temporal{"ActionID"} ) ) {
- if ( $hash_temporal{"ActionID"} =~ /^timeout/i ) {
- my @partes = split( /\|/, $hash_temporal{"ActionID"} );
- $canalid = $partes[1];
- $timeout = $partes[2];
- $evento = "Timeout";
- $unico_id = "YYYY-$server";
- }
- }
-
- log_debug( "$heading canalid $canalid unico_id $unico_id evento $evento enlazado $enlazado", 128 ) if DEBUG;
-
- # Populates a global hash to keep track of
- # 'active' channels, the ones that are not
- # state down.
- if ( defined($unico_id) ) {
- if ( $unico_id !~ /^YYYY/ ) {
-
- if ($fill_datos) { # Ignores blocks without Uniqueid
- log_debug( "$heading LLENANDO el global datos $unico_id", 64 ) if DEBUG;
- delete $datos{$unico_id}{"State"};
- while ( my ( $key, $val ) = each(%hash_temporal) ) {
- if ( $key eq "Uniqueid" ) {
- if ( $val !~ /-/ ) {
- $val .= "-" . $server;
- }
- }
- if ( !defined($val) ) {
- $val = "";
- }
- $datos{$unico_id}{"$key"} = $val;
- log_debug( "$heading POPULATES datos($unico_id){ $key } = $val", 128 ) if DEBUG;
- }
- }
- }
- else {
- log_debug( "$heading NO LLENO el global datos $unico_id", 64 ) if DEBUG;
- }
- }
-
- $evento =~ s/UserEvent//g;
- if ( $evento =~ /Newchannel/ ) { $evento = "newchannel"; }
- elsif ( $evento =~ /Newcallerid/ ) { $evento = "newcallerid"; }
- elsif ( $evento =~ /^Status$/ ) { $evento = "status"; }
- elsif ( $evento =~ /^StatusComplete/ ) { $evento = "statuscomplete"; }
- elsif ( $evento =~ /Newexten/ ) { $evento = "newexten"; }
- elsif ( $evento =~ /^ParkedCall$/ ) { $evento = "parkedcall"; }
- elsif ( $evento =~ /^UnParkedCall$/ ) { $evento = "unparkedcall"; }
- elsif ( $evento =~ /Newstate/ ) { $evento = "newstate"; }
- elsif ( $evento =~ /Hangup/ ) { $evento = "hangup"; }
- elsif ( $evento =~ /Rename/ ) { $evento = "rename"; }
- elsif ( $evento =~ /MessageWaiting/ ) { $evento = "voicemail"; }
- elsif ( $evento =~ /Regstatus/ ) { $evento = "regstatus"; }
- elsif ( $evento =~ /^Unlink/ ) { $evento = "unlink"; }
- elsif ( $evento =~ /QueueParams/ ) { $evento = "queueparams"; }
- elsif ( $evento =~ /QueueEntry/ ) { $evento = "queueentry"; }
- elsif ( $evento =~ /^QueueMember$/ ) { $evento = "queuemember"; }
- elsif ( $evento =~ /^QueueMemberStatus$/ ) { $evento = "queuememberstatus"; }
- elsif ( $evento =~ /QueueMemberAdded/ ) { $evento = "queuememberadded"; }
- elsif ( $evento =~ /QueueMemberRemoved/ ) { $evento = "queuememberremoved"; }
- elsif ( $evento =~ /QueueMemberPaused/ ) { $evento = "queuememberpaused"; }
- elsif ( $evento =~ /QueueStatus$/ ) { $evento = "queuestatus"; }
- elsif ( $evento =~ /QueueStatusComplete/ ) { $evento = "queuestatuscomplete"; }
- elsif ( $evento =~ /^Link/ ) { $evento = "link"; }
- elsif ( $evento =~ /^Join/ ) { $evento = "join"; }
- elsif ( $evento =~ /^MeetmeJoin/ ) { $evento = "meetmejoin"; }
- elsif ( $evento =~ /^MeetmeLeave/ ) { $evento = "meetmeleave"; }
- elsif ( $evento =~ /^meetmemute/ ) { $evento = "meetmemute"; }
- elsif ( $evento =~ /^meetmeunmute/ ) { $evento = "meetmeunmute"; }
- elsif ( $evento =~ /^Agentlogin/ ) { $evento = "agentlogin"; }
- elsif ( $evento =~ /^RefreshQueue/ ) { $evento = "refreshqueue"; }
- elsif ( $evento =~ /^Timeout/ ) { $evento = "timeout"; }
- elsif ( $evento =~ /^AgentCalled/ ) { $evento = "agentcalled"; }
- elsif ( $evento =~ /^AgentConnect/ ) { $evento = "agentconnect"; }
- elsif ( $evento =~ /^AgentComplete/ ) { $evento = "agentcomplete"; }
- elsif ( $evento =~ /^Agentcallbacklogin/ ) { $evento = "agentcblogin"; }
- elsif ( $evento =~ /^Agentcallbacklogoff/ ) { $evento = "agentlogoff"; }
- elsif ( $evento =~ /^Agentlogoff/ ) { $evento = "agentlogoff"; }
- elsif ( $evento =~ /^IsMeetmeMember/ ) { $evento = "fakeismeetmemember"; }
- elsif ( $evento =~ /^PeerStatus/ ) { $evento = "peerstatus"; }
- elsif ( $evento =~ /^Leave/ ) { $evento = "leave"; }
- elsif ( $evento =~ /^FOP_Popup/i ) { $evento = "foppopup"; }
- elsif ( $evento =~ /^FOP_LedColor/i ) { $evento = "fopledcolor"; }
- elsif ( $evento =~ /^Dial/ ) { $evento = "dial"; }
- elsif ( $evento =~ /^ASTDB/ ) { $evento = "astdb"; }
- elsif ( $evento =~ /^DNDState/ ) { $evento = "zapdndstate"; }
- elsif ( $evento =~ /^ZapShowChannels$/ ) { $evento = "zapdndstate"; }
- elsif ( $evento =~ /^ExtensionStatus$/ ) { $evento = "extensionstatus"; }
- else { log_debug( "$heading No event match ($evento)", 32 ); }
-
- if ( defined( $hash_temporal{"Link"} ) ) {
- if ( defined( $hash_temporal{"Seconds"} ) ) {
- my $unid = find_uniqueid( $hash_temporal{"Link"}, $server ) if DEBUG;
- $fake_bloque[$fakecounter]{Event} = "Newexten";
- $fake_bloque[$fakecounter]{Channel} = $hash_temporal{Link};
- $fake_bloque[$fakecounter]{State} = "Up";
- $fake_bloque[$fakecounter]{Seconds} = $hash_temporal{Seconds};
- $fake_bloque[$fakecounter]{CallerID} = $hash_temporal{CallerID};
- $fake_bloque[$fakecounter]{Uniqueid} = $unid;
- $fake_bloque[$fakecounter]{Server} = $hash_temporal{Server};
- $fakecounter++;
- log_debug( "$heading Fake bloque canal $hash_temporal{Link} con seconds $hash_temporal{Seconds}", 128 )
- if DEBUG;
- }
- }
-
- if ( $evento eq "agentcomplete" ) {
-
- # Hook for queue statistics?
- #Event: AgentComplete
- #Privilege: agent,all
- #Queue: soporte
- #Uniqueid: 1130872017.1364
- #Channel: SIP/16-6b1b
- #HoldTime: 17
- #TalkTime: 557
- #Reason: agent
- my ( $canal, $nada ) = separate_session_from_channel( $hash_temporal{Channel} );
- request_queue_status( $socket, $canal );
- }
-
- if ( $evento eq "agentcalled" ) {
-
- # We use this event to send the ringing state for an Agent
- $estado_final = "ringing";
- $canal = $hash_temporal{"AgentCalled"};
- $canal =~ tr/a-z/A-Z/;
- $canalid = $canal . "-XXXX";
- $clidnum = $hash_temporal{"CallerID"};
- $clidname = $hash_temporal{"CallerIDName"};
- $texto = "&incoming,[" . format_clid( $clidnum, $clid_format ) . "]";
- my $base64_clidnum = encode_base64( $clidnum . " " );
- my $base64_clidname = encode_base64( $clidname . " " );
- push @return, "$canal|clidnum|$base64_clidnum|$canalid-$server|$canalid";
- push @return, "$canal|clidname|$base64_clidname|$canalid-$server|$canalid";
- push @return, "$canal|$estado_final|$texto|$canalid-$server|$canalid";
- $evento = "";
- }
-
- if ( $evento eq "agentconnect" ) {
-
- # We use this event to fake the ringing state
- $estado_final = "ocupado";
- $texto = "Taking call from $hash_temporal{\"Queue\"}";
- $canal = $hash_temporal{"Channel"};
- $canal =~ tr/a-z/A-Z/;
- $canalid = $canal . "-XXXX";
- push @return, "$canal|$estado_final|$texto|$canalid-$server|$canalid"; #NEW
- $evento = "";
- }
-
- if ( $evento eq "dial" ) {
-
- # We use this hashes to store the remote callerid for CVS-HEAD
- my $key = "$server^$hash_temporal{'Destination'}";
- my $dorigen = "";
- my $ddestino = "";
- my $dnada = "";
- $remote_callerid{$key} = $hash_temporal{"CallerID"};
- $remote_callerid_name{$key} = $hash_temporal{"CallerIDName"};
-
- # We also look for Dial from Local/XX at context to TECH/XX for
- # matching agentcallbacklogins exten at context to real channels
- # so we can map outgoing calls to Agent buttons
- # It will only work after the agent receives at least one call
- ( $dorigen, $dnada ) = separate_session_from_channel( $hash_temporal{'Source'} );
- ( $ddestino, $dnada ) = separate_session_from_channel( $hash_temporal{'Destination'} );
- if ( exists( $channel_to_agent{"$server^$dorigen"} ) ) {
- my $agente = $channel_to_agent{"$server^$dorigen"};
-
- # delete $channel_to_agent{$dorigen};
- $channel_to_agent{"$server^$ddestino"} = $agente;
- }
- }
-
- if ( $evento eq "zapdndstate" ) {
- $canal = $hash_temporal{"Channel"};
- my $zstatus = "";
- if ( $canal !~ m/Zap/i ) {
- $canal = "Zap/$canal";
- }
- if ( defined( $hash_temporal{Status} ) ) {
- $zstatus = $hash_temporal{Status};
- }
- if ( defined( $hash_temporal{DND} ) ) {
- $zstatus = $hash_temporal{DND};
- }
- if ( $zstatus =~ /disabled/i ) {
- $zstatus = "";
- }
-
- # If we receive a zap dnd state, we fake the ASTDB
- # event with family 'dnd'. So it will execute the
- # actions listed on op_astdb.cfg inside [dnd]
- $fake_bloque[$fakecounter]{Event} = "ASTDB";
- $fake_bloque[$fakecounter]{Channel} = $canal;
- $fake_bloque[$fakecounter]{Family} = "dnd";
- $fake_bloque[$fakecounter]{Server} = $hash_temporal{Server};
- $fake_bloque[$fakecounter]{Value} = $zstatus;
- $fakecounter++;
-
- $evento = "";
- }
-
- if ( $evento eq "astdb" ) {
- my $valor = "";
- $estado_final = "astdb";
- ( $canal, my $nada ) = separate_session_from_channel( $hash_temporal{"Channel"} );
- $canalid = $hash_temporal{"Channel"} . "-XXXX";
- my $clave = $hash_temporal{"Family"};
- if ( !defined( $hash_temporal{"State"} ) ) {
- $valor = "";
- }
- else {
- $valor = $hash_temporal{"State"};
- }
-
- foreach my $item ( @{ $astdbcommands{$clave} } ) {
- my $item_temp = $item;
- $item_temp =~ s/\${value}/$valor/g;
- my ( $comando, $datos ) = split( /=/, $item_temp );
- if ( $valor ne "" ) {
- push @return, "$canal|$comando|$datos|$canalid-$server|$canalid";
- }
- else {
- push @return, "$canal|$comando||$canalid-$server|$canalid";
- }
- }
- $evento = "";
- }
-
- if ( $evento eq "timeout" ) {
- $estado_final = "timeout";
- $texto = $timeout;
- my $ahora = time();
- my $unique = find_uniqueid( $canalid, $server );
- $datos{$unique}{"Timeout"} = $ahora + $timeout;
- $timeouts{$canalid} = $ahora + $timeout;
- push @return, "$canal|$estado_final|$texto|$unique|$canalid"; #NEW
- $evento = "";
- }
-
- if ( $evento eq "regstatus" ) {
-
- # Sends the IP address of the peer to the flash client
- # XXXX It will have to store this value internally in future version
- # to avoid polling asterisk every time
- ( $canal, my $nada ) = separate_session_from_channel( $hash_temporal{"Channel"} );
- $texto = $hash_temporal{"IP"};
- my $serv = $hash_temporal{"Server"};
- if ($show_ip) {
-
- # $estado_final = "ip";
- $estado_final = "settext";
- $boton_ip{$canalid} = $texto;
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
-
- # $evento = "";
- }
- }
-
- if ( $evento eq "fopledcolor" ) {
- my $color = "";
- my $state = "";
- ( $canal, my $nada ) = separate_session_from_channel( $hash_temporal{"Channel"} );
- $color = $hash_temporal{"Color"};
- $state = $hash_temporal{"State"};
- $estado_final = "fopledcolor";
- push @return, "$canal|$estado_final|$color^$state|$unico_id|$canalid";
- $evento = "";
- }
-
- if ( $evento eq "foppopup" ) {
- ( $canal, my $nada ) = separate_session_from_channel( $hash_temporal{"Channel"} );
- my $url = $hash_temporal{"URL"};
- my $target = $hash_temporal{"Target"};
- my $button = $hash_temporal{"Button"};
- if ( !defined($button) ) { $button = ""; }
- my $data = "$url^$target^$button";
- $estado_final = "foppopup";
- push @return, "$canal|$estado_final|$data|$unico_id|$canalid";
- $evento = "";
- }
-
- if ( $evento eq "refreshqueue" ) {
- ( $canal, my $nada ) = separate_session_from_channel( $hash_temporal{"Channel"} );
-
- # Turns off led of the agent that generated the refresh
- if ( $change_led == 1 ) {
- $estado_final = "changelabel" . $change_led;
- push @return, "$canal|$estado_final|original|$unico_id|$canalid";
- }
- request_queue_status( $socket, $hash_temporal{"Channel"} );
- $evento = "";
- }
-
- if ( $evento eq "agentcblogin" ) {
- my $canal = "";
- my $canallocal = "";
- my $labeltext = ".";
- my $texto = $hash_temporal{"Agent"};
-
- if ( $canalid eq "" ) {
- $canalid = "Agent/$texto-XXXX";
- }
-
- if ( defined( $agent_to_channel{"$server^Agent/$texto"} ) ) {
-
- # The agent was already logged in, fake a logout event
-
- if ( $ren_agentlogin == 1 || $ren_cbacklogin == 1 || $change_led == 1 ) {
-
- $canal = $agent_to_channel{"$server^Agent/$texto"};
- $estado_final = "changelabel" . $change_led;
- if ( $canal =~ /^AGENT/i ) {
- push @return, "AGENT/$texto|setalpha|100|$unico_id|$canalid";
- }
- else {
- push @return, "$canal|$estado_final|original|$unico_id|$canalid";
-
- # Change back the label to the old localtion/button
- }
- delete $agent_to_channel{"$server^Agent/$texto"};
- delete $channel_to_agent{"$server^$canal"};
- }
- }
-
- if ( defined( $datos{$unico_id}{"Channel"} ) ) {
-
- # If we have this defined, its a REAL and LIVE event!
- # so we populate some internal structures. If not, its a fake
- # callbacklogin from the show agents cli command
- ( $canal, my $nada ) = separate_session_from_channel( $datos{$unico_id}{Channel} );
- $canal =~ tr/a-z/A-Z/;
- }
- else {
-
- # It is a fake login, probably from a first run (show agents)
- # or a queuemember event. We have the extension at context but not
- # the real channel. In order to monitor OUTBOUND calls, we need
- # to find out the real channel. There is no easy way around this
- # problem. We have to make some assumptions.
-
- my $ext_transf_key = $hash_temporal{"Server"} . "^" . $hash_temporal{"Loginchan"};
-
- if ( defined( $extension_transfer_reverse{$ext_transf_key} ) ) {
-
- # Our first assumption would be to look for a button definition
- # that has the same extension at context and extract the channel name
- # from there. Drawback: there has to be a butotn with the same exten at context
- # in op_buttons.cfg.
- $canal = $extension_transfer_reverse{$ext_transf_key};
- $canal =~ s/(.*)&(.*)/$1/g;
- if ( $canal =~ /\^/ ) {
- my @pedacete = split( /\^/, $canal );
- $canal = $pedacete[1];
- }
- }
- }
-
- # We also add a Local channel just in case. It will be used to match but
- # not to keep track of sessions. We skip the agent_to_channel, we dont
- # mind on local channels as monitoring buttons.
-
- $canallocal = "Local/$hash_temporal{'Loginchan'}";
- $canallocal =~ tr/a-z/A-Z/;
- $channel_to_agent{"$server^$canallocal"} = "Agent/$texto";
-
- if ( $canal ne "" ) {
-
- # So, we find a channel. Lets send the responses and fill the hashes
-
- $channel_to_agent{"$server^$canal"} = "Agent/$texto";
- $agent_to_channel{"$server^Agent/$texto"} = $canal;
-
- print_agents();
-
- $estado_final = "changelabel" . $change_led;
- if ( $ren_cbacklogin == 1 ) {
- $labeltext = "Agent/$texto";
- if ( $ren_agentname == 1 ) {
- if ( defined( $agents_name{"$server^$texto"} ) ) {
- $labeltext = $agents_name{"$server^$texto"};
- }
- }
- push @return, "$canal|$estado_final|$labeltext|$unico_id|$canalid";
- }
- if ( $agent_status == 1 ) {
- push @return, "$canal|isagent|0|$unico_id|$canalid";
- push @return, "$canal|settimer|0\@IDLE|$unico_id|$canalid";
- push @return, "$canal|settext|Idle|$unico_id|$canalid";
- }
- }
-
- # Now send AGENT/ events
- if ( $ren_cbacklogin == 1 ) {
- $labeltext = "Agent/$texto";
- if ( $ren_agentname == 1 ) {
- if ( defined( $agents_name{"$server^$texto"} ) ) {
- $labeltext = $agents_name{"$server^$texto"};
- }
- }
- }
- push @return, "AGENT/$texto|changelabel$change_led|$labeltext|$unico_id|$canalid";
-
- if ( $agent_status == 1 ) {
- push @return, "AGENT/$texto|isagent|0|$unico_id|$canalid";
- }
-
- $evento = "";
- }
-
- if ( $evento eq "queuememberpaused" && $agent_status == 1 ) {
- my $canal = $hash_temporal{Location};
- my $cola = $hash_temporal{Queue};
- my $canalid = $canal . "-XXXX";
-
- # Paused
- # Event: QueueMemberPaused
- # Privilege: agent,all
- # Queue: soporte
- # Location: SIP/17
- # Paused: 1
- # Server: 0
-
- # Unpaused
- # Event: QueueMemberPaused
- # Privilege: agent,all
- # Queue: soporte
- # Location: SIP/17
- # Paused: 0
- # Server: 0
-
- my $color = "";
- if ( $hash_temporal{Paused} eq "1" ) {
- my ( $text, $textriginal, $buttontext ) = translate( $canal, "&paused", "", "" );
- $texto = $text;
- $texto = "&paused";
- $color = "ledcolor_paused";
- }
- else {
- my ( $text, $textriginal, $buttontext ) = translate( $canal, "&idle", "", "" );
- $texto = $text;
- $texto = "&idle";
- $color = "ledcolor_agent";
- }
- $boton_ip{$canalid} = $texto;
- push @return, "$canal|settext|$texto|$unico_id|$canalid";
- push @return, "$canal|settimer|1\@UP|$unico_id|$canalid";
- push @return, "$canal|settimer|0\@IDLE|$unico_id|$canalid";
- push @return, "$canal|fopledcolor|$color^2|$unico_id|$canalid";
- push @return, "$canal|state|free|$unico_id|$canalid";
- $evento = "";
-
- }
-
- if ( $evento eq "queuememberremoved" ) {
- my $cola = $hash_temporal{Queue};
- my $canal = $hash_temporal{Location};
- $fake_bloque[$fakecounter]{Event} = "Agentlogoff";
- $fake_bloque[$fakecounter]{Channel} = $canal . "-XXXX";
- $fake_bloque[$fakecounter]{Agent} = $canal;
- $fake_bloque[$fakecounter]{Queue} = $cola;
- $fake_bloque[$fakecounter]{Fake} = "removed";
- $fake_bloque[$fakecounter]{Server} = $hash_temporal{Server};
- $fakecounter++;
- $evento = "";
- }
-
- if ( $evento eq "queuememberadded" ) {
-
- my $cola = $hash_temporal{Queue};
- my $canal = $hash_temporal{Location};
-
- $fake_bloque[$fakecounter]{Event} = "Agentlogin";
- $fake_bloque[$fakecounter]{Channel} = $canal . "-XXXX";
- $fake_bloque[$fakecounter]{Agent} = $canal;
- $fake_bloque[$fakecounter]{Queue} = $cola;
- $fake_bloque[$fakecounter]{Server} = $hash_temporal{Server};
- $fake_bloque[$fakecounter]{Addhash} = 1;
- $fakecounter++;
-
- $evento = "";
-
- # Add the channel to the agents_on_queue hash
- ( $server, $canal ) = local_channels_are_driving_me_mad( $server, $canal );
- reserve_next_available_agent_button( $server, $canal, $hash_temporal{Queue} );
-
- # Remove cache hit to force find panel buttons to look for new positions
- foreach my $kkey ( keys %cache_hit ) {
- if ( $kkey =~ /^$canal/ ) {
- delete $cache_hit{$kkey};
- }
- }
-
- }
-
- if ( $evento eq "agentlogin" ) {
-
- my $labeltext = ".";
- my $texto = $hash_temporal{"Agent"};
-
- if ( defined( $datos{$unico_id}{Channel} ) ) {
-
- # This catches a live real Agentlogin event
- ( my $canalreal, my $nada ) = separate_session_from_channel( $datos{$unico_id}{Channel} );
- $canalreal =~ tr/a-z/A-Z/;
- $channel_to_agent{"$server^$canalreal"} = "Agent/$texto";
- $agent_to_channel{"$server^Agent/$texto"} = $canalreal;
- log_debug( "channel_to_agent($server^$canalreal) = " . $channel_to_agent{"$server^$canalreal"}, 64 ) if DEBUG;
- }
-
- ( $canal, my $sess ) = separate_session_from_channel( $hash_temporal{Channel} );
- $estado_final = "changelabel" . $change_led;
-
- if ( $sess ne "XXXX" ) {
-
- # If we have a real session, its an agentlogin on op_server startup (from show agents)
- $channel_to_agent{"$server^$canal"} = "Agent/$texto";
- $agent_to_channel{"$server^Agent/$texto"} = $canal;
- }
-
- if ( defined( $agent_label{$canal} ) && ( $ren_agentlogin == 1 || $ren_cbacklogin == 1 ) ) {
- $labeltext = $agent_label{$canal};
- }
-
- if ( $canalid eq "" ) {
- $canalid = "AGENT/$texto-XXXX";
- }
-
- if ( $ren_agentlogin == 1 && !defined( $hash_temporal{'Fake'} ) ) {
- if ( $texto !~ /\// ) {
- $labeltext = "Agent/$texto";
- }
- else {
- $labeltext = $texto;
- }
- if ( $ren_agentname == 1 ) {
- if ( defined( $agents_name{"$server^$texto"} ) ) {
- $labeltext = $agents_name{"$server^$texto"};
- }
- }
- }
-
- if ( $ren_queuemember == 1 ) {
- if ( $texto !~ /\// ) {
- $labeltext = "Agent/$texto";
- }
- else {
- $labeltext = $texto;
- }
- if ( $ren_agentname == 1 ) {
- if ( defined( $agents_name{"$server^$texto"} ) ) {
- $labeltext = $agents_name{"$server^$texto"};
- }
- }
- }
-
- if ( $labeltext eq "original" ) {
- $labeltext = ".";
- }
-
- if ( $canal =~ m/^AGENT/i ) {
- push @return, "$canal-FOPdummy|setalpha|100|$unico_id|$canalid";
-
- my $agent_num = $texto;
- $agent_num =~ s/^Agent\///gi;
- if ( $ren_agentname == 1 ) {
- if ( defined( $agents_name{"$server^$agent_num"} ) ) {
- $labeltext = $agents_name{"$server^$agent_num"};
- }
- else {
- $labeltext = $texto;
- }
- }
- else {
-
- # If its an Agent channel, and rename to agent name is not
- # set, rename it anyways to Agent/XXXX
- $labeltext = "Agent/$agent_num";
- }
-
- # push @return, "$canal-FOPdummy|setlabel|$labeltext|$unico_id|$canalid";
-
- }
- else {
- push @return, "$canal|$estado_final|$labeltext|$unico_id|$canalid";
- push @return, "$canal|corto||$unico_id|$canalid";
- }
-
- if ( $agent_status == 1 ) {
- my $textopaused = "&idle";
- if ( defined( $hash_temporal{Paused} ) ) {
- $textopaused = $hash_temporal{Paused};
- }
- if ( defined( $hash_temporal{LastCall} ) ) {
- if ( $hash_temporal{LastCall} > 0 ) {
-
- # Max_lastcall saves the maximum epoch time, so I can
- # show only the lowest lastcall time if an agent is member
- # or more than one queue
- if ( !defined( $max_lastcall{$canal} ) ) {
- $max_lastcall{$canal} = $hash_temporal{LastCall};
- }
- if ( $hash_temporal{LastCall} > $max_lastcall{$canal} ) {
- $max_lastcall{$canal} = $hash_temporal{LastCall} + 0;
- }
- }
- }
- push @return, "$canal|isagent|0|$unico_id|$canalid";
- push @return, "$canal|settext|$textopaused|$unico_id|$canalid";
- }
-
- $evento = "";
-
- $is_agent{ uc("$server^$texto") } = 1;
-
- if ( defined( $hash_temporal{Queue} ) ) {
- if ( keys(%count_queue) ) {
- my $contaconta = 0;
- my %temp_queue = ();
- my $valor = "$server^$hash_temporal{Queue}";
-
- push @{ $count_queue{$valor} }, "$server^$texto";
-
- my %count;
- my @unique_queues = grep { ++$count{$_} < 2 } @{ $count_queue{$valor} };
- @{ $count_queue{$valor} } = @unique_queues;
-
- if ( exists( $count_queue{$valor} ) && $count_queue{$valor} ne "" ) {
- my $texto3 = "";
- foreach my $qmem ( @{ $count_queue{$valor} } ) {
- $texto3 .= "$qmem\n";
- }
- $contaconta = @{ $count_queue{$valor} };
- my $texto2 = "Agents Logged: $contaconta\n" . $texto3 . " ";
- $texto2 = encode_base64($texto2);
- push @return, "QUEUE/" . uc( $hash_temporal{Queue} ) . "|infoqstat2|$texto2|$unico_id|$canalid";
- print_countqueue("final de agentlogin tenia queue");
- }
- }
- }
- }
-
- if ( $evento eq "agentlogoff" ) {
-
- $canal = "Agent/" . $hash_temporal{Agent};
- if ( $hash_temporal{Agent} !~ /^Agent/ ) {
- $canal = $hash_temporal{Agent};
- }
-
- my $texto = $hash_temporal{Agent};
- $canalid = $canal . "-XXXX";
-
- if ( $ren_agentlogin == 1 || $ren_cbacklogin == 1 || $change_led == 1 ) {
- $estado_final = "changelabel" . $change_led;
-
- if ( defined( $agent_to_channel{"$server^Agent/$canal"} ) || defined( $channel_to_agent{"$server^$canal"} ) ) {
- if ( defined( $agent_to_channel{"$server^Agent/$canal"} ) ) {
-
- # ( $canal, my $nada ) = separate_session_from_channel( $agent_to_channel{"$server^Agent/$canal"} );
- $canal = $agent_to_channel{"$server^Agent/$canal"};
- }
- else {
-
- # ( $canal, my $nada ) = separate_session_from_channel( $channel_to_agent{"$server^$canal"} );
- $canal = $channel_to_agent{"$server^$canal"};
- }
-
- if ( defined( $agent_label{$canal} ) ) {
- delete $agent_label{$canal};
- }
-
- if ( $canalid eq "" ) {
- $canalid = "AGENT/$texto-XXXX";
- }
-
- #delete $agent_to_channel{"$server^$canal"};
- #delete $agent_to_channel{"$server^$agente"};
- delete $reverse_agents{$texto};
- delete $reverse_agents{$canal};
-
- push @return, "$canal|$estado_final|original|$unico_id|$canalid";
- push @return, "$canal|agentlogoff|original|$unico_id|$canalid";
- }
- else {
- log_debug( "No esta definido agente $server^$canal", 32 ) if DEBUG;
- push @return, "$canal|$estado_final|original|$unico_id|$canalid";
- push @return, "$canal|agentlogoff|original|$unico_id|$canalid";
- }
-
- # if ( defined( $hash_temporal{Fake} ) ) {
-
- # We dont want queueagent buttons to be renamed back to the orignal label
- # push @return, "AGENT/$texto|$estado_final|original|$unico_id|$canalid";
- # }
-
- if ( $agent_status == 1 ) {
- push @return, "$canal|isagent|-1|$unico_id|$canalid" if ( $canal ne "" );
- push @return, "AGENT/$texto|isagent|-1|$unico_id|$canalid";
- }
-
- # Its form a removequeuemember, we have to mantain the agents_on_queue hash
- # after finding buttons in digest_event_block, so the led and label go back
- # to normal. If we do it here, we will always have the AGENTQUEUE button marked
- # as an agent even if its removed
- if ( defined( $hash_temporal{Fake} ) && $canal ne "" ) {
- if ( $hash_temporal{Fake} eq "removed" ) {
- push @return, "$canal|queueremoved|$hash_temporal{Queue}|$unico_id|$canalid";
- }
- }
-
- $evento = "";
- }
-
- delete( $is_agent{ uc("$server^$texto") } );
-
- if ( keys(%count_queue) ) {
- print_countqueue("agentlogoff principio count_queue");
- my $contaconta = 0;
- my %temp_queue = ();
- my $valor = "";
- foreach $valor ( sort ( keys(%count_queue) ) ) {
- foreach my $vvalor ( @{ $count_queue{$valor} } ) {
- if ( $vvalor !~ /^$server\^$canal$/i && $vvalor !~ /^$server\^AGENT\/$texto$/i ) {
- push @{ $temp_queue{$valor} }, $vvalor;
- }
- my %count;
- my @unique_queues = grep { ++$count{$_} < 2 } @{ $temp_queue{$valor} };
- @{ $temp_queue{$valor} } = @unique_queues;
- }
- }
- %count_queue = %temp_queue;
- if ( defined( $hash_temporal{Queue} ) ) {
- $valor = $hash_temporal{Queue};
- if ( exists( $count_queue{"$server^$valor"} ) && $count_queue{"$server^$valor"} ne "" ) {
- my $texto3 = "";
- foreach my $qmem ( @{ $count_queue{"$server^$valor"} } ) {
- $texto3 .= "$qmem\n";
- }
- $contaconta = @{ $count_queue{"$server^$valor"} };
- my $texto2 = "Agents Logged: $contaconta\n" . $texto3 . " ";
- $texto2 = encode_base64($texto2);
- push @return, "QUEUE/" . uc( $hash_temporal{Queue} ) . "|infoqstat2|$texto2|$unico_id|$canalid";
- print_countqueue("al final");
- }
- }
- }
-
- }
-
- if ( $evento eq "queueentry" ) {
-
- if ( defined( $max_queue_waiting_time_for{"$hash_temporal{Queue}-$hash_temporal{Server}"} ) ) {
- if ( $hash_temporal{Wait} > $max_queue_waiting_time_for{"$hash_temporal{Queue}-$hash_temporal{Server}"} ) {
- $max_queue_waiting_time_for{"$hash_temporal{Queue}-$hash_temporal{Server}"} = $hash_temporal{Wait};
- }
- }
- else {
- $max_queue_waiting_time_for{"$hash_temporal{Queue}-$hash_temporal{Server}"} = $hash_temporal{Wait};
- }
- foreach my $keyh ( keys(%hash_temporal) ) {
- if ( $keyh eq "Event" ) {
- $fake_bloque[$fakecounter]{$keyh} = "Join";
- }
- elsif ( $keyh eq "Position" ) {
- $fake_bloque[$fakecounter]{Count} = $hash_temporal{$keyh};
- $fake_bloque[$fakecounter]{Position} = $hash_temporal{$keyh};
- }
- else {
- $fake_bloque[$fakecounter]{$keyh} = $hash_temporal{$keyh};
- }
- }
- $fakecounter++;
- }
-
- if ( $evento eq "queuestatuscomplete" ) {
- for my $cola_server ( keys %max_queue_waiting_time_for ) {
- my ( $cola, $server ) = ( $cola_server =~ m/(.*)-(.*)/ );
- push @return, "QUEUE/$cola|settimer|" . $max_queue_waiting_time_for{"$cola-$server"} . "|$cola-$server|QUEUE/$cola-XXXX";
- }
-
- # Sends the lowest lastcall time of all possible queues
- for my $canala ( keys %max_lastcall ) {
- my $idleseconds = time() - $max_lastcall{$canala};
- push @return, "$canala|settimer|$idleseconds\@IDLE|$unico_id|$canala-XXXX";
- }
- $evento = "";
- }
-
- if ( $evento eq "queuemember" || $evento eq "queuememberstatus" ) {
-
- my $canalag = $hash_temporal{"Location"};
- $canalag =~ tr/a-z/A-Z/;
- my $canalagid = $canalag . "-XXXX";
- my $unicoag_id = "$canalag-$server";
- $canal = $hash_temporal{"Location"};
-
- ( $server, $canal ) = local_channels_are_driving_me_mad( $server, $canal );
-
- if ( $canal =~ /^AGENT/i ) {
- my $temp = $canal;
- $temp =~ s/^AGENT\///gi;
-
- if ( defined( $hash_temporal{Status} ) && $evento eq "queuemember" ) {
- if ( $hash_temporal{Status} == 5 ) {
-
- # If its logged off, fake the event, but only for queuemember
- $fake_bloque[$fakecounter]{Event} = "Agentlogoff";
- $fake_bloque[$fakecounter]{Agent} = $temp;
- $fake_bloque[$fakecounter]{Server} = $server;
- $fake_bloque[$fakecounter]{Fake} = "1";
- $fakecounter++;
-
- push @return, "$canalag|changelabel$change_led|original|$unicoag_id|$canal-XXXX";
- }
- else {
-
- # Generates Fake Agent Login to change led color and label renaming
- $fake_bloque[$fakecounter]{Event} = "Agentlogin";
- $fake_bloque[$fakecounter]{Channel} = $canal . "-XXXX";
- $fake_bloque[$fakecounter]{Agent} = $canal;
- $fake_bloque[$fakecounter]{Fake} = "1";
- $fake_bloque[$fakecounter]{Server} = $server;
- $fakecounter++;
-
- # push @return, "$canalag|changelabel$change_led|.|$unicoag_id|$canal-XXXX";
- }
- }
- }
-
- if ( $evento eq "queuemember" ) {
-
- # We only want to reserve positions on queuemember (initial query status) and
- # to AGENT channels
- reserve_next_available_agent_button( $server, $canal, $hash_temporal{Queue} );
- $is_agent{ uc("$server^$canalag") } = 1;
-
- #if ( $agent_status == 1 ) {
- # if ( $hash_temporal{Paused} eq "1" ) {
- # push @return, "$canal|settext|&paused|$unico_id|$canalid";
- # push @return, "$canal|settimer|0\@IDLE|$unico_id|$canalid";
- # }
- # else {
- # push @return, "$canal|settext|&idle|$unico_id|$canalid";
- # push @return, "$canal|settimer|0\@IDLE|$unico_id|$canalid";
- # }
- #}
-
- }
- if ( $canal !~ /^Local/ ) {
- $canal =~ tr/a-z/A-Z/;
- }
- $estado_final = "info";
- $texto = "";
-
- my $contaconta = 0;
- my $vval = $hash_temporal{Queue};
- my $has_status_ast_12 = 0;
-
- while ( ( $key, $val ) = each(%hash_temporal) ) {
- if ( !defined($val) ) { $val = " "; }
- $texto .= "$key = $val\n";
- if ( $key eq "Status" && $val != 5 ) {
- $estado_final .= $vval;
- push @{ $count_queue{"$server^$vval"} }, "$server^$canal";
- $has_status_ast_12 = 1;
- }
- }
- if ( $has_status_ast_12 == 0 ) {
-
- # If there is no status on the events, is asterisk stable, count the agent in
- $estado_final .= $vval;
- push @{ $count_queue{"$server^$vval"} }, "$server^$canal";
- }
- my %count;
- my @unique_queues = grep { ++$count{$_} < 2 } @{ $count_queue{"$server^$vval"} };
- @{ $count_queue{"$server^$vval"} } = @unique_queues;
- $contaconta = @{ $count_queue{"$server^$vval"} };
-
- my $texto3 = "";
- foreach my $qmem ( @{ $count_queue{"$server^$vval"} } ) {
- $texto3 .= "$qmem\n";
- }
- $unico_id = "$canal-$server";
- my $texto2 = "Agents Logged: $contaconta\n" . $texto3 . " ";
- $texto .= " ";
- $texto = encode_base64($texto);
- print_countqueue("en queuemember");
- $texto2 = encode_base64($texto2);
- $canalid = $canal . "-XXXX";
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
-
- if ( $canal !~ /$canalag/i ) {
- push @return, "$canalag|$estado_final|$texto|$unicoag_id|$canalagid";
- }
- push @return, "QUEUE/" . uc( $hash_temporal{Queue} ) . "|infoqstat2|$texto2|$unico_id|$canalid";
-
- if ( $canal !~ /^Local/i && $canal !~ /^Agent/i && $evento eq "queuemember" ) {
-
- #if (!exists($is_agent{"$server^$canal"})) {
- # If we have a queuemember event and is not recorded as agent, fake login
- my $pausetext = "";
- if ( $hash_temporal{Paused} eq "1" ) {
- $pausetext = "&paused";
- }
- else {
- $pausetext = "&idle";
- }
-
- # Generates Fake Agent Login to change led color and label renaming
- $fake_bloque[$fakecounter]{Event} = "Agentlogin";
- $fake_bloque[$fakecounter]{Channel} = $canal . "-XXXX";
- $fake_bloque[$fakecounter]{Agent} = $canal;
- $fake_bloque[$fakecounter]{Fake} = "1";
- $fake_bloque[$fakecounter]{Server} = $server;
-
- # we sent the folowing two headers (paused,lastcall) to the fake agentlogin
- $fake_bloque[$fakecounter]{Paused} = $pausetext;
- $fake_bloque[$fakecounter]{LastCall} = $hash_temporal{LastCall};
- $fakecounter++;
- }
-
- #}
- $evento = "";
- }
-
- if ( $evento eq "queuestatus" ) {
- $canal = $hash_temporal{Queue};
- $canalid = $canal . "-XXXX";
- print_countqueue("en queuestatus");
- $canal =~ tr/a-z/A-Z/;
- $canal = "QUEUE/$canal";
- $estado_final = "infoqstat";
- $texto = "";
- while ( ( $key, $val ) = each(%hash_temporal) ) {
- $texto .= "$key = $val\n";
- }
- $unico_id = "$canal-$server";
- $texto .= " ";
- $texto = encode_base64($texto);
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
- $evento = "";
- }
-
- if ( $evento eq "meetmemute" || $evento eq "meetmeunmute" ) {
- my ( $canal, $nada ) = separate_session_from_channel($canalid);
- $estado_final = $evento;
- push @return, "$canal|$evento||$unico_id|$canalid";
- $evento = "";
- }
-
- if ( $evento eq "queueparams" ) {
- $canal = $hash_temporal{Queue};
- $canal =~ tr/a-z/A-Z/;
- $estado_final = "ocupado";
- my $plural = "";
- if ( $hash_temporal{Calls} > 0 ) {
- if ( $hash_temporal{Calls} > 1 ) { $plural = "s"; }
- $texto = "&waitingonqueue," . $hash_temporal{Calls} . ",$plural&";
- $unico_id = "$canal-$server";
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
- }
- else {
-
- # If the queue has no users waiting, delete the hash element
- delete $max_queue_waiting_time_for{"$hash_temporal{Queue}-$hash_temporal{Server}"};
- }
-
- # Generates a Fake Block/Event for sending info status to queues
- while ( ( $key, $val ) = each(%hash_temporal) ) {
- $fake_bloque[$fakecounter]{$key} = $val;
- }
- $fake_bloque[$fakecounter]{Event} = "QueueStatus";
- $fakecounter++;
- $evento = "";
- }
-
- if ( $evento eq "join" ) {
- my $qclidnum = "";
- my $qclidname = "";
- $canal = "QUEUE/" . $hash_temporal{Queue};
- my $position = $hash_temporal{Position};
- $canal =~ tr/a-z/A-Z/;
- $estado_final = "ocupado1";
- my $plural = "";
- if ( $hash_temporal{Count} > 1 ) { $plural = "s"; }
- $texto = "&waitingonqueue," . $hash_temporal{Count} . ",$plural&";
- $unico_id = "$canal-$server";
-
- if ( defined( $hash_temporal{CallerIDName} ) ) {
- $qclidnum = $hash_temporal{CallerID};
- $qclidname = $hash_temporal{CallerIDName};
- }
- elsif ( defined( $hash_temporal{CalleridName} ) ) {
- $qclidnum = $hash_temporal{Callerid};
- $qclidname = $hash_temporal{CalleridName};
- }
- else {
- ( $qclidnum, $qclidname ) = split_callerid( $hash_temporal{CallerID} );
- }
- my $texto_pos = "[$qclidname $qclidnum]";
-
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
- push @return, "$canal=$position|$estado_final|$texto_pos|$unico_id|$canalid";
- push @return, "$canal=$position|setalpha|100|$unico_id|$canalid";
- $evento = "";
-
- my $tiempo = time();
- if ( defined( $hash_temporal{Wait} ) ) {
- $tiempo = $tiempo - $hash_temporal{Wait};
- push @return, "$canal=$position|settimer|$hash_temporal{Wait}\@UP|$unico_id|$canalid";
- }
- $cola->{$canalid}{POSITION} = $position;
- $cola->{$canalid}{QUEUE} = $canal;
- $cola->{$canalid}{CLID} = $qclidnum;
- $cola->{$canalid}{CLIDNAME} = $qclidname;
- $cola->{$canalid}{SERVER} = $server;
- $cola->{$canalid}{TIME} = $tiempo;
-
- }
-
- if ( $evento eq "meetmejoin" ) {
- my $originate = "no";
- my $nada = "";
- my $contexto = "";
-
- if ( $hash_temporal{Channel} =~ /^Local/ ) {
-
- # We have to ignore Local channels when counting users
- $hash_temporal{Fake} = 1;
- }
-
- $canal = $hash_temporal{Meetme};
- my $uni_id = $hash_temporal{Uniqueid} . "-" . $server;
- log_debug( "$heading MEETMEJOIN uni_id = $uni_id y canal = $canal", 128 ) if DEBUG;
- $datos{$uni_id}{Extension} = $canal;
- log_debug( "$heading 2 BORRO datos $uni_id { link }", 128 ) if DEBUG;
- delete $datos{$uni_id}{Link};
-
- $canal =~ tr/a-z/A-Z/;
-
- for $quehay ( keys %auto_conference ) {
-
- if ( $quehay eq $hash_temporal{Channel} ) {
- $originate = $auto_conference{"$quehay"};
- $contexto = $barge_context{$canal};
- }
- }
-
- if ( $originate ne "no" ) {
- log_debug( "$heading origino a meetme en el contexto $contexto!", 128 ) if DEBUG;
- my $comando = "Action: Originate\r\n";
- $comando .= "Channel: $originate\r\n";
- $comando .= "Exten: $canal\r\n";
- $comando .= "Context: " . $config->{$contexto}{'conference_context'} . "\r\n";
- $comando .= "Priority: 1\r\n";
- $comando .= "\r\n";
- send_command_to_manager( $comando, $socket, 0, $astmanproxy_server );
-
- if ($barge_muted) {
- $start_muted{"$server^$originate"} = 1;
- }
- }
-
- $estado_final = "ocupado9"; # 9 for conference
- my $plural = "";
-
- if ( !defined( $hash_temporal{Fake} ) ) {
- if ( !defined( $datos{"$canal-$server"}{Count} ) ) {
- $datos{"$canal-$server"}{Count} = 0;
- log_debug( "$heading POPULATES datos($canal-$server){ count } = 0", 64 ) if DEBUG;
- }
- if ( exists( $meetme_pos{"$server^$canal"}{ $hash_temporal{Usernum} } ) ) {
-
- # Already logged in, buggy channed driver! (SCCP?)
- log_debug( "$heading ignoring already joined channel", 16 );
- }
- else {
- $datos{"$canal-$server"}{Count}++;
- }
- log_debug( "$heading pongo DATOS ($canal-$server) {count} en $datos{\"$canal-$server\"}{Count}", 16 )
- if DEBUG;
- }
-
- # Its a fake meetmejoin generated from the meetme status at startup
- my ( $canalsinses, $pedses ) = separate_session_from_channel( $hash_temporal{Channel} );
- push @return, "$hash_temporal{Meetme}|setlink|$hash_temporal{Channel}|YYYY-$server|$hash_temporal{Channel}";
- push @return, "$canalsinses|setlink|$hash_temporal{Meetme}|$hash_temporal{Meetme}-$server|$hash_temporal{Channel}";
- push @return, "$canalsinses|meetmeuser|$hash_temporal{Usernum},$hash_temporal{Meetme}|YYYY-$server|$hash_temporal{Channel}";
-
- if ( defined( $hash_temporal{Total} ) ) {
- $datos{"$canal-$server"}{Count} = $hash_temporal{Total};
- log_debug( "$heading pongo DATOS de ($canal-$server) {count} en $hash_temporal{Total}", 64 ) if DEBUG;
- }
-
- $barge_rooms{"$canal"} = $datos{"$canal-$server"}{"Count"};
-
- if ( defined( $datos{"$canal-$server"}{"Count"} ) ) {
- if ( $datos{"$canal-$server"}{"Count"} > 1 ) { $plural = "s"; }
- $texto = "&memberonconference," . $datos{"$canal-$server"}{"Count"} . ",$plural&";
- }
-
- if ( exists( $start_muted{"$server^$canalsinses"} ) ) {
- my $boton_con_contexto = $buttons{"$server^$canalsinses"};
- my $comando = "Action: Command\r\n";
- $comando .= "ActionID: meetmemute$boton_con_contexto\r\n";
- $comando .= "Command: meetme mute $hash_temporal{Meetme} $hash_temporal{Usernum}\r\n\r\n";
- send_command_to_manager( $comando, $socket, 0, $astmanproxy_server );
- delete $start_muted{"$server^$canalsinses"};
- }
-
- $unico_id = $canal . "-" . $server;
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
- $evento = "";
-
- # From here we send MEETME=POS button responses
- my $position = $hash_temporal{Usernum};
- my $realunique = "";
- if ( $hash_temporal{Uniqueid} =~ m/(.*)-\d+/ ) {
- $realunique = $hash_temporal{Uniqueid};
- }
- else {
- $realunique = $hash_temporal{Uniqueid} . "-" . $server;
- }
- my $qclidnum = "";
- my $qclidname = "";
- if ( defined( $datos{$realunique}{CallerIDName} ) ) {
- $qclidname = $datos{$realunique}{CallerIDName};
- $qclidnum = $datos{$realunique}{CallerID};
- }
- elsif ( defined( $datos{$realunique}{CalleridName} ) ) {
- $qclidname = $datos{$realunique}{CalleridName};
- $qclidnum = $datos{$realunique}{Callerid};
- }
- else {
- print_datos(99);
- ( $qclidnum, $qclidname ) = split_callerid( $datos{$realunique}{CallerID} );
- }
- my $texto_pos = "[$qclidnum]";
- if ( $qclidnum ne $qclidname ) {
- $texto_pos = "[$qclidname $qclidnum]";
- }
- my $canalfin = get_meetme_pos( $server, $canal, $position );
- push @return, "$canalfin|$estado_final|$texto_pos|YYYY-$server|$hash_temporal{Channel}";
- push @return, "$canalfin|meetmeuser|$hash_temporal{Usernum},$hash_temporal{Meetme}|YYYY-$server|$hash_temporal{Channel}";
- }
-
- if ( $evento eq "meetmeleave" ) {
- $canal = $hash_temporal{Meetme};
- $canal =~ tr/a-z/A-Z/;
- $estado_final = "ocupado9"; # 9 for meetme
- my $plural = "";
- $datos{"$canal-$server"}{"Count"}--;
- log_debug( "$heading pongo DATOS ( $canal-$server) (count) en $datos{\"$canal-$server\"}{'Count'} leave", 64 )
- if DEBUG;
- $barge_rooms{$canal} = $datos{"$canal-$server"}{Count};
- if ( $datos{"$canal-$server"}{Count} > 1 ) { $plural = "s"; }
- if ( $datos{"$canal-$server"}{Count} <= 0 ) { $estado_final = "corto"; }
- $texto = "&memberonconference," . $datos{"$canal-$server"}{Count} . ",$plural&";
- $unico_id = $canal . "-" . $server;
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
- my $canaleja = $hash_temporal{Channel};
- delete $auto_conference{$canaleja};
- log_debug( "$heading Erasing auto_conference $canaleja", 64 ) if DEBUG;
-
- for $quehay ( keys %auto_conference ) {
- log_debug( "$heading Remaining conferences: $quehay", 64 ) if DEBUG;
- }
-
- my ( $canal1, $nada1 ) = separate_session_from_channel($canaleja);
- push @return, "$canal1|unsetlink|$canal|$unico_id|$canalid";
- $evento = "";
-
- my $canalfin = get_meetme_pos( $server, $canal, $hash_temporal{Usernum} );
- delete $meetme_pos{"$server^$canal"}{ $hash_temporal{Usernum} };
- push @return, "$canalfin|corto||$hash_temporal{Uniqueid}-$server|$canaleja";
- }
-
- if ( $evento eq "leave" ) {
- $canal = "QUEUE/" . $hash_temporal{"Queue"};
- $canal =~ tr/a-z/A-Z/;
- $estado_final = "ocupado";
- my $plural = "";
- if ( $hash_temporal{"Count"} > 1 ) { $plural = "s"; }
- if ( $hash_temporal{"Count"} == 0 ) { $estado_final = "corto"; }
- $texto = "&waitingonqueue," . $hash_temporal{"Count"} . ",$plural&";
- $unico_id = "$canal-$server";
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
- $evento = "";
-
- print_sesbot(1);
- my @queue_events = recompute_queues($canalid);
- foreach my $valor (@queue_events) {
- push @return, $valor;
- }
- print_sesbot(2);
- }
-
- if ( $evento eq "voicemail" ) {
- my @canalesvoicemail = ();
-
- while ( my ( $ecanal, $eextension ) = each(%mailbox) ) {
- if ( $eextension eq $hash_temporal{"Mailbox"} ) {
- $canal = $ecanal;
- $canal =~ s/(.*)\&(.*)/$1/g; # Remove &context
- $canal =~ s/(.*)\^(.*)/$2/g; # Remove Server
- push @canalesvoicemail, $canal;
- }
- }
- foreach my $canal (@canalesvoicemail) {
- $unico_id = $canal;
- $canalid = $canal . "-XXXX";
- if ( defined( $hash_temporal{"Waiting"} ) ) {
- $estado_final = "voicemail";
- $texto = $hash_temporal{"Waiting"};
-
- #$texto = 1;
- if ( $texto eq "1" ) {
-
- # If it has new voicemail, ask for mailboxcount
- send_command_to_manager( "Action: MailboxCount\r\nMailbox: $hash_temporal{Mailbox}\r\n\r\n",
- $socket, 0, $astmanproxy_server );
- }
- }
- else {
- $estado_final = "voicemailcount";
- my $nuevos = $hash_temporal{"NewMessages"};
- my $viejos = $hash_temporal{"OldMessages"};
- $texto = "&newold,$nuevos,$viejos";
- $canalid = $canal . "-XXXX";
- }
- push @return, "$canal|$estado_final|$texto|$unico_id-$server|$canalid";
- }
- $evento = "";
- }
-
- if ( $evento eq "link" ) {
- my $uniqueid1 = $hash_temporal{"Uniqueid1"};
- my $uniqueid2 = $hash_temporal{"Uniqueid2"};
- if ( $uniqueid1 !~ /-\d+$/ ) {
- $uniqueid1 .= "-" . $server;
- }
- if ( $uniqueid2 !~ /-\d+$/ ) {
- $uniqueid2 .= "-" . $server;
- }
- my $channel1 = $hash_temporal{"Channel1"};
- my $channel2 = $hash_temporal{"Channel2"};
-
- log_debug( "$heading DATOS de $uniqueid1 { link } en $channel2", 64 ) if DEBUG;
- log_debug( "$heading DATOS de $uniqueid2 { link } en $channel1", 64 ) if DEBUG;
- $datos{$uniqueid1}{"Link"} = $channel2;
- $datos{$uniqueid2}{"Link"} = $channel1;
- my ( $canal1, $sesion1 ) = separate_session_from_channel($channel1);
- my ( $canal2, $sesion2 ) = separate_session_from_channel($channel2);
-
- my $channel1conses = $channel1;
- if ( $channel1 !~ /${sesion1}$/ ) {
- $channel1conses = "$canal1-$sesion1";
- }
-
- my $channel2conses = $channel2;
- if ( $channel2 !~ /${sesion2}$/ ) {
- my $channel2conses = "$canal2-$sesion2";
- }
-
- # push @return, "$canal1|link|$canal2|$uniqueid2|${canal1}-XXXX";
- # delete $datos{$unico_id};
- # print "3 BORRO datos $unico_id \n";
- $evento = "";
- $canal = $canal1;
- $estado_final = "ocupado7"; # 7 for linked channel, start billing
-
- if ( exists( $parked{"$server^$channel1"} ) ) {
- log_debug( "$heading EXISTE parked{$server^$channel1} ", 128 ) if DEBUG;
- my $parkexten = $parked{"$server^$channel1"};
- delete $parked{"$server^$channel1"};
- push @return, "PARK/$parkexten|corto||YYYY-$server|$channel1conses";
- push @return, "$canal1|ocupado5||$uniqueid1|$channel1conses";
- }
- else {
- log_debug( "$heading NO EXISTE parked{$server^$channel1}", 128 ) if DEBUG;
- }
-
- if ( exists( $parked{"$server^$channel2"} ) ) {
- log_debug( "$heading EXISTE parked{$server^$channel2} ", 128 ) if DEBUG;
- log_debug( "$heading SI EXISTE!", 128 ) if DEBUG;
- my $parkexten = $parked{"$server^$channel2"};
- delete $parked{"$server^$channel2"};
- push @return, "PARK/$parkexten|corto||YYYY-$server|$channel2conses";
- push @return, "$canal2|ocupado5||$uniqueid2|$channel2conses";
- }
- else {
- log_debug( "$heading NO EXISTE parked{$server^$channel2}", 128 ) if DEBUG;
- }
- my $clid1 = "";
- my $clid2 = "";
-
- if ( defined( $datos{$uniqueid2}{"Callerid"} ) ) {
- $clid1 = $datos{$uniqueid2}{"Callerid"};
- }
- if ( defined( $datos{$uniqueid2}{"CallerID"} ) ) {
- $clid1 = $datos{$uniqueid2}{"CallerID"};
- }
- if ( defined( $datos{$uniqueid1}{"Callerid"} ) ) {
- $clid2 = $datos{$uniqueid1}{"Callerid"};
- }
- if ( defined( $datos{$uniqueid1}{"CallerID"} ) ) {
- $clid2 = $datos{$uniqueid1}{"CallerID"};
- }
- if ( $clid1 ne "" && $channel2 ne "" ) {
- my $clid_with_format = format_clid( $clid1, $clid_format );
- push @return, "$canal1|settext|[$clid_with_format]|$uniqueid1|$channel1conses";
- }
- if ( $clid2 ne "" && $channel1 ne "" ) {
- my $clid_with_format = format_clid( $clid2, $clid_format );
- push @return, "$canal2|settext|[$clid_with_format]|$uniqueid2|$channel2conses";
- }
- push @return, "$canal1|setlink|$channel2|$uniqueid1|$channel1conses";
- push @return, "$canal2|setlink|$channel1|$uniqueid2|$channel2conses";
- $evento = ""; #NEW
- }
-
- if ( $evento eq "unlink" ) {
- my $uniqueid1 = $hash_temporal{Uniqueid1};
- my $uniqueid2 = $hash_temporal{Uniqueid2};
- my $channel1 = $hash_temporal{Channel1};
- my $channel2 = $hash_temporal{Channel2};
- my ( $canal1, $sesion1 ) = separate_session_from_channel($channel1);
- my ( $canal2, $sesion2 ) = separate_session_from_channel($channel2);
-
- my $channel1conses = $channel1;
- if ( $channel1 !~ /${sesion1}$/ ) {
- my $channel1conses = "$canal1-$sesion1";
- }
-
- my $channel2conses = $channel2;
- if ( $channel2 !~ /${sesion2}$/ ) {
- my $channel2conses = "$canal2-$sesion2";
- }
-
- log_debug( "$heading Unlink $canal1 and $canal2", 64 ) if DEBUG;
- $evento = "";
-
- $estado_final = "unsetlink";
- $canal = $canal1;
-
- my $boton1 = 0;
- my $boton2 = 0;
-
- for my $mnroboton ( keys %sesbot ) {
- foreach my $msesion ( @{ $sesbot{$mnroboton} } ) {
- if ( $msesion eq $channel1 ) {
- $boton1 = $mnroboton;
- }
- if ( $msesion eq $channel2 ) {
- $boton2 = $mnroboton;
- }
- }
- }
-
- #push @return, "$boton1|unsetlink|$boton2|$uniqueid1|$channel2";
- #push @return, "$boton2|unsetlink|$boton1|$uniqueid2|$channel1";
- push @return, "$canal1|unsetlink|$channel2|$uniqueid1-$server|$channel1conses";
- push @return, "$canal2|unsetlink|$channel1|$uniqueid2-$server|$channel2conses";
- $evento = ""; #NEW
- }
-
- if ( $evento eq "rename" ) {
- my $nuevo_nombre = "";
- my $viejo_nombre = "";
- log_debug( "$heading RENAME Event", 32 ) if DEBUG;
- $evento = "";
- while ( ( $key, $val ) = each(%hash_temporal) ) {
- if ( $key =~ /newname/i ) {
- $nuevo_nombre = $val;
- }
- if ( $key =~ /oldname/i ) {
- $viejo_nombre = $val;
- }
- }
- log_debug( "$heading RENAME $viejo_nombre por $nuevo_nombre (id $unico_id)", 64 ) if DEBUG;
-
- if ( $nuevo_nombre =~ /<ZOMBIE>/ ) {
- log_debug( "$heading $nuevo_nombre, asterisk bug, sometimes misses the hangup, so we fake it", 64 ) if DEBUG;
- my ( $canalnuevo, $nada ) = separate_session_from_channel($nuevo_nombre);
- push @return, "$canalnuevo|corto||$unico_id|$nuevo_nombre";
- }
-
- # Directamente borra la sesion que se debe renombrar
- #if ( ( $nuevo_nombre !~ /</ ) && ( $viejo_nombre !~ /</ ) ) {
- my @final = ();
-
- # A rename means that the channel was masqueraded, or going somewhere else
- # we dont want to fiddle with sesbot variables. Because the new/old names
- # maybe we want to REMOVE the old name from sesbot
-
- for my $mnroboton ( keys %sesbot ) {
- @final = ();
- foreach my $msesion ( @{ $sesbot{$mnroboton} } ) {
- if ( $msesion ne $viejo_nombre ) {
- push @final, $msesion;
- }
- }
- $sesbot{$mnroboton} = [@final];
- }
-
- # We need to remove the channel from the cola hash
- $cola->{$nuevo_nombre} = $cola->{$viejo_nombre};
- delete $cola->{$viejo_nombre};
-
- for my $mnroboton ( keys %linkbot ) {
- @final = ();
- foreach my $msesion ( @{ $linkbot{$mnroboton} } ) {
- log_debug( "$heading RENAME iteracion cada linkbot($mnroboton)", 32 ) if DEBUG;
- if ( $msesion ne $viejo_nombre ) {
- push @final, $msesion;
- log_debug( "$heading RENAME dejo $msesion en linkbot($mnroboton)", 32 ) if DEBUG;
- }
- else {
- &print_sesbot(20);
- log_debug( "$heading RENAME viejo $viejo_nombre no va, en realidad va $nuevo_nombre", 32 )
- if DEBUG;
- push @final, $nuevo_nombre;
- $estado_final = "setlink";
- my $botoncambiado = $buttons{"$mnroboton"};
- log_debug( "$heading RENAME buttons($mnroboton)", 32 ) if DEBUG;
- log_debug( "$heading RENAME sesbot($botoncambiado)[0]", 32 ) if DEBUG;
- my $canalcambiado = $sesbot{$botoncambiado}[0];
-
- if ( defined($canalcambiado) ) {
- my ( $canalito, $nada ) = separate_session_from_channel($canalcambiado);
- push @return, "$canalito|$estado_final|$nuevo_nombre|$unico_id|$canalcambiado";
- ( $canalito, $nada ) = separate_session_from_channel($nuevo_nombre);
- push @return, "$canalito|$estado_final|$canalcambiado|$unico_id|$nuevo_nombre";
- $canal = $canalito;
- }
- }
- }
- $linkbot{$mnroboton} = [@final];
- }
-
- for $quehay ( keys %datos ) {
- while ( ( $key, $val ) = each( %{ $datos{$quehay} } ) ) {
- if ( ( $key eq "Channel" ) && ( $val eq $viejo_nombre ) ) {
- $datos{"$quehay"}{"$key"} = $nuevo_nombre;
- log_debug( "$heading POPULATES datos($quehay){ $key } = $nuevo_nombre", 32 ) if DEBUG;
- }
- }
- }
- for $quehay ( keys %parked ) {
- if ( $quehay eq "$server^$viejo_nombre" ) {
- $parked{"$server^$nuevo_nombre"} = $parked{"$quehay"};
- delete $parked{"$quehay"};
- my ( $rcanal, $rses ) = separate_session_from_channel($nuevo_nombre);
- $texto = "&parked," . $parked{"$server^$nuevo_nombre"} . "&";
- push @return, "$rcanal|ocupado3|$texto|$unico_id|$nuevo_nombre";
- }
- }
- $evento = ""; #NEW
- }
-
- if ( $evento eq "peerstatus" ) {
- my $tiempo = 0;
- $canal = $hash_temporal{Peer};
- $canal =~ tr/a-z/A-Z/;
- $state = $hash_temporal{PeerStatus};
-
- if ( defined $hash_temporal{Time} ) {
- $tiempo = $hash_temporal{Time};
- }
-
- if ( $state eq "Registered" ) {
- $estado_final = "registrado";
- $texto = "®istered";
- }
- elsif ( $state eq "Reachable" ) {
- $estado_final = "registrado";
- $texto = "&reachable,$tiempo";
- }
- elsif ( $state eq "Unreachable" ) {
- $estado_final = "unreachable";
- $texto = "&unreachable,$tiempo";
- }
- elsif ( $state eq "Lagged" ) {
- $estado_final = "noregistrado";
- $texto = "&lagged,$tiempo";
- }
- $canalid = $canal . "-XXXX";
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
- $evento = "";
- }
-
- if ( $evento eq "extensionstatus" ) {
- $canal = $hash_temporal{"Exten"};
- $canal =~ s/(\d+)/SCCP\/$1/g;
- $state = $hash_temporal{"Status"};
- if ( $hash_temporal{"Status"} == 0 ) {
- $estado_final = "registrado";
- $texto = "®istered";
- }
- elsif ( $hash_temporal{"Status"} == 4 ) {
- $estado_final = "unreachable";
- $texto = "&unreachable";
- }
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
- $evento = "";
- }
-
- if ( $evento eq "status" ) {
- $evento = "";
- }
-
- if ( $evento eq "statuscomplete" ) {
-
- # When done with the status retrieval, generate events to send to
- # flash clients. Do it only when finishing receiving status from
- # all asterisk servers monitored
-
- my @ids = ();
- if ( keys(%datos) ) {
- my $hay_activos = 0;
-
- for ( keys %datos ) {
- my $ignorame = 0;
- my @pedazote = split( /-/, $_ );
- my $current_server = $pedazote[1];
- if ( "$server" ne "$current_server" ) {
- next;
- }
-
- log_debug( "$heading STATUSCOMPLETE datos { $_ }", 128 ) if DEBUG;
- push @ids, $_;
- my $myevent = "Newexten";
- while ( my ( $key, $val ) = each( %{ $datos{$_} } ) ) {
- log_debug( "$heading STATUSCOMPLETE datos { $key } = $val", 128 ) if DEBUG;
-
- if ( defined($val) ) {
- $hay_activos = 1;
- $fake_bloque[$fakecounter]{$key} = $val;
- if ( $key eq "Extension" ) {
- $myevent = "Ring";
- $fake_bloque[$fakecounter]{Origin} = "true";
- }
- if ( $key eq "Channel" ) {
- if ( $timeouts{$val} ) {
- $datos{$_}{Timeout} = $timeouts{$val};
- }
- }
- if ( $key eq "Link" && $val =~ /^Agent/ ) {
- $ignorame = 1;
- }
- }
- }
- if ( $hay_activos == 1 ) {
- $fake_bloque[$fakecounter]{"Event"} = $myevent;
- if ( $ignorame == 1 ) {
- $fake_bloque[$fakecounter]{"Event"} = "Ignoreme-Bad-CLID";
- $fake_bloque[$fakecounter]{"State"} = "Ignoreme";
- }
- log_debug( "$heading fake bloque de $fakecounter (evento) lo pongo en $myevent", 128 ) if DEBUG;
- $fakecounter++;
- }
- }
- }
- else {
- log_debug( "$heading En statuscomplete datos esta vacio!", 64 ) if DEBUG;
- }
-
- foreach my $valor (@ids) {
- log_debug( "$heading foreach statuscomplete $valor", 32 ) if DEBUG;
- if ( exists( $datos{"$valor"} ) ) {
- if ( exists( $datos{"$valor"}{Link} ) ) {
- if ( $datos{"$valor"}{Link} !~ /^Agent/ ) {
- log_debug( "$heading datos de $valor tiene defined Link genero un Fake bloque", 128 ) if DEBUG;
-
- my $channel1 = $datos{$valor}{"Channel"};
- my $channel2 = $datos{$valor}{"Link"};
- my $unique1 = $datos{$valor}{"Uniqueid"};
- my $unique2 = find_uniqueid( $channel2, $server );
-
- $fake_bloque[$fakecounter]{"Event"} = "Link";
- $fake_bloque[$fakecounter]{"Channel1"} = $channel1;
- $fake_bloque[$fakecounter]{"Channel2"} = $channel2;
- $fake_bloque[$fakecounter]{"Uniqueid1"} = $unique1;
- $fake_bloque[$fakecounter]{"Uniqueid2"} = $unique2;
-
- while ( my ( $quey, $vail ) = each( %{ $fake_bloque[$fakecounter] } ) ) {
- log_debug( "$heading FAKEBLOQUE contiene $quey = $vail", 128 ) if DEBUG;
- }
-
- $fakecounter++;
- }
- else {
- log_debug( "$heading datos de $valor linked to Agent, IGNORE", 128 ) if DEBUG;
- }
- }
- if ( exists( $datos{"$valor"}{"Timeout"} ) ) {
- my $calltimeout = $datos{"$valor"}{"Timeout"} - time();
- $fake_bloque[$fakecounter]{"ActionID"} = "timeout|$datos{$valor}{'Channel'}|$calltimeout";
- $fakecounter++;
- }
- }
- }
-
- $evento = ""; #NEW (estaba comentado)
- }
-
- if ( $evento eq "fakeismeetmemember" ) {
- my @bot1 = ();
- my $bot2 = 0;
- $estado_final = "meetmeuser";
- $texto = $hash_temporal{"Usernum"} . "," . $hash_temporal{"Meetme"};
- my ( $chan1, $nada1 ) = separate_session_from_channel( $hash_temporal{'Channel'} );
- push @return, "$hash_temporal{'Meetme'}|setlink|$hash_temporal{'Channel'}||$hash_temporal{'Channel'}";
- push @return, "$chan1|setlink|$hash_temporal{'Meetme'}||$hash_temporal{'Channel'}";
- $evento = ""; #NEW
- }
-
- if ( $evento eq "newexten" ) {
-
- # If its a new extension without state, defaults to 'Up'
- if ( !defined( $datos{$unico_id}{'State'} ) && $fill_datos ) {
- $datos{$unico_id}{'State'} = "Up";
- log_debug( "$heading POPULATES datos($unico_id){ State } = Up", 128 ) if DEBUG;
- }
-
- # If its a parked channel, set the PARK button to 'Down'
- if ( exists( $parked{"$server^$canalid"} ) ) {
- log_debug( "$heading EXISTE parked{$server^$canalid}", 128 ) if DEBUG;
- my $parkexten = $parked{"$server^$canalid"};
- delete $parked{"$server^$canalid"};
- push @return, "PARK/$parkexten|corto||YYYY-$server|$canalid";
- }
- else {
- log_debug( "$heading NO EXISTE parked{$server^$canalid}", 128 ) if DEBUG;
- }
- }
-
- if ( $evento eq "hangup" ) {
- if ( exists( $datos{$unico_id} ) ) {
- $datos{$unico_id}{'State'} = "Down";
- log_debug( "$heading POPULATES datos($unico_id){ State } = down", 128 ) if DEBUG;
- }
- else {
- $hash_temporal{'State'} = "Down";
- }
-
- # Look if the channel was parked and clear that button too
- if ( exists( $parked{"$server^$canalid"} ) ) {
- log_debug( "$heading 2 EXISTE parked{$server^$canalid}", 128 ) if DEBUG;
- my $parkexten = $parked{"$server^$canalid"};
- delete $parked{"$server^$canalid"};
- push @return, "PARK/$parkexten|corto||YYYY-$server|$canalid";
- }
- else {
- log_debug( "$heading NO EXISTE parked{$server^$canalid}", 128 ) if DEBUG;
- }
- }
-
- if ( $evento eq "unparkedcall" ) {
- my $channel1 = $hash_temporal{"Channel"};
-
- if ( exists( $parked{"$server^$channel1"} ) ) {
- my $unidchan = find_uniqueid( $hash_temporal{'Channel'}, $server );
- log_debug( "$heading EXISTE parked{$server^$channel1} ", 128 ) if DEBUG;
- my $parkexten = $parked{"$server^$channel1"};
- delete $parked{"$server^$channel1"};
- push @return, "PARK/$parkexten|corto||YYYY-$server|$channel1";
- my ( $canal1, $sesion1 ) = separate_session_from_channel($channel1);
- push @return, "$canal1|ocupado5||$unidchan|$channel1";
- }
- }
-
- if ( $evento eq "parkedcall" ) {
- $texto = "&parked," . $hash_temporal{'Exten'} . "&";
- $estado_final = "ocupado3";
- my ( $canal, $nada ) = separate_session_from_channel( $hash_temporal{'Channel'} );
- my $textid = "";
- my $timeout = "";
- my $unidchan = find_uniqueid( $hash_temporal{'Channel'}, $server );
- $textid = $datos{$unidchan}{'Callerid'}
- if ( defined( $datos{$unidchan}{'Callerid'} ) );
- $textid = $datos{$unidchan}{'CallerID'}
- if ( defined( $datos{$unidchan}{'CallerID'} ) );
- $timeout = "(" . $hash_temporal{'Timeout'} . ")";
- $textid =~ s/\"//g;
- $textid =~ s/\<//g;
- $textid =~ s/\>//g;
- push @return, "$canal|ocupado3|$texto|$unidchan|$canalid";
- push @return, "PARK/$hash_temporal{'Exten'}|park|[$textid]$timeout|$hash_temporal{'Timeout'}-$server|$hash_temporal{'Channel'}";
-
- log_debug( "$heading pongo parked($server^$hash_temporal{'Channel'}) en $hash_temporal{'Exten'}", 64 ) if DEBUG;
- $parked{"$server^$hash_temporal{'Channel'}"} = $hash_temporal{'Exten'};
- $evento = ""; #NEW
- }
-
- if ( $evento eq "newcallerid" ) {
- $estado_final = "setstatus";
- $state = "Newcallerid";
- my $save_clidnum = "";
- my $save_clidname = "";
- if ( defined( $hash_temporal{'CallerIDName'} ) ) {
- $save_clidnum = $hash_temporal{'CallerID'};
- $save_clidname = $hash_temporal{'CallerIDName'};
- }
- elsif ( defined( $hash_temporal{'CalleridName'} ) ) {
- $save_clidnum = $hash_temporal{'Callerid'};
- $save_clidname = $hash_temporal{'CalleridName'};
- }
- else {
- ( $save_clidnum, $save_clidname ) = split_callerid( $hash_temporal{'CallerID'} );
- }
- $saved_clidnum{"$server^$hash_temporal{'Channel'}"} = $save_clidnum;
- $saved_clidname{"$server^$hash_temporal{'Channel'}"} = $save_clidname;
- }
-
- # From now on, we only look for the State of the datos block
- # Dont check for $evento bellow this line!
-
- if ( $evento ne "" ) {
- log_debug( "$heading Event $evento, canal '$canal'", 32 ) if DEBUG;
-
- # De acuerdo a los datos de la extension genera
- # la linea con info para el flash
-
- $elemento = $canalid;
-
- if ( exists( $datos{$unico_id} ) ) {
- if ( exists( $datos{$unico_id}{'Channel'} ) ) {
- $elemento = $datos{$unico_id}{'Channel'};
-
- # Old IAX naming convention
- if ( $elemento =~ /^IAX2\[/ && $elemento =~ /\@/ ) {
-
- # The channel is IAX2 and has the @context
- # I will remove the @context/host because it varies
- $elemento =~ s/IAX2\[(.*)@(.*)\](.*)/IAX2\[$1\]$3/g;
- }
-
- if ( $elemento =~ /^IAX2\// && $elemento =~ /\@/ ) {
- $elemento =~ s/IAX2\/(.*)@(.*)\/(.*)/IAX2\/$1\/$3/g;
- }
- }
- }
- ( $canal, $sesion ) = separate_session_from_channel($elemento);
-
- if ( defined($canal) ) {
- $canal =~ tr/a-z/A-Z/;
- }
- else {
- log_debug( "$heading canal not defined!! END $elemento", 32 ) if DEBUG;
- while ( my ( $key, $val ) = each(%hash_temporal) ) {
- log_debug( "$heading hash_temporal $key = $val", 128 ) if DEBUG;
- }
- return;
- }
-
- if ( $canal =~ m/^Local/i ) { # ZZ nico
- # return;
- }
-
- if ( defined($sesion) ) {
- log_debug( "$heading canal $canal sesion $sesion", 128 ) if DEBUG;
- }
-
- if ( exists( $datos{$unico_id} ) ) {
-
- log_debug( "$heading EXISTE datos($unico_id) ", 32 ) if DEBUG;
-
- if ( exists( $datos{$unico_id}{'Extension'} ) ) {
- $exten = $datos{$unico_id}{'Extension'};
- }
-
- if ( exists( $datos{$unico_id}{'State'} ) ) {
- log_debug( "$heading EXISTE datos($unico_id){state}", 32 ) if DEBUG;
- $state = $datos{$unico_id}{'State'};
- }
-
- if ( exists( $datos{$unico_id}{'Callerid'} ) ) {
- $clid = $datos{$unico_id}{'Callerid'};
- }
-
- if ( exists( $datos{$unico_id}{'CallerID'} ) ) {
- $clid = $datos{$unico_id}{'CallerID'};
- }
- if ( $clid ne "" ) {
- ( $clidnum, $clidname ) = split_callerid($clid);
- }
- if ( exists( $datos{$unico_id}{'CallerIDName'} ) ) {
- $clidname = $datos{$unico_id}{'CallerIDName'};
- }
-
- # The ones below are for catching the callerid from the
- # Dial event on CVS-HEAD
- if ( exists( $remote_callerid{"$server^$canalid"} ) ) {
- $clidnum = $remote_callerid{"$server^$canalid"};
- }
- if ( exists( $remote_callerid_name{"$server^$canalid"} ) ) {
- $clidname = $remote_callerid_name{"$server^$canalid"};
- }
- }
- else {
- log_debug( "$heading NO EXISTE datos($unico_id)", 32 ) if DEBUG;
- }
-
- if ( $state eq "" ) {
- if ( defined( $hash_temporal{'State'} ) ) {
- $state = $hash_temporal{'State'};
- }
- else {
- $state = "";
- }
- }
-
- my $clid_with_format = format_clid( $clidnum, $clid_format );
-
- if ( $state eq "Ringing" ) {
- my $ret = "";
- if ( $clidnum ne "" ) {
- my $base64_clidnum = encode_base64( $clidnum . " " );
- $ret = "$canal|clidnum|$base64_clidnum|$unico_id|$hash_temporal{'Channel'}";
- push @return, $ret;
- }
- if ( defined($clidname) ) {
- my $base64_clidname = encode_base64( $clidname . " " );
- $ret = "$canal|clidname|$base64_clidname|$unico_id|$hash_temporal{'Channel'}";
- push @return, $ret;
- }
- }
-
- if ( $state eq "Rsrvd" ) {
- $state = "Ring";
- }
-
- if ( $state eq "Ring" ) {
- $texto = "&calling";
- $estado_final = "ring";
- $datos{$unico_id}{'Origin'} = "true";
- log_debug( "$heading POPULATES datos($unico_id){ Origin } = true", 128 ) if DEBUG;
- }
-
- if ( $state eq "Dialing" ) {
- $texto = "&dialing";
- $estado_final = "ring";
- if ( $canal =~ /^OH323/ ) {
-
- # OH323 use a random channel name when Dialing
- # that later changes its name. So we just discard
- # this event/name to avoid getting Dialing channels
- # foerever (because we never receive a Down status)
- $estado_final = "";
- }
- }
-
- if ( $state eq "OffHook" ) {
- $texto = "&calling";
- $estado_final = "ring";
- $datos{$unico_id}{'Origin'} = "true";
- log_debug( "$heading POPULATES datos($unico_id){ Origin } = true", 128 );
- }
-
- if ( $state =~ /^UNK/ ) {
- $texto = "¬registered";
- $estado_final = "noregistrado";
- $unico_id = "YYYY-$server";
- if ( $canalid !~ /(.*)-XXXX$/ ) {
- $canalid = $canalid .= "-XXXX";
- }
- }
-
- if ( $state =~ /^UNR/ ) {
- $texto = "&unreachable";
- $estado_final = "unreachable";
- $unico_id = "YYYY-$server";
- if ( $canalid !~ /(.*)-XXXX$/ ) {
- $canalid = $canalid .= "-XXXX";
- }
- }
-
- if ( $state =~ /^Unm/ ) {
- $texto = "®istered";
- $estado_final = "registrado";
- $unico_id = "YYYY-$server";
- if ( $canalid !~ /(.*)-XXXX$/ ) {
- $canalid = $canalid .= "-XXXX";
- }
- }
-
- if ( $state =~ /^OK/ ) {
- $texto = "®istered";
- $estado_final = "registrado";
- $unico_id = "YYYY-$server";
- if ( $canalid !~ /(.*)-XXXX$/ ) {
- $canalid = $canalid .= "-XXXX";
- }
- }
-
- if ( $state eq "Newcallerid" ) {
- $texto = "&incoming,[" . $clid_with_format . "]";
- }
-
- if ( $state eq "Ringing" ) {
- $texto = "&incoming,[" . $clid_with_format . "]";
- $estado_final = "ringing";
- }
-
- if ( $state eq "Down" ) {
-
- if ( $evento eq "hangup" ) {
-
- # Solo nos interesa mandar a flash los down por hangup
- # para evitar enviar eventos redundantes
- $estado_final = "corto";
- if ( $agent_status == 1 ) {
- if ( exists( $agent_to_channel{"$server^$canal"} ) || exists( $reverse_agents{$canal} ) ) {
- push @return, "$canal|isagent|0|$unico_id|$canalid";
- }
- }
- }
- delete $timeouts{$canalid};
- delete $remote_callerid{"$server^$canalid"};
- delete $remote_callerid_name{"$server^$canalid"};
- delete $saved_clidname{"$server^$canalid"};
- delete $saved_clidnum{"$server^$canalid"};
-
- #erase_instances_for_trunk_buttons($canalsesion);
- }
-
- my $exclude = 0;
- my $exten_clid = "";
- if ( $state eq "Up" ) {
- if ( $exten ne "" ) {
- if ( is_number($exten) ) {
- $exten_clid = format_clid( $exten, $clid_format );
- if ( defined( $saved_clidnum{"$server^$canalid"} ) ) {
- $exten_clid = format_clid( $saved_clidnum{"$server^$canalid"}, $clid_format );
- }
- if ($clid_privacy) {
- $exten_clid = "n/a";
- }
- $conquien = "[" . $exten_clid . "]";
- }
- else {
- if ( length($exten) == 1 ) {
- $conquien = $exten;
- $exclude = 1; # We ignore events that have letter extensions 's', 'h', etc
- $exclude = 0; # Do we? UserEvent fake events dont work if we ignore them
- log_debug( "$heading CLID is not a number! $exten", 32 ) if DEBUG;
- }
- else {
- $conquien = $exten;
- }
- }
- }
- else {
- $conquien = $clid_with_format;
- }
-
- if ( defined( $hash_temporal{'Seconds'} ) ) {
-
- # $conquien .= " (" . $hash_temporal{'Seconds'} . ")";
- push @return, "$canal|settimer|$hash_temporal{'Seconds'}\@UP|$unico_id|$canalid";
- push @return, "$canal|state|busy|$unico_id|$canalid";
-
- }
-
- if ( defined( $datos{$unico_id}{'Origin'} ) ) {
- if ( $datos{$unico_id}{'Origin'} eq "true" ) {
- if ( $exclude == 1 ) {
- $texto = "skip";
- }
- else {
- $texto = "&calling,[$exten_clid]";
- }
- $estado_final = "ocupado2"; # 2 for origin button
- }
- }
- else {
-
- $texto = "&incoming,[$conquien]";
- $estado_final = "ocupado1"; # 1 for destination button
- }
- }
-
- # Remove special character from Caller ID string
- $texto =~ s/\"/'/g;
- $texto =~ s/</[/g;
- $texto =~ s/>/]/g;
- $texto =~ s/\|/ /g;
-
- push @return, "$canal|$estado_final|$texto|$unico_id|$canalid";
-
- }
-
- @return = unique(@return);
-
- my $cuantos = $#return + 1;
- log_debug( "$heading returns $cuantos", 16 ) if DEBUG;
- foreach (@return) {
- log_debug( "$heading END SUB returns $_", 32 ) if DEBUG;
- }
- $tab = substr( $tab, 0, -1 );
- return @return;
-}
-
-sub local_channels_are_driving_me_mad {
-
- # This tidbit checks if the channel is Local and we happen to have a regular
- # channel button with the same ext @ context, if so, we replace the Local
- # !$##@ channel to the regular/basic channel.
-
- my $server = shift;
- my $canal = shift;
- my @return = ();
-
- log_debug( "** LOCAL_CHANNELS entra server $server canal $canal", 32 );
-
- if ( $canal =~ /^Local/i ) {
- my $local_channel = $canal;
- $local_channel =~ s/Local\///gi;
- if ( defined( $extension_transfer_reverse{"$server^$local_channel"} ) ) {
- if ( $extension_transfer_reverse{"$server^$local_channel"} !~ /\d+\^CLID/ ) {
-
- # We dont want to return CLID buttons
- $canal = $extension_transfer_reverse{"$server^$local_channel"};
- if ( $canal =~ /(\d+)\^(.*)/ ) {
- $server = $1;
- $canal = $2;
- }
- }
- else {
- log_debug( "** LOCAL_CHANNELS ignoro el CLID button $canal", 32 ) if DEBUG;
- }
- }
- }
-
- # Remove &context from $canal
- $canal =~ s/(.*)&(.*)/$1/g;
-
- # if( $canal =~ m/^CLID/ ) {
- # my $extr = $extension_transfer{"$server^$canal"};
- # $extr =~ s/\d+\^(.*)/$1/g;
- # $canal = "Local/$extr";
- # }
-
- log_debug( "** LOCAL_CHANNELS devuelvo $server canal $canal", 32 ) if DEBUG;
- push @return, $server;
- push @return, $canal;
- return @return;
-}
-
-sub digest_event_block {
- my $bleque = shift;
- my $tipo = shift;
- my $socket = shift;
- my $astmanproxy_server = shift;
- my @blique = @$bleque;
- my @respuestas = ();
- my $canal = "";
- my $quehace = "";
- my $dos = "";
- my $uniqueid = "";
- my $canalid = "";
- my $quehay = "";
- my @mensajes = ();
- my $interno = "";
- my $todo = "";
- my @mensajefinal;
- my $cuantas;
- my $server = 0;
- my %cambiaron;
- my $heading = "** DIGEST_EVENT:";
-
- $tab = $tab . "\t" if DEBUG;
-
- log_debug( "$heading start", 16 ) if DEBUG;
-
- @fake_bloque = ();
- delete $datos{""};
- foreach my $blaque (@blique) {
-
- if (DEBUG) {
- if ( $tipo eq "fake" ) {
- $tab = substr( $tab, 0, -1 );
- my $totdebug = "";
- while ( my ( $key, $val ) = each( %{$blaque} ) ) {
- if ( $key ne "" ) {
- $totdebug .= sprintf( "%-15s <- %s\n", "fake", "$key: $val" );
- }
- }
- log_debug( $totdebug, 1 );
- $tab = $tab . "\t";
- }
- }
- @mensajes = procesa_bloque( $blaque, $socket, $astmanproxy_server );
- foreach my $mensaje (@mensajes) {
- if ( defined($mensaje) && $mensaje ne "" ) {
- log_debug( "$heading GOT $mensaje", 32 ) if DEBUG;
- delete $datos{""}; # Erase the hash with no uniqueid
- ( $canal, $quehace, $dos, $uniqueid, $canalid ) =
- split( /\|/, $mensaje );
-
- if ( !defined($dos) ) { $dos = ""; }
- if ( !defined($quehace) ) { $quehace = ""; }
-
- if ( $canal =~ /\/PSEUDO/ ) {
- log_debug( "$heading Ignoring pseudo channel $canal", 32 ) if DEBUG;
- next;
- }
-
- if ( $dos eq "skip" ) {
- log_debug( "$heading SALTEO $canal tiene skip", 32 ) if DEBUG;
- next;
- }
- if ( $quehace eq "" ) {
- log_debug( "$heading SALTEO $canal no tiene quehace", 32 ) if DEBUG;
- next;
- }
-
- log_debug( "$heading canal: $canal", 32 ) if DEBUG;
- log_debug( "$heading quehace: $quehace", 32 ) if DEBUG;
- log_debug( "$heading dos: $dos", 32 ) if DEBUG;
- log_debug( "$heading uniqueid: $uniqueid", 32 ) if DEBUG;
- log_debug( "$heading canalid: $canalid", 32 ) if DEBUG;
-
- # if ( !defined($canal) ) { $canal = ""; }
- # if ( !defined($quehace) ) { $quehace = ""; }
- # if ( !defined($dos) ) { $dos = ""; }
-
- $canalid =~ s/\s+//g; # Removes whitespace from CHANNEL-ID
- my $canalidzombie = $canalid; # Removes whitespace from CHANNEL-ID
- $canalid =~ s/(.*)<(.*)>/$1/g; # discards ZOMBIE or MASQ
-
- if ( $canal =~ /^vpb\//i ) {
-
- # For vpb channels, we fake a session number
- $canal = $canalid;
- $canal =~ tr/a-z/A-Z/;
- $canalid = $canalid .= "-VPB1";
- }
-
- $server = $uniqueid;
- $server =~ s/(.*)-(.*)/$2/g;
-
- log_debug( "$heading Quehace $quehace", 64 ) if DEBUG;
-
- my $buttontext = $dos;
- if ( $buttontext =~ /\Q[\E/ ) {
- $buttontext =~ s/.*\Q[\E(.*)\Q]\E.*/$1/g;
- }
- else {
- $buttontext = "";
- }
-
- my @canaleja = find_panel_buttons( $canal, $canalid, $server );
- my $cuantos = @canaleja;
-
- if ( $quehace eq "corto" || $quehace eq "info" ) {
-
- # We collect the last state of the channel on hangup
- while ( my ( $key, $val ) = each( %{ $datos{$uniqueid} } ) ) {
- $todo .= "$key = $val\n"
- if ( $key ne "E" ) && ( defined($val) );
- log_debug( "$heading \tAgrego $key = $val", 128 ) if DEBUG;
- }
- $todo .= " ";
- $todo = encode_base64($todo);
-
- delete $datos{$uniqueid};
- delete $cola->{$canalidzombie};
- log_debug( "$heading erasing datos{$uniqueid}", 128 ) if DEBUG;
-
- if ( $cuantos == 0 ) {
-
- # We delete all appeareance in sesbot because the channel without
- # a button might occupy one slot in sesbot. If we have a button
- # match then skip this step for later
- erase_all_sessions_from_channel( $canalid, $canal, $server );
- }
- }
-
- if ( $quehace eq "queueremoved" ) {
-
- # Remove the agent from the agents_on_queue hash
- my $colita = $dos;
- my @elementos = ();
-
- if ( keys(%agents_on_queue) ) {
-
- # remove from agents_on_queue hash only if it has anything on it
- foreach my $vvalor ( @{ $agents_on_queue{"$server^$colita"} } ) {
- if ( $vvalor ne "$server^$canal" ) {
- push @elementos, $vvalor;
- }
- else {
- push @elementos, "!" . $vvalor;
- }
- }
- @{ $agents_on_queue{"$server^$colita"} } = @elementos;
- }
-
- #Remove cache hit to force find panel buttons to look for new positions
- foreach my $kkey ( keys %cache_hit ) {
- if ( $kkey =~ /^$canal/ ) {
- delete $cache_hit{$kkey};
- }
- }
- }
-
- my $dosoriginal = "";
-
- foreach $canal (@canaleja) {
- log_debug( "", 32 ) if DEBUG;
- log_debug( "$heading canaleja LOOP; is $canal turn", 32 ) if DEBUG;
-
- if ( $dosoriginal ne "" ) {
- $dos = $dosoriginal;
- }
-
- # Try to find the text string in the lang conf hash
- if ( $dos =~ m/^\&/ ) {
- ( $dos, $dosoriginal, $buttontext ) = translate( $canal, $dos, $dosoriginal, $buttontext );
- }
-
- if ( !defined( $buttons{"$server^$canal"} ) ) {
- log_debug( "$heading \tNo tengo botones para $server^$canal, END FUNCTION", 128 ) if DEBUG;
- for ( keys %buttons ) {
- log_debug( "$heading \t\tKey $_", 128 ) if DEBUG;
- }
- next;
- }
-
- # If its a REGEXP button, we have to ignore all events
- # except ocupado*, corto, setlink and unsetlink
- if ( $canal =~ /^_/ ) {
- log_debug( "$heading canal $canal es un WILD y quehace vale $quehace", 32 ) if DEBUG;
-
- if ( $quehace =~ /registr/
- || $quehace =~ /reacha/
- || $quehace =~ /^inf/ )
- {
- log_debug( "$heading IGNORO $quehace porque es un wildcard", 32 ) if DEBUG;
- next;
- }
-
- if ( $quehace !~ /^ocupado/
- && $quehace !~ /^corto/
- && $quehace !~ /^state/
- && $quehace !~ /^settext/
- && $quehace !~ /^setlabel/
- && $quehace !~ /^setlink/
- && $quehace !~ /^meetme/
- && $quehace !~ /^ring/
- && $quehace !~ /^settimer/
- && $quehace !~ /^clidnum/
- && $quehace !~ /^clidname/
- && $quehace !~ /^setstatus/
- && $quehace !~ /^unsetlink/ )
- {
- my ( $nada, $elcontexto ) = split( /\&/, $canal );
- if ( !defined($elcontexto) ) { $elcontexto = ""; }
- if ( $elcontexto ne "" ) {
- $elcontexto = "&" . $elcontexto;
- }
- my ( $canalsolo, $nrotrunk ) = split( /=/, $canal );
- $canal = $canalsolo . "=1" . $elcontexto;
- log_debug( "$heading quehace=$quehace, elijo el 1ero del trunk $canal", 32 ) if DEBUG;
-
- #next;
- }
-
- # If we have a wildcard button with changelabel
- # and change led_color (the 1 after changelabel)
- # change it so to not change the led color.
- if ( $quehace =~ /changelabel1/ ) {
- log_debug( "$heading el wildcard tiene changelabel1, lo cambio por changelabel0!", 32 )
- if DEBUG;
- $quehace = "changelabel0";
- }
- }
-
- if ( $canal ne "" ) {
-
- if ( $quehace eq 'corto' || $quehace eq 'info' ) {
-
- my @linked = erase_all_sessions_from_channel( $canalid, $canal, $server );
- push @linked, $canal;
- my $btnorinum = "";
- foreach my $canaleje (@linked) {
- if ( $canaleje =~ /\^/ ) {
- $btnorinum = $buttons{$canaleje};
- }
- else {
- $btnorinum = $buttons{"$server^$canaleje"};
- }
- log_debug( "$heading call GEN_LINKED 1", 32 ) if DEBUG;
- my $listabotones = generate_linked_buttons_list( $canaleje, $server );
- push @respuestas, "$btnorinum|linked|$listabotones";
- }
-
- delete $datos{$uniqueid};
- log_debug( "$heading REMOVING datos { $uniqueid }", 32 ) if DEBUG;
- }
-
- if ( $quehace eq "setlink" ) {
- log_debug( "$heading IF quehace = SETLINK", 32 ) if DEBUG;
- my ( $nada1, $contexto1 ) = split( /\&/, $canal );
- if ( !defined($contexto1) ) { $contexto1 = ""; }
- my $listabotones = "";
-
- if ( !defined( @{ $linkbot{"$server^$canal"} } ) ) {
- push @{ $linkbot{"$server^$canal"} }, "";
- pop @{ $linkbot{"$server^$canal"} };
- log_debug( "$heading DEFINIENDO linkbot ($server^$canal)", 32 ) if DEBUG;
- }
-
- my ( $canal1, $sesion1 ) = separate_session_from_channel($dos);
- my @linkbotones = find_panel_buttons( $canal1, $dos, $server );
- foreach (@linkbotones) {
- my ( $nada2, $contexto2 ) = split( /\&/, $_ );
- if ( !defined($contexto2) ) { $contexto2 = ""; }
- if ( $contexto1 eq $contexto2 ) {
- push @{ $linkbot{"$server^$canal"} }, $dos;
- log_debug( "$heading AGREGO a linkbot{ $server^$canal} el valor $dos", 32 )
- if DEBUG;
- }
- }
-
- #my %seen = ();
- #my @uniq =
- # grep { !$seen{$_}++ } @{ $linkbot{"$server^$canal"} };
- #$linkbot{"$server^$canal"} = \@uniq;
- my @uniq = unique( @{ $linkbot{"$server^$canal"} } );
- $linkbot{"$server^$canal"} = \@uniq;
-
- foreach my $valorad (@uniq) {
- log_debug( "$heading linkbot ($server^$canal) = $valorad", 32 ) if DEBUG;
- }
- my $btnorinum = $buttons{"$server^$canal"};
- log_debug( "$heading llamo a GENERATE_LINKED", 32 ) if DEBUG;
- $listabotones = generate_linked_buttons_list( $canal, $server );
- push @respuestas, "$btnorinum|linked|$listabotones";
- $botonlinked{$btnorinum} = $listabotones;
- log_debug( "$heading linkeado con $listabotones", 32 ) if DEBUG;
- log_debug( "$heading ENDIF quehace = SETLINK", 32 ) if DEBUG;
- }
-
- if ( $quehace eq "unsetlink" ) {
- log_debug( "$heading IF quehace = UNSETLINK", 32 ) if DEBUG;
- my @final = ();
- foreach my $msesion ( @{ $linkbot{"$server^$canal"} } ) {
- if ( $msesion ne $dos ) {
- push @final, $msesion;
- }
- }
- $linkbot{"$server^$canal"} = [@final];
- log_debug( "$heading ENDIF quehace = UNSETLINK", 32 ) if DEBUG;
- }
-
- $interno = $buttons{"$server^$canal"};
- $interno = "" if ( !defined($interno) );
-
- if ( $interno ne "" ) {
- if ( defined( $clid_private{$interno} ) && $clid_private{$interno} == 1 ) {
- if ( $dos =~ m/\[/ ) {
- $dos =~ s/([^\[]*)?(\[.*\])/$1 \[n\/a\]/g;
- }
- }
- }
-
- if ( $quehace eq "queueremoved" ) {
- delete $botonvoicemail{$interno};
- delete $botonvoicemailcount{$interno};
- delete $botonpark{$interno};
- delete $botonmeetme{$interno};
- delete $botonclid{$interno};
- delete $botonlinked{$interno};
- delete $botontimer{$interno};
- delete $botontimertype{$interno};
- delete $botonqueue_count{$interno};
- delete $botonqueue{$interno};
- delete $botonled{$interno};
- push @mensajefinal, "$interno|voicemail|0";
- }
-
- if ( $interno eq "" ) {
- log_debug( "$heading NO HAY INTERNO buttons($server^$canal), ABORTO", 32 ) if DEBUG;
- next;
- }
- log_debug( "$heading EL INTERNO es $interno", 32 ) if DEBUG;
-
- if ( !defined( $laststatus{$interno} ) ) {
- $laststatus{$interno} = "";
- }
- if ( !defined( $estadoboton{$interno} ) ) {
- $estadoboton{$interno} = "";
- }
-
- # Mantains hash of arrays with sessions for each button number
- # %sesbot{key}=value where:
- #
- # key is the button number (anything after '@' is the panel context)
- # value is an array containing the sessions Eg: SIP/mary-43xZ
- #
- # The rename manager event also modifies this hash
- #
- # There are other hashes to maintain a 'view' of the status:
- #
- # %estadoboton{key} = shows busy, free or ringing
- #
- if ( $canalid eq "" || $canalid =~ /zombie/i || $canalid =~ /(.*)-XXXX$/ ) {
- log_debug( "$heading ATENCION canalid es $canalid, NO PROCESAR?", 32 ) if DEBUG;
- }
- else {
-
- if ( $quehace eq "corto" ) {
-
- log_debug( "$heading CORTO interno $interno canal $canal", 32 ) if DEBUG;
-
- delete $botonpark{$interno};
- delete $botonmeetme{$interno};
- delete $botonclid{$interno};
- delete $botonlinked{$interno};
- delete $botontimer{$interno};
- delete $botontimertype{$interno};
- delete $togle_action{$interno};
- delete $togle_response{$interno};
-
- my $canalbotonreverse = $buttons_reverse{$interno};
-
- if ( $canal =~ /^_/ && $ren_wildcard == 1 ) {
- push @respuestas, "$interno|changelabel0|labeloriginal";
- }
-
- delete $linkbot{$interno};
- delete $linkbot{$canalbotonreverse};
-
- if ( !defined( $sesbot{$interno} ) ) {
- push @{ $sesbot{$interno} }, "";
- pop @{ $sesbot{$interno} };
- }
- my $cuantos = @{ $sesbot{$interno} };
- if ( $cuantos == 0 ) {
- log_debug( "$heading CORTO y SE DESOCUPO estadoboton($interno) = free, sesbot($interno) esta vacio",
- 32 )
- if DEBUG;
- $cambiaron{$interno} = 1;
- $estadoboton{$interno} = "free";
- }
- else {
- log_debug( "$heading CORTO y SIGUE OCUPADO estadoboton($interno) = busy, sesbot($interno) tiene algo",
- 32 )
- if DEBUG;
- &print_sesbot(3);
- if ( $laststatus{$interno} ne "busy|${buttontext}" ) {
- $cambiaron{$interno} = 1;
-
- push @respuestas, "$interno|state|busy";
-
- # Justin from Fry's has prolems with callerid being cleared while a call is connected
- # from a queue using Local channels, so commnet these out
- #push @respuestas, "$interno|settext|";
- #push @respuestas, "$interno|setstatus|";
- $laststatus{$interno} = "busy|${buttontext}";
-
- log_debug(
- "$heading Y es distinto al ultimo estado $laststatus{$interno} ne $estadoboton{$interno}", 32 )
- if DEBUG;
- }
- $estadoboton{$interno} = "busy|${buttontext}";
- }
-
- }
- else {
-
- # quehace no es "corto"
- #
-
- # MAINTAINS SESBOT HASH
- if ( $canalid !~ /^Agent/ ) {
-
- # settimer agent needs to be discarded
- if ( !defined( @{ $sesbot{$interno} } ) ) {
- push @{ $sesbot{$interno} }, "";
- pop @{ $sesbot{$interno} };
- }
-
- push @{ $sesbot{$interno} }, "$canalid";
-
- log_debug( "$heading AGREGO a sesbot($interno) el valor $canalid", 32 ) if DEBUG;
-
- my @uniq = unique( @{ $sesbot{$interno} } );
- $sesbot{$interno} = [@uniq];
-
- foreach my $vavi ( @{ $sesbot{$interno} } ) {
- log_debug( "$heading sesbot($interno) tiene $vavi", 32 ) if DEBUG;
- log_debug( "$heading --------------------", 32 ) if DEBUG;
- }
- }
-
- if ( $canal =~ /^_/ && $quehace =~ /^ring/ ) {
- log_debug( "$heading TENGO UN WILDCARD ORIGINANDO LLAMADO! $canal $quehace $canalid", 32 )
- if DEBUG;
- if ( $quehace eq "ring" ) {
-
- # $quehace = "ocupado1";
- }
- if ( $ren_wildcard == 1 ) {
- push @respuestas, "$interno|changelabel0|$canalid";
- $botonlabel{$interno} = $canalid;
- }
- }
-
- if ( $quehace eq "ringing" ) {
- if ( $laststatus{$interno} ne "ringing|${buttontext}" ) {
- $cambiaron{$interno} = 1;
- }
- $estadoboton{$interno} = "ringing|${buttontext}";
- if ( $dos =~ m/(.*)?\[(.*)\].*?/ ) {
- my $clidtext = $2;
- $botonclid{$interno} = $clidtext;
- }
-
- # We dont want a timer when ringing - Local channels
- # generate a previous state and timer
- push @mensajefinal, "$interno|settimer|0\@STOP";
-
- }
- elsif ( $quehace =~ /^ocupado/ ) {
- if ( $laststatus{$interno} ne "busy|${buttontext}" ) {
- $cambiaron{$interno} = 1;
- }
- $estadoboton{$interno} = "busy|${buttontext}";
- }
- }
- }
-
- log_debug( "$heading Continuo proceso...", 32 ) if DEBUG;
- if ( $quehace =~ /changelabel/ ) {
- log_debug( "$heading quehace = changelabel", 32 ) if DEBUG;
-
- # Mantains state of label and led
- my $cambia_el_led = $quehace;
- $cambia_el_led =~ s/changelabel//g;
- my $labdos = "";
- if ( $canal =~ /^QUEUEAGENT/ ) {
- $labdos = $canalid;
- $labdos = substr( $labdos, 0, -5 );
- $labdos =~ s/(.*)\&(.*)/$1/g;
-
- if ( $labdos =~ m/^Agent/i && $ren_agentname == 1 ) {
- $labdos =~ s/^Agent\///g;
- if ( defined( $agents_name{"$server^$labdos"} ) ) {
- $labdos = $agents_name{"$server^$labdos"};
- }
- }
-
- $botonled{$interno} = $cambia_el_led;
- if ( defined( $botonlabelonly{$interno} ) ) {
- $labdos = $botonlabelonly{$interno};
- }
- $botonlabel{$interno} = $dos;
- $botonlabelonly{$interno} = $labdos;
- $agent_label{$canal} = $dos;
- push @mensajefinal, "$interno|setlabel|$labdos";
- }
- else {
- $botonled{$interno} = $cambia_el_led;
- $botonlabel{$interno} = $dos;
- $agent_label{$canal} = $dos;
- }
-
- }
- if ( $quehace eq "park" ) {
- log_debug( "$heading quehace = park", 32 ) if DEBUG;
- $dos =~ m/(.*)\((.*)\)/;
- my $texto = $1;
- my $timeout = $2;
- $timeout = time() + $timeout;
- $botonpark{$interno} = "$texto|$timeout";
- }
- if ( $quehace eq "meetmeuser" ) {
- $botonmeetme{$interno} = $dos;
- }
-
- if ( $quehace eq "infoqstat" ) {
- $botonqueue{$interno} = $dos;
- }
- elsif ( $quehace eq "infoqstat2" ) {
- $botonqueue_count{$interno} = $dos;
- }
- elsif ( $quehace =~ /info/ ) {
- my $mcola = $quehace;
- $mcola =~ s/^info//g;
- push @{ $botonqueuemember{$interno} }, "$mcola|$dos";
- }
-
- if ( $quehace eq "settext" ) {
- $botonclid{$interno} = $dos;
- push @respuestas, "$interno|settext|$dos";
- }
- if ( $quehace eq "setalpha" ) {
- $botonalpha{$interno} = $dos;
- push @respuestas, "$interno|setalpha|$dos";
- }
- if ( $quehace eq "flip" ) {
- push @respuestas, "$interno|flip|$dos";
- }
- if ( $quehace eq "setlabel" ) {
- if ( $dos ne "."
- && $dos ne "original"
- && $dos ne "labeloriginal" )
- {
- $botonsetlabel{$interno} = $dos;
- push @respuestas, "$interno|setlabel|$dos";
- }
- }
- if ( $quehace eq "voicemail" ) {
- $botonvoicemail{$interno} = $dos;
- }
- if ( $quehace eq "voicemailcount" ) {
- $botonvoicemailcount{$interno} = $dos;
- }
-
- # linkbot{key} hash mantains the list of linked channels
- # for a button. key is the button number, the value is the
- # channel-session, like SIP/jose-AxiD
-
- if ( ( $quehace !~ /^corto/ )
- && ( $quehace !~ /^ocupado/ )
- && ( $quehace !~ /link/ ) )
- {
- $cambiaron{$interno} = 1;
- log_debug( "$heading es distinto de corto,ocupado,link pongo cambiaron=1", 32 ) if DEBUG;
- }
-
- if ( !defined( $sesbot{$interno} ) ) {
- push @{ $sesbot{$interno} }, "";
- pop @{ $sesbot{$interno} };
- }
-
- if ( @{ $sesbot{$interno} } > 0 && $quehace eq 'corto' ) {
- log_debug( "$heading Still busy...sesbot($interno) is not empty, ignoring hangup", 32 )
- if DEBUG;
- }
- else {
-
- # This block is for the voicemail client
- if ( $quehace =~ "^voicemail" ) {
- my $canalsincontexto = $canal;
- $canalsincontexto =~ s/(.*)&(.*)/$1/g;
- push @mensajefinal, "$canalsincontexto\@$canalsincontexto|$quehace|$dos";
- }
-
- # This block is for the voicemail client, popups
- if ( $quehace =~ "^ringing" ) {
- my $canalsincontexto = $canal;
- $canalsincontexto =~ s/(.*)&(.*)/$1/g;
- my $calleridpop = $dos;
- $calleridpop =~ s/(.*)\Q[\E(.*)/$2/g;
- $calleridpop =~ s/\]//g;
- $calleridpop =~ s/\s+//g;
- push @mensajefinal, "$canalsincontexto\@$canalsincontexto|$quehace|$calleridpop";
- }
- if ( $quehace eq "corto" ) {
- my $canalsincontexto = $canal;
- $canalsincontexto =~ s/(.*)&(.*)/$1/g;
- push @mensajefinal, "$canalsincontexto\@$canalsincontexto|$quehace|corto!";
- }
-
- my $quehace2 = $quehace;
-
- if ( $quehace2 eq "ring" ) {
-
- #$quehace2 = "ocupado";
- }
-
- next unless ( $quehace2 ne "setlink" );
- next unless ( $quehace2 ne "unsetlink" );
-
- log_debug( "$heading sigo quehace quehace2", 32 ) if DEBUG;
-
- if ( $quehace2 eq "isagent" && $dos == -1 ) {
- log_debug( "$heading quehace2 = isagent", 32 ) if DEBUG;
- push @mensajefinal, "$interno|changelabel1|original";
- push @mensajefinal, "$interno|settimer|0\@STOP";
- push @mensajefinal, "$interno|settext|";
- push @mensajefinal, "$interno|corto|";
- }
-
- if ( $quehace2 eq "agentlogoff" ) {
-
- # clear the agent helper hashes. We do it here because we first need to map
- log_debug( "$heading quehace2 = agentlogoff", 32 ) if DEBUG;
- my $canalag = $canalid;
- $canalag = substr( $canalag, 0, -5 );
- if ( $canalag !~ /^Agent/ ) {
- $canalag = "Agent/" . $canalag;
- }
- print_agents();
-
- my %temp_channel_to_agent = %channel_to_agent;
- while ( my ( $key, $val ) = each(%temp_channel_to_agent) ) {
- if ( $val eq $canalag ) {
- delete $channel_to_agent{$key};
- log_debug( "$heading borro channel_to_agent($key)", 64 ) if DEBUG;
- }
- }
- undef %temp_channel_to_agent;
-
- if ( defined( $agent_to_channel{"$server^$canalag"} ) ) {
- delete $agent_to_channel{"$server^$canalag"};
- log_debug( "$heading borro agent_to_channel($server^$canalag)", 64 ) if DEBUG;
- }
-
- $quehace2 = "corto";
- delete $estadoboton{$interno};
- delete $botonpark{$interno};
- delete $botonmeetme{$interno};
- delete $botonclid{$interno};
- delete $botonlinked{$interno};
- delete $botontimer{$interno};
- delete $botontimertype{$interno};
- }
-
- if ( $quehace2 !~ /isagent/ && $quehace2 !~ /^agentlogoff/ ) {
- log_debug( "$heading pushing respuestas $interno|$quehace2|$dos", 32 ) if DEBUG;
-
- # Discard events that we dont want to send
- # to flash clients
- # "isagent". "agentlogoff"
- # everything else is pushed
- push @respuestas, "$interno|$quehace2|$dos";
- }
-
- if ( $quehace2 =~ /ocupado/ ) {
- if ( $dos =~ m/(.*)?\[(.*)\].*?/ ) {
- my $clidtext = $2;
- $botonclid{$interno} = $clidtext;
- }
-
- #push @mensajefinal, "$interno|state|busy";
- push @mensajefinal, "$interno|settimer|0\@UP";
- }
- if ( $quehace2 eq "settimer" ) {
- my $tiempo = $dos;
- my $nada = "";
- if ( $tiempo =~ /\@/ ) {
- ( $tiempo, $nada ) = split( /\@/, $tiempo );
- }
- if ( $nada ne "" ) {
- $botontimertype{$interno} = $nada;
- $nada = "\@" . $nada;
- }
- $botontimer{$interno} = time() - $tiempo;
- push @mensajefinal, "$interno|settimer|$tiempo$nada";
- }
-
- if ( $quehace eq "ring" || $quehace eq "ocupado1" || $quehace eq "ocupado9" ) {
- push @mensajefinal, "$interno|settimer|0\@UP";
- if ( !defined( $botontimer{$interno} ) ) {
- $botontimer{$interno} = time();
- $botontimertype{$interno} = "UP";
- }
- }
- if ( $quehace2 eq "ring" ) {
- push @mensajefinal, "$interno|state|busy";
-
- #push @mensajefinal, "$interno|settext|$dos";
- }
- if ( $quehace2 =~ /corto/ ) {
- log_debug( "$heading quehace2 corto", 32 ) if DEBUG;
-
- my $canalsincontexto = $canal;
- $canalsincontexto =~ s/(.*)&(.*)/$1/g;
- $canalsincontexto =~ s/^AGENT/Agent/g;
- if (
- (
- exists( $agent_to_channel{"$server^$canalsincontexto"} )
- || exists( $channel_to_agent{"$server^$canalsincontexto"} )
- || exists( $is_agent{"$server^$canalsincontexto"} )
-
- # || ( $canalsincontexto =~ /^QUEUEAGENT/i )
- )
- && $agent_status == 1
- )
- {
- my $valip = "";
- my $iniagent = "";
- if ( defined( $agent_to_channel{"$server^$canalsincontexto"} ) ) {
- $iniagent = $agent_to_channel{"$server^$canalsincontexto"};
- }
- elsif ( defined( $channel_to_agent{"$server^$canalsincontexto"} ) ) {
- $iniagent = $channel_to_agent{"$server^$canalsincontexto"};
- }
- log_debug( "$heading quehace2 corto y es agente, pushing settimer y settext to idle", 1 ) if DEBUG;
- $botontimer{$interno} = time();
- $botontimertype{$interno} = "IDLE";
- push @mensajefinal, "$interno|settimer|0\@IDLE";
- if ( exists( $boton_ip{"$iniagent-XXXX"} ) ) {
- $valip = $boton_ip{"$iniagent-XXXX"};
- }
- if ( $valip eq "" ) { $valip = "Idle"; }
- $botonclid{$interno} = $valip;
- push @mensajefinal, "$interno|settext|$valip";
- }
- else {
- my $valip = "";
- log_debug( "$heading quehace2 corto, no es agente, pongo timer en cero", 1 ) if DEBUG;
- print_agents();
-
- push @mensajefinal, "$interno|settimer|0\@STOP";
- if ( defined( $boton_ip{"$canal-XXXX"} ) ) {
- $valip = $boton_ip{"$canal-XXXX"};
- push @mensajefinal, "$interno|settext|$valip";
- $botonclid{$interno} = $valip;
- }
- else {
- $botonclid{$interno} = "";
- }
-
- if ( defined( $botonalpha{$interno} ) ) {
- if ( $botonalpha{$interno} ne "" ) {
- push @mensajefinal, "$interno|setalpha|$botonalpha{$interno}";
- }
- }
- }
- }
-
- if ( $quehace eq "registrado" ) {
- if ( defined( $botonalpha{$interno} ) ) {
- if ( $botonalpha{$interno} ne "" ) {
- push @mensajefinal, "$interno|setalpha|50";
- }
- else {
- push @mensajefinal, "$interno|setalpha|100";
- }
- }
- }
-
- if ( $quehace eq "registrado" || $quehace eq "noregistrado" || $quehace eq "unreachable" ) {
- $botonregistrado{$interno} = "$quehace|$dos";
- }
-
- log_debug( "$heading Agrego mensaje final $interno|$quehace2|$dos", 32 ) if DEBUG;
-
- #if (defined($mensajefinal) && $interno ne "")
- $cuantas = @mensajefinal;
- if ( $cuantas > 0 && $interno ne "" ) {
- if ( exists $cambiaron{$interno} ) {
-
- log_debug( "$heading Existe cambiaron($interno) = $cambiaron{$interno}", 32 )
- if DEBUG;
-
- #push(@respuestas, $mensajefinal);
- foreach (@mensajefinal) {
- push @respuestas, $_;
- }
- }
- else {
-
- log_debug( "$heading No existe cambiaron($interno)", 32 ) if DEBUG;
- foreach (@mensajefinal) {
-
- # If the last status was not modified, avoid sending info
- # push @respuestas, $_;
- }
- }
- if ( $todo ne "" ) {
- my $otromensajefinal = "$interno|info|$todo";
- push( @respuestas, $otromensajefinal );
- }
- }
- }
-
- $laststatus{$interno} = $estadoboton{$interno};
- }
- else { # endif canal distinto de nada
- log_debug( "$heading There is no command defined", 32 ) if DEBUG;
- }
- }
- }
- }
- }
-
- @respuestas = unique(@respuestas);
- $cuantas = $#respuestas + 1;
- log_debug( "$heading end, return $cuantas", 16 ) if DEBUG;
- foreach my $valor (@respuestas) {
- log_debug( "$heading END SUB: returns $valor", 32 ) if DEBUG;
- }
- $tab = substr( $tab, 0, -1 ) if DEBUG;
- return @respuestas;
-}
-
-sub translate {
-
- my $canal = shift;
- my $dos = shift;
- my $dosoriginal = shift;
- my $buttontext = shift;
-
- my @return;
-
- # Try to find the text string in the lang conf hash
- my $ctx = "";
- if ( $canal =~ m/.*\&(.*)/ ) {
- $ctx = $1;
- }
- else {
- $ctx = "DEFAULT";
- }
- my ( $partstring, $varsub ) = split( /,/, $dos, 2 );
- $partstring =~ s/&(.*)/$1/g;
- if ( !defined($varsub) ) { $varsub = ""; }
- my $traduc = $language->{$ctx}{$partstring};
- if ( $varsub =~ m/.*&/ ) {
-
- # Horrible hack, if variable ends in &, set the text
- # between brackets so it will be displayed as a whole in the
- # button's clid area
- $varsub = substr( $varsub, 0, -1 );
- my ( $var1, $var2 ) = split( /,/, $varsub );
- $traduc =~ s/\$1/$var1/g if defined $var1;
- $traduc =~ s/\$2/$var2/g if defined $var2;
- $traduc =~ s/\$1//g;
- $traduc =~ s/\$2//g;
- $dosoriginal = $dos;
- $dos = "[" . $traduc . "]";
- $buttontext = $dos;
- }
- else {
- my ( $var1, $var2 ) = split( /,/, $varsub );
- $traduc =~ s/\$1/$var1/g if defined $var1 && $var1 ne "";
- $traduc =~ s/\$2/$var2/g if defined $var2 && $var1 ne "";
- $traduc =~ s/\$1//g;
- $traduc =~ s/\$2//g;
- $dosoriginal = $dos;
- $dos = $traduc;
- }
-
- push @return, $dos;
- push @return, $dosoriginal;
- push @return, $buttontext;
-
- return @return;
-}
-
-sub nonblock {
- my $socket = shift;
- my $flags;
-
- $flags = fcntl( $socket, F_GETFL, 0 )
- or die "Can't get flags for socket: $!\n";
- fcntl( $socket, F_SETFL, $flags | O_NONBLOCK )
- or die "Can't make socket nonblocking: $!\n";
-}
-
-sub clean_inmemory_state_for_server {
- my $server = shift;
- my @botones_a_limpiar;
- log_debug( "CLEAN_INMEMORY from server $server)", 16 ) if DEBUG;
- foreach ( keys(%buttons) ) {
- my $btn_server = $_;
- $btn_server =~ s/^(\d+)\^.*/$1/g;
- if ( $btn_server eq $server ) {
- push @botones_a_limpiar, $buttons{$_};
- }
- }
-
- foreach (@botones_a_limpiar) {
- delete $estadoboton{$_};
- delete $botonled{$_};
- delete $botonlabelonly{$_};
- delete $botonvoicemail{$_};
- delete $botonvoicemailcount{$_};
- delete $botonalpha{$_};
- delete $botonqueue{$_};
- delete $botonqueuemember{$_};
- delete $botonqueue_count{$_};
- delete $botonpark{$_};
- }
-}
-
-sub manager_connection {
- my $host = "";
- my $user = "";
- my $pass = "";
- my $heading = "** MANAGER CONNECTION";
- my $temphandle = "";
- my $contador = 0;
- my $port = "5038";
-
- foreach my $mhost (@manager_host) {
- if ( defined($mhost) ) {
- $host = $mhost;
- $user = $manager_user[$contador];
- $pass = $manager_secret[$contador];
- $port = $manager_port[$contador] if defined( $manager_port[$contador] );
-
- if ( defined( $manager_conectado[$contador] ) ) {
- if ( $manager_conectado[$contador] == 1 ) {
- $contador++;
- next;
- }
- }
-
- log_debug( "$heading Connecting to $mhost:$port (Server $contador)", 1 ) if DEBUG;
-
- $p[$contador] = new IO::Socket::INET->new(
- PeerAddr => $manager_host[$contador],
- PeerPort => $port,
- Proto => "tcp",
- Type => SOCK_STREAM
- );
-
- if ( !$p[$contador] ) {
- log_debug( "$heading Couldn't connect to $mhost:$port (Server $contador)", 1 ) if DEBUG;
- $p[$contador] = "";
- $manager_conectado[$contador] = 0;
- $manager_desconectado{$contador} = time();
- $contador++;
- next;
- }
- else {
- log_debug( "$heading Connected to $mhost:$port (Server $contador)", 1 ) if DEBUG;
- $manager_conectado[$contador] = 1;
- if ( defined( $manager_desconectado{$contador} ) ) {
- delete $manager_desconectado{$contador};
- }
- $p[$contador]->autoflush(1);
- $ip_addy{ $p[$contador] } = peerinfo( $p[$contador], 1 );
- clean_inmemory_state_for_server($contador);
- }
-
- my $mask = "";
- if ( defined( $event_mask[$contador] ) ) {
- $mask_hash{ $p[$contador] } = $event_mask[$contador];
- }
-
- $manager_socket{ $p[$contador] } = $manager_host[$contador] . "|" . $manager_user[$contador] . "|" . $manager_secret[$contador];
- my $command = "";
-
- # If using astmanproxy, override authentication
- if ( $astmanproxy_host ne "" ) {
- $autenticado{ $p[$contador] } = 1;
- send_eventmask( $p[$contador] );
- send_initial_status( $p[$contador] );
- }
- else {
- if ( $auth_md5 == 1 ) {
- $command = "Action: Challenge\r\n";
- $command .= "AuthType: MD5\r\n\r\n";
- }
- else {
- $command = "Action: Login\r\n";
- $command .= "Username: $user\r\n";
- $command .= "Secret: $pass\r\n\r\n";
- }
- send_command_to_manager( $command, $p[$contador], 1 );
- }
-
- }
- $contador++;
- }
-
- # Adds AMI handles into IO::Select
- foreach (@p) {
- if ( defined($_) ) {
- $O->add($_);
- }
- }
-
-}
-
-sub send_eventmask {
- my $socket = shift;
- if ( defined( $mask_hash{$socket} ) ) {
- my $comando = "Action: Events\r\n";
- $comando .= "EventMask: " . $mask_hash{$socket} . "\r\n\r\n";
- send_command_to_manager( $comando, $socket );
- }
-}
-
-sub clean_socket {
- my $socket = shift;
- my $heading = "** CLEAN SOCKET ";
- log_debug( "$heading connection lost removing socket $socket", 1 ) if DEBUG;
-
- $O->remove($socket);
- $socket->close;
- delete $ip_addy{$socket};
- if ( exists( $manager_socket{$socket} ) ) {
- delete $manager_queue{$socket};
-
- # The closed connections belong to an asterisk manager port
- my @partes = split( /\|/, $manager_socket{$socket} );
- my @pp = ();
- my $counter = 0;
- foreach my $cual (@p) {
- if ( defined($cual) ) {
- if ( $cual eq $_ ) {
- log_debug( "$heading Connection lost to server $counter", 1 ) if DEBUG;
- $manager_conectado[$counter] = 0;
- $manager_desconectado{$counter} = time();
- delete $autenticado{$_};
- push @pp, "";
- }
- else {
- log_debug( "$heading still connected to $ip_addy{$cual}", 16 ) if DEBUG;
- push @pp, $cual;
- }
- }
- $counter++;
- }
- @p = @pp;
- }
- else {
-
- # The closed socket was from a client
- log_debug( "$heading flash client connection lost", 1 ) if DEBUG;
- delete $client_queue{$socket};
- delete $client_queue_nocrypt{$socket};
- my $cualborrar = $socket;
- my @temp = grep( !/\Q$cualborrar\E/, @flash_clients );
- @flash_clients = @temp;
- delete $keys_socket{$socket};
- &print_clients();
- }
-}
-
-collect_includes( "op_buttons.cfg", "buttons" );
-collect_includes( "op_style.cfg", "style" );
-read_buttons_config();
-read_server_config();
-read_language_config();
-read_astdb_config();
-genera_config();
-
-# Tries to open the listening socket
-$m = new IO::Socket::INET( Listen => 1, LocalAddr => $listen_addr, LocalPort => $listen_port, ReuseAddr => 1, Blocking => 0 )
- or die "\nCan't listen to port $listen_port\n";
-$O = new IO::Select();
-$O->add($m);
-
-# Connects to the asterisk boxes
-manager_connection();
-
-$/ = "\0";
-
-# MAIN
-# Endless loop
-while (1) {
- my $heading = "** MAIN";
-
- # Attempt reconnections to dead asterisk servers every 10 seconds
- if (%manager_desconectado) {
- while ( my ( $key, $val ) = each(%manager_desconectado) ) {
- my $seconds_to_go = ( time() - $val ) % 10;
- if ( $seconds_to_go == 9 ) {
- manager_connection();
- }
- }
- }
-
- while ( @S = $O->can_read(0.1) ) # profile
- {
- foreach (@S) {
- my $handle = $_;
-
- if ( $_ == $m ) {
-
- # New client connection
- my $C = $m->accept;
- $ip_addy{$C} = peerinfo( $C, 1 );
- log_debug( "$heading New client connection $ip_addy{$C}", 1 ) if DEBUG;
- push( @flash_clients, $C );
- $O->add($C);
- nonblock($C);
- }
- else {
-
- # Its not a new client connection
- my %i;
- my $R;
- $R = sysread( $_, $i{$handle}, BYTES_TO_READ ); # profile
- if ( defined($R) && $R == 0 ) {
-
- # Could not read.. close the socket
- log_debug( "$heading closing $ip_addy{$_}", 1 ) if DEBUG;
- clean_socket($_);
- }
- else {
- $bloque_completo{$handle} = ""
- if ( !defined( $bloque_completo{$handle} ) );
- $buferbloque{$handle} = ""
- if ( !defined( $buferbloque{$handle} ) );
- if ( $buferbloque{$handle} ne "" ) {
- $bloque_completo{$handle} = $buferbloque{$handle};
- $buferbloque{$handle} = "";
- }
- $bloque_completo{$handle} .= $i{$handle};
-
- next
- if ( $bloque_completo{$handle} !~ /\r\n\r\n/
- && $bloque_completo{$handle} !~ /\0/ );
-
- # From here we have one or more Event block
- # to process. The last one might be incomplete
- # so we have to buffer it for the next can_read
-
- my @event_blocks = ();
- if ( $bloque_completo{$handle} =~ /\0/ ) {
- $bloque_completo{$handle} =~ s/\0/\$\$\$\0/g;
- @event_blocks = split /\0/, $bloque_completo{$handle};
- }
- else {
- $bloque_completo{$handle} =~ s/\r\n\r\n/\$\$\$\r\n\r\n/g;
- @event_blocks = split /\r\n\r\n/, $bloque_completo{$handle};
- }
-
- foreach my $block (@event_blocks) {
-
- if ( $block !~ /\$\$\$/ ) {
-
- # if there is no end, buffer the block
- $buferbloque{$handle} = $block;
- }
- else {
- $block =~ s/\$\$\$/\n/g;
-
- # process an individual manager block stored in $block
- if ( exists( $manager_socket{$handle} ) ) {
- my @part = split( /\|/, $manager_socket{$handle} );
- log_debug( "$heading End of block from $part[0]", 16 ) if DEBUG;
- }
-
- $bloque_final = $block;
- $bloque_final =~ s/([^\r])\n/$1\r\n/g; # Reemplaza \n solo por \r\n
- $bloque_final =~ s/\r\n\r\n/\r\n/g;
- $bloque_completo{$handle} = "";
-
- ##################################################
- # If we have a Server header, asume this is comming from astmanproxy
- # and replace the server address to the server index number that FOP uses
- # and that is specified in op_server.cfg file with the astmanproxy_server
- # keyword
- if ( $bloque_final =~ /.*?^Server: .*$/xms ) {
- $astmanproxy_server = $bloque_final;
- $astmanproxy_server =~ s/.*?^Server: \s ([\.\w]*) .*? \z/$1/xms;
- my $que_manager = 0;
- foreach my $address (@astmanproxy_servers) {
- if ( $address eq $astmanproxy_server ) {
- $bloque_final =~ s/(.*?^Server: \s)([\.\w]*)( .*? \z)/${1}${que_manager}${3}/xms;
- }
- $que_manager++;
- }
- }
- else {
-
- # Add the asterisk server number as a part of the event block
- my $que_manager = 0;
- foreach my $handle_manager_connected (@p) {
- if ( $handle_manager_connected eq $handle ) {
-
- $bloque_final = $bloque_final . "Server: $que_manager";
- }
- $que_manager++;
- }
- }
-
- ####################################################
- # This block is just for logging in the event
- # to stdout
- if ( ( $debuglevel & 1 ) && DEBUG ) {
- my @lineas = split( "\r\n", $bloque_final );
- foreach my $linea (@lineas) {
- if ( exists( $manager_socket{$handle} ) ) {
- my $linea_formato = sprintf( "%-15s <- %s", $ip_addy{$handle}, $linea );
- log_debug( $linea_formato, 1 ) if DEBUG;
- }
- }
- $global_verbose = 'separator';
- }
- ##################################################
-
- foreach my $C ( $O->handles ) {
- if ( $C == $handle ) {
- log_debug( "$heading AST event received...", 16 ) if DEBUG;
-
- # Asterisk event received
- # Read the info and arrange it into blocks
- # for processing in 'procesa_bloque'
- if ( $bloque_final =~ /Event:/
- || $bloque_final =~ /Message: Mailbox/
- || $bloque_final =~ /Message: Timeout/ )
- {
- log_debug( "$heading There's an 'Event' in the event block", 32 ) if DEBUG;
- my @lineas = split( /\r\n/, $bloque_final );
- @bloque = ();
- my $block_count = -1;
- foreach my $p (@lineas) {
- my $my_event = "";
- if ( $p =~ /Event:/ ) {
- $block_count++;
- log_debug( "$heading Event detected block_count = $block_count", 128 )
- if DEBUG;
- }
- elsif ( $p =~ /Message: Mailbox/ ) {
- $my_event = "MessageWaiting"; # Fake event
- $block_count++;
- log_debug( "$heading Event mailbox detected block_count = $block_count", 128 )
- if DEBUG;
- }
- my ( $atributo, $valor ) = split( /: /, $p, 2 );
- if ( defined $atributo && $atributo ne "" ) {
- if ( $my_event ne "" ) {
- $atributo = "Event";
- $valor = $my_event;
- log_debug( "$heading Fake event generated $atributo=$valor", 128 )
- if DEBUG;
- }
- if ( length($atributo) >= 1 ) {
- if ( $block_count < 0 ) {
- $block_count = 0;
- }
- $bloque[$block_count]{"$atributo"} = $valor;
- }
- }
- }
- log_debug( "$heading There are $block_count blocks for processing", 128 )
- if DEBUG;
- @respuestas = ();
- log_debug( "$heading Answer block cleared", 32 ) if DEBUG;
- @respuestas = digest_event_block( \@bloque, "real", $C, $astmanproxy_server );
- @masrespuestas = ();
- while (@fake_bloque) {
- my @respi = digest_event_block( \@fake_bloque, "fake", $C, $astmanproxy_server );
- foreach (@respi) {
- push @masrespuestas, $_;
- }
- }
- }
- elsif ( $bloque_final =~ /--END COMMAND--/ ) {
- log_debug( "$heading There's an 'END' in the event block", 32 ) if DEBUG;
- $todo .= $bloque_final;
- process_cli_command($todo);
- my $cuantos = @bloque;
- log_debug( "$heading There are $cuantos blocks for processing", 128 ) if DEBUG;
- @respuestas = digest_event_block( \@bloque, "real", $C, $astmanproxy_server );
- @masrespuestas = ();
- while (@fake_bloque) {
- my @respi = digest_event_block( \@fake_bloque, "fake", $C, $astmanproxy_server );
- foreach (@respi) {
- push @masrespuestas, $_;
- }
- }
- $todo = "";
- }
- elsif ( $bloque_final =~ /<msg/ ) {
- $bloque_final =~ s/\n//g;
- log_debug( "$heading Processing command received from flash clients...", 32 )
- if DEBUG;
- process_flash_command( $bloque_final, $_ );
- @respuestas = ();
- $bloque_final = "";
- $todo = "";
- }
- elsif ( $bloque_final =~ /Challenge:/ ) {
- my @lineas = split( /\r\n/, $bloque_final );
- foreach my $p (@lineas) {
- if ( $p =~ /Challenge:/ ) {
- $p =~ s/^Challenge: (.*)/$1/g;
- $md5challenge = $p;
- }
- }
- manager_login_md5( $md5challenge, $C );
- }
- elsif ( $bloque_final =~ /Message: Authentication ac/i ) {
-
- # Authentication Accepted, enable sending commands
- $autenticado{$C} = 1;
- send_eventmask($C);
- send_initial_status($C);
- }
- else {
- log_debug( "$heading No 'Event' nor 'End'. Erasing block...", 32 ) if DEBUG;
-
- # No Event in the block. Lets clear it up...
- @bloque = ();
- $todo .= $bloque_final;
- }
- }
- else {
-
- # Send messages to Flash clients
- @respuestas = ( @respuestas, @masrespuestas );
- @masrespuestas = ();
- @respuestas = unique(@respuestas);
-
- if ( !defined( $autenticado{$C} ) ) { # try to exclude manager connections
- foreach my $valor (@respuestas) {
- if ( defined( $flash_contexto{$C} ) ) {
- send_status_to_flash( $C, $valor, 0 );
- }
- } # end foreach respuestas
- }
- }
- } # end foreach handles
-
- }
- }
-
- } # end else the handle is readable
- } # end else for active connections
- } # end foreach @S -> can read
- } # while can read
-
- foreach my $sacket ( $O->can_write(0.1) ) # profile
- {
- if ( defined( $client_queue{$sacket} ) ) {
-
- # Loop through command buffer to send to clients
- while ( my $comd = shift @{ $client_queue{$sacket} } ) {
- my $tolog = shift @{ $client_queue_nocrypt{$sacket} };
- my $ret = actual_syswrite( $sacket, $comd, "isclient", $tolog );
- if ( $ret == -1 ) {
- log_debug( "Partial syswrite, buffering for client $ip_addy{$sacket}", 1 ) if DEBUG;
- last;
- }
-
- }
- }
- if ( defined( $manager_queue{$sacket} ) ) {
-
- # Loop through command buffer to send to managers
- while ( my $comd = shift @{ $manager_queue{$sacket} } ) {
- my $cuantos = @{ $manager_queue{$sacket} };
-
- my $ret = actual_syswrite( $sacket, $comd, "ismanager", $comd );
- if ( $ret == -1 ) {
- log_debug( "Partial syswrite, buffering for server $ip_addy{$sacket}", 1 ) if DEBUG;
- last;
- }
-
- }
- }
- }
-} # endless loop
-
-sub actual_syswrite {
- my ( $socket, $encriptadofinal, $whom, $log ) = @_;
- my $largo = length($encriptadofinal);
- my $res = syswrite( $socket, $encriptadofinal, $largo );
-
- if ( defined $res && $res > 0 ) {
- if ( $res != $largo ) {
-
- # Could not write the whole command, buffer
- # the rest for later
- my $offset = $largo - $res;
- $offset = $offset * -1;
- my $buf = substr( $encriptadofinal, $offset );
- unshift( @{ $client_queue{$socket} }, $buf );
- unshift( @{ $client_queue_nocrypt{$socket} }, $log );
- log_debug( "Partial syswrite, len $res but $largo written", 1 ) if DEBUG;
-
- my $cuantos = @{ $client_queue{$socket} };
- if ( $cuantos > 200 ) {
- &clean_socket($socket);
- }
- return -1;
- }
- else {
-
- # Write succesfull, log to stdout
- $log = substr( $log, 0, -1 );
- if ( $debuglevel > 0 ) {
- if ( $whom eq "isclient" ) {
- my $linea_formato = sprintf( "%-15s => %s", $ip_addy{$socket}, $log );
- log_debug( "$linea_formato", 8 ) if DEBUG;
- $global_verbose = "separador";
- }
- else {
- $log =~ s/\r//g;
- $log =~ s/\n//g;
- if ( $log ne "" ) {
- my $linea_formato = sprintf( "%-15s -> %s", $ip_addy{$socket}, $log );
- log_debug( "$linea_formato", 2 ) if DEBUG;
- }
- else {
- $global_verbose = "separador";
- }
- }
- }
- }
- }
- elsif ( $! == EWOULDBLOCK ) {
-
- # would block: not an error
- # handle blocking, by trying again later
- log_debug( "Write wouldblock, buffering for $ip_addy{$socket}", 1 ) if DEBUG;
- push( @{ $client_queue{$socket} }, $encriptadofinal );
- push( @{ $client_queue_nocrypt{$socket} }, $log );
- my $cuantos = @{ $client_queue{$socket} };
- if ( $cuantos > 200 ) {
- &clean_socket($socket);
- }
- }
- else {
- log_debug( "Write error on $ip_addy{$socket}", 1 ) if DEBUG;
- &clean_socket($socket);
- }
- return 0;
-}
-
-sub get_transfer_channel {
-
- my $origin_channel = shift;
- my $datosflash = shift;
-
- my @cuales_transferir = ();
-
- my $local_reverse = $reverse_transfer;
-
- if ( $origin_channel =~ m/^PARK/i || $origin_channel =~ m/^QUEUE/i || $origin_channel =~ m/^\d/ ) {
- $local_reverse = 0;
- log_debug("** GET TRANSFER Disable reverse transfer for $origin_channel!",16) if DEBUG;
- }
-
- if ( $local_reverse == 1 ) {
- log_debug( "** !! REVERSE TRANSFER", 16 ) if DEBUG;
-
- # Transfer the session from the *other* button
- @cuales_transferir = extraer_todos_los_enlaces_de_un_canal( $origin_channel, $button_server{$datosflash} );
- if (@cuales_transferir == 0) {
- log_debug( "** !! REVERSE TRANSFER No reverse available, using regular sesbot", 16 ) if DEBUG;
- if ( @{ $sesbot{$datosflash} } ) {
- @cuales_transferir = @{ $sesbot{$datosflash} };
- }
- }
- }
- else {
- log_debug( "** !! NORMAL TRANSFER", 16 ) if DEBUG;
-
- # Transfer the session from the same button
- if ( @{ $sesbot{$datosflash} } ) {
- @cuales_transferir = @{ $sesbot{$datosflash} };
- }
- else {
- @cuales_transferir = ();
- }
- }
-
- return @cuales_transferir;
-
-}
-
-sub process_flash_command {
-
- # This function process a command received from a Flash client
- # Including request of transfers, hangups, etc
- my $comando = shift;
- my $socket = shift;
- my $datosflash = "";
- my $accion = "";
- my $password = "";
- my $valor = "";
- my $origin_channel = "";
- my $origin_server = "";
- my $canal_destino = "";
- my $destin_server = "";
- my $contexto = "";
- my $btn_destino = "0";
- my $extension_destino;
- my $origin_context = "";
- my $canal;
- my $nroboton;
- my $destino;
- my $sesion;
- my @partes;
- my $ultimo;
- my $clid;
- my $myclave;
- my $md5clave;
- my @pedazos;
- my $panelcontext;
- my $auto_conf_exten;
- my $conference_context;
- my $bargerooms;
- my $found_room;
- my $servidor_dial = "";
- my $heading = "-- PROCESS_FLASH_COMMAND";
- my $calltimeout = 0;
-
- my $linea_formato = sprintf( "%-15s <= %s", $ip_addy{$socket}, $comando );
- log_debug( "$linea_formato", 4 ) if DEBUG;
-
- $tab = $tab . "\t" if DEBUG;
-
- $comando =~ s/<msg data=\"(.*)\"\s?\/>/$1/g; # Removes XML markup
- ( $datosflash, $accion, $password ) = split( /\|/, $comando );
- chop $password;
- log_debug( "$heading datosflash $datosflash accion $accion password $password", 16 ) if DEBUG;
-
- if ( $accion =~ /\+/ ) {
-
- # The command has a timeout for the call
- $accion =~ s/(.*)\+(.*)\+(.*)/$1$3/g;
- $calltimeout = $2;
- }
-
- my $elementname = $datosflash;
- $elementname =~ s/(.*)\.(.*)/$2/g;
- $elementname =~ s/([^\@]*)(.*)/$1/g;
- $elementname =~ s/\d//g;
-
- if ( $datosflash =~ /_level0\.casilla/ ) {
- $datosflash =~ s/_level0\.casilla(\d+)/$1/g;
- }
- if ( $datosflash =~ /_level0\.rectangulo/ ) {
- $datosflash =~ s/_level0\.rectangulo(\d+).*/$1/g;
- }
-
- log_debug( "$heading datosflash before context $datosflash", 128 ) if DEBUG;
-
- # Appends context if defined because my crappy regexp only extracts digits
- # FIXME make a regexp that extract digits and digits at context
- if ( defined( $flash_contexto{$socket} ) ) {
- if ( $flash_contexto{$socket} ne "" ) {
- if ( $datosflash =~ /\@/ ) {
-
- # No need to append context
- }
- else {
- $datosflash .= "\@" . $flash_contexto{$socket};
- }
- }
- }
-
- log_debug( "$heading datosflash after context $datosflash", 128 ) if DEBUG;
-
- undef $origin_channel;
-
- # Flash clients send a "contexto" command on connect indicating
- # the panel context they want to receive. We populate a hash with
- # sockets/contexts in order to send only the events they want
- # And because this is an initial connection, it triggers a status
- # request to Asterisk
-
- if ( $accion =~ /^contexto\d+/ ) {
-
- my ( $nada, $contextoenviado ) = split( /\@/, $datosflash );
-
- if ( defined($contextoenviado) ) {
- $flash_contexto{$socket} = $contextoenviado;
- }
- else {
- $flash_contexto{$socket} = "";
- }
- if ( $datosflash =~ /^1/ ) {
- $no_encryption{$socket} = 1;
- }
- else {
- $no_encryption{$socket} = 0;
- }
-
- sends_key($socket);
- sends_version($socket);
-
- # send_initial_status();
- first_client_status($socket);
- $tab = substr( $tab, 0, -1 ) if DEBUG;
- return;
- }
- if ( defined( $flash_contexto{$socket} ) ) {
- $panelcontext = $flash_contexto{$socket};
- }
- else {
- $panelcontext = "";
- }
- if ( $panelcontext eq "" ) { $panelcontext = "GENERAL"; }
-
- if ( defined( $config->{$panelcontext}{conference_context} ) ) {
- $conference_context = $config->{$panelcontext}{conference_context};
- }
- else {
- if ( defined( $config->{GENERAL}{conference_context} ) ) {
- $conference_context = $config->{GENERAL}{conference_context};
- }
- else {
- $conference_context = "";
- }
- }
-
- if ( defined( $config->{$panelcontext}{barge_rooms} ) ) {
- $bargerooms = $config->{$panelcontext}{barge_rooms};
- ( $first_room, $last_room ) = split( /-/, $bargerooms );
- }
- else {
- if ( defined( $config->{GENERAL}{barge_rooms} ) ) {
- $bargerooms = $config->{GENERAL}{barge_rooms};
- ( $first_room, $last_room ) = split( /-/, $bargerooms );
- }
- else {
- $bargerooms = "";
- }
- }
-
- # We have the origin button number from the drag&drop in the 'datos'
- # variable. We need to traverse the %buttons hash in order to extract
- # the channel name and the panel context, used to find the destination
- # button of the command if any
- if ( $accion =~ /^meetmemute/
- || $accion =~ /^meetmeunmute/
- || $accion =~ /^bogus/
- || $accion =~ /^restart/ )
- {
- $origin_channel = "bogus";
- }
- else {
- my $datosflash_sincontexto = $datosflash;
- $datosflash_sincontexto =~ s/(.*)\@(.*)/$1/g;
-
- if ( is_number($datosflash_sincontexto) ) {
-
- # If the originator is a number, assume button position
- # on fop, extract the channel name from the button_reverse hash
-
- $canal = $buttons_reverse{$datosflash};
-
- # A button key with an & is for a context channel
- # A button key with an = is for a trunk channel
- # This bit of code just cleans the channel name and context
- if ( $canal =~ m/&/ ) {
- @pedazos = split( /&/, $canal );
- $origin_context = $pedazos[1];
- my @pedazos2 = split( /\^/, $pedazos[0] );
- $origin_server = $pedazos2[0];
- $origin_channel = $pedazos2[1];
- }
- else {
- my @pedazos2 = split( /\^/, $canal );
- $origin_server = $pedazos2[0];
- $origin_channel = $pedazos2[1];
- }
- }
- else {
-
- # The origin has letters, assume its a channel name
- # with a possible extensions.conf context after '@'
- # (We have already removed the '@fop_context')
-
- if ( $datosflash_sincontexto =~ /\@/ ) {
- $contexto = $datosflash_sincontexto;
- $datosflash_sincontexto =~ s/(.*)\@(.*)/$1/g;
- $contexto =~ s/(.*)\@(.*)/$2/g;
- }
-
- $origin_channel = $datosflash_sincontexto;
-
- # If we receive a channel name for the dial command
- # we default to server number 1 to send the command
- $servidor_dial = "default";
-
- }
- }
-
- if ( $origin_channel =~ m/^clid/i ) {
- $contexto = $datosflash;
-
- if ( $contexto =~ m/\@/ ) {
- $contexto =~ s/(.*)\@(.*)/$2/g;
- if ( defined($contexto) && $contexto ne "" ) {
- $contexto = "&" . $contexto;
- }
- }
- else {
- $contexto = "";
- }
-
- my $local_channel_for_clid_buttons = $extension_transfer{"$origin_server^$origin_channel$contexto"};
- $local_channel_for_clid_buttons =~ s/\d+\^(.*)/$1/g;
- $origin_channel = "Local/" . $local_channel_for_clid_buttons;
-
- # Add the reverse transfer extension to make the callerid in originate work
- $extension_transfer{"$origin_server^$origin_channel$contexto"} = "Local/$local_channel_for_clid_buttons";
- }
-
- if ( $accion =~ /^restrict/ && defined($origin_channel) ) {
- my $contextoaagregar = "";
- if ( $panelcontext ne "GENERAL" ) {
- $contextoaagregar = "&$panelcontext";
- }
- $restrict_channel = $origin_channel;
- log_debug( "$heading RESTRICT commands to channel $restrict_channel", 32 ) if DEBUG;
- my $indice = "0^$restrict_channel$contextoaagregar";
- log_debug( "$heading RESTRICT indice $indice", 32 ) if DEBUG;
- my $btn_num = "0";
- if ( defined( $buttons{$indice} ) ) {
- $btn_num = $buttons{$indice};
- $btn_num =~ s/(.*)\@(.*)/$1/g;
- }
- if ( $btn_num ne "0" ) {
- log_debug( "$heading RESTRICT btn_num $btn_num", 32 ) if DEBUG;
- my $manda = "$btn_num|restrict|0";
- send_status_to_flash( $socket, $manda, 0 );
- }
- else {
- log_debug( "$heading RESTRICT channel not found $indice!", 32 ) if DEBUG;
- }
- $tab = substr( $tab, 0, -1 ) if DEBUG;
- return;
- }
-
- if ( defined($origin_channel) ) {
- log_debug( "$heading origin_channel = $origin_channel", 64 ) if DEBUG;
-
- if ( defined( $config->{$panelcontext}{security_code} ) ) {
- $myclave = $config->{$panelcontext}{security_code} . $keys_socket{$socket};
- log_debug( "$heading usando key " . $keys_socket{$socket}, 16 ) if DEBUG;
- }
- else {
- $myclave = "";
- $myclave = $config->{GENERAL}{security_code} . $keys_socket{$socket};
- log_debug( "$heading usando key " . $keys_socket{$socket}, 16 ) if DEBUG;
- }
-
- if ( $myclave ne "" ) {
- $md5clave = MD5HexDigest($myclave);
- }
-
- if ( ( "$password" eq "$md5clave" )
- || ( $accion =~ /^dial/ && $cdial_nosecure == 1 ) )
- {
- sends_correct($socket);
- log_debug( "** The channel selected is $origin_channel and the security code matches", 16 ) if DEBUG;
- sends_key($socket);
- if ( $accion =~ /^restart/ ) {
-
- $comando = "Action: Command\r\n";
- $comando .= "Command: restart when convenient\r\n\r\n";
- log_debug( "!! Command received: restart when convenient", 32 ) if DEBUG;
- send_command_to_manager( $comando, $p[0], 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
-
- # FIXME restart only works for the 1st server defined
- alarm(10);
- $tab = substr( $tab, 0, -1 ) if DEBUG;
- return;
- }
-
- if ( $accion =~ /-/ ) {
-
- #if action has an "-" the command has clid text to pass
- @partes = split( /-/, $accion );
- $ultimo = @partes;
- $ultimo--;
- $btn_destino = $partes[$ultimo];
- $ultimo--;
- $clid = $partes[$ultimo];
-
- if ( defined($origin_context) ) {
-
- if ( length($origin_context) > 0 ) {
- $btn_destino = $btn_destino . "@" . $origin_context;
- }
- }
- }
- else {
-
- #strips the destination button (number at the end)
- $btn_destino = $accion;
- $btn_destino =~ s/[A-Za-z- ]//g;
- if ( $btn_destino eq "" ) { $btn_destino = "0"; }
-
- if ( defined($origin_context) ) {
- if ( length($origin_context) > 0 ) {
- $btn_destino = $btn_destino . "@" . $origin_context;
- }
- }
- }
- if ( $btn_destino eq "" ) { $btn_destino = "0"; }
- if ( $btn_destino eq "0" ) {
- log_debug( "$heading btn_destino es igual a cero!", 32 ) if DEBUG;
- }
- else {
-
- log_debug( "$heading btn_destino = $btn_destino", 32 ) if DEBUG;
- if ( defined( $buttons_reverse{$btn_destino} ) ) {
- $canal = $buttons_reverse{$btn_destino};
- $canal =~ s/(.*)=(.*)/$1/g;
- }
- else {
- $canal = "";
- }
- $destino = $canal;
- }
-
- if ( defined($destino) && $destino ne "" ) {
- if ( $destino ne "0" ) {
- log_debug( "$heading destino es igual a $destino", 32 ) if DEBUG;
- my @pedazos2 = split( /\^/, $destino );
- $destin_server = $pedazos2[0];
- $destino = $pedazos2[1];
- ( $destino, my $nada ) = split( /\&/, $pedazos2[1] );
- log_debug( "$heading El boton de destino es $destino en el server $destin_server", 64 ) if DEBUG;
- }
- }
-
- if ( $accion =~ /^tovoicemail/ ) {
-
- my $keyext = "$origin_server^$origin_channel";
- my $exttran = $tovoicemail{$btn_destino};
- my ( $extx, $contextx ) = split( /\@/, $exttran, 2 );
-
- my @cuales_transferir = get_transfer_channel( $origin_channel, $datosflash );
- my $cuantos = @cuales_transferir;
-
- if ( $cuantos > 0 ) {
- $comando = "Action: Redirect\r\n";
- $comando .= "Channel: $cuales_transferir[0]\r\n";
- $comando .= "Exten: $extx\r\n";
- $comando .= "ActionID: 1234\r\n";
- $comando .= "Context: $contextx\r\n";
- $comando .= "Priority: 1\r\n\r\n";
- }
- else {
- $comando = "Action: Originate\r\n";
- $comando .= "Channel: $origin_channel\r\n";
- $comando .= "Exten: $extx\r\n";
- $comando .= "ActionID: 1234\r\n";
- $comando .= "Context: $contextx\r\n";
- $comando .= "Priority: 1\r\n\r\n";
- }
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
-
- return;
- }
- if ( $accion =~ /^voicemail/ ) {
- my $vext = "";
- my $vcontext = "";
-
- if ( defined( $config->{$panelcontext}{voicemail_extension} ) ) {
- my $voicemailext = $config->{$panelcontext}{voicemail_extension};
- ( $vext, $vcontext ) = split( /\@/, $voicemailext );
- }
- else {
- log_debug( "There is no voicemail_extension defined in op_server.cfg!", 32 ) if DEBUG;
- $tab = substr( $tab, 0, -1 ) if DEBUG;
- return;
- }
-
- my $keyext = "$origin_server^$origin_channel";
- if ( $contexto ne "" ) { $keyext .= "\&$contexto"; }
- my $vclid = $extension_transfer{$keyext};
- $vclid =~ s/\d+\^(.*)/$1/g;
- $vclid =~ s/^Local\///g;
- $vclid =~ s/(.*)\@(.*)/$1/g;
-
- $comando = "Action: Originate\r\n";
- $comando .= "Channel: $origin_channel\r\n";
- $comando .= "Callerid: $vclid <$vclid>\r\n";
- $comando .= "Async: True\r\n";
- $comando .= "Exten: $vext\r\n";
- if ( defined($vcontext) ) {
- $comando .= "Context: $vcontext\r\n";
- }
- $comando .= "Priority: 1\r\n";
- $comando .= "\r\n";
-
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
- $tab = substr( $tab, 0, -1 ) if DEBUG;
- return;
- }
-
- if ( is_number($destino) ) {
-
- # If the selected channel name is only digits, its a
- # conference. So treat a conference command as a regular
- # transfer or redirect. (We do not want to send into a
- # meetme conference another ongoing meetme conference)
- my @sesiones_del_canal = extraer_todas_las_sesiones_de_un_canal($origin_channel);
- my $cuantos = @sesiones_del_canal;
-
- if ( $accion =~ /^conference/ ) {
- if ( $cuantos == 0 ) {
- $accion =~ s/conference/originate/g;
- }
- elsif ( $cuantos > 0 ) {
- $accion =~ s/conference/transferir/g;
- }
- }
- }
-
- if ( $accion eq "cortar" ) {
- my $buton_number = $datosflash;
- log_debug( "$heading Will try to hangup channel para el boton $buton_number", 16 ) if DEBUG;
-
- foreach ( @{ $sesbot{$buton_number} } ) {
- log_debug( "$heading hanging up channel $_", 16 ) if DEBUG;
- $comando = "Action: Hangup\r\n";
- $comando .= "Channel: $_\r\n\r\n";
- log_debug( "-- Command received: $accion chan $_", 32 ) if DEBUG;
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
-
- # $comando = "Action: Command\r\n";
- # $comando .= "Command: soft hangup $_\r\n\r\n";
- # send_command_to_manager($comando, $p[$button_server{$datosflash}]);
- }
- }
- elsif ( $accion =~ /^meetmemute/ ) {
- my $conference = $btn_destino;
- my $meetmemember = $datosflash;
- $conference =~ s/(.*)\@(.*)/$1/g;
- $meetmemember =~ s/(.*)\@(.*)/$1/g;
- my $boton_con_contexto = $clid;
- $boton_con_contexto =~ s/^meetmemute//g;
- $comando = "Action: Command\r\n";
- $comando .= "ActionID: meetmemute$boton_con_contexto\r\n";
- $comando .= "Command: meetme mute $conference $meetmemember\r\n\r\n";
- send_command_to_manager( $comando, $p[ $button_server{$boton_con_contexto} ],
- 0, $astmanproxy_servers[ $button_server{$boton_con_contexto} ] );
- }
- elsif ( $accion =~ /^meetmeunmute/ ) {
- my $conference = $btn_destino;
- my $meetmemember = $datosflash;
- $conference =~ s/(.*)\@(.*)/$1/g;
- $meetmemember =~ s/(.*)\@(.*)/$1/g;
- my $boton_con_contexto = $clid;
- $boton_con_contexto =~ s/^meetmeunmute//g;
- $comando = "Action: Command\r\n";
- $comando .= "ActionID: meetmeunmute$boton_con_contexto\r\n";
- $comando .= "Command: meetme unmute $conference $meetmemember\r\n\r\n";
- send_command_to_manager( $comando, $p[ $button_server{$boton_con_contexto} ],
- 0, $astmanproxy_servers[ $button_server{$boton_con_contexto} ] );
- }
- elsif ( $accion =~ /^conference/ ) {
- log_debug( "$heading CONFERENCE extension_transfer($origin_channel)", 1 ) if DEBUG;
-
- my $indice = $origin_server . "^" . $origin_channel;
- my $originate = $extension_transfer{$indice};
- $originate =~ s/\d+\^(.*)/$1/;
- foreach ( keys(%buttons) ) {
- log_debug( "$heading comparo $buttons{$_} con btn_destino $btn_destino", 1 ) if DEBUG;
- if ( $buttons{$_} eq $btn_destino ) {
- if ( $canal =~ /^_/ ) {
- my @canalarray = @{ $sesbot{$btn_destino} };
- my $canalses = $canalarray[0];
- my ( $newcanal, $newses ) = separate_session_from_channel($canalses);
- $canal = $newcanal;
- }
- $canal =~ s/(.*)=(.*)/$1/g;
- log_debug( "$heading coincidencia para btn_destino $btn_destino el canal es $canal", 1 )
- if DEBUG;
- my @links = extraer_todos_los_enlaces_de_un_canal( $canal, $button_server{$datosflash} );
-
- my @canal_transferir = @{ $sesbot{$btn_destino} };
-
- my $cuantos = @links;
- if ( $cuantos <= 0 ) {
- my @extensiondialed = extracts_exten_from_active_channel($canal);
- $comando = "Action: Originate\r\n";
- $comando .= "Channel: $origin_channel\r\n";
- $comando .= "Exten: $extensiondialed[0]\r\n";
- $comando .= "Priority: 1\r\n\r\n";
- }
- else {
-
- log_debug( "** $canal_transferir[0] $links[0] will be conferenced together with $origin_channel ($originate)",
- 16 )
- if DEBUG;
-
- # Try to find an empty conference
- my $empty_room = $first_room;
- for ( my $at = $first_room ; $at <= $last_room ; $at++ ) {
- log_debug( "room $at = " . $barge_rooms{"$at"}, 128 ) if DEBUG;
- if ( $barge_rooms{"$at"} == 0 ) {
- $found_room = 1;
- $empty_room = $at;
- last;
- }
- }
-
- if ( $found_room == 1 ) {
- $comando = "Action: Redirect\r\n";
- $comando .= "Channel: $canal_transferir[0]\r\n";
- $comando .= "ExtraChannel: $links[0]\r\n";
- $comando .= "Exten: $empty_room\r\n";
- $comando .= "ActionID: 1234\r\n";
- $comando .= "Context: $conference_context\r\n";
- $comando .= "Priority: 1\r\n\r\n";
- $auto_conference{ $canal_transferir[0] } = $origin_channel;
- }
- else {
- log_debug( "$heading No hay meetme vacio!", 64 ) if DEBUG;
- $comando = "";
- }
- }
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
- last;
- }
- }
- }
- elsif ( $accion =~ /transferir/ ) {
-
- if ( $accion =~ /^ctransferir/ ) {
-
- # Sets db variable to set callerid on dialplan
- $comando = "Action: Command\r\n";
- $comando .= "Command: database put clid $destino ";
- $comando .= "\"$clid\"\r\n\r\n";
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
- }
-
- $canal_destino = retrieve_extension($btn_destino);
-
- if ( $origin_channel =~ /\*/ ) {
- my @canalarray = @{ $sesbot{$datosflash} };
- my $canalses = $canalarray[0];
- my ( $newcanal, $newses ) = separate_session_from_channel($canalses);
- $origin_channel = $newcanal;
- }
-
- if ( $canal_destino ne "-1" ) {
- if ( $canal_destino =~ /\@/ ) {
- @pedazos = split( /\@/, $canal_destino );
- $canal_destino = $pedazos[0];
- $contexto = $pedazos[1];
- }
-
- my @cuales_transferir = get_transfer_channel( $origin_channel, $datosflash );
-
- foreach my $valor (@cuales_transferir) {
- log_debug( "$heading Will try to transfer $valor to extension number $canal_destino!", 16 )
- if DEBUG;
- $comando = "Action: Redirect\r\n";
- $comando .= "Channel: $valor\r\n";
- $comando .= "Exten: $canal_destino\r\n";
- if ( $contexto ne "" ) {
- $comando .= "Context: $contexto\r\n";
- }
- $comando .= "Priority: 1\r\n\r\n";
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
-
- if ( $calltimeout > 0 ) {
- $comando = "Action: AbsoluteTimeout\r\n";
- $comando .= "Channel: $valor\r\n";
- $comando .= "Timeout: $calltimeout\r\n";
- $comando .= "ActionID: timeout|$valor|$calltimeout\r\n";
- $comando .= "\r\n";
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- , 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
- }
-
- }
- }
- else {
- log_debug( "** Untransferable destination! ($origin_channel)", 16 ) if DEBUG;
- }
- }
- elsif ( $accion =~ /originate/ ) {
-
- if ( $origin_channel =~ /\*/ ) {
- log_debug( "** Cannot originate from wildcard buttons ($origin_channel)", 16 ) if DEBUG;
- $tab = substr( $tab, 0, -1 ) if DEBUG;
- return;
- }
-
- if ( $accion =~ /^coriginate/ ) {
- $comando = "Action: Command\r\n";
- $comando .= "Command: database put clid $destino ";
- $comando .= "\"$clid\"\r\n\r\n";
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
- }
-
- $extension_destino = retrieve_extension($btn_destino);
-
- $destino = "";
- while ( my ( $canloop, $nrobotonloop ) = each(%buttons_preserve_case) ) {
- if ( $nrobotonloop eq $btn_destino ) {
- $destino = $canloop;
- }
- }
- if ( $destino ne "" ) {
- $destino =~ s/(.*)=(.*)/$1/g;
- $destino =~ s/^\d+\^(.*)/$1/g;
- }
-
- if ( $destino =~ m/QUEUE\//i ) {
- $destino =~ s/^QUEUE\/(.*)/$1/g;
- $destino =~ s/(.*)&(.*)/$1/g;
-
- my $member = 0;
- while ( my ( $key, $val ) = each(%count_queue) ) {
- if ( $key eq "$button_server{$datosflash}^$destino" ) {
- foreach my $qmember (@$val) {
- my $canal_compara = "$button_server{$datosflash}^$origin_channel";
- if ( uc($qmember) eq uc($canal_compara) ) {
- $member++;
- }
- }
- }
- }
- if ( $origin_channel !~ /^QUEUEAGENT/ ) {
- if ( $member > 0 ) {
- $comando = "Action: QueueRemove\r\n";
- $comando .= "Queue: $destino\r\n";
- $comando .= "Interface: $origin_channel\r\n";
- $comando .= "\r\n";
- }
- else {
- $comando = "Action: QueueAdd\r\n";
- $comando .= "Queue: $destino\r\n";
- $comando .= "Interface: $origin_channel\r\n";
- $comando .= "\r\n";
- }
- }
- }
- else {
-
- if ( $extension_destino =~ /\@/ ) {
- @pedazos = split( /\@/, $extension_destino );
- $extension_destino = $pedazos[0];
- $contexto = $pedazos[1];
- }
-
- log_debug( "$heading Originate from $origin_channel to extension $extension_destino!", 16 ) if DEBUG;
- my $keyext = "$origin_server^$origin_channel";
-
- if ( $panelcontext ne "" && $panelcontext ne "GENERAL" ) { $keyext .= "\&$panelcontext"; }
-
- my $dclid = $extension_transfer{$keyext};
- $dclid =~ s/\d+\^(.*)/$1/g;
- $dclid =~ s/^Local\///g;
- $dclid =~ s/(.*)\@(.*)/$1/g;
-
- $clid = $textos{"$datosflash"} . " <$dclid>";
-
- if ( $origin_channel =~ /^IAX2\[/ ) {
- $origin_channel =~ s/^IAX2\[(.*)\]/IAX2\/$1/g;
- }
- $comando = "Action: Originate\r\n";
- $comando .= "Channel: $origin_channel\r\n";
- $comando .= "Async: True\r\n";
- $comando .= "Callerid: $clid\r\n";
- $comando .= "Exten: $extension_destino\r\n";
-
- if ( $contexto ne "" ) {
- $comando .= "Context: $contexto\r\n";
- }
- $comando .= "Priority: 1\r\n";
- $comando .= "\r\n";
- }
- send_command_to_manager( $comando, $p[ $button_server{$datosflash} ],
- 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
- }
- elsif ( $accion =~ /^dial/ ) {
- if ( $servidor_dial eq "default" ) {
- $servidor_dial = $p[0];
- }
- else {
- $servidor_dial = $p[ $button_server{$datosflash} ];
- }
- my $numero_a_discar = $accion;
- $numero_a_discar =~ s/^dial//g;
- $comando = "Action: Originate\r\n";
- $comando .= "Channel: $origin_channel\r\n";
- $comando .= "Async: True\r\n";
- $comando .= "Exten: $numero_a_discar\r\n";
- if ( $contexto ne "" ) {
- $comando .= "Context: $contexto\r\n";
- }
- $comando .= "Priority: 1\r\n";
- $comando .= "\r\n";
- send_command_to_manager( $comando, $servidor_dial, 0, $astmanproxy_servers[ $button_server{$datosflash} ] );
- }
- }
- else {
- log_debug( "$heading Password mismatch -$password-$md5clave-!", 1 ) if DEBUG;
- sends_key($socket);
- sends_incorrect($socket);
- }
- }
- else {
- log_debug( "$heading There is no channel selected ?", 16 ) if DEBUG;
- }
- $tab = substr( $tab, 0, -1 ) if DEBUG;
-}
-
-sub retrieve_extension {
- my $param = shift;
- my $canal = "";
- my $canal_destino = "";
- my $heading = "** RETRIEVE_EXTEN";
- my $contexto = "";
-
- my $param_sin_contexto = $param;
- $param_sin_contexto =~ s/(.*)(\@.*)/$1/g;
- if ( defined($2) ) {
- $contexto = $2;
- $contexto =~ s/\@/&/g;
- }
-
- log_debug( "$heading param $param param_sin_con $param_sin_contexto", 32 ) if DEBUG;
-
- if ( is_number($param_sin_contexto) ) {
- log_debug( "$heading I guess its a button number", 32 ) if DEBUG;
-
- # If the parameter is a number, assume button number
- foreach ( keys(%buttons) ) {
- if ( $buttons{$_} eq $param ) {
- log_debug( "$heading coincide con $param", 64 ) if DEBUG;
- $canal = $_;
- $canal =~ s/(.*)=(.*)/$1/g;
- $canal =~ s/(.*)&(.*)/$1/g;
- log_debug( "$heading canal $canal contexto $contexto", 64 ) if DEBUG;
- $canal_destino = $extension_transfer{"$canal$contexto"};
- last;
- }
- }
- }
- else {
- log_debug( "$heading I guess its a channel name", 32 ) if DEBUG;
-
- # If its not a number, asume channel name (technology/name)
- foreach ( keys(%buttons) ) {
- my $linealog = sprintf( "%-20s %-10s", $_, $buttons{$_} );
-
- # log_debug("$heading $linealog",64) if DEBUG;
- if ( $_ eq $param ) {
- log_debug( "$heading coincide con $param", 64 ) if DEBUG;
- $canal = $_;
- $canal =~ s/(.*)=(.*)/$1/g;
- $canal_destino = $extension_transfer{"$canal"};
- last;
- }
- }
- }
-
- log_debug( "$heading canal_destino = $canal_destino", 32 ) if DEBUG;
- $canal_destino =~ s/\d+\^(.*)/$1/g;
- log_debug( "$heading La extension para $param es $canal_destino", 32 ) if DEBUG;
- return $canal_destino;
-}
-
-sub request_astdb_status {
-
- for my $key ( keys %astdbcommands ) {
- my $nro_servidor = 0;
- foreach my $socket (@p) {
- if ( defined($socket) && $socket ne "" ) {
- for ( keys %buttons_preserve_case ) {
- my $canal = $_;
- $canal =~ m/(\d+)\^([^&]*)(.*)/g;
- my $servidor = $1;
- my $canalito = $2;
- if ( $canalito !~ m/^_/ && $nro_servidor == $servidor && $canalito !~ m/=/ ) {
- my $comando = "Action: Command\r\n";
- $comando .= "ActionID: astdb-$key-$canalito\r\n";
- $comando .= "Command: database get $key $canalito\r\n\r\n";
- if ( defined( $autenticado{$socket} ) ) {
- if ( $autenticado{$socket} == 1 ) {
- send_command_to_manager( $comando, $socket );
- }
- }
- }
- }
- }
- $nro_servidor++;
- }
- }
-}
-
-sub request_queue_status {
- my $socket = shift;
- my $canalid = shift;
- my $member = "";
- my $nada = "";
- my $showagents = 0;
-
- if ( defined($canalid) ) {
- if ( $canalid eq "initialrequest" ) {
-
- # We only ask for agents on startup
- $showagents = 1;
- }
- else {
- ( $member, $nada ) = separate_session_from_channel($canalid);
- }
- }
-
- my @todos = ();
-
- if ( $socket eq "all" ) {
- @todos = @p;
- }
- else {
- push @todos, $socket;
- }
-
- foreach my $socket2 (@todos) {
- if ( defined($socket2) && $socket2 ne "" ) {
- if ( $showagents == 1 ) {
- send_command_to_manager( "Action: Command\r\nActionId: agents\r\nCommand: show agents\r\n\r\n", $socket2 );
- }
- if ( defined($member) ) {
- my @agentes = ();
- push @agentes, $member;
- if ( exists( $reverse_agents{$member} ) ) {
- push @agentes, "Agent/" . $reverse_agents{$member};
- }
- foreach my $cual (@agentes) {
- send_command_to_manager( "Action: QueueStatus\r\nMember: $cual\r\n\r\n", $socket2 );
-
- }
- }
- else {
- send_command_to_manager( "Action: QueueStatus\r\nActionID: QueueStatus\r\n", $socket2 );
- }
-
- # if($showagents==1) {
- # send_command_to_manager( "Action: Command\r\nActionId: agents\r\nCommand: show agents\r\n\r\n", $socket2 );
- # }
- }
- }
-}
-
-sub first_client_status {
-
- # This functions traverses all FOP internal hashes and send the proper
- # commands to the flash client to reflect the status of each button.
-
- my $socket = shift;
- my $interno = "";
-
- if ( $queue_hide == 1 ) {
-
- # If queue_hide is set, hide queue positions
- for my $key ( keys %buttons ) {
- if ( $key =~ m/\d+\^QUEUE\/[^=]*=\d/i ) {
- $interno = $buttons{$key};
- send_status_to_flash( $socket, "$interno|setalpha|00", 0 );
- }
- }
- }
-
- if ( keys(%estadoboton) ) {
- for $interno ( keys %botonled ) {
- if ( $botonled{$interno} == 1 ) {
- send_status_to_flash( $socket, "$interno|changelabel1|$botonlabel{$interno}", 0 );
- }
- }
- for $interno ( keys %botonlabelonly ) {
- send_status_to_flash( $socket, "$interno|setlabel|$botonlabelonly{$interno}", 0 );
- }
- for $interno ( keys %botonvoicemail ) {
- if ( $botonvoicemail{$interno} >= 0 ) {
- send_status_to_flash( $socket, "$interno|voicemail|$botonvoicemail{$interno}", 0 );
- }
- }
- for $interno ( keys %botonvoicemailcount ) {
- send_status_to_flash( $socket, "$interno|voicemailcount|$botonvoicemailcount{$interno}", 0 );
- }
- for $interno ( keys %botonalpha ) {
- if ( $botonalpha{$interno} ne "" ) {
- send_status_to_flash( $socket, "$interno|setalpha|$botonalpha{$interno}", 0 );
- }
- }
- for $interno ( keys %botonqueue ) {
- send_status_to_flash( $socket, "$interno|infoqstat|$botonqueue{$interno}", 0 );
- }
- for $interno ( keys %botonqueue_count ) {
- send_status_to_flash( $socket, "$interno|infoqstat2|$botonqueue_count{$interno}", 0 );
- }
- if ( keys(%botonqueuemember) ) {
- for $interno ( keys %botonqueuemember ) {
- if ( defined( @{ $botonqueuemember{$interno} } ) ) {
- my %temphash = ();
- foreach my $val ( @{ $botonqueuemember{$interno} } ) {
- my @datos = split( /\|/, $val );
- $temphash{ $datos[0] } = $datos[1];
-
- # send_status_to_flash($socket, "$interno|info$datos[0]|$datos[1]", 0);
- }
- while ( my ( $key, $val ) = each(%temphash) ) {
- send_status_to_flash( $socket, "$interno|info$key|$val", 0 );
- }
- }
- }
- }
- if ( keys(%botonpark) ) {
- for $interno ( keys %botonpark ) {
- $botonpark{$interno} =~ m/(.*)\|(.*)/;
- my $texto = $1;
- my $timeout = $2;
- my $diftime = $timeout - time();
- if ( $diftime > 0 ) {
- send_status_to_flash( $socket, "$interno|park|$texto($diftime)", 0 );
- }
- }
- }
- for $interno ( keys %estadoboton ) {
-
- #if ( $estadoboton{$interno} !~ /^free/ ) {
- if ( $estadoboton{$interno} =~ /^busy/ ) {
- send_status_to_flash( $socket, "$interno|state|busy", 0 );
- if ( defined( $botonlabel{$interno} ) ) {
- send_status_to_flash( $socket, "$interno|changelabel0|$botonlabel{$interno}", 0 );
- }
- }
- elsif ( $estadoboton{$interno} =~ /ringi/ ) {
- send_status_to_flash( $socket, "$interno|state|ringing", 0 );
- }
- if ( defined( $botonclid{$interno} ) ) {
- if ( $botonclid{$interno} ne "" ) {
- send_status_to_flash( $socket, "$interno|settext|$botonclid{$interno}", 0 );
- }
- }
-
- #}
- }
- if ( keys(%botonlinked) ) {
- for $interno ( keys %botonlinked ) {
- if ( $botonlinked{$interno} ne "" ) {
- send_status_to_flash( $socket, "$interno|linked|$botonlinked{$interno}", 0 );
- }
- }
- }
- if ( keys(%botonmeetme) ) {
- for $interno ( keys %botonmeetme ) {
- if ( $botonmeetme{$interno} ne "" ) {
- send_status_to_flash( $socket, "$interno|meetmeuser|$botonmeetme{$interno}", 0 );
- }
- }
- }
- if ( keys(%botontimer) ) {
- for $interno ( keys %botontimer ) {
- if ( $botontimer{$interno} ne "" ) {
- my $diftime = time() - $botontimer{$interno};
- my $type = "";
- if ( defined( $botontimertype{$interno} ) ) {
- $type = "\@" . $botontimertype{$interno};
- }
- send_status_to_flash( $socket, "$interno|settimer|$diftime$type", 0 );
- if ( $type eq "\@UP" ) {
- send_status_to_flash( $socket, "$interno|state|busy", 0 );
- }
- }
- }
- }
- if ( keys(%botonsetlabel) ) {
- for $interno ( keys %botonsetlabel ) {
- if ( $botonsetlabel{$interno} ne ""
- && $botonsetlabel{$interno} ne "."
- && $botonsetlabel{$interno} ne "original"
- && $botonsetlabel{$interno} ne "labeloriginal" )
- {
- send_status_to_flash( $socket, "$interno|setlabel|$botonsetlabel{$interno}", 0 );
- }
- }
- }
- if ( keys(%botonregistrado) ) {
- for $interno ( keys %botonregistrado ) {
- if ( $botonregistrado{$interno} ne "" ) {
- my ( $quehace, $dos ) = split( /\|/, $botonregistrado{$interno} );
- send_status_to_flash( $socket, "$interno|$quehace|$dos", 0 );
- }
- }
- }
- }
-}
-
-sub send_initial_status {
- %datos = ();
- my $nro_servidor = 0;
- my $heading = "** SEND INITIAL STATUS";
- my $cual = shift;
- my @socket_manager;
-
- if ( defined($cual) ) {
- push @socket_manager, $cual;
- }
- else {
- @socket_manager = @p;
- }
-
- log_debug( "$heading START SUB", 16 ) if DEBUG;
-
- request_astdb_status();
-
- foreach my $socket (@socket_manager) {
-
- if ( defined($socket) && $socket ne "" ) {
- my @pedazos = split( /\|/, $manager_socket{$socket} );
- if ( $pedazos[0] eq $ip_addy{$socket} ) {
- my $contador = 0;
- foreach my $valor (@manager_host) {
- if ( $valor eq $pedazos[0] ) {
- $nro_servidor = $contador;
- }
- $contador++;
- }
- }
-
- # If we send the channel status after the queue status, the agentlogin will be displayed as busy
- # when they are actually waiting for a call, trying to put it at the end
- request_queue_status( $socket, "initialrequest" );
-
- send_command_to_manager( "Action: Status\r\n\r\n", $socket );
-
- send_command_to_manager( "Action: ZapShowChannels\r\n\r\n", $socket );
-
- send_command_to_manager( "Action: Command\r\nActionID: parkedcalls\r\nCommand: show parkedcalls\r\n\r\n", $socket );
-
- # request_queue_status( $socket, "initialrequest" );
- # Send commands to check the mailbox status for each mailbox defined
- while ( my ( $key, $val ) = each(%mailbox) ) {
- my @pedacitos = split( /\^/, $key );
- my $servidormbox = $pedacitos[0];
- if ( "$servidormbox" eq "$nro_servidor" ) {
- log_debug( "$heading mailbox $ip_addy{$socket} $key $val", 32 ) if DEBUG;
- send_command_to_manager( "Action: MailboxStatus\r\nMailbox: $val\r\n\r\n", $socket );
- }
- }
- my @all_meetme_rooms = ();
-
- # generates an array with all meetme rooms to check on init
- for my $valor ( keys %barge_rooms ) {
- push( @all_meetme_rooms, $valor );
- }
-
- for my $key ( keys %buttons ) {
- if ( $key =~ /^\d+\^\d+$/ ) {
- push( @all_meetme_rooms, $key );
- }
- }
-
- my %count = ();
- my @unique_meetme_rooms =
- grep { ++$count{$_} < 2 } @all_meetme_rooms;
-
- foreach my $valor (@unique_meetme_rooms) {
- my $servidormeetme = 0;
- my $meetmeroom = "";
-
- if ( $valor =~ /\^/ ) {
- my @pedacitos = split( /\^/, $valor );
- $servidormeetme = $pedacitos[0];
- $meetmeroom = $pedacitos[1];
- }
- else {
-
- # If there is no server defined (its a barge_room)
- # we will query all servers - quick hack FIX IT or
- # try to figure out a way to have barge-rooms separated
- # in panel_contexts (as it is now) and also asterisk
- # servers.
- $servidormeetme = $nro_servidor;
- $meetmeroom = $valor;
- }
-
- if ( "$servidormeetme" eq "$nro_servidor" ) {
- send_command_to_manager( "Action: Command\r\nActionID: meetme_$meetmeroom\r\nCommand: meetme list $meetmeroom\r\n\r\n",
- $socket );
- }
- }
- }
- }
- alarm(2);
-}
-
-sub process_cli_command {
-
- # This subroutine process the output for a manager "Command"
- # sent, as 'sip show peers'
-
- my $texto = shift;
- @bloque = ();
- my @lineas = split( "\r\n", $texto );
- my $contador = 0;
- my $interno = "";
- my $estado = "";
- my $nada = "";
- my $conference = 0;
- my $usernum = 0;
- my $canal = "";
- my $sesion = "";
- my $heading = "** PROCESS_CLI";
- my $server = 0;
-
- foreach my $valor (@lineas) {
- if ( $valor =~ /^Server/ ) {
- $server = $valor;
- $server =~ s/Server: (.*)/$1/g;
- }
- }
-
- if ( $texto =~ /ActionID: meetme_/ ) {
- log_debug( "$heading process meetme", 16 ) if DEBUG;
-
- # Its a meetme status report
- foreach my $valor (@lineas) {
- $valor =~ s/\s+/ /g;
- my ( $key, $value ) = split( /: /, $valor, 2 );
-
- if ( defined($key) ) {
-
- if ( $key eq "ActionID" ) {
- $value =~ s/meetme_(\d+)$/$1/g;
- $conference = $value;
- }
- if ( $key eq "User #" ) {
- my @partes = split( /Channel:/, $value );
- $usernum = $partes[0];
- $usernum =~ s/(\d+)(.*)/$1/g;
- $usernum = $usernum * 1;
- $usernum =~ s/\s+//g;
- $canal = $partes[1];
- $canal =~ s/^\s+//g;
- $canal =~ s/(.*?)\((.*)/$1/g;
- my $uniqueid = find_uniqueid( $canal, $server );
- $bloque[$contador]{"Event"} = "MeetmeJoin";
- $bloque[$contador]{"Meetme"} = $conference;
- $bloque[$contador]{"Count"} = $contador;
- $bloque[$contador]{"Channel"} = $canal;
- $bloque[$contador]{"Usernum"} = $usernum;
- $bloque[$contador]{"Fake"} = "hola";
- $bloque[$contador]{"Server"} = "$server";
- $bloque[$contador]{"Uniqueid"} = $uniqueid;
- $contador++;
- }
- }
- }
- my $cuentamenos = $contador - 1;
- if ( $cuentamenos >= 0 ) {
- $bloque[$cuentamenos]{"Total"} = $contador;
- }
- }
- elsif ( $texto =~ "ActionID: agents" ) {
- log_debug( "$heading process agents", 16 ) if DEBUG;
- my $agent_number;
- my $agent_state;
- my $agent_name;
-
- # Show Agents CLI command, generates fake events
-
- foreach (@lineas) {
- $_ =~ s/\s+/ /g;
- /(\d+) \((.*)\) (.*) (\(.*\))/;
- if ( defined($1) ) {
- $agent_number = $1;
- $agent_name = $2;
- $agent_state = $3;
- $agents_name{"$server^$agent_number"} = $agent_name;
- }
-
- if ( defined($3) ) {
- if ( $agent_state =~ /available at/ ) {
-
- # Agent callback login
- $agent_state =~ s/.*'(.*)'.*/$1/g;
- $bloque[$contador]{"Event"} = "Agentcallbacklogin";
- $bloque[$contador]{"Loginchan"} = $agent_state;
- $bloque[$contador]{"Agent"} = $agent_number;
- $bloque[$contador]{"Server"} = "$server";
- $contador++;
- }
-
- if ( $agent_state =~ /logged in on/ ) {
-
- # Agent login
- $agent_state =~ s/\s+/ /g;
- $agent_state =~ s/logged in on //g;
- $agent_state =~ s/([^ ]*).*/$1/g;
-
- $bloque[$contador]{Event} = "Agentlogin";
- $bloque[$contador]{Channel} = $agent_state;
- $bloque[$contador]{Agent} = $agent_number;
- $bloque[$contador]{Server} = $server;
- $contador++;
- }
- if ( $agent_state =~ /not logged in/ ) {
- $bloque[$contador]{Event} = "Agentlogoff";
- $bloque[$contador]{Agent} = $agent_number;
- $bloque[$contador]{Server} = $server;
- $bloque[$contador]{Fake} = 1;
- $contador++;
- }
- }
- }
- }
- elsif ( $texto =~ /ActionID: astdb-/ ) {
- log_debug( "$heading process astdb", 16 ) if DEBUG;
- my $astdbk = "";
- my $canalk = "";
- my $valork = "";
- foreach (@lineas) {
- if (/^ActionID/) {
- $_ =~ m/ActionID: astdb-([^-]*)-(.*)/;
- $astdbk = $1;
- $canalk = $2;
- }
- if (/^Value:/) {
- $valork = $_;
- $valork =~ s/Value: //g;
- }
- }
- if ( $valork ne "" ) {
- $bloque[$contador]{"Event"} = "ASTDB";
- $bloque[$contador]{"Channel"} = $canalk;
- $bloque[$contador]{"Value"} = $valork;
- $bloque[$contador]{"Family"} = $astdbk;
- $contador++;
- }
-
- }
- elsif ( $texto =~ /ActionID: meetmeun/ || $texto =~ /ActionID: meetmemute/ ) {
- log_debug( "$heading process meetmemute/meetmeunmute", 16 ) if DEBUG;
- my $quecomando = "";
- my $quecanal = "";
- foreach my $valor (@lineas) {
- if ( $valor =~ /^ActionID:/ ) {
- $quecomando = $valor;
- $quecomando =~ s/^ActionID: //g;
- if ( $quecomando =~ /meetmemute/ ) {
- $quecanal = $quecomando;
- $quecanal =~ s/meetmemute//g;
- $quecomando = "meetmemute";
- }
- else {
- $quecanal = $quecomando;
- $quecanal =~ s/meetmeunmute//g;
- $quecomando = "meetmeunmute";
- }
- }
- }
- my $canal_a_mutear = $buttons_reverse{$quecanal};
- my @pedazos = split /\^/, $canal_a_mutear;
- $canal_a_mutear = $pedazos[1];
- $canal_a_mutear =~ s/(.*)\&(.*)/$1/g;
- $bloque[$contador]{"Event"} = $quecomando;
- $bloque[$contador]{"Channel"} = $canal_a_mutear . "-XXXX";
- $bloque[$contador]{"Server"} = "$server";
- $contador++;
- }
- elsif ( $texto =~ "ActionID: iaxpeers" ) {
- log_debug( "$heading process iaxpeers", 16 ) if DEBUG;
- my $info = 0;
- my $statPos = 74;
- foreach my $valor (@lineas) {
- log_debug( "$heading Line iaxpeers: $valor", 32 ) if DEBUG;
- if ( $valor =~ /^Name\/User/i ) {
- $statPos = index( $valor, "Status" );
- $info = 1;
- next;
- }
- last if $valor =~ /^--End/i;
- next unless $info;
- next unless ( length($valor) > $statPos );
- my $estado = substr( $valor, $statPos );
- $valor =~ s/\s+/ /g;
- my @parametros = split( " ", $valor );
- my $interno = $parametros[0];
-
- if ( $interno =~ /\// ) {
- my @partecitas = split( /\//, $interno );
- $interno = $partecitas[0];
- }
- my $dirip = $parametros[1];
-
- if ( defined($estado) && $estado ne "" ) {
- $interno = "IAX2/" . $interno . "-XXXX";
- log_debug( "$heading State: $estado Extension: $interno", 32 ) if DEBUG;
- $bloque[$contador]{"Event"} = "Regstatus";
- $bloque[$contador]{"Channel"} = $interno;
- $bloque[$contador]{"State"} = $estado;
- $bloque[$contador]{"IP"} = $dirip;
- $bloque[$contador]{"Server"} = "$server";
- $contador++;
- }
- }
- }
- elsif ( $texto =~ "ActionID: sccppeers" ) {
- log_debug( "$heading process sccppeers", 16 ) if DEBUG;
- my $info = 0;
- foreach my $valor (@lineas) {
- log_debug( "$heading Line sccppeers: $valor", 32 ) if DEBUG;
- last if $valor =~ /^--END/i;
- next unless ( $valor =~ /(.*?)\t+|\s+(.*?)\t+|\s+.*?O.*/ );
- $valor =~ s/\s+/ /g;
- my @parametros = split( " ", $valor );
- my $status = 0;
- if ( $parametros[1] eq "--" ) {
- $status = 4;
- }
- log_debug( "$heading State: 4 Extension: $interno", 32 ) if DEBUG;
- $bloque[$contador]{"Event"} = "ExtensionStatus";
- $bloque[$contador]{"Exten"} = $parametros[0];
- $bloque[$contador]{"Status"} = $status;
- $bloque[$contador]{"Server"} = "$server";
- $contador++;
- }
- }
- elsif ( $texto =~ "ActionID: parkedcalls" ) {
- log_debug( "$heading process parkedcalls", 16 ) if DEBUG;
- my $info = 0;
- foreach my $valor (@lineas) {
- log_debug( "$heading Line parkedcalls: $valor", 32 ) if DEBUG;
- if ( $valor =~ /Timeout/ ) {
- $info = 1;
- next;
- }
- last if $valor =~ /^--End/i;
- last if $valor =~ /^\d+ parked/i;
- next unless $info;
- $valor =~ s/\s+/ /g;
- my @parametros = split( " ", $valor );
- my $timeout = $parametros[6];
- $timeout =~ s/(\d+)s/$1/;
-
- $bloque[$contador]{"Event"} = "ParkedCall";
- $bloque[$contador]{"Channel"} = $parametros[1];
- $bloque[$contador]{"Exten"} = $parametros[0];
- $bloque[$contador]{"Timeout"} = $timeout;
- $bloque[$contador]{"Server"} = "$server";
- $contador++;
-
- }
- }
- else {
- my $info = 0;
- my $statPos = 74;
-
- log_debug( "$heading process sip peers", 16 ) if DEBUG;
-
- # Its a sip show peers report
- foreach my $valor (@lineas) {
- if ( $valor =~ /^Name\/User/i ) {
- $statPos = index( $valor, "Status" );
- $info = 1;
- next;
- }
- last if $valor =~ /^--End/i;
- next unless $info;
- next unless ( length($valor) > $statPos );
- log_debug( "$heading Line: $valor", 32 ) if DEBUG;
-
- if ( length($valor) < $statPos ) {
- log_debug( "$heading SIP PEER line $valor does not match $statPos!", 32 ) if DEBUG;
- next;
- }
-
- my $estado = substr( $valor, $statPos );
- $valor =~ s/\s+/ /g;
- if ( $valor eq "" ) { next; }
- my @parametros = split( " ", $valor );
- my $interno = $parametros[0];
- my $dirip = $parametros[1];
- $interno =~ s/(.*)\/(.*)/$1/g;
-
- if ( defined($interno) ) {
-
- if ( $interno =~ /(.*)\/(.*)/ ) {
- if ( $1 eq $2 ) {
- $interno = $1 . "-XXXX";
- }
- else {
- $interno .= "-XXXX";
- }
- }
- }
- if ( defined($estado)
- && $estado ne "" ) # If set, is the status of 'sip show peers'
- {
- $interno = "SIP/" . $interno;
- log_debug( "$heading State: $estado Extension: $interno", 32 ) if DEBUG;
- $bloque[$contador]{"Event"} = "Regstatus";
- $bloque[$contador]{"Channel"} = $interno . "-XXXX";
- $bloque[$contador]{"State"} = $estado;
- $bloque[$contador]{"IP"} = $dirip;
- $bloque[$contador]{"Server"} = "$server";
- $contador++;
- }
- }
- }
-}
-
-sub get_meetme_pos {
- my $server = shift;
- my $meetmeroom = shift;
- my $userpos = shift;
-
- my $trunk_pos = 1;
- my $heading = "** GET MEETME ";
-
- # This routine gets the usernum for a meetmejoin/meetmeleave event
- # and coverts it to a button position for meetme=1 channels.
- # Meetme's usernum starts from one, but if there are already members
- # in the conference, then it counts for the last members number up.
- # (no matter if some participants left the room)
-
- if ( exists( $meetme_pos{"$server^$meetmeroom"}{"$userpos"} ) ) {
- log_debug( "$heading Found meetme_pos($server^$meetmeroom)($userpos)", 64 ) if DEBUG;
- $trunk_pos = $meetme_pos{"$server^$meetmeroom"}{"$userpos"};
- }
- else {
- log_debug( "$heading Not Found meetme_pos($server^$meetmeroom)($userpos)", 64 ) if DEBUG;
- my %busy_slots = ();
- foreach my $key1 ( sort ( keys(%meetme_pos) ) ) {
- if ( $key1 eq "$server^$meetmeroom" ) {
- foreach my $key2 ( sort ( keys( %{ $meetme_pos{$key1} } ) ) ) {
- my $indice = $meetme_pos{$key1}{$key2};
- $busy_slots{$indice} = 1;
- }
- }
- }
- for ( $trunk_pos = 1 ; ; $trunk_pos++ ) {
- last if ( !exists( $busy_slots{$trunk_pos} ) );
- }
- $meetme_pos{"$server^$meetmeroom"}{"$userpos"} = $trunk_pos;
- }
- log_debug( "$heading devuelve $meetmeroom=$trunk_pos", 32 ) if DEBUG;
- return "$meetmeroom=$trunk_pos";
-}
-
-sub reserve_next_available_agent_button {
- my $server = shift;
- my $canal = shift;
- my $queue = shift;
-
- my @temparray = ();
- my $done = 0;
-
- if ( $queueagent_buttons != 1 ) {
-
- # Do not waste memory or cpu cicles if we do not have queueagent buttons
- return;
- }
-
- # agents_on_queue stores every agent that is member of that queue
- # no matter if its logged in or not. We only need to add/remove items
- # from here when queuememberadded or queuememberremoved events
-
- if ( $canal =~ m/^CLID/ ) {
- my $extr = $extension_transfer{"$server^$canal"};
- $extr =~ s/\d+\^(.*)/$1/g;
- $canal = "Local/$extr";
- }
-
- log_debug( "RESERVE_AGENT_BUTTON server $server, canal $canal, queue $queue", 16 );
-
- foreach my $vvalor ( @{ $agents_on_queue{"$server^$queue"} } ) {
- if ( $vvalor eq "$server^$canal" ) {
- log_debug( "RESERVE_AGENT_BUTTON no thanks, we already have it", 32 );
-
- # We already have it here, return
- return;
- }
- }
-
- foreach my $vvalor ( @{ $agents_on_queue{"$server^$queue"} } ) {
- if ( $vvalor =~ /^!/ ) {
-
- # If it starts with ! it is available
- log_debug( "RESERVE_AGENT_BUTTON yes please, we have a previous reservation", 32 );
- push @temparray, "$server^$canal";
- $done = 1;
- last;
- }
- else {
- push @temparray, $vvalor;
- }
- }
- if ( $done == 0 ) {
-
- # if there is no empty slot, insert at the end
- push @temparray, "$server^$canal";
- log_debug( "RESERVE_AGENT_BUTTON yes, but you will have to wait at the end of the line", 32 );
- }
- @temparray = unique(@temparray);
- @{ $agents_on_queue{"$server^$queue"} } = @temparray;
- print_agentonqueue("en reserve");
-}
-
-sub find_uniqueid {
-
- # returns the uniqueid of a given channel
- my $canal = shift;
- $canal =~ s/\s//g;
- my $server = shift;
- my $uniqid = "";
- my $match = 0;
-
- if ( keys(%datos) ) {
- for ( keys %datos ) {
- $match = 0;
- while ( my ( $key, $val ) = each( %{ $datos{$_} } ) ) {
- if ( $key eq "Channel" && $val =~ m/\Q$canal\E/ ) {
- $match++;
- }
- if ( $key eq "Server" && $val eq $server ) {
- $match++;
- }
- }
- if ( $match > 1 ) {
- $uniqid = $_;
- last;
- }
- }
- }
-
- return $uniqid;
-}
-
-sub log_debug {
- my $texto = shift;
- my $nivel = shift;
- my $verbose = "0";
-
- if ( !defined($nivel) ) { $nivel = 1; }
-
- if ( !defined($texto) ) { return }
-
- if ( $debuglevel & $nivel ) {
- $texto =~ s/\0//g;
- if ( $texto !~ m/^\d+\.\d+\.\d+\.\d+/ ) {
- $verbose = $texto;
- $verbose =~ s/^\*\* ([^\s]*).*/$1/g;
- }
- else {
- my $parte = $texto;
- $parte =~ s/(\d+\.\d+\.\d+\.\d+)\s+(.*)/$1/g;
- $verbose = $parte;
- }
- if ( $debuglevel == -1 ) {
-
- # Debug log Cache
- $debuglevel_cache .= "$texto\n";
- $cont_debug_cache++;
- if ( $cont_debug_cache > 1000 ) {
- $debuglevel_cache = "";
- $debuglevel = 0;
- }
- }
- else {
- if ( $debuglevel_cache ne "" ) {
- print $debuglevel_cache. "\n";
- $debuglevel_cache = "";
- }
- if ( $verbose ne $global_verbose ) {
- print "\n";
- }
- $global_verbose = $verbose;
- print "$tab$texto\n";
- }
- }
-}
-
-sub alarma_al_minuto {
- my $nro_servidor = 0;
- my $heading = "** ALARM ";
- manager_connection();
-
- # %cache_hit = (); # Clears button cache
- foreach (@p) {
- if ( defined($_) && $_ ne "" ) {
- log_debug( "$heading Enviando status a " . $ip_addy{$_}, 16 ) if DEBUG;
- my @pedazos = split( /\|/, $manager_socket{$_} );
-
- if ( $pedazos[0] eq $ip_addy{$_} ) {
- my $contador = 0;
- foreach my $valor (@manager_host) {
- if ( $valor eq $pedazos[0] ) {
- $nro_servidor = $contador;
- }
- $contador++;
- }
- }
-
- my $comando = "Action: Command\r\n";
- $comando .= "Command: sip show peers\r\n\r\n";
- send_command_to_manager( $comando, $_ );
-
- $comando = "Action: Command\r\n";
- $comando .= "ActionID: iaxpeers\r\n";
- $comando .= "Command: iax2 show peers\r\n\r\n";
- send_command_to_manager( $comando, $_ );
-
- $comando = "Action: Command\r\n";
- $comando .= "ActionID: sccppeers\r\n";
- $comando .= "Command: sccp show lines\r\n\r\n";
- send_command_to_manager( $comando, $_ );
-
- if ( $poll_voicemail == 1 ) {
-
- # Send commands to check the mailbox status for each mailbox defined
- while ( my ( $key, $val ) = each(%mailbox) ) {
- my @pedacitos = split( /\^/, $key );
- my $servidormbox = $pedacitos[0];
- if ( "$servidormbox" eq "$nro_servidor" ) {
- log_debug( "$heading mailbox $ip_addy{$_} $key $val", 32 ) if DEBUG;
- send_command_to_manager( "Action: MailboxStatus\r\nMailbox: $val\r\n\r\n", $_ );
- }
- }
- }
- }
- }
- alarm($poll_interval);
-}
-
-sub send_status_to_flash {
- my $socket = shift;
- my $status = shift;
- my $nocrypt = shift;
- my $encriptado = $status;
- my $but_no = 0;
- my $heading = "** SEND_STATUS_TO_FLASH ";
- my $contexto = "";
- my $cmd = "";
- my $cmd_crypt = "";
- my $data = "";
- my $data_crypt = "";
- my $noencriptado = "";
-
- if ( !defined($socket) ) {
- log_debug( "$heading socket $socket not open!!!", 64 ) if DEBUG;
- }
-
- if ( $encriptado =~ /key\|0/ ) {
- $but_no = '0';
- $encriptado =~ m/(.*)\|(.*)\|(.*)/;
- $cmd = $2;
- $data = $1;
-
- }
- else {
- $but_no = $status;
- $but_no =~ s/(\d+)(.*)\|(.*)/$1/g;
- $contexto = $status;
- $contexto =~ s/([^\|]*).*/$1/g;
- $contexto =~ m/(.*)\@(.*)/;
-
- if ( defined($2) ) {
- $contexto = $2;
- }
- else {
- $contexto = "";
- }
- $status =~ m/(.*)\|(.*)\|(.*)/;
- $cmd = $2;
- $data = $3;
-
- if ( $contexto ne "" && $cmd ne "restrict" ) {
- $but_no .= "\@$contexto";
- }
-
- }
-
- if ( $flash_contexto{$socket} ne $contexto && $but_no ne "0" ) {
-
- # If the context does not match, exit without queueing anything
- return;
- }
-
- if ( !defined( $no_encryption{"$socket"} ) ) {
- $no_encryption{"$socket"} = 0;
- }
-
- $noencriptado = "<response btn=\"$but_no\" cmd=\"$cmd\" data=\"$data\"/>\0";
- if ( !defined( $keys_socket{$socket} ) || $nocrypt == 1 || $no_encryption{$socket} == 1 ) {
- $encriptado = "<response btn=\"$but_no\" cmd=\"$cmd\" data=\"$data\"/>\0";
- if ( $cmd eq "key" ) {
- $keys_socket{$socket} = $data;
- }
- }
- else {
- $cmd_crypt = &TEAencrypt( $cmd, $keys_socket{"$socket"} );
- $data_crypt = &TEAencrypt( $data, $keys_socket{"$socket"} );
- $encriptado = "<response btn=\"$but_no\" cmd=\"$cmd_crypt\" data=\"$data_crypt\">\0";
- if ( $cmd eq "key" ) {
- $keys_socket{$socket} = $data;
- }
- }
- if ( !defined( $ip_addy{$socket} ) ) {
- log_debug( "Skip actual_syswrite to $socket cause it does not exists!", 128 ) if DEBUG;
- }
- else {
- actual_syswrite( $socket, $encriptado, "isclient", $noencriptado );
- }
-
-}
-
-sub manager_login_md5 {
- my $challenge = shift;
- my $handle = shift;
- my @partes = split( /\|/, $manager_socket{$handle} );
-
- my $md5clave = MD5HexDigest( $challenge . $partes[2] );
-
- $command = "Action: Login\r\n";
- $command .= "Username: $partes[1]\r\n";
- $command .= "AuthType: MD5\r\n";
- $command .= "Key: $md5clave\r\n\r\n";
- send_command_to_manager( $command, $handle, 1 );
-}
-
-sub send_command_to_manager {
- my $comando = shift;
- my $socket = shift;
- my $noneedtoauth = shift;
- my $astmanproxy_server = shift;
- my @todos_sockets = ();
-
- if ( !defined($socket) && $astmanproxy_server eq "" ) {
- log_debug( "No socket defined nor astmanproxy", 32 ) if DEBUG;
- return;
- }
-
- if ( !defined($noneedtoauth) ) {
- $noneedtoauth = 0;
- }
-
- if ( defined($astmanproxy_server) ) {
- $comando = "Server: $astmanproxy_server\r\n" . $comando;
- }
-
- if ( !defined($astmanproxy_server) ) {
- $astmanproxy_server = "";
- }
-
- if ( !defined( $autenticado{$socket} ) && $noneedtoauth == 0 && $astmanproxy_server eq "" ) {
- log_debug( "Cannot send command to " . $ip_addy{$socket} . " (unauthenticated or connection failed)", 1 )
- if DEBUG;
- return;
- }
-
- # my @partes = split( /\|/, $manager_socket{$socket} );
-
- # $comando = "";
-
- if ( $comando eq "" ) {
- return;
- }
-
- if ( !defined($socket) ) {
- @todos_sockets = @p;
- }
- else {
- push @todos_sockets, $socket;
- }
-
- foreach (@todos_sockets) {
- my $sockwrite = $_;
- if ( !defined($sockwrite) || $sockwrite eq "" ) { next; }
- my @lineas = split( "\r\n", $comando );
- foreach my $linea (@lineas) {
- push @{ $manager_queue{$sockwrite} }, "$linea\r\n";
- }
- $global_verbose = "separator";
- push @{ $manager_queue{$sockwrite} }, "\r\n";
- }
-}
-
-sub recompute_queues {
- my $canalid = shift;
- my @return_corto;
- my @return_ocupado;
- my $maxtime = 0;
-
- my $header = "**RECOMP QUEUE";
- log_debug( "$header canalid $canalid", 1 ) if DEBUG;
- my $queue_to_recompute = $cola->{$canalid}{QUEUE};
- my $position_removed = $cola->{$canalid}{POSITION};
-
- log_debug( "$header queue_to_recompute $queue_to_recompute", 1 ) if DEBUG;
- log_debug( "$header position removed $position_removed", 1 ) if DEBUG;
-
- if ( $queue_hide == 1 ) {
- push @return_corto,
- $cola->{$canalid}{QUEUE} . "="
- . $cola->{$canalid}{POSITION}
- . "|setalpha|000|"
- . $cola->{$canalid}{QUEUE} . "-"
- . $cola->{$canalid}{SERVER}
- . "|$canalid";
- }
- push @return_corto,
- $cola->{$canalid}{QUEUE} . "="
- . $cola->{$canalid}{POSITION}
- . "|corto||"
- . $cola->{$canalid}{QUEUE} . "-"
- . $cola->{$canalid}{SERVER}
- . "|$canalid";
- delete $cola->{$canalid};
- my $save_id;
-
- foreach my $id ( keys %{$cola} ) {
- if ( $queue_to_recompute eq $cola->{$id}{QUEUE} ) {
- $save_id = $id;
- my $diftime = time() - $cola->{$id}{TIME};
- if ( $diftime > $maxtime ) {
- $maxtime = $diftime;
- }
-
- if ( $cola->{$id}{POSITION} > $position_removed ) {
- my $clidtext = $cola->{$id}{CLIDNAME} . " " . $cola->{$id}{CLID};
- if ( $queue_hide == 1 ) {
- push @return_corto,
- $cola->{$id}{QUEUE} . "="
- . $cola->{$id}{POSITION}
- . "|setalpha|000|"
- . $cola->{$id}{QUEUE} . "-"
- . $cola->{$id}{SERVER} . "|$id";
- }
- push @return_corto,
- $cola->{$id}{QUEUE} . "="
- . $cola->{$id}{POSITION}
- . "|corto||"
- . $cola->{$id}{QUEUE} . "-"
- . $cola->{$id}{SERVER} . "|$id";
- $cola->{$id}{POSITION}--;
- push @return_ocupado,
- $cola->{$id}{QUEUE} . "="
- . $cola->{$id}{POSITION}
- . "|settimer|$diftime|"
- . $cola->{$id}{QUEUE} . "-"
- . $cola->{$id}{SERVER} . "|$id";
- push @return_ocupado,
- $cola->{$id}{QUEUE} . "="
- . $cola->{$id}{POSITION}
- . "|state|busy|"
- . $cola->{$id}{QUEUE} . "-"
- . $cola->{$id}{SERVER} . "|$id";
- push @return_ocupado, $cola->{$id}{QUEUE} . "|state|busy|" . $cola->{$id}{QUEUE} . "-" . $cola->{$id}{SERVER} . "|$id";
- push @return_ocupado,
- $cola->{$id}{QUEUE} . "|settimer|0\@STOP|" . $cola->{$id}{QUEUE} . "-" . $cola->{$id}{SERVER} . "|$id";
- push @return_ocupado,
- $cola->{$id}{QUEUE} . "="
- . $cola->{$id}{POSITION}
- . "|settext|[$clidtext]|"
- . $cola->{$id}{QUEUE} . "-"
- . $cola->{$id}{SERVER} . "|$id";
- }
- }
- }
- if ( defined($save_id) ) {
- push @return_ocupado,
- $cola->{$save_id}{QUEUE} . "|settimer|$maxtime\@UP|" . $cola->{$save_id}{QUEUE} . "-" . $cola->{$save_id}{SERVER} . "|$save_id";
- }
-
- @return_ocupado = unique(@return_ocupado);
-
- if (@return_corto) {
- my @todos = ();
- push @todos, @return_corto;
- push @todos, @return_ocupado;
- return @todos;
- }
-
- # TEST|corto|&waitingonqueue,0,&|TEST-0|SIP/16-ea0c
-}
-
-sub split_callerid {
- my $clid = shift;
- my @return = ();
- my $calleridname = "";
- my $calleridnum = "";
-
- if ( $clid =~ /</ ) {
-
- #$clid =~ /"?(.*)<(.*)>/;
- $clid =~ /"?'?([^"']*)"?'?\s+?<(.*)>/;
- $calleridname = $1;
- $calleridnum = $2;
- if ( !defined($calleridname) ) { $calleridname = ""; }
- if ( !defined($calleridnum) ) { $calleridnum = ""; }
- if ( $calleridname eq $calleridnum ) {
- $calleridname = "";
- }
- }
- else {
- $calleridnum = $clid;
- $calleridname = "";
- }
- push @return, $calleridnum;
- push @return, $calleridname;
-
- return @return;
-}
-
-sub is_number {
- my $num = shift;
- if ( !defined($num) ) { return 1; }
- if ( $num =~ /[^0-9]/ ) {
- return 0;
- }
- else {
- return 1;
- }
-}
-
-sub close_all {
- foreach my $file (@all_flash_files) {
- log_debug( "Removing $file...", 1 ) if DEBUG;
- unlink($file);
- }
- foreach my $hd ( $O->handles ) {
- my $peer_ip = $ip_addy{$hd};
- if ( defined($peer_ip) ) {
- log_debug( "Closing " . $peer_ip, 1 ) if DEBUG;
- }
-
- $O->remove($hd);
- close($hd);
- }
-
- log_debug( "Exiting...", 1 ) if DEBUG;
- exit(0);
-}
-
-sub inArray {
- my $val = shift;
- for my $elem (@_) {
- if ( $val eq $elem ) {
- return 1;
- }
- }
- return 0;
-}
-
-sub encode_base64 {
- my $res = "";
- my $eol = "\n";
- pos( $_[0] ) = 0;
- while ( $_[0] =~ /(.{1,45})/gs ) {
- $res .= substr( pack( "u", $1 ), 1 );
- chop($res);
- }
- $res =~ tr|` -_|AA-Za-z0-9+/|; # `
- my $padding = ( 3 - length( $_[0] ) % 3 ) % 3;
- $res =~ s/.{$padding}$/"=" x $padding/e if $padding;
-
- return $res;
-}
-
-sub format_clid {
-
- # Subroutine to format the caller id number
- # The format string is in the form "(xxx) xxx-xxxx"
- # Every x is counted as a digit, any other text is
- # displayed as is. The digits are replaced from right
- # to left. If there are digits left, they are discarded
-
- my $numero = shift;
- my $format = shift;
- my @chars_number = ();
- my @chars_format = ();
- my @result = ();
- my $devuelve = "";
-
- if ( !is_number($numero) ) {
- return $numero;
- }
-
- if ($clid_privacy) {
- return "n/a";
- }
-
- @chars_number = split( //, $numero );
- @chars_format = split( //, $format );
-
- @chars_format = reverse @chars_format;
-
- my $parate = 0;
- foreach (@chars_format) {
- if (@chars_number) {
- if ( $_ eq "x" or $_ eq "X" ) {
- push( @result, pop @chars_number );
- }
- else {
- push( @result, $_ );
- }
- }
- else {
- if ($parate) { last; }
-
- if ( $_ eq "x" or $_ eq "X" or $_ ne "(" ) {
- $parate = 1;
- next;
- }
- else {
- push( @result, $_ );
- last;
- }
- }
- }
-
- @result = reverse @result;
- $devuelve = join( "", @result );
- return $devuelve;
-}
-
-sub generate_random_password {
- my $passwordsize = shift;
- my @alphanumeric = ( 'a' .. 'z', 'A' .. 'Z', 0 .. 9 );
- my $randpassword = join '', map $alphanumeric[ rand @alphanumeric ], 0 .. $passwordsize;
-
- return $randpassword;
-}
-
-sub sends_incorrect {
- my $socket = shift;
- my $manda = "0|incorrect|0";
- my $T = send_status_to_flash( $socket, $manda, 0 );
-}
-
-sub sends_correct {
- my $socket = shift;
- my $manda = "0|correct|0";
- my $T = send_status_to_flash( $socket, $manda, 0 );
-}
-
-sub sends_version {
- my $socket = shift;
- my $nocrypt = 0;
- my $contexto = $flash_contexto{$socket};
- my $boton = "0";
- if ( $contexto ne "" ) {
- $boton .= "\@$contexto";
- }
- my $version_string = "$boton|version|$FOP_VERSION";
- if ( !$keys_socket{"$socket"} ) {
- $nocrypt = 1;
- }
- send_status_to_flash( $socket, $version_string, $nocrypt );
-}
-
-sub sends_key {
-
- # Generate random key por padding the password
- # and write it to the client
- my $socket = shift;
- my $keylen = int( rand(22) );
- my $nocrypt = 0;
- $keylen += 15;
- my $randomkey = generate_random_password($keylen);
- my $mandakey = "$randomkey|key|0";
- if ( !$keys_socket{"$socket"} ) {
- $nocrypt = 1;
- }
- if ( !defined( $keys_socket{$socket} ) ) {
- $keys_socket{$socket} = $randomkey;
- }
- send_status_to_flash( $socket, $mandakey, $nocrypt );
-}
-
-sub unique {
- my %seen;
- my @return = ();
- return grep { !$seen{$_}++ } @_;
-
- #@return = grep { !$seen{$_}++ } @_;
- #@return = sort ( @return );
- #return @return;
-}
-
-sub MD5Digest {
- my $context = &MD5Init();
-
- # security feature: uncomment and put your own "magic string"
- # note: MD5test.pl will not work with your magic string, of course
- # my $magicString = '!@#$%^';
- # &MD5Update($context, $magicString, length($magicString));
-
- # this should be done always
- &MD5Update( $context, $_[0], length( $_[0] ) );
-
- return &MD5Final($context);
-}
-
-#
-# same as Digest but returns digest in a printable (hex) form
-#
-
-sub MD5HexDigest {
- return unpack( "H*", &MD5Digest(@_) );
-}
-
-#
-# MD5 implementation is below
-#
-
-# derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
-
-# Original context structure
-# typedef struct {
-#
-# UINT4 state[4]; /* state (ABCD) */
-# UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
-# unsigned char buffer[64]; /* input buffer */
-#
-# } MD5_CTX;
-
-# Constants for MD5Transform routine.
-
-sub S11 { 7 }
-sub S12 { 12 }
-sub S13 { 17 }
-sub S14 { 22 }
-sub S21 { 5 }
-sub S22 { 9 }
-sub S23 { 14 }
-sub S24 { 20 }
-sub S31 { 4 }
-sub S32 { 11 }
-sub S33 { 16 }
-sub S34 { 23 }
-sub S41 { 6 }
-sub S42 { 10 }
-sub S43 { 15 }
-sub S44 { 21 }
-
-# F, G, H and I are basic MD5 functions.
-
-sub F { my ( $x, $y, $z ) = @_; ( ( ($x) & ($y) ) | ( ( ~$x ) & ($z) ) ); }
-sub G { my ( $x, $y, $z ) = @_; ( ( ($x) & ($z) ) | ( ($y) & ( ~$z ) ) ); }
-sub H { my ( $x, $y, $z ) = @_; ( ($x) ^ ($y) ^ ($z) ); }
-sub I { my ( $x, $y, $z ) = @_; ( ($y) ^ ( ($x) | ( ~$z ) ) ); }
-
-# ROTATE_LEFT rotates x left n bits.
-# Note: "& ~(-1 << $n)" is not in C version
-#
-sub ROTATE_LEFT {
- my ( $x, $n ) = @_;
- ( $x << $n ) | ( ( $x >> ( 32 - $n ) & ~( -1 << $n ) ) );
-}
-
-# FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-# Rotation is separate from addition to prevent recomputation.
-
-sub FF {
- my ( $a, $b, $c, $d, $x, $s, $ac ) = @_;
-
- $a += &F( $b, $c, $d ) + $x + $ac;
- $a = &ROTATE_LEFT( $a, $s );
- $a += $b;
-
- return $a;
-}
-
-sub GG {
- my ( $a, $b, $c, $d, $x, $s, $ac ) = @_;
-
- $a += &G( $b, $c, $d ) + $x + $ac;
- $a = &ROTATE_LEFT( $a, $s );
- $a += $b;
-
- return $a;
-}
-
-sub HH {
- my ( $a, $b, $c, $d, $x, $s, $ac ) = @_;
- $a += &H( $b, $c, $d ) + $x + $ac;
- $a = &ROTATE_LEFT( $a, $s );
- $a += $b;
-
- return $a;
-}
-
-sub II {
- my ( $a, $b, $c, $d, $x, $s, $ac ) = @_;
-
- $a += &I( $b, $c, $d ) + $x + $ac;
- $a = &ROTATE_LEFT( $a, $s );
- $a += $b;
-
- return $a;
-}
-
-# MD5 initialization. Begins an MD5 operation, writing a new context.
-
-sub MD5Init {
- my $context = {};
-
- @{ $context->{count} } = 2;
- $context->{count}[0] = $context->{count}[1] = 0;
- $context->{buffer} = '';
-
- # Load magic initialization constants.
-
- @{ $context->{state} } = 4;
- $context->{state}[0] = 0x67452301;
- $context->{state}[1] = 0xefcdab89;
- $context->{state}[2] = 0x98badcfe;
- $context->{state}[3] = 0x10325476;
-
- return $context;
-}
-
-# MD5 block update operation. Continues an MD5 message-digest
-# operation, processing another message block, and updating the context.
-
-sub MD5Update {
- my ( $context, $input, $inputLen ) = @_;
-
- # Compute number of bytes mod 64
- my $index = ( ( $context->{count}[0] >> 3 ) & 0x3F );
-
- # Update number of bits
- if ( ( $context->{count}[0] += ( $inputLen << 3 ) ) < ( $inputLen << 3 ) ) {
- $context->{count}[1]++;
- $context->{count}[1] += ( $inputLen >> 29 );
- }
-
- my $partLen = 64 - $index;
-
- # Transform as many times as possible.
-
- my $i;
- if ( $inputLen >= $partLen ) {
-
- substr( $context->{buffer}, $index, $partLen ) = substr( $input, 0, $partLen );
-
- &MD5Transform( \@{ $context->{state} }, $context->{buffer} );
-
- for ( $i = $partLen ; $i + 63 < $inputLen ; $i += 64 ) {
- &MD5Transform( $context->{state}, substr( $input, $i ) );
- }
-
- $index = 0;
- }
- else {
- $i = 0;
- }
-
- # Buffer remaining input
- substr( $context->{buffer}, $index, $inputLen - $i ) = substr( $input, $i, $inputLen - $i );
-}
-
-# MD5 finalization. Ends an MD5 message-digest operation, writing the
-# the message digest and zeroizing the context.
-
-sub MD5Final {
- my $context = shift;
-
- # Save number of bits
- my $bits = &Encode( \@{ $context->{count} }, 8 );
-
- # Pad out to 56 mod 64.
- my ( $index, $padLen );
- $index = ( $context->{count}[0] >> 3 ) & 0x3f;
- $padLen = ( $index < 56 ) ? ( 56 - $index ) : ( 120 - $index );
-
- &MD5Update( $context, $PADDING, $padLen );
-
- # Append length (before padding)
- MD5Update( $context, $bits, 8 );
-
- # Store state in digest
- my $digest = &Encode( \@{ $context->{state} }, 16 );
-
- # &MD5_memset ($context, 0);
-
- return $digest;
-}
-
-# MD5 basic transformation. Transforms state based on block.
-
-sub MD5Transform {
- my ( $state, $block ) = @_;
-
- my ( $a, $b, $c, $d ) = @{$state};
- my @x = 16;
-
- &Decode( \@x, $block, 64 );
-
- # Round 1
- $a = &FF( $a, $b, $c, $d, $x[0], S11, 0xd76aa478 ); # 1
- $d = &FF( $d, $a, $b, $c, $x[1], S12, 0xe8c7b756 ); # 2
- $c = &FF( $c, $d, $a, $b, $x[2], S13, 0x242070db ); # 3
- $b = &FF( $b, $c, $d, $a, $x[3], S14, 0xc1bdceee ); # 4
- $a = &FF( $a, $b, $c, $d, $x[4], S11, 0xf57c0faf ); # 5
- $d = &FF( $d, $a, $b, $c, $x[5], S12, 0x4787c62a ); # 6
- $c = &FF( $c, $d, $a, $b, $x[6], S13, 0xa8304613 ); # 7
- $b = &FF( $b, $c, $d, $a, $x[7], S14, 0xfd469501 ); # 8
- $a = &FF( $a, $b, $c, $d, $x[8], S11, 0x698098d8 ); # 9
- $d = &FF( $d, $a, $b, $c, $x[9], S12, 0x8b44f7af ); # 10
- $c = &FF( $c, $d, $a, $b, $x[10], S13, 0xffff5bb1 ); # 11
- $b = &FF( $b, $c, $d, $a, $x[11], S14, 0x895cd7be ); # 12
- $a = &FF( $a, $b, $c, $d, $x[12], S11, 0x6b901122 ); # 13
- $d = &FF( $d, $a, $b, $c, $x[13], S12, 0xfd987193 ); # 14
- $c = &FF( $c, $d, $a, $b, $x[14], S13, 0xa679438e ); # 15
- $b = &FF( $b, $c, $d, $a, $x[15], S14, 0x49b40821 ); # 16
-
- # Round 2
- $a = &GG( $a, $b, $c, $d, $x[1], S21, 0xf61e2562 ); # 17
- $d = &GG( $d, $a, $b, $c, $x[6], S22, 0xc040b340 ); # 18
- $c = &GG( $c, $d, $a, $b, $x[11], S23, 0x265e5a51 ); # 19
- $b = &GG( $b, $c, $d, $a, $x[0], S24, 0xe9b6c7aa ); # 20
- $a = &GG( $a, $b, $c, $d, $x[5], S21, 0xd62f105d ); # 21
- $d = &GG( $d, $a, $b, $c, $x[10], S22, 0x2441453 ); # 22
- $c = &GG( $c, $d, $a, $b, $x[15], S23, 0xd8a1e681 ); # 23
- $b = &GG( $b, $c, $d, $a, $x[4], S24, 0xe7d3fbc8 ); # 24
- $a = &GG( $a, $b, $c, $d, $x[9], S21, 0x21e1cde6 ); # 25
- $d = &GG( $d, $a, $b, $c, $x[14], S22, 0xc33707d6 ); # 26
- $c = &GG( $c, $d, $a, $b, $x[3], S23, 0xf4d50d87 ); # 27
- $b = &GG( $b, $c, $d, $a, $x[8], S24, 0x455a14ed ); # 28
- $a = &GG( $a, $b, $c, $d, $x[13], S21, 0xa9e3e905 ); # 29
- $d = &GG( $d, $a, $b, $c, $x[2], S22, 0xfcefa3f8 ); # 30
- $c = &GG( $c, $d, $a, $b, $x[7], S23, 0x676f02d9 ); # 31
- $b = &GG( $b, $c, $d, $a, $x[12], S24, 0x8d2a4c8a ); # 32
-
- # Round 3
- $a = &HH( $a, $b, $c, $d, $x[5], S31, 0xfffa3942 ); # 33
- $d = &HH( $d, $a, $b, $c, $x[8], S32, 0x8771f681 ); # 34
- $c = &HH( $c, $d, $a, $b, $x[11], S33, 0x6d9d6122 ); # 35
- $b = &HH( $b, $c, $d, $a, $x[14], S34, 0xfde5380c ); # 36
- $a = &HH( $a, $b, $c, $d, $x[1], S31, 0xa4beea44 ); # 37
- $d = &HH( $d, $a, $b, $c, $x[4], S32, 0x4bdecfa9 ); # 38
- $c = &HH( $c, $d, $a, $b, $x[7], S33, 0xf6bb4b60 ); # 39
- $b = &HH( $b, $c, $d, $a, $x[10], S34, 0xbebfbc70 ); # 40
- $a = &HH( $a, $b, $c, $d, $x[13], S31, 0x289b7ec6 ); # 41
- $d = &HH( $d, $a, $b, $c, $x[0], S32, 0xeaa127fa ); # 42
- $c = &HH( $c, $d, $a, $b, $x[3], S33, 0xd4ef3085 ); # 43
- $b = &HH( $b, $c, $d, $a, $x[6], S34, 0x4881d05 ); # 44
- $a = &HH( $a, $b, $c, $d, $x[9], S31, 0xd9d4d039 ); # 45
- $d = &HH( $d, $a, $b, $c, $x[12], S32, 0xe6db99e5 ); # 46
- $c = &HH( $c, $d, $a, $b, $x[15], S33, 0x1fa27cf8 ); # 47
- $b = &HH( $b, $c, $d, $a, $x[2], S34, 0xc4ac5665 ); # 48
-
- # Round 4
- $a = &II( $a, $b, $c, $d, $x[0], S41, 0xf4292244 ); # 49
- $d = &II( $d, $a, $b, $c, $x[7], S42, 0x432aff97 ); # 50
- $c = &II( $c, $d, $a, $b, $x[14], S43, 0xab9423a7 ); # 51
- $b = &II( $b, $c, $d, $a, $x[5], S44, 0xfc93a039 ); # 52
- $a = &II( $a, $b, $c, $d, $x[12], S41, 0x655b59c3 ); # 53
- $d = &II( $d, $a, $b, $c, $x[3], S42, 0x8f0ccc92 ); # 54
- $c = &II( $c, $d, $a, $b, $x[10], S43, 0xffeff47d ); # 55
- $b = &II( $b, $c, $d, $a, $x[1], S44, 0x85845dd1 ); # 56
- $a = &II( $a, $b, $c, $d, $x[8], S41, 0x6fa87e4f ); # 57
- $d = &II( $d, $a, $b, $c, $x[15], S42, 0xfe2ce6e0 ); # 58
- $c = &II( $c, $d, $a, $b, $x[6], S43, 0xa3014314 ); # 59
- $b = &II( $b, $c, $d, $a, $x[13], S44, 0x4e0811a1 ); # 60
- $a = &II( $a, $b, $c, $d, $x[4], S41, 0xf7537e82 ); # 61
- $d = &II( $d, $a, $b, $c, $x[11], S42, 0xbd3af235 ); # 62
- $c = &II( $c, $d, $a, $b, $x[2], S43, 0x2ad7d2bb ); # 63
- $b = &II( $b, $c, $d, $a, $x[9], S44, 0xeb86d391 ); # 64
-
- $state->[0] += $a;
- $state->[1] += $b;
- $state->[2] += $c;
- $state->[3] += $d;
-
- # Zeroize sensitive information.
- # MD5_memset ((POINTER)x, 0, sizeof (x));
-}
-
-# Encodes input (UINT4) into output (unsigned char). Assumes len is
-# a multiple of 4.
-
-sub Encode {
- my ( $input, $len ) = @_;
-
- my $output = '';
- my ( $i, $j );
- for ( $i = 0, $j = 0 ; $j < $len ; $i++, $j += 4 ) {
- substr( $output, $j + 0, 1 ) = chr( $input->[$i] & 0xff );
- substr( $output, $j + 1, 1 ) = chr( ( $input->[$i] >> 8 ) & 0xff );
- substr( $output, $j + 2, 1 ) = chr( ( $input->[$i] >> 16 ) & 0xff );
- substr( $output, $j + 3, 1 ) = chr( ( $input->[$i] >> 24 ) & 0xff );
- }
-
- return $output;
-}
-
-# Decodes input (unsigned char) into output (UINT4). Assumes len is
-# a multiple of 4.
-
-sub Decode {
- my ( $output, $input, $len ) = @_;
-
- my ( $i, $j );
-
- for ( $i = 0, $j = 0 ; $j < $len ; $i++, $j += 4 ) {
- $output->[$i] =
- ( ord( substr( $input, $j + 0, 1 ) ) ) | ( ord( substr( $input, $j + 1, 1 ) ) << 8 ) |
- ( ord( substr( $input, $j + 2, 1 ) ) << 16 ) | ( ord( substr( $input, $j + 3, 1 ) ) << 24 );
- }
-}
-#########################################################################
-# TEA Encryption algorithm
-#
-#########################################################################
-# This Perl module is Copyright (c) 2000, Peter J Billam #
-# c/o P J B Computing, www.pjb.com.au #
-#########################################################################
-
-sub binary2ascii {
- return &str2ascii( &binary2str(@_) );
-}
-
-sub ascii2binary {
- return &str2binary( &ascii2str( $_[$[] ) );
-}
-
-sub str2binary {
- my @str = split //, $_[$[];
- my @intarray = ();
- my $ii = $[;
- while (1) {
- last unless @str;
- $intarray[$ii] = ( 0xFF & ord shift @str ) << 24;
- last unless @str;
- $intarray[$ii] |= ( 0xFF & ord shift @str ) << 16;
- last unless @str;
- $intarray[$ii] |= ( 0xFF & ord shift @str ) << 8;
- last unless @str;
- $intarray[$ii] |= 0xFF & ord shift @str;
- $ii++;
- }
- return @intarray;
-}
-
-sub binary2str {
- my @str = ();
- foreach my $i (@_) {
- push @str, chr( 0xFF & ( $i >> 24 ) ), chr( 0xFF & ( $i >> 16 ) ), chr( 0xFF & ( $i >> 8 ) ), chr( 0xFF & $i );
- }
- return join '', @str;
-}
-
-sub ascii2str {
- my $a = $_[$[]; # converts pseudo-base64 to string of bytes
- $a =~ tr#A-Za-z0-9+_##cd;
- my $ia = $[ - 1;
- my $la = length $a; # BUG not length, final!
- my $ib = $[;
- my @b = ();
- my $carry;
- while (1) { # reads 4 ascii chars and produces 3 bytes
- $ia++;
- last if ( $ia >= $la );
- $b[$ib] = $a2b{ substr $a, $ia + $[, 1 } << 2;
- $ia++;
- last if ( $ia >= $la );
- $carry = $a2b{ substr $a, $ia + $[, 1 };
- $b[$ib] |= ( $carry >> 4 );
- $ib++;
-
- # if low 4 bits of $carry are 0 and its the last char, then break
- $carry = 0xF & $carry;
- last if ( $carry == 0 && $ia == ( $la - 1 ) );
- $b[$ib] = $carry << 4;
- $ia++;
- last if ( $ia >= $la );
- $carry = $a2b{ substr $a, $ia + $[, 1 };
- $b[$ib] |= ( $carry >> 2 );
- $ib++;
-
- # if low 2 bits of $carry are 0 and its the last char, then break
- $carry = 03 & $carry;
- last if ( $carry == 0 && $ia == ( $la - 1 ) );
- $b[$ib] = $carry << 6;
- $ia++;
- last if ( $ia >= $la );
- $b[$ib] |= $a2b{ substr $a, $ia + $[, 1 };
- $ib++;
- }
- return pack 'c*', @b;
-}
-
-sub str2ascii {
- my $b = $_[$[]; # converts string of bytes to pseudo-base64
- my $ib = $[;
- my $lb = length $b;
- my @s = ();
- my $b1;
- my $b2;
- my $b3;
- my $carry;
-
- while (1) { # reads 3 bytes and produces 4 ascii chars
- if ( $ib >= $lb ) { last; }
- $b1 = ord substr $b, $ib + $[, 1;
- $ib++;
- push @s, $b2a{ $b1 >> 2 };
- $carry = 03 & $b1;
- if ( $ib >= $lb ) { push @s, $b2a{ $carry << 4 }; last; }
- $b2 = ord substr $b, $ib + $[, 1;
- $ib++;
- push @s, $b2a{ ( $b2 >> 4 ) | ( $carry << 4 ) };
- $carry = 0xF & $b2;
- if ( $ib >= $lb ) { push @s, $b2a{ $carry << 2 }; last; }
- $b3 = ord substr $b, $ib + $[, 1;
- $ib++;
- push @s, $b2a{ ( $b3 >> 6 ) | ( $carry << 2 ) }, $b2a{ 077 & $b3 };
- if ( !$ENV{REMOTE_ADDR} && ( ( $ib % 36 ) == 0 ) ) { push @s, "\n"; }
- }
- return join( '', @s );
-}
-
-sub asciidigest { # returns 22-char ascii signature
- return &binary2ascii( &binarydigest( $_[$[] ) );
-}
-
-sub binarydigest {
- my $str = $_[$[]; # returns 4 32-bit-int binary signature
- # warning: mode of use invented by Peter Billam 1998, needs checking !
- return '' unless $str;
-
- # add 1 char ('0'..'15') at front to specify no of pad chars at end ...
- my $npads = 15 - ( ( length $str ) % 16 );
- $str = chr($npads) . $str;
- if ($npads) { $str .= "\0" x $npads; }
- my @str = &str2binary($str);
- my @key = ( 0x61626364, 0x62636465, 0x63646566, 0x64656667 );
-
- my ( $cswap, $v0, $v1, $v2, $v3 );
- my $c0 = 0x61626364;
- my $c1 = 0x62636465; # CBC Initial Value. Retain !
- my $c2 = 0x61626364;
- my $c3 = 0x62636465; # likewise (abcdbcde).
- while (@str) {
-
- # shift 2 blocks off front of str ...
- $v0 = shift @str;
- $v1 = shift @str;
- $v2 = shift @str;
- $v3 = shift @str;
-
- # cipher them XOR'd with previous stage ...
- ( $c0, $c1 ) = &tea_code( $v0 ^ $c0, $v1 ^ $c1, @key );
- ( $c2, $c3 ) = &tea_code( $v2 ^ $c2, $v3 ^ $c3, @key );
-
- # mix up the two cipher blocks with a 4-byte left rotation ...
- $cswap = $c0;
- $c0 = $c1;
- $c1 = $c2;
- $c2 = $c3;
- $c3 = $cswap;
- }
- return ( $c0, $c1, $c2, $c3 );
-}
-
-sub TEAencrypt {
- my ( $str, $key ) = @_; # encodes with CBC (Cipher Block Chaining)
- use integer;
- return '' unless $str;
- return '' unless $key;
- @key = &binarydigest($key);
-
- # add 1 char ('0'..'7') at front to specify no of pad chars at end ...
- my $npads = 7 - ( ( length $str ) % 8 );
- $str = chr( $npads | ( 0xF8 & &rand_byte ) ) . $str;
- if ($npads) {
- my $padding = pack 'CCCCCCC', &rand_byte, &rand_byte, &rand_byte, &rand_byte, &rand_byte, &rand_byte, &rand_byte;
- $str = $str . substr( $padding, $[, $npads );
- }
- my @pblocks = &str2binary($str);
- my $v0;
- my $v1;
- my $c0 = 0x61626364;
- my $c1 = 0x62636465; # CBC Initial Value. Retain !
- my @cblocks;
- while (1) {
- last unless @pblocks;
- $v0 = shift @pblocks;
- $v1 = shift @pblocks;
- ( $c0, $c1 ) = &tea_code( $v0 ^ $c0, $v1 ^ $c1, @key );
- push @cblocks, $c0, $c1;
- }
- my $btmp = &binary2str(@cblocks);
- return &str2ascii( &binary2str(@cblocks) );
-}
-
-sub TEAdecrypt {
- my ( $acstr, $key ) = @_; # decodes with CBC
- use integer;
- return '' unless $acstr;
- return '' unless $key;
- @key = &binarydigest($key);
- my $v0;
- my $v1;
- my $c0;
- my $c1;
- my @pblocks = ();
- my $de0;
- my $de1;
- my $lastc0 = 0x61626364;
- my $lastc1 = 0x62636465; # CBC Init Val. Retain!
- my @cblocks = &str2binary( &ascii2str($acstr) );
-
- while (1) {
- last unless @cblocks;
- $c0 = shift @cblocks;
- $c1 = shift @cblocks;
- ( $de0, $de1 ) = &tea_decode( $c0, $c1, @key );
- $v0 = $lastc0 ^ $de0;
- $v1 = $lastc1 ^ $de1;
- push @pblocks, $v0, $v1;
- $lastc0 = $c0;
- $lastc1 = $c1;
- }
- my $str = &binary2str(@pblocks);
-
- # remove no of pad chars at end specified by 1 char ('0'..'7') at front
- my $npads = 0x7 & ord $str;
- substr( $str, $[, 1 ) = '';
- if ($npads) { substr( $str, 0 - $npads ) = ''; }
- return $str;
-}
-
-sub triple_encrypt {
- my ( $plaintext, $long_key ) = @_; # not yet ...
-}
-
-sub triple_decrypt {
- my ( $cyphertext, $long_key ) = @_; # not yet ...
-}
-
-sub tea_code {
- my ( $v0, $v1, $k0, $k1, $k2, $k3 ) = @_;
-
- # TEA. 64-bit cleartext block in $v0,$v1. 128-bit key in $k0..$k3.
- # &prn("tea_code: v0=$v0 v1=$v1");
- use integer;
- my $sum = 0;
- my $n = 32;
- while ( $n-- > 0 ) {
- $sum += 0x9e3779b9; # TEA magic number delta
- $v0 += ( ( $v1 << 4 ) + $k0 ) ^ ( $v1 + $sum ) ^ ( ( 0x07FFFFFF & ( $v1 >> 5 ) ) + $k1 );
- $v1 += ( ( $v0 << 4 ) + $k2 ) ^ ( $v0 + $sum ) ^ ( ( 0x07FFFFFF & ( $v0 >> 5 ) ) + $k3 );
- }
- return ( $v0, $v1 );
-}
-
-sub tea_decode {
- my ( $v0, $v1, $k0, $k1, $k2, $k3 ) = @_;
-
- # TEA. 64-bit cyphertext block in $v0,$v1. 128-bit key in $k0..$k3.
- use integer;
- my $sum = 0;
- my $n = 32;
- $sum = 0x9e3779b9 << 5; # TEA magic number delta
- while ( $n-- > 0 ) {
- $v1 -= ( ( $v0 << 4 ) + $k2 ) ^ ( $v0 + $sum ) ^ ( ( 0x07FFFFFF & ( $v0 >> 5 ) ) + $k3 );
- $v0 -= ( ( $v1 << 4 ) + $k0 ) ^ ( $v1 + $sum ) ^ ( ( 0x07FFFFFF & ( $v1 >> 5 ) ) + $k1 );
- $sum -= 0x9e3779b9;
- }
- return ( $v0, $v1 );
-}
-
-sub rand_byte {
- if ( !$rand_byte_already_called ) {
- srand( time() ^ ( $$ + ( $$ << 15 ) ) ); # could do better, but its only padding
- $rand_byte_already_called = 1;
- }
- int( rand 256 );
-}
-
-#
-# End TEA
-
-sub print_agentonqueue {
- my $valor = shift;
- if ( keys(%agents_on_queue) ) {
- log_debug( $valor, 1 ) if DEBUG;
- foreach my $valor ( sort ( keys(%agents_on_queue) ) ) {
- foreach my $vvalor ( @{ $agents_on_queue{$valor} } ) {
- log_debug( "agents_on_queue{$valor} = $vvalor", 1 ) if DEBUG;
- }
- }
- }
-}
-
-sub print_countqueue {
- my $valor = shift;
- if ( keys(%count_queue) ) {
- foreach my $valor ( sort ( keys(%count_queue) ) ) {
- foreach my $vvalor ( @{ $count_queue{$valor} } ) {
- log_debug( "\t| count_queue{$valor} = $vvalor", 32 ) if DEBUG;
- }
- }
- }
-}
-
-sub print_datos {
- if ( $debuglevel & 1 ) {
- my $num = shift;
-
- if ( keys(%datos) ) {
- print "---------------------------------------------------\n";
- print "DATOS $num\n";
- print "---------------------------------------------------\n";
- for ( keys %datos ) {
- print $_. "\n";
- while ( my ( $key, $val ) = each( %{ $datos{$_} } ) ) {
- if ( defined($val) ) {
- print "\t$key = $val\n";
- }
- }
- print "---------------------------------------------------\n";
- }
- }
- else {
- print "NO DATOS TO DISPLAY\n";
- }
- }
-}
-
-sub print_cachehit {
- if ( $debuglevel & 1 ) {
- print "---------------------------------------------------\n";
- print "CACHE HIT\n";
- print "---------------------------------------------------\n";
- if ( keys(%cache_hit) ) {
- for ( keys %cache_hit ) {
- print "key $_\n";
-
- if ( defined( @{ $cache_hit{$_} } ) ) {
- my @final = ();
- foreach my $val ( @{ $cache_hit{$_} } ) {
- print "\tcache_hit($_) = $val\n";
- }
- }
- }
- }
- else {
- print "NO CACHE HITS TO DISPLAY\n";
- }
- print "---------------------------------------------------\n";
- }
-}
-
-sub print_linkbot {
- if ( $debuglevel & 1 ) {
- print "---------------------------------------------------\n";
- print "LINKS BOTONES\n";
- print "---------------------------------------------------\n";
- if ( keys(%linkbot) ) {
- for ( keys %linkbot ) {
- if ( defined( @{ $linkbot{$_} } ) ) {
- my @final = ();
- foreach my $val ( @{ $linkbot{$_} } ) {
- print "\tlinkbot($_) = $val\n";
- }
- }
- }
- }
- else {
- print "NO DATOS TO DISPLAY\n";
- }
- print "---------------------------------------------------\n";
- }
-}
-
-sub print_sesbot {
- my $quien = shift;
-
- if ( $debuglevel & 1 ) {
- print "---------------------------------------------------\n";
- print "SESIONES BOTONES $quien\n";
- print "---------------------------------------------------\n";
- if ( keys(%sesbot) ) {
- for ( keys %sesbot ) {
- if ( defined( @{ $sesbot{$_} } ) ) {
- my @final = ();
- foreach my $val ( @{ $sesbot{$_} } ) {
- print "\tsesbot($_) = $val\n";
- }
- }
- }
- }
- else {
- print "NO DATOS TO DISPLAY\n";
- }
- print "---------------------------------------------------\n";
-
- }
-}
-
-sub print_instancias {
- if ( $debuglevel & 1 ) {
- my $num = shift;
- print "---------------------------------------------------\n";
- print "Instancias 2 $num\n";
- print "---------------------------------------------------\n";
- foreach my $caca ( sort ( keys(%instancias) ) ) {
- print $caca. "\n";
- foreach my $pipu ( sort ( keys( %{ $instancias{$caca} } ) ) ) {
- print "\t$pipu = $instancias{$caca}{$pipu}\n";
- }
- }
- print "---------------------------------------------------\n";
- }
-}
-
-sub print_botones {
- if ( $debuglevel & 1 ) {
- my $num = shift;
- print "---------------------------------------------------\n";
- print "Botones $num\n";
- print "---------------------------------------------------\n";
- foreach ( sort ( keys(%buttons) ) ) {
- printf( "%-20s %-10s %-10s\n", $_, $buttons{$_}, $button_server{ $buttons{$_} } );
- }
- }
-}
-
-sub print_cola_write {
- my $socket = shift;
- if ( !defined($socket) ) {
- for ( keys %client_queue ) {
- my $contame = 0;
- foreach my $val ( @{ $client_queue{$_} } ) {
- $contame++;
- print "cola $contame $_ comando $val\n";
- }
- }
- }
- else {
- my $contame = 0;
- foreach my $val ( @{ $client_queue{$socket} } ) {
- $contame++;
- print "cola $contame $socket comando $val\n";
- }
- }
-}
-
-sub print_timers {
- if ( $debuglevel & 1 ) {
- if ( keys(%botontimer) ) {
- for my $interno ( keys %botontimer ) {
- print "botontimer $interno = $botontimer{$interno}, type $botontimertype{$interno}\n";
- }
- }
- }
-}
-
-sub print_clients {
- if ( $debuglevel & 1 ) {
- my $number_of_flash_clients_connected = @flash_clients;
-
- if ( $number_of_flash_clients_connected > 0 ) {
- print "\nFlash clients connected: $number_of_flash_clients_connected\n";
- print "---------------------------------------------------\n";
-
- foreach my $C (@flash_clients) {
- print peerinfo($C) . " $C\n";
- }
- print "---------------------------------------------------\n";
- }
- else {
- print "No flash clients connected\n";
- }
- }
-}
-
-sub print_agents {
-
- if ( $debuglevel & 1 ) {
- if ( keys(%agent_to_channel) ) {
- print "Agent_to_channel: \n";
- foreach my $valor ( sort ( keys(%agent_to_channel) ) ) {
- print "agent_to_channel{$valor} = $agent_to_channel{$valor}\n";
- }
- }
- if ( keys(%reverse_agents) ) {
- print "Reverse Agents: \n";
- foreach my $valor ( sort ( keys(%reverse_agents) ) ) {
- print "reverse_agents{$valor} = $reverse_agents{$valor}\n";
- }
- }
- if ( keys(%channel_to_agent) ) {
- print "Channel to Agent: \n";
- foreach my $valor ( sort ( keys(%channel_to_agent) ) ) {
- print "channel_to_agent{$valor} = $channel_to_agent{$valor}\n";
- }
- }
- if ( keys(%agents_on_queue) ) {
- print "Agents on queue: \n";
- foreach my $valor ( sort ( keys(%agents_on_queue) ) ) {
- print "agents_on_queue{$valor} = $agents_on_queue{$valor}\n";
- }
- }
- if ( keys(%is_agent) ) {
- print "is Agents: \n";
- foreach my $valor ( sort ( keys(%is_agent) ) ) {
- print "is_agent{$valor} = $is_agent{$valor}\n";
- }
- }
- if ( keys(%count_queue) ) {
- print "Count on queue: \n";
- foreach my $valor ( sort ( keys(%count_queue) ) ) {
- print "count_queue{$valor} = $count_queue{$valor}\n";
- }
- }
-
- }
-}
-
-sub print_status {
- if ( keys(%estadoboton) ) {
- print "---------------------------------------------------\n";
- print "ESTADO BOTONES\n";
- print "---------------------------------------------------\n";
- for ( keys %estadoboton ) {
- my $separador = 0;
- my $nroboton = $_;
- print "$nroboton\t $estadoboton{$nroboton}\t \n";
- }
- print "---------------------------------------------------\n";
- }
- else {
- print "No estadoboton populated\n";
- }
-
- if ( keys(%botonled) ) {
- print "----- LEDS --------\n";
- for ( keys %botonled ) {
- print "$_ = $botonled{$_} $botonlabel{$_}\n";
- }
- }
- if ( keys(%botonvoicemail) ) {
- print "----- VOICEMAIL --------\n";
- for ( keys %botonvoicemail ) {
- print "$_ = $botonvoicemail{$_}\n";
- }
- }
-}
-
-__END__
-
-=head1 NAME
-
-op_server.pl - Proxy server for the Asterisk Flash Operator Panel
-
-=head1 SYNOPSIS
-
-op_server.pl [options]
-
- Options:
- -?, --help
- -p, --pidfile
- -c, --confdir
- -l, --logdir
- -d, --daemon
- -v, --version
- -X, --debuglevel
-
-=head1 OPTIONS
-
-=over 8
-
-=item B<--help>
-
-Print a brief help message and exits
-
-=item B<--pidfile>
-
-Specify the pid file to use when running in daemon mode. Defaults to /var/run/op_panel.pid
-
-=item B<--confdir>
-
-Specify where to look for the configuration files. If omited, it will look for them in the same directory where op_server.pl resides
-
-=item B<--logdir>
-
-If specified, will write the log files to that directory. If not, it will output to STDOUT and STDERR
-
-=item B<--daemon>
-
-Run the server in daemon mode, detaching itself from the console
-
-=item B<--version>
-
-Display the version and exits
-
-=item B<--debuglevel>
-
-Sets the debug level for the logs. It overrides the value inside op_server.cfg
-
-=back
-
-=head1 DESCRIPTION
-
-B<This program> will read the given input file(s) and do someting useful with the contents thereof.
-
-=cut
Deleted: op-panel/trunk/op_style.cfg
===================================================================
--- op-panel/trunk/op_style.cfg 2007-04-27 22:54:23 UTC (rev 3495)
+++ op-panel/trunk/op_style.cfg 2007-04-27 22:57:32 UTC (rev 3496)
@@ -1,78 +0,0 @@
-[general]
-shake_pixels=2
-dimm_noregister_by=20
-dimm_lagged_by=60
-enable_label_background=0
-enable_crypto=0 ; set to 1 for encrypting server to client traffic
-enable_animation=1
-use_embed_fonts=1
-ledcolor_ready=0x00A000
-ledcolor_busy=0xA01020
-ledcolor_agent=0xD0d020
-label_font_size=20
-label_font_family=Verdana ; only valid when use_embed_fonts is disabled
-label_font_color=000000
-label_shadow_color=dddddd
-label_margin_top=20
-label_margin_left=38
-label_shadow=1
-clid_font_color=00dd00
-timer_font_color=4000ff
-clid_font_size=13
-clid_font_family=Verdana ; only valid when use_embed_fonts is disabled
-clid_margin_top=0
-clid_margin_left=25
-timer_font_size=13
-timer_font_family=Courier ; only valid when use_embed_fonts is disabled
-timer_margin_top=48
-timer_margin_left=6
-btn_width=246
-btn_height=70
-btn_padding=4
-btn_line_width=2
-btn_line_color=0x000000
-btn_fadecolor_1=ccccff
-btn_fadecolor_2=ffffff
-btn_round_border=8
-btn_highlight_color=ff0000
-led_scale=90
-led_margin_top=34
-led_margin_left=20
-arrow_scale=70
-arrow_margin_top=10
-arrow_margin_left=15
-icon1_margin_top=43
-icon1_margin_left=-34
-icon1_scale=17
-icon2_margin_top=46
-icon2_margin_left=-29
-icon2_scale=14
-icon3_margin_top=34
-icon3_margin_left=-36
-icon3_scale=20
-icon4_margin_top=33
-icon4_margin_left=-34
-icon4_scale=16
-icon5_margin_top=32
-icon5_margin_left=-33
-icon5_scale=16
-icon6_margin_top=32
-icon6_margin_left=-33
-icon6_scale=16
-mail_margin_left=-23
-mail_margin_top=13
-mail_scale=9
-show_security_code=1
-show_clid_info=0
-show_btn_help=3
-show_btn_debug=0
-show_btn_reload=2
-show_status=4
-
-;[sip]
-; You can have different styles per panel context
-; You need to copy all the variables, they will not be
-; inherited. If you fail to include an option the flash
-; client migth hang. So, copy the complete [general]
-; section an change the header to the panel context name.
-; Then adjust the parameters to your liking.
More information about the Pkg-voip-commits
mailing list