diff -r 000000000000 -r 3da2a79470a7 testexecmgmt/ucc/Source/mncontroller/CSMncontroller.cpp --- /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 +#include +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#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; +}