<%@ page language="java" import="com.cisco.ipphone.sdk.*, com.cisco.ipphone.sdk.push2phone.PushMessage, java.net.InetAddress, java.util.*" %>

<%
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Title:  		Push2Phone
// Author: 		kstearns
// Source File(s):  	push2phone.jsp
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  Description:
//
//  Push2Phone provides a form to enter a message to be sent to a group of phones.
//  A text message is entered, a group of phones are selected from a list, and Send send's the
//  message.
//  The list of phones is generated by query the CallManager database via the AVVID XML-Layer Database
//  API (AXL).
//  Once the message is entered and the phones are selected, the submit action of the form POSTs the
//  information back to this same .jsp script which handles PUSHing the message to the phones.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  Requirements and Caveats:
//
// -  Client: HTML Browser (PC-based web browser)
//
//  - In order for the user names to appear next to the phone names, the phones must be associated
//    to the users in the CallManager directory.
//
// - In order for Push2Phone to work, the PUSH userID and PUSH password hard-coded below
//   MUST have authority to PUSH to all phones used by the application.
//   For example, a new application user ID of 'sdkapps' could be created in the Global Directory.
//   All phones using the application are then selected as Associated Devices for user 'sdkapps'.
//
//   NOTE: For large-scale PUSH applications, associating hundreds or even thousands of devices to a single user
//         (for purposes of PUSH authentication) is *NOT ACCEPTABLE*.
//         In this case, the PUSH authentication *MUST* be offloaded from the CallManager server to an external
//         web server - see the PushAuthenticate ASP sample script for more information.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////

//
//  Edit the following Strings for your environment.
//  This is for sample purposes only - placing passwords and other
//  sensitive information in an open text file is obviously NOT recommended !!!
//

String thisServer = InetAddress.getLocalHost().getHostAddress();
String thisPath = request.getRequestURI();
String messageURL = "http://" + thisServer + ":8080" + thisPath + "?action=get";

String callManager = "10.32.250.141";
String callManagerUserId = "administrator";
String callManagerPassword = "c1sc0";

String ldapServer = "10.32.250.141";
String ldapRoot = "o=cisco.com";
String ldapUserId = "cn=Directory Manager, o=cisco.com";
String ldapPassword = "c1sc0";
int ldapPort = 8404;

String pushUserId = "sdkapps";
String pushPassword = "sdkapps";

  // The old IPAddressProvider was used on older CallManager servers that only supported the DeviceListX page
  // Recent CUCM versions support the new RIS interface for realtime information
  // IPAddressProvider ipProv = new IPAddressProvider(callManager, callManagerUserId, callManagerPassword);
IPAddressProviderIF ipProv = new RisProvider(callManager, callManagerUserId, callManagerPassword);

LDAPProvider ldapProv = new LDAPProvider(ldapServer, ldapUserId, ldapPassword, ldapPort, ldapRoot);

String action = request.getParameter("action");
if (action == null) action="list";

/////////////////////////////////////////////////////////////////
// If no action was specified, then create the PhonePush form
/////////////////////////////////////////////////////////////////

if (action.equals("list"))
{
  out.println("<html>");
  out.println("<body>");
  out.println("<h1>Push2Phone</h1>");

  out.println("<form method=\"POST\" action=push2phone.jsp?action=push>");
  out.println("<textarea rows=\"20\" name=\"message\">Type your\nurgent message\nhere !!!</textarea>");
  out.println("<select size=\"20\" name=\"phones\" multiple>");

  // Exclude the 'sdkapps' user because it will be associated with all phones
  // The only other associated User should be the real owner of the phone

  String[] excludedUsers = { pushUserId };

  HashMap registeredDevices = ipProv.getAllIPAddresses();
  Iterator deviceIter = registeredDevices.keySet().iterator();

  while (deviceIter.hasNext()) {
    String deviceName = (String)deviceIter.next();
    out.print("<option>" + deviceName + ": ");
    Phone thePhone = Phone.getPhone(deviceName);
    User[] users = thePhone.getControllingUsers(ldapProv, excludedUsers);
    // Get the first user - it should be the only one
    if (users.length > 0) {
      User user = users[0];
      user.loadAttributes(ldapProv);
      out.print(user.getFirstName() + " " + user.getLastName());
      out.print(" (" + user.getUserId() + ")");
      out.println("</option>");
    }
  }

  %>
  </select>
  <p><input type="submit" value="Send" name="B1">&nbsp;&nbsp;&nbsp;&nbsp;<input type="reset" value="Reset" name="B2"></p>
  </form>
  </body>
  </html>
  <%

}

////////////////////////////////////////////////////////////
// If action = push then PUSH the message to the phones
////////////////////////////////////////////////////////////

if (action.equals("push"))
{
  response.setHeader("Refresh", "3; URL=push2phone.jsp");
  out.println("<html>");
  out.println("<body>");
  out.println("<h1>Push2Phone</h1>");
  out.println("<br><br><b>Sending Message ...</b>");

  if (request.getParameterValues("phones") != null)
  {
     // Inform the PushMessage class to update the message
     PushMessage.setMessageText(request.getParameter("message"));

     String[] phoneNames = request.getParameterValues("phones");
     String phoneIP;

     // Step thru the list of phones specified, getting their active IP address, and
     // PUSHing a URL command to retrieve the message

     Phone[] phones = new Phone[phoneNames.length];
     for (int i=0; i < phones.length; i++)
       phones[i] = Phone.getPhone(phoneNames[i].substring(0, phoneNames[i].indexOf(":")));

     String[] ipAddrs = ipProv.getIPAddresses(phones);

     String[] uris = { messageURL, "Play:chime.raw" };
     for (int i=0; i < phones.length;i++) {
       if (ipAddrs[i] != null) {
         out.println("<br>Sent: " + phones[i].getDeviceName() + " at " + ipAddrs[i]);
         phones[i].push(uris, ipAddrs[i], pushUserId, pushPassword, false);
       }
     }
  }
  out.println("</body>");
  out.println("</html>");
}

//////////////////////////////////////////////////////////////////////////////
// If action = get then this is a request from an IP phone for the message
//////////////////////////////////////////////////////////////////////////////

if (action.equals("get"))
{
  // So read the XML object from the text file and return it to the phone

  response.setContentType("text/xml");
  out.print(PushMessage.getMessageXML());
}



//  THIS SAMPLE APPLICATION AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND BY CISCO, 
//  EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY
//  FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, SATISFACTORY QUALITY OR ARISING FROM A COURSE
//  OF DEALING, LAW, USAGE, OR TRADE PRACTICE.  CISCO TAKES NO RESPONSIBILITY REGARDING ITS USAGE IN AN
//  APPLICATION., THE APPLICATION IS PROVIDED AS AN EXAMPLE ONLY, THEREFORE CISCO DOES NOT MAKE ANY
//  REPRESENTATIONS REGARDING ITS RELIABILITY, SERVICEABILITY, OR FUNCTION.  IN NO EVENT DOES CISCO
//  WARRANT THAT THE SOFTWARE IS ERROR FREE OR THAT CUSTOMER WILL BE ABLE TO OPERATE THE SOFTWARE WITHOUT
//  PROBLEMS OR INTERRUPTIONS.  NOR DOES CISCO WARRANT THAT THE SOFTWARE OR ANY EQUIPMENT ON WHICH THE
//  SOFTWARE IS USED WILL BE FREE OF VULNERABILITY TO INTRUSION OR ATTACK.  THIS SAMPLE APPLICATION IS
//  NOT SUPPORTED BY CISCO IN ANY MANNER. CISCO DOES NOT ASSUME ANY LIABILITY ARISING FROM THE USE OF THE
//  APPLICATION. FURTHERMORE, IN NO EVENT SHALL CISCO OR ITS SUPPLIERS BE LIABLE FOR ANY INCIDENTAL OR
//  CONSEQUENTIAL DAMAGES, LOST PROFITS, OR LOST DATA, OR ANY OTHER INDIRECT DAMAGES EVEN IF CISCO OR ITS
//  SUPPLIERS HAVE BEEN INFORMED OF THE POSSIBILITY THEREOF.


%>


