BasicExtensionMobility-Csharp - Wiki
Wiki
BasicExtensionMobility-Csharp
About the Application#
When triggered by an HTTP request, the application handles basic login and logout.
You would need to create a extension mobility device profile for the specific device you are applying the profile on. Also, you would need to create a phone service in communications manager and point to the CUAE server hosting this particular application.
Create the Application project#
1. Open a command shell
2. The cuae requires at a minimum the name of the application project, the implementation language and the module name in the csharp to get started. If the language and or the module name are omitted the tool will prompt the you for them. Lets use the cuae tool to create a new application.
cuae create BasicExtensionMobility_CSharp
3. First the tool will ask you if you are building an application or a plugin. Answer application:
Project Type? [application or plugin] application
4. Next the tool will ask you to specify the programming language. Answer csharp:
Programming language? [java or csharp] csharp
5. Next the tool will ask you for the namespace for the application. You can provide a name or accept the default. Let's accept the default for this sample application basicextensionmobility_csharp:
Project namespace? [default: basicextensionmobility_csharp] <Return>
5. Finally the tool will ask if you would like to specify a triggering event. All CUAE applications will need to register against at least one triggering event. You can specify the triggering event now or wait and specify the triggering event later. You can also change the triggering event during development. Again since we know that this application needs to be triggered on an Http request, lets go ahead and specify the triggering event now. Select cisco.uc.cuae.legacy.Http.GotRequest (option 5):
Available application triggering event: 0: Skip this step 1: cisco.uc.cuae.legacy.JTapi.JTapiIncomingCall 2: cisco.uc.cuae.legacy.JTapi.JTapiCallInitiated 3: cisco.uc.cuae.legacy.JTapi.JTapiCallEstablished 4: cisco.uc.cuae.legacy.CallControl.IncomingCall 5: cisco.uc.cuae.legacy.Http.GotRequest 6: cisco.uc.cuae.legacy.Presence.SubscriptionTerminated 7: cisco.uc.cuae.legacy.Presence.Notify 8: cisco.uc.cuae.legacy.TimerFacility.TimerFire Triggering event? [0-8] 5
The tool now has enough information to generate the project template.
Generating: * application named "BasicExtensionMobility_CSharp" * with namespace "basicextensionmobility_csharp" * with laguage "csharp" * with trigger event "cisco.uc.cuae.legacy.CallControl.Http.GotRequest" * in location C:\workspace\ Created project "BasicExtensionMobility_CSharp" in directory "C:\workspace\BasicExtensionMobility_CSharp\"
Mixin services#
The first step in building an Etch-based CUAE application is identifying which services the application requires and updating the .etch file to mixin those services into the application. For this application we will want to service an incoming HTTP request and display miscellaneous menus on the phone screen.
The default etch file already has a mixin for Http as we selected it as the triggering event:
mixin cisco.uc.cuae.legacy.Http
So we need to add a mixin declaration for CiscoIpPhone and CiscoExtensionMobility:
mixin cisco.uc.cuae.legacy.CiscoIpPhone mixin cisco.uc.cuae.legacy.CiscoExtensionMobility }}}
Config Runtime Parameter#
Some parameters are passed in to the program at runtime. These are specified through config.yaml file as follows:
configuration:
- name: deviceName
displayName: Device Name
format: String
- name: callManagerAdmin
displayName: Call Manager Administrator
format: String
- name: callManagerAdminPassword
format: String
displayName: Call Manager Admin Password
- name: callManagerHost
format: String
displayName: Call Manager Host
- name: extensionMobilityProfile
format: String
displayName: Extension Mobility Profile
- name: deviceIP
format: String
displayName: Device IPGenerate Sources - MSBuild#
- To use "MSBuild" to generate the source file templates for this application and a build.xml file, enter the following command from the application directory
BasicExtensionMobility> msbuild
Making a connection to the listener#
1. Call server.registerApplication() to do the actual registration.
Write the following code after the line " TODO: Insert Your Code Here" in MainBasicExtensionMobility_CSharpClient.cs
string key = server.registerApplication( "BasicExtensionMobility_CSharp", "Default", "<username>", "<password>" ); Console.WriteLine( " CUAE application registered with key : " + key ); Console.WriteLine( "Hit any key to exit" ); Console.ReadLine();
Code Sample#
public static void Main(String[] args)
{
// TODO: Change to correct URI
string uri = "tcp://localhost:9000";
RemoteBasicExtensionMobility_CSharpServer server = BasicExtensionMobility_CSharpHelper.NewServer( uri, null, new MainBasicExtensionMobility_CSharpClient());
// Connect to the service
server._StartAndWaitUp( 4000 );
// TODO: Insert Your Code Here
// Disconnect from the service
server._StopAndWaitDown( 4000 );
}Note: This code causes the application to remain registered and running once started until either you stop your application or the application looses connectivity to the cuae server.
2. Modify the String URI to match the IP address and port of the Cisco Unified Application Server.
URI settings vary slightly between 2.5(1) Beta 1 and more recent versions of 2.5(1), as follows:
2.5(1) and 2.5(1) Beta 2, Beta 3, Beta 4 & later releases#
// TODO Change to correct URI String uri = "tls://appserver_ipaddress:9000?TlsConnection.authReqd=false&filter=KeepAlive &KeepAlive.Count=5&Packetizer.maxPktSize=102400&TcpTransport.reconnectDelay=4000;
Note: In Beta 2, the Etch Bridge was updated to use Transport Layer Security for encryption by default. For your applications to work, you must specify TLS as the protocol in the URI and set the authReqd parameter to false. In the example above, the KeepAlive filter and Max Packet Size and Reconnect Delay parameters have also been set.
2.5(1) Beta 1#
// TODO Change to correct URI String uri = "tcp://appserver_ipaddress:9000?&TcpConnection.reconnect_delay=4000";
Note: In addition to setting the correct IP address and port for the Cisco Unfied Application Server, the Reconnect Delay parameter should be set on all connection URIs.
Servicing incoming triggering event#
- We need to call a specific function to service incoming gotRequest event. This is achieved by calling gotRequest() function. Inside this function, parse options.url object to access the incoming parameters and perform various actions accordingly. Idea is to format an xml object based on end user choices and pass it back to the phone that activated the service.
Code Sample#
Edit the "ImplBasicExtensionMobility_CSharpClient.cs" file to add the following code after the lines // TODO: Implement delegates or provide implementation of BasicExtensionMobility_CSharpClient messages from the server
string deviceName;
string deviceIP;
string callManagerIP;
string pushUserName;
string pushUserPassword;
string deviceProfile;
public override void gotRequest(string sessionId, GotRequestOptions options)
{
ConfigEntry[] configs = null;
try
{
configs = server.getConfig( "Default" );
}
catch ( Exception e )
{
Console.WriteLine( "Failed to get config entries for partition Default" + e);
server.removeCuaeSession( sessionId );
return;
}
try
{
for (int i = 0; i < configs.Length; i++)
{
if (configs[i].name == "deviceName")
deviceName = Convert.ToString(configs[i].configValue);
else if (configs[i].name == "deviceIP")
deviceIP = Convert.ToString(configs[i].configValue);
else if (configs[i].name == "callManagerIP")
callManagerIP = Convert.ToString(configs[i].configValue);
else if (configs[i].name == "pushUserName")
pushUserName = Convert.ToString(configs[i].configValue);
else if (configs[i].name == "pushUserPassword")
pushUserPassword = Convert.ToString(configs[i].configValue);
else if (configs[i].name == "extensionMobilityProfile")
deviceProfile = Convert.ToString(configs[i].configValue);
}
}
catch (Exception e)
{
Console.WriteLine("Error reading application configs: " + e.Message);
}
if (options.url.StartsWith("/mobilitySelection"))
{
// extract query params
Console.WriteLine("/mobilitySelection String: " + options.query);
int userIndex = options.query.IndexOf("userID=");
int pinIndex = options.query.IndexOf("userPin=");
int valueIndex = options.query.IndexOf("value=");
int userIndexDiff = pinIndex - (userIndex + 7) - 1;
int pinIndexDiff = options.query.Length - (pinIndex + 8);
int valueIndexDiff = userIndex - (valueIndex + 6) - 1;
string queryUserID = options.query.Substring((userIndex + 7), userIndexDiff);
string queryUserPin = options.query.Substring((pinIndex + 8), pinIndexDiff);
string queryValue = options.query.Substring((valueIndex + 6), valueIndexDiff);
Console.WriteLine("1: " + queryUserID + " 2: " + queryUserPin + " 3: >" + queryValue + "<");
// send a log indicating ongoing "logging in" process
server.sendResponse(sessionId, options.remoteHost, 200, "text/html", queryUserID + " is logging in ...", "OK", null);
// check if user requested 'login' or 'logout'
if (queryValue.Equals("Login"))
{
LoginOptions lio = new LoginOptions();
lio.deviceProfile = deviceProfile;
LoginResult lir = server.login(sessionId, queryUserID, deviceName, callManagerIP,
cisco.uc.cuae.legacy.types.CiscoExtensionMobility.Version.V6, pushUserName, pushUserPassword, lio);
if (lir.returnValue.Equals("success"))
Console.WriteLine("Login successful");
// CreateExecute
CreateExecuteOptions ceo = new CreateExecuteOptions();
ceo.url1 = "Init:Services";
CreateExecuteResult cer = server.createExecute(sessionId, ceo);
// SendExecute
SendExecuteOptions seo = new SendExecuteOptions();
seo.username = queryUserID;
seo.password = queryUserPin;
SendExecuteResult ser = server.sendExecute(sessionId, cer.xmlObject, deviceIP, seo);
if (!ser.returnValue.Equals("success"))
server.sendResponse(sessionId, options.remoteHost, 200, "text/plain", "SendExecute failed!", "OK", null);
else
server.sendResponse(sessionId, options.remoteHost, 200, "text/plain", "Done!", "OK", null);
}
else if (queryValue.Equals("Logout"))
{
LogoutResult lor = server.logout(sessionId, deviceName, callManagerIP,
cisco.uc.cuae.legacy.types.CiscoExtensionMobility.Version.V6, pushUserName, pushUserPassword, null);
if (lor.returnValue.Equals("success"))
Console.WriteLine("Logout successful");
}
// End Script
server.removeCuaeSession(sessionId);
}
if (options.url.StartsWith("/processUserInput"))
{
int userIndex = options.query.IndexOf("userID=");
int pinIndex = options.query.IndexOf("userPin=");
int userIndexDiff = pinIndex - (userIndex + 7) - 1;
int pinIndexDiff = options.query.Length - (pinIndex + 8);
string queryUserID = options.query.Substring((userIndex + 7), userIndexDiff);
string queryUserPin = options.query.Substring((pinIndex + 8), pinIndexDiff);
Console.WriteLine("1: " + queryUserID + " 2: " + queryUserPin);
CreateMenuOptions cmo = new CreateMenuOptions();
cmo.prompt = "Please make a selection";
cmo.title = "Extension mobility";
CreateMenuResult cmr = server.createMenu(sessionId, cmo);
// Add menu item for "login"
AddMenuItemOptions amio1 = new AddMenuItemOptions();
amio1.name = "Login";
amio1.uRL = "http://" + options.host + "/mobilitySelection?metreosSessionId=" +
sessionId + "&value=Login" + "&userID=" + queryUserID + "&userPin=" + queryUserPin;
AddMenuItemResult amir1 = server.addMenuItemToMenu(sessionId, amio1);
// Add menu item for "logout"
AddMenuItemOptions amio2 = new AddMenuItemOptions();
amio2.name = "Logout";
amio2.uRL = "http://" + options.host + "/mobilitySelection?metreosSessionId=" + sessionId +
"&value=Logout" + "&userID=" + queryUserID + "&userPin=" + queryUserPin;
amio2.xmlObject = amir1.xmlObject;
AddMenuItemResult amir2 = server.addMenuItemToMenu(sessionId, amio2);
server.sendResponse(sessionId, options.remoteHost, 200, "text/xml", amir2.xmlObject, "OK", null);
}
else
{
CreateInputOptions cio = new CreateInputOptions();
cio.title = "Extension Mobility";
cio.uRL = "http://" + options.host + "/processUserInput?metreosSessionId=" + sessionId;
CreateInputResult cir = server.createInput(sessionId, cio);
AddInputItemOptions aiio = new AddInputItemOptions();
aiio.xmlObject = cir.xmlObject;
aiio.displayName = "User";
aiio.inputFlags = "A";
aiio.queryStringParam = "userID";
AddInputItemResult aiir = server.addInputItem(sessionId, aiio);
AddInputItemOptions aiio2 = new AddInputItemOptions();
aiio2.xmlObject = aiir.xmlObject;
aiio2.displayName = "Pin";
aiio2.inputFlags = "A";
aiio2.queryStringParam = "userPin";
AddInputItemResult aiir2 = server.addInputItem(sessionId, aiio2);
// Http SendResponse
server.sendResponse(sessionId, options.remoteHost, 200, "text/xml", aiir2.xmlObject, "OK", null);
}
server.removeCuaeSession(sessionId);
}
Packaging The Test Application#
- Execute a successful build request for you test application within your IDE
- To package the application, run execute the "cuae package" command from a DOS command shell in test application parent directory of the test application.
C:\workspace\BasicExtensionMobility_CSharp>cuae package Created package file "C:\workspace\BasicExtensionMobility_CSharp\bin\BasicExtensionMobility_CSharp.mca"
Installing The Test Application#
- To install the test application on a CUAE server, execute the cuae install command from a DOS command shell in test application parent directory of the test application. The cuae install command varies slightly between 2.5(1) Beta 1 and Beta 2.
2.5(1) Beta 2,Beta 3 & Beta 4 & later releases#
You are prompted to enter an IP address, username, and password (to view the help, run the cuae install -h command). When prompted, enter Y or N to save management settings. This will save the answers to the above three questions in the properties file and remember them the next time you go to install.
Note: You are also prompted for the communications protocol (TCP or TLS). Select the protocol that is set on the Management Service. TLS is the default supported protocol. If you want to use TCP, follow the instructions in Management Service Transport Layer Security (TLS) to change the default URI of the Management Service before running these commands.
C:\workspace\BasicExtensionMobility_CSharp>cuae package Created package file "C:\workspace\BasicExtensionMobility_CSharp\bin\BasicExtensionMobility_CSharp.mca" C:\workspace\BasicExtensionMobility_CSharp>cuae install Enter the hostname or IP address of the management service (for example: localhost, 1.1.1.1): localhost Protocol: tls Generated mgmt-service uri: tls://localhost:9001?TlsConnection.authReqd=false Enter management service login username: Entermanagement service login password: ******** Save the amanagement settings with the project? [yes or no] no Application : C:\workspace\BasicExtensionMobility_CSharp\bin\BasicExtensionMobility_CSharp.mca Uploading : ===========================> 100% Application has been installed successfully
2.5(1) Beta 1#
You are prompted to enter an IP address, username, and password (to view the help, run the cuae install -h command). When prompted, enter Y or N to save management settings. This will save the answers to the above three questions in the properties file and remember them the next time you go to install.
C:\workspace\BasicExtensionMobility_CSharp>cuae package Created package file "C:\workspace\BasicExtensionMobility_CSharp\bin\BasicExtensionMobility_CSharp.mca" C:\workspace\BasicExtensionMobility_CSharp>cuae install Enter management service uri or host/IP <for example: localhost, tcp://1.1.1.1.:4001>: Enter management service login username: Entermanagement service login password: ******** Save the amanagement settings with the project? [YyNn] n Application : C:\workspace\BasicExtensionMobility_CSharp\bin\BasicExtensionMobility_CSharp.mca Uploading : ===========================> 100% Application ahas been installed successfully
Executing the application.#
- Once the client application is installed on the server, the phone service is created on the CCM, and the service is pointing to the CUAE server, the client application can be invoked. Once the client application is invoked (through console or from within your IDE), it is ready to service the incoming triggers from the CUAE server.
- You need to add trigger parameters. Goto Applications -> List triggers, Click on BasicExtensionMobility link and add following different url as parameters and its values.
* [http://<cuae-server>:8000/<Your application trigger>]
- [http://<cuae-server>:8000/processUserInput]
- [http://<cuae-server>:8000/mobilitySelection] }}}