--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecmgmt/ucc/Source/mncontroller/CSMncontroller.cpp Mon Mar 08 15:04:18 2010 +0800
@@ -0,0 +1,1151 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* This file was autogenerated by rpcgen, but should be modified by the developer.
+* Make sure you don't use the -component_mod flag in future or this file will be overwritten.
+* Wed Oct 01 09:46:52 2003
+* System Includes
+*
+*/
+
+
+
+
+#include <stdio.h>
+#include <signal.h>
+#ifndef WIN32
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+/****************************************************************************************
+ *
+ * Local Includes
+ *
+ ***************************************************************************************/
+#include "CSvcMncontroller.h"
+#include "CSMncontroller.h"
+#include "standard_unix.h"
+#include "strncpynt.h"
+
+
+/****************************************************************************************
+ *
+ * Definitions
+ *
+ ***************************************************************************************/
+#define TEMPLATE_CONFIG_FILE "dynmnd.template.conf"
+#define MOBILE_AGENT_COMMAND_LINE "./dynmnd --fg --debug --config "
+#define MAXCOMMANDLINELENGTH (31 + 256 + 1)
+#define MAXFOREIGNAGENTCOUNT 32
+#define MAXINTERFACECONFIGENTRY (IFNAMSIZ + 128)
+
+
+/****************************************************************************************
+ *
+ * Implementation
+ *
+ ***************************************************************************************/
+CSMncontroller::CSMncontroller()
+{
+ iDynamicsCallTimeout = -1;
+ iAgentProcess = NULL;
+}
+
+CSMncontroller::~CSMncontroller()
+{
+ assert( iAgentProcess == NULL );
+}
+
+int CSMncontroller::GetKey()
+{
+ return iKey;
+}
+
+void CSMncontroller::SetKey( int aKey )
+{
+ iKey = aKey;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: cstr_createagent
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::cstr_createagent( void )
+{
+ TResult rv;
+ int errcode;
+ TDCFError terr;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // create a local copy of the configuration file
+ terr = iDynamicsConfigFile.SetReferenceFile( TEMPLATE_CONFIG_FILE );
+ if( terr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)terr;
+ return rv;
+ }
+ terr = iDynamicsConfigFile.CreateLocalCopy( &errcode );
+ if( terr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)terr;
+ return rv;
+ }
+
+ // done - success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: dstr_removeagent
+ *
+ ***************************************************************************************/
+int CSMncontroller::dstr_removeagent( int aArgs, int *aDeleteInstance )
+{
+ int rv = ERR_NONE, errcode;
+ TDCFError terr;
+
+ // make sure that the proces isn't running
+ if( iAgentProcess != NULL ) {
+ *aDeleteInstance = 0;
+ rv = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // clean up the config file
+ terr = iDynamicsConfigFile.RemoveLocalCopy( &errcode );
+ if( terr != DCE_NONE ) {
+ rv = ERR_CONFIG_FILE_ERROR;
+ return rv;
+ }
+
+ // done - success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: startmobileagent
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::startmobileagent( int aArgs )
+{
+ TResult rv;
+ int errcode;
+ TCAProcessError perr;
+ char command_line_str[MAXCOMMANDLINELENGTH];
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // check that there is currently no process
+ if( iAgentProcess != NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // create the new process object
+ iAgentProcess = new CAProcess();
+ assert( iAgentProcess != NULL );
+
+ // construct the command line
+ snprintf( command_line_str, MAXCOMMANDLINELENGTH, "%s%s", MOBILE_AGENT_COMMAND_LINE, iDynamicsConfigFile.GetLocalFilename() );
+
+ // start the actual process
+ perr = iAgentProcess->StartProcess( command_line_str, &errcode, false, false, false );
+ if( perr != CAE_NONE ) {
+ rv.iServiceResult = ERR_START_PROCESS_ERROR;
+ rv.iSubComponentResult = (int)perr;
+ delete iAgentProcess;
+ iAgentProcess = NULL;
+ return rv;
+ }
+
+ // done - success
+ rv.iServiceResult = ERR_NONE;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: stopmobileagent
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::stopmobileagent( int aArgs )
+{
+ TResult rv;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // if the process isn't started then invalid state
+ if( iAgentProcess == NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // if the process isn't running then it has died outside the scope of this controller, clean up the state, return an error since
+ // this is noteworthy and should be either expected or not happen.
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ assert( (pstatus == PS_STOPPED) || (pstatus == PS_ABANDONNED) );
+ delete iAgentProcess;
+ iAgentProcess = NULL;
+ rv.iServiceResult = ERR_PROCESS_TERMINATED_OUTSIDE_SCOPE;
+ return rv;
+ }
+
+ // request the process to stop
+ perr = iAgentProcess->RequestStop( SIGTERM );
+ if( perr != CAE_NONE ) {
+ rv.iServiceResult = ERR_STOP_PROCESS_ERROR;
+ rv.iSubComponentResult = (int)perr;
+ return rv;
+ }
+
+ // wait for the process to stop
+ perr = iAgentProcess->WaitForProcessToTerminate( -1 );
+ if( perr != CAE_NONE ) {
+ rv.iServiceResult = ERR_WAIT_PROCESS_ERROR;
+ rv.iSubComponentResult = (int)perr;
+ return rv;
+ }
+
+ // remove the process
+ delete iAgentProcess;
+ iAgentProcess = NULL;
+
+ // done - success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: getmobileagentstatus
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::getmobileagentstatus( int aArgs )
+{
+ TResult rv;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // init the rv - note that we include the result even though it is always ERR_NONE
+ // here because the stub may return an error
+ memset( &rv, 0, sizeof(rv) );
+ rv.iServiceResult = ERR_NONE;
+
+ // if the process doesn't exist then we return PS_INVALID
+ if( iAgentProcess == NULL ) {
+ rv.iData0 = PS_INVALID;
+ return rv;
+ }
+
+ // otherwise just return whatever iAgentProcess->GetProcessStatus() returns
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ rv.iData0 = (int)pstatus;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: setsingleoption
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::setsingleoption( TOptionDesc aArgs )
+{
+ TResult rv;
+ int errcode;
+ TDCFError cerr;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // make sure that the process isn't running
+ if( iAgentProcess != NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // modify the config file
+ cerr = iDynamicsConfigFile.SetSingleOption( aArgs.iOptionToken, aArgs.iOptionValue, &errcode );
+ if( cerr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)cerr;
+ rv.iData0 = errcode;
+ return rv;
+ }
+
+ // return success
+ rv.iServiceResult = ERR_NONE;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: removesingleoption
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::removesingleoption( TOptionDesc aArgs )
+{
+ TResult rv;
+ int errcode;
+ TDCFError cerr;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // make sure that the process isn't running
+ if( iAgentProcess != NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // modify the config file
+ cerr = iDynamicsConfigFile.RemoveSingleOption( aArgs.iOptionToken, &errcode );
+ if( cerr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)cerr;
+ rv.iData0 = errcode;
+ return rv;
+ }
+
+ // return success
+ rv.iServiceResult = ERR_NONE;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: addlistoption
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::addlistoption( TOptionDesc aArgs )
+{
+ TResult rv;
+ int errcode;
+ TDCFError cerr;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // make sure that the process isn't running
+ if( iAgentProcess != NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // modify the config file
+ cerr = iDynamicsConfigFile.AddListOption( aArgs.iOptionBlockStart, aArgs.iOptionBlockEnd, aArgs.iOptionValue, &errcode );
+ if( cerr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)cerr;
+ rv.iData0 = errcode;
+ return rv;
+ }
+
+ // return success
+ rv.iServiceResult = ERR_NONE;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: removelistoption
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::removelistoption( TOptionDesc aArgs )
+{
+ TResult rv;
+ int errcode;
+ TDCFError cerr;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // make sure that the process isn't running
+ if( iAgentProcess != NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // modify the config file
+ cerr = iDynamicsConfigFile.RemoveListOption( aArgs.iOptionBlockStart, aArgs.iOptionBlockEnd, aArgs.iOptionToken, &errcode );
+ if( cerr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)cerr;
+ rv.iData0 = errcode;
+ return rv;
+ }
+
+ // return success
+ rv.iServiceResult = ERR_NONE;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: getcareofaddress
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::sethomeaddress( THomeAddressDesc aArgs )
+{
+ TResult rv;
+ char dynamics_config[MAXINTERFACECONFIGENTRY];
+ struct in_addr home_address, home_network_address, home_agent_address;
+ TDCFError terr;
+ int errcode;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // make sure that the process isn't running
+ if( iAgentProcess != NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // validate the arguments
+ if( aArgs.iHomeAddress == -1 ) {
+ rv.iServiceResult = ERR_INVALIDARG;
+ rv.iData0 = 2;
+ return rv;
+ }
+ if( (aArgs.iHomeAddressPrefix < 1) || (aArgs.iHomeAddressPrefix > 31) ) {
+ rv.iServiceResult = ERR_INVALIDARG;
+ rv.iData0 = 3;
+ return rv;
+ }
+ if( aArgs.iHomeAgentAddress == -1 ) {
+ rv.iServiceResult = ERR_INVALIDARG;
+ rv.iData0 = 4;
+ return rv;
+ }
+
+ // if the home address specified is zero, then we take this as meaning that the user
+ // wants to reset the interface back to it's original (PPP configured) address. This
+ // doesn't effect the entries in the configuration file at all
+ if( aArgs.iHomeAddress == 0 ) {
+ return rv;
+ }
+
+ // set the home address on the interface
+ rv = SetInterfaceAddress( aArgs.iInterfaceName, aArgs.iHomeAddress );
+ if( rv.iServiceResult != ERR_NONE ) {
+ return rv;
+ }
+
+ // set the home address in the dynamics config file
+ home_address.ADDRESS_INTEGER = aArgs.iHomeAddress;
+ snprintf( dynamics_config, MAXINTERFACECONFIGENTRY, "MNHomeIPAddress %s", inet_ntoa(home_address) );
+ terr = iDynamicsConfigFile.SetSingleOption( "MNHomeIPAddress", dynamics_config, &errcode );
+ if( terr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)terr;
+ rv.iData0 = errcode;
+ return rv;
+ }
+
+ // set the home network prefix in the dynamics config file
+ home_network_address = GetNetworkAddressFromHostAddress( aArgs.iHomeAddress, aArgs.iHomeAddressPrefix );
+ snprintf( dynamics_config, MAXINTERFACECONFIGENTRY, "HomeNetPrefix %s/%d", inet_ntoa(home_network_address), aArgs.iHomeAddressPrefix );
+ terr = iDynamicsConfigFile.SetSingleOption( "HomeNetPrefix", dynamics_config, &errcode );
+ if( terr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)terr;
+ rv.iData0 = errcode;
+ return rv;
+ }
+
+ // set the home agent address
+ home_agent_address.ADDRESS_INTEGER = aArgs.iHomeAgentAddress;
+ snprintf( dynamics_config, MAXINTERFACECONFIGENTRY, "HAIPAddress %s", inet_ntoa(home_agent_address) );
+ fprintf( stderr, "DEBUG: setting option '%s'\n", dynamics_config );
+ terr = iDynamicsConfigFile.SetSingleOption( "HAIPAddress", dynamics_config, &errcode );
+ if( terr != DCE_NONE ) {
+ rv.iServiceResult = ERR_CONFIG_FILE_ERROR;
+ rv.iSubComponentResult = (int)terr;
+ rv.iData0 = errcode;
+ return rv;
+ }
+
+ // done
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: getcareofaddress
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::getcareofaddress( int aArgs )
+{
+ TResult rv;
+ struct in_addr addr = { 0 };
+ TDynamicsCallInfo cres;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // use the dynamics command wrapper to make the call
+ cres = iDynamicsCommand.MobileNodeAgentGetCareofAddress( &addr );
+
+ // if the call failed then set the TResult correctly
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iSubComponentResult = cres.iResult;
+ rv.iData0 = cres.iErrorCode;
+ rv.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // otherwise pack up the successful return info
+ rv.iServiceResult = ERR_NONE;
+ rv.iData0 = addr.ADDRESS_INTEGER;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: getstatus
+ *
+ ***************************************************************************************/
+TMobileNodeStatus CSMncontroller::getstatus( int aArgs )
+{
+ TMobileNodeStatus rv;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+ TDynamicsCallInfo cres;
+ TMobileNodeAgentStatusInfo mobile_node_status;
+
+ // init the return value
+ memset( &rv, 0, sizeof(rv) );
+ rv.iCallResult.iServiceResult = ERR_NONE;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iCallResult.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iCallResult.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // make the call
+ cres = iDynamicsCommand.MobileNodeAgentGetStatus( &mobile_node_status );
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iCallResult.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iCallResult.iSubComponentResult = cres.iResult;
+ rv.iCallResult.iData0 = cres.iErrorCode;
+ rv.iCallResult.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // copy the data from mobile_node_status to the rv
+ rv.iColocatedAddress = mobile_node_status.iColocatedAddress;
+ rv.iConnected = mobile_node_status.iConnected;
+ rv.iForeignAgentAddress = mobile_node_status.iForeignAgentAddress;
+ rv.iHomeAddress = mobile_node_status.iHomeAddress;
+ rv.iHomeAgentAddress = mobile_node_status.iHomeAgentAddress;
+ memcpy( rv.iInfoText, mobile_node_status.iInfoText, X_MAXINFOLEN );
+ memcpy( rv.iLastErrorString, mobile_node_status.iLastErrorString, X_MAXERRORSTRING );
+ rv.iLifetimeRemaining = mobile_node_status.iLifetimeRemaining;
+ rv.iLocalAddress = mobile_node_status.iLocalAddress;
+ rv.iReplyCode = mobile_node_status.iReplyCode;
+ rv.iSecondsSinceLastReply = mobile_node_status.iSecondsSinceLastReply;
+ rv.iSecondsSinceLastRequest = mobile_node_status.iTunnelMode;
+ rv.iTunnelUp = mobile_node_status.iTunnelUp;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: connect
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::connect( TTunnelingModeDesc aArgs )
+{
+ TResult rv;
+ TDynamicsCallInfo cres;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // call the wrapper
+ cres = iDynamicsCommand.MobileNodeAgentConnect();
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iSubComponentResult = cres.iResult;
+ rv.iData0 = cres.iErrorCode;
+ rv.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: disconnect
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::disconnect( int aArgs )
+{
+ TResult rv;
+ TDynamicsCallInfo cres;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // call the wrapper
+ cres = iDynamicsCommand.MobileNodeAgentDisconnect();
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iSubComponentResult = cres.iResult;
+ rv.iData0 = cres.iErrorCode;
+ rv.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: confirm
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::confirm( int aArgs )
+{
+ TResult rv;
+ TDynamicsCallInfo cres;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // call the wrapper
+ cres = iDynamicsCommand.MobileNodeAgentConfirm();
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iSubComponentResult = cres.iResult;
+ rv.iData0 = cres.iErrorCode;
+ rv.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: rescaninterfaces
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::rescaninterfaces( int aArgs )
+{
+ TResult rv;
+ TDynamicsCallInfo cres;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // call the wrapper
+ cres = iDynamicsCommand.MobileNodeAgentRescan();
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iSubComponentResult = cres.iResult;
+ rv.iData0 = cres.iErrorCode;
+ rv.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: setfapolicy - aPolicyDesc is a bitfield with each bit representing
+ * a particular policy that should be turned on or off. The values for each
+ * policy are in the interface file (.x). We try and set the policy for each
+ * bit regardless of whether some calls fail. The result is the OR of all the
+ * results (i.e. if one fails the op fails). To get more info about which
+ * succeeded you can just call getpolicy.
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::setfapolicy( TPolicyRequest aArgs )
+{
+ TResult rv;
+ TDynamicsCallInfo cres;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // call the wrapper
+ cres = iDynamicsCommand.MobileNodeAgentSetPolicy( aArgs.iPolicy );
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iSubComponentResult = cres.iResult;
+ rv.iData0 = cres.iErrorCode;
+ rv.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: getfapolicy
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::getfapolicy( int aArgs )
+{
+ TResult rv;
+ TDynamicsCallInfo cres;
+ int policy_vector;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+
+ // initialise the return value
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // call the wrapper
+ cres = iDynamicsCommand.MobileNodeAgentGetPolicy( &policy_vector );
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iSubComponentResult = cres.iResult;
+ rv.iData0 = cres.iErrorCode;
+ rv.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // success
+ rv.iServiceResult = ERR_NONE;
+ rv.iData0 = policy_vector;
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: listforeignagents
+ *
+ ***************************************************************************************/
+TForeignAgentList CSMncontroller::listforeignagents( int aArgs )
+{
+ TDynamicsCallInfo cres;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+ int foreign_agent_count = MAXFOREIGNAGENTCOUNT, i;
+ TMobileNodeForeignAgentInfo foreign_agent_list[MAXFOREIGNAGENTCOUNT];
+ TForeignAgentList rv = { 0, NULL };
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ return rv;
+ }
+
+ // call the dynamics wrapper
+ cres = iDynamicsCommand.MobileNodeAgentGetForeignAgentList( &foreign_agent_count, foreign_agent_list);
+ if( cres.iResult != DC_SUCCESS ) {
+ return rv;
+ }
+
+ // allocate the memory
+ rv.TForeignAgentList_len = foreign_agent_count;
+ rv.TForeignAgentList_val = (TForeignAgentInfo*)calloc( foreign_agent_count, sizeof(TForeignAgentInfo) );
+ assert( rv.TForeignAgentList_val != NULL );
+
+ // copy the entries - all entries default to 0 due to calloc()
+ for( i = 0; i < foreign_agent_count; i++ ) {
+ (rv.TForeignAgentList_val)[i].iCallResult.iServiceResult = ERR_NONE;
+ (rv.TForeignAgentList_val)[i].iForeignAgentAddress = (foreign_agent_list[i]).iForeignAgentAddress;
+ (rv.TForeignAgentList_val)[i].iInterfaceIndex = (foreign_agent_list[i]).iInterfaceIndex;
+ (rv.TForeignAgentList_val)[i].iInUse = (foreign_agent_list[i]).iInUse;
+ (rv.TForeignAgentList_val)[i].iLastAdvertisement = (foreign_agent_list[i]).iLastAdvertisement;
+ (rv.TForeignAgentList_val)[i].iPriority = (foreign_agent_list[i]).iPriority;
+ memcpy( (rv.TForeignAgentList_val)[i].iInterfaceName, (foreign_agent_list[i]).iInterfaceName, X_MAXINTERFACENAMELEN );
+ memcpy( (rv.TForeignAgentList_val)[i].iNAI, (foreign_agent_list[i]).iNAI, X_MAXNAILEN );
+ }
+
+ // done - success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: getforeignagentinfo
+ *
+ ***************************************************************************************/
+TForeignAgentInfo CSMncontroller::getforeignagentinfo( TForeignAgentInfoRequest aArgs )
+{
+ TDynamicsCallInfo cres;
+ TCAProcessError perr;
+ TProcessStatus pstatus;
+ TMobileNodeForeignAgentInfo foreign_agent_info;
+ TForeignAgentInfo rv;
+
+ // init the result
+ memset( &rv, 0, sizeof(rv) );
+ rv.iCallResult.iServiceResult = ERR_NONE;
+
+ // check that the agent was running
+ if( iAgentProcess == NULL ) {
+ rv.iCallResult.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // check that the agent is still runnning
+ perr = iAgentProcess->GetProcessStatus( &pstatus );
+ assert( perr == CAE_NONE );
+ if( pstatus != PS_STARTED ) {
+ rv.iCallResult.iServiceResult = ERR_INVALIDSTATE;
+ return rv;
+ }
+
+ // call the dynamics wrapper
+ cres = iDynamicsCommand.MobileNodeAgentGetForeignAgentInfo( aArgs.iForeignAgentID, &foreign_agent_info );
+ if( cres.iResult != DC_SUCCESS ) {
+ rv.iCallResult.iServiceResult = ERR_DYNAMICS_CALL_FAILED;
+ rv.iCallResult.iSubComponentResult = cres.iResult;
+ rv.iCallResult.iData0 = cres.iErrorCode;
+ rv.iCallResult.iData1 = cres.iErrorDetail;
+ return rv;
+ }
+
+ // set the result
+ rv.iForeignAgentAddress = foreign_agent_info.iForeignAgentAddress;
+ rv.iInterfaceIndex = foreign_agent_info.iInterfaceIndex;
+ rv.iInUse = foreign_agent_info.iInUse;
+ rv.iLastAdvertisement = foreign_agent_info.iLastAdvertisement;
+ rv.iPriority = foreign_agent_info.iPriority;
+ memcpy( rv.iInterfaceName, foreign_agent_info.iInterfaceName, X_MAXINTERFACENAMELEN );
+ memcpy( rv.iNAI, foreign_agent_info.iNAI, X_MAXNAILEN );
+
+ // done - success
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: settimeout
+ *
+ ***************************************************************************************/
+void CSMncontroller::settimeout( TTimeoutRequest aArgs )
+{
+ iDynamicsCallTimeout = aArgs.iTimeout;
+ iDynamicsCommand.SetTimeout( aArgs.iTimeout );
+}
+
+
+/****************************************************************************************
+ *
+ * PRIVATE FUNCTION: SetInterfaceAddress
+ *
+ ***************************************************************************************/
+TResult CSMncontroller::SetInterfaceAddress( char *aInterfaceName, int aAddress )
+{
+ TResult rv;
+ int sockfd, err;
+ struct ifreq ifr;
+ struct sockaddr_in destination_address, *saddr;
+
+ // check parameters
+ assert( aInterfaceName );
+
+ // init the response
+ rv.iServiceResult = ERR_NONE;
+ rv.iSubComponentResult = 0;
+ rv.iData0 = 0;
+ rv.iData1 = 0;
+
+ // create a socket to make ioctl calls on
+ sockfd = socket( AF_INET, SOCK_DGRAM, 0 );
+ if( sockfd <= 0 ) {
+ rv.iServiceResult = ERR_SET_INTERFACE_ADDRESS_ERROR;
+ rv.iSubComponentResult = SIE_SOCKET_FAILED;
+ rv.iData0 = errno;
+ return rv;
+ }
+
+ // setup the request
+ STRNCPY_NULL_TERMINATE( ifr.ifr_name, aInterfaceName, IFNAMSIZ );
+
+ // get the current pointopoint address
+ err = ioctl( sockfd, SIOCGIFDSTADDR, &ifr );
+ if( err == -1 ) {
+ rv.iServiceResult = ERR_SET_INTERFACE_ADDRESS_ERROR;
+ rv.iSubComponentResult = SIE_IOCTL_GET_DESTINATION_ADDRESS_FAILED;
+ rv.iData0 = errno;
+ return rv;
+ }
+ destination_address = (*((struct sockaddr_in*)(&(ifr.ifr_dstaddr))));
+
+ // set the interface address
+ saddr = (struct sockaddr_in*)(&(ifr.ifr_addr));
+ saddr->sin_family = AF_INET;
+ saddr->sin_port = 0;
+ saddr->sin_addr.ADDRESS_INTEGER = aAddress;
+ err = ioctl( sockfd, SIOCSIFADDR, &ifr );
+ if( err == -1 ) {
+ rv.iServiceResult = ERR_SET_INTERFACE_ADDRESS_ERROR;
+ rv.iSubComponentResult = SIE_IOCTL_SET_ADDRESS_FAILED;
+ rv.iData0 = errno;
+ return rv;
+ }
+
+ // setting the interface address seems to also set the the pointopoint (destination)
+ // address to the same thing, so set it back to what it was or routing won't work
+ saddr = (struct sockaddr_in*)(&(ifr.ifr_dstaddr));
+ *saddr = destination_address;
+ err = ioctl( sockfd, SIOCSIFDSTADDR, &ifr );
+ if( err == -1 ) {
+ rv.iServiceResult = ERR_SET_INTERFACE_ADDRESS_ERROR;
+ rv.iSubComponentResult = SIE_IOCTL_SET_DESTINATION_ADDRESS_FAILED;
+ rv.iData0 = errno;
+ return rv;
+ }
+
+ // done
+ return rv;
+}
+
+
+/****************************************************************************************
+ *
+ * PRIVATE FUNCTION: GetNetworkAddressFromHostAddress
+ *
+ ***************************************************************************************/
+struct in_addr CSMncontroller::GetNetworkAddressFromHostAddress( int aAddress, int aNetmask )
+{
+ struct in_addr rv;
+ int netmask, i;
+
+ // create the netmask
+ for( netmask = 0, i = 0; i < aNetmask; i++ ) {
+ netmask |= 1<<(31-i);
+ }
+
+ // get the
+ rv.ADDRESS_INTEGER = ntohl( aAddress );
+ rv.ADDRESS_INTEGER &= netmask;
+ rv.ADDRESS_INTEGER = htonl( rv.ADDRESS_INTEGER );
+
+ // done
+ return rv;
+}