mirror of
https://github.com/thug1src/thug.git
synced 2024-11-30 12:06:44 +00:00
3220 lines
93 KiB
C++
3220 lines
93 KiB
C++
/*****************************************************************************
|
|
** **
|
|
** Neversoft Entertainment **
|
|
** **
|
|
** Copyright (C) 1999 - All Rights Reserved **
|
|
** **
|
|
******************************************************************************
|
|
** **
|
|
** Project: GEL (Game Engine Library) **
|
|
** **
|
|
** Module: Net (OBJ) **
|
|
** **
|
|
** File name: net.cpp **
|
|
** **
|
|
** Created: 01/29/01 - spg **
|
|
** **
|
|
** Description: Network Manager code **
|
|
** **
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
** Includes **
|
|
*****************************************************************************/
|
|
|
|
#include <gel/net/net.h>
|
|
|
|
#include <core/defines.h>
|
|
|
|
#include <sys/timer.h>
|
|
#include <sys/config/config.h>
|
|
#include <sys/sioman.h>
|
|
#include <sys/file/filesys.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <gel/net/server/netserv.h>
|
|
#include <gel/net/client/netclnt.h>
|
|
|
|
#ifndef __PLAT_WN32__
|
|
#include <gel/music/music.h>
|
|
#endif
|
|
|
|
#ifdef __PLAT_XBOX__
|
|
//#include <xonline.h>
|
|
#include <winsockx.h>
|
|
#endif
|
|
|
|
#include <gel/mainloop.h>
|
|
|
|
#ifdef __PLAT_NGPS__
|
|
|
|
#include <sifdev.h>
|
|
#include <libcdvd.h>
|
|
|
|
#endif
|
|
/*****************************************************************************
|
|
** Externals **
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
** Defines **
|
|
*****************************************************************************/
|
|
|
|
//#define USE_DECI2
|
|
|
|
#define DEFAULT_SNPS2_SUB_MSK "255.255.255.0"
|
|
#define DEFAULT_SNPS2_GATEWAY "192.168.0.1"
|
|
|
|
const char spduartArgs[] = "-nogci\0dial=cdrom0:\\IOP\\DIAL_SPD.CNF;1";
|
|
|
|
/*****************************************************************************
|
|
** DBG Defines **
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
namespace Net
|
|
{
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
** Private Types **
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
** Private Data **
|
|
*****************************************************************************/
|
|
|
|
DefineSingletonClass( Manager, "Network Manager" )
|
|
|
|
#ifdef __PLAT_NGPS__
|
|
/* Set up the following list with one or more suitable DNS servers */
|
|
|
|
/*static const sn_char* dns_servers[] =
|
|
{
|
|
"205.147.0.100",
|
|
"205.147.0.102",
|
|
"" // List is terminated by null string
|
|
};*/
|
|
static sn_char custom_built_script[SN_MAX_SCRIPT_LINES][SN_MAX_SCRIPT_LEN+1];
|
|
static const char *s_custom_isp_script[] =
|
|
{
|
|
"input 30 ogin:", /* Line 0 */
|
|
"output ", /* Line 1 */
|
|
"input 10 word:", /* Line 2 */
|
|
"output ", /* Line 3 */
|
|
"input 10 ing PPP", /* Line 4 */
|
|
"" /* script is terminated with null string */
|
|
};
|
|
|
|
#define vCUSTOM_USERNAME_LINE 1
|
|
#define vCUSTOM_PASSWORD_LINE 3
|
|
|
|
static bool s_cancel_dialup_conn;
|
|
static int s_conn_semaphore;
|
|
#endif // __PLAT_NGPS__
|
|
|
|
/*****************************************************************************
|
|
** Public Data **
|
|
*****************************************************************************/
|
|
|
|
|
|
/*****************************************************************************
|
|
** Private Prototypes **
|
|
*****************************************************************************/
|
|
|
|
|
|
/*****************************************************************************
|
|
** Private Functions **
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
** Private Functions **
|
|
*****************************************************************************/
|
|
|
|
#ifdef __PLAT_NGPS__
|
|
|
|
#define vPOWEROFF_STACK_SIZE (2 * 1024)
|
|
|
|
static u_char s_poweroff_stack[vPOWEROFF_STACK_SIZE] __attribute__ ((aligned(16)));
|
|
|
|
/******************************************************************/
|
|
/* The thread which waits for */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
static void s_power_off_thread(void *arg)
|
|
{
|
|
int sid = (int)arg;
|
|
int stat;
|
|
while( 1 )
|
|
{
|
|
WaitSema(sid);
|
|
// dev9 power off, need to power off PS2
|
|
//while( sceDevctl("dev9x:", DDIOC_OFF, NULL, 0, NULL, 0 ) < 0 );
|
|
while( sceDevctl("dev9x:", DDIOC_OFF, NULL, 0, NULL, 0 ) < 0 );
|
|
// PS2 power off
|
|
while( !sceCdPowerOff( &stat ) || stat );
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
static void s_power_off_handler(void *arg)
|
|
{
|
|
int sid = (int)arg;
|
|
iSignalSema(sid);
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
static void s_prepare_power_off(void)
|
|
{
|
|
struct ThreadParam tparam;
|
|
struct SemaParam sparam;
|
|
int tid, sid;
|
|
|
|
sparam.initCount = 0;
|
|
sparam.maxCount = 1;
|
|
sparam.option = 0;
|
|
sid = CreateSema(&sparam);
|
|
|
|
tparam.stackSize = vPOWEROFF_STACK_SIZE;
|
|
tparam.gpReg = &_gp;
|
|
tparam.entry = s_power_off_thread;
|
|
tparam.stack = (void *) s_poweroff_stack;
|
|
tparam.initPriority = 1;
|
|
tid = CreateThread( &tparam );
|
|
StartThread( tid, (void *) sid );
|
|
|
|
sceCdPOffCallback( s_power_off_handler, (void *) sid );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
static sn_int32 set_host_name( sn_char* host_name )
|
|
{
|
|
sndev_set_dhost_type optval;
|
|
sn_int32 host_size, r;
|
|
|
|
|
|
|
|
Dbg_Assert( host_name );
|
|
|
|
host_size = strlen(host_name) + 1;
|
|
|
|
// Check host_name isn't too big
|
|
if (host_size > (sn_int32) sizeof(optval.host))
|
|
{
|
|
Dbg_Printf("EE:set_host_name():error host_name too big\n");
|
|
return -1;
|
|
}
|
|
|
|
// I'm going to fill optval with zeros to start with, not strictly
|
|
// necessary but this is only an example.
|
|
memset(&optval,0,sizeof(optval));
|
|
|
|
// Fill in the optval structure
|
|
optval.flags = 0; // Steve, you could set one of these two
|
|
// values SN_DFLAG_EXCL_DIS or
|
|
// SN_DFLAG_EXCL_REQ in the flags to
|
|
// *exclude* either the discovery or
|
|
// request message from the operation with
|
|
// flags set to zero the option will be
|
|
// applied to both messages
|
|
|
|
if( host_name[0] == '\0' )
|
|
{
|
|
Dbg_Printf( "Clearing Host Name Option\n" );
|
|
optval.clear_option = 1; // Steve, you would set this to 1 if you
|
|
// wanted to remove the host name
|
|
}
|
|
else
|
|
{
|
|
Dbg_Printf( "Setting Host Name Option to %s\n", host_name );
|
|
optval.clear_option = 0;
|
|
}
|
|
|
|
|
|
optval.include_null = 0; // Steve, if you wanted the null terminator
|
|
// included in the host name that's sent in
|
|
// the DHCP msg you would set this to 1
|
|
|
|
optval.reserved = 0; // Must be 0
|
|
|
|
memcpy(optval.host, host_name, host_size);
|
|
|
|
// Send the option to the IOP
|
|
|
|
r = sndev_set_options(0, SN_DEV_SET_DHOST, &optval, sizeof(optval));
|
|
|
|
if (r != 0)
|
|
{
|
|
Dbg_Printf("EE:sndev_set_options():error %d\n",r);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::stop_stack( void )
|
|
{
|
|
|
|
|
|
int result, stack_state;
|
|
|
|
Dbg_Printf( "EE:Stopping the TCP/IP stack\n" );
|
|
|
|
result = sn_stack_state(SN_STACK_STATE_STOP, &stack_state);
|
|
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "EE:sn_stack_sate() failed %d\n", result );
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
|
|
Dbg_Printf( "EE:Stack Stopped\n" );
|
|
|
|
return true;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::start_stack( void )
|
|
{
|
|
sn_int32 result, stack_state;
|
|
Tmr::Time start_time;
|
|
|
|
|
|
|
|
// Start the stack
|
|
Dbg_Printf("EE:Starting the TCP/IP stack\n");
|
|
|
|
result = sn_stack_state( SN_STACK_STATE_START, &stack_state );
|
|
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "EE:sn_stack_sate() failed %d\n", result );
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
|
|
Dbg_Printf( "EE:Stack Started\n" );
|
|
if(( GetConnectionType() == vCONN_TYPE_MODEM ) ||
|
|
( GetConnectionType() == vCONN_TYPE_PPPOE ))
|
|
{
|
|
int modem_state, prev_modem_state;
|
|
Tmr::Time start_time;
|
|
|
|
modem_state = -1; // Invalid
|
|
prev_modem_state = -2; // Ivalid and != modem_state
|
|
|
|
start_time = Tmr::GetTime();
|
|
Dbg_Printf( "EE:Calling snmdm_get_state() - until modem ready\n" );
|
|
while( modem_state != SN_MODEM_READY )
|
|
{
|
|
result = snmdm_get_state( &modem_state );
|
|
|
|
if (result != 0)
|
|
{
|
|
Dbg_Printf("EE:snmdm_get_state() failed %d\n", result);
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
|
|
if (modem_state == prev_modem_state)
|
|
{
|
|
sn_delay(10);
|
|
}
|
|
else
|
|
{
|
|
prev_modem_state = modem_state;
|
|
Dbg_Printf(" Modem state = %d %s\n", modem_state, sntc_str_modem_state( modem_state ));
|
|
}
|
|
|
|
// After 5 seconds, time out and say there was no dialtone
|
|
if(( Tmr::GetTime() - start_time ) > Tmr::Seconds( 10 ))
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Dbg_Printf( "EE:Ready\n" );
|
|
}
|
|
|
|
|
|
// Wait for the stack to come up
|
|
Dbg_Printf( "EE:Waiting for socket API to be ready\n" );
|
|
start_time = Tmr::GetTime();
|
|
while( sn_socket_api_ready() == SN_FALSE )
|
|
{
|
|
// Delay to avoid hogging the processor
|
|
sn_delay( 500 );
|
|
if(( Tmr::GetTime() - start_time ) > Tmr::Seconds( 10 ))
|
|
{
|
|
Dbg_Printf( "EE:Timed out waiting for socket API to be ready\n" );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if( ShouldUseDHCP())
|
|
{
|
|
struct hostent* hentp = NULL;
|
|
sn_bool got_ip_addr = SN_FALSE;
|
|
struct in_addr ip_addr;
|
|
|
|
Dbg_Printf( "EE:Waiting for DHCP server to supply IP addr etc\n" );
|
|
start_time = Tmr::GetTime();
|
|
do
|
|
{
|
|
// A way of getting the local IP address
|
|
hentp = gethostbyname(LOCAL_NAME);
|
|
|
|
if(( hentp != NULL ) && ( hentp->h_addr_list[0] != NULL ))
|
|
{
|
|
// Read the IP address from the hostent struct
|
|
memcpy( &ip_addr,hentp->h_addr_list[0], sizeof( ip_addr ));
|
|
|
|
if( ip_addr.s_addr != 0 )
|
|
{
|
|
got_ip_addr = SN_TRUE;
|
|
Dbg_Printf( "DHCP allocated IP addr %s\n", inet_ntoa( ip_addr ));
|
|
}
|
|
}
|
|
|
|
// Delay to avoid hogging the processor
|
|
if( got_ip_addr == SN_FALSE )
|
|
{
|
|
sn_delay(500);
|
|
}
|
|
if(( Tmr::GetTime() - start_time ) > Tmr::Seconds( 10 ))
|
|
{
|
|
Dbg_Printf( "EE:Timed out waiting for DHCP response\n" );
|
|
SetError( vRES_ERROR_DHCP );
|
|
return false;
|
|
}
|
|
} while( got_ip_addr == SN_FALSE );
|
|
|
|
strcpy( m_local_ip, inet_ntoa( ip_addr ));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::setup_ethernet_params( void )
|
|
{
|
|
sndev_set_ether_ip_type params;
|
|
int result;
|
|
|
|
if( ShouldUseDHCP())
|
|
{
|
|
Dbg_Printf( "\n\n\n*********************** USING DHCP ******************* \n\n\n" );
|
|
memset( ¶ms,0, sizeof( params ));
|
|
}
|
|
else
|
|
{
|
|
inet_aton( GetLocalIP(), (struct in_addr*) ¶ms.ip_addr );
|
|
Dbg_Printf( "======================== Ip is %d : %d\n", params.ip_addr, htonl( params.ip_addr ));
|
|
inet_aton( GetSubnetMask(), (struct in_addr*) ¶ms.sub_mask );
|
|
inet_aton( GetGateway(), (struct in_addr*) ¶ms.gateway );
|
|
}
|
|
|
|
result = sndev_set_options( 0, SN_DEV_SET_ETHER_IP, ¶ms, sizeof(params));
|
|
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "EE:Error sndev_set_options() returned %d\n", result );
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
|
|
if( ShouldUseDHCP())
|
|
{
|
|
result = set_host_name( m_host_name );
|
|
if( result != 0 )
|
|
{
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::initialize_device( void )
|
|
{
|
|
sn_int32 result;
|
|
sn_int32 device_type;
|
|
sn_int16 idVendor;
|
|
sn_int16 idProduct;
|
|
sn_bool first_time;
|
|
Tmr::Time start_time;
|
|
Tmr::Time timeout;
|
|
|
|
// Initialise the socket API, if fails print error and return
|
|
Dbg_Printf( "EE:Initialising socket API\n" );
|
|
|
|
result = sockAPIinit( 6 );
|
|
if( ( result != 0 ) &&
|
|
( result != SN_EALRDYINIT ))
|
|
{
|
|
Dbg_Printf( "EE:sockAPIinit() failed %d\n", result );
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
|
|
// If we've already init'd the sockets API, don't re-register this thread
|
|
// just let it run through the rest of setup
|
|
if( result != SN_EALRDYINIT )
|
|
{
|
|
// Register this thread with the socket API
|
|
result = sockAPIregthr();
|
|
|
|
if (result != 0)
|
|
{
|
|
Dbg_Printf( "EE:sockAPIregthr() failed %d\n", result );
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Now wait for DECI2 'device' to be 'attached'
|
|
device_type = SN_DEV_TYPE_NONE;
|
|
first_time = SN_TRUE;
|
|
start_time = Tmr::GetTime();
|
|
// It takes longer to init the sony modem
|
|
if( GetDeviceType() == vDEV_TYPE_SONY_MODEM )
|
|
{
|
|
timeout = Tmr::Seconds( 15 );
|
|
}
|
|
else
|
|
{
|
|
timeout = Tmr::Seconds( 10 );
|
|
}
|
|
|
|
while( device_type == SN_DEV_TYPE_NONE )
|
|
{
|
|
result = sndev_get_attached( 0, &device_type, &idVendor, &idProduct );
|
|
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "EE:sndev_get_attached() failed %d\n", result );
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
|
|
if( device_type == SN_DEV_TYPE_NONE )
|
|
{
|
|
if( first_time == SN_TRUE )
|
|
{
|
|
first_time = SN_FALSE;
|
|
Dbg_Printf( "EE:Waiting for network device to be attached ...\n" );
|
|
}
|
|
sn_delay( 10 );
|
|
}
|
|
|
|
if(( Tmr::GetTime() - start_time ) > timeout )
|
|
{
|
|
Dbg_Printf( "EE:Timed out waiting for network device to be attached\n" );
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch( device_type )
|
|
{
|
|
case SN_DEV_TYPE_DECI2:
|
|
Dbg_Printf( "Using DECI-2 ethernet emulation\n" );
|
|
break;
|
|
case SN_DEV_TYPE_USB_MODEM:
|
|
Dbg_Printf("EE:USB-Modem Attached (idVendor=0x%04X idProduct=0x%04X)\n",
|
|
((int)idVendor) & 0xFFFF,
|
|
((int)idProduct) & 0xFFFF);
|
|
break;
|
|
case SN_DEV_TYPE_USB_ETHER:
|
|
Dbg_Printf("EE:USB-Ethernet Attached (idVendor=0x%04X idProduct=0x%04X)\n",
|
|
((int)idVendor) & 0xFFFF,
|
|
((int)idProduct) & 0xFFFF);
|
|
break;
|
|
default:
|
|
{
|
|
if( idVendor == 0 )
|
|
{
|
|
Dbg_Printf( "Unknown Device %d\n", device_type );
|
|
SetError( vRES_ERROR_UNKNOWN_DEVICE );
|
|
}
|
|
else
|
|
{
|
|
Dbg_Assert( idVendor == 1 );
|
|
SetError( vRES_ERROR_DEVICE_NOT_HOT );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::sn_stack_setup( void )
|
|
{
|
|
// Set up the list of DNS servers
|
|
char* dns_servers[3];
|
|
int result, i;
|
|
sn_int32 stack_state;
|
|
|
|
|
|
|
|
sn_stack_state( SN_STACK_STATE_READ, &stack_state );
|
|
if( stack_state == SN_STACK_STATE_START )
|
|
{
|
|
if( stop_stack() == false )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if( GetConnectionType() == vCONN_TYPE_ETHERNET )
|
|
{
|
|
if(( setup_ethernet_params() == false ))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < 3; i++ )
|
|
{
|
|
dns_servers[i] = m_dns_servers[i];
|
|
Dbg_Printf( "DNS Server %d is %s\n", i, dns_servers[i] );
|
|
}
|
|
result = sntc_set_dns_server_list((const sn_char**) dns_servers);
|
|
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "EE:sntc_set_dns_server_list() failed %d\n", result );
|
|
SetError( vRES_ERROR_GENERAL );
|
|
|
|
return false;
|
|
}
|
|
|
|
if( GetConnectionType() == vCONN_TYPE_PPPOE )
|
|
{
|
|
sndev_set_pppoe_opt_type pppoe;
|
|
|
|
// Enable PPPoE
|
|
pppoe.flags = 1;
|
|
|
|
Dbg_Printf( "Enabling PPPoE\n" );
|
|
result = sndev_set_options( 0, SN_DEV_SET_PPPOE_OPT, &pppoe, sizeof(pppoe));
|
|
|
|
Dbg_Printf( "EE:sndev_set_options(pppoe) returned %d\n", result );
|
|
}
|
|
if(( GetConnectionType() == vCONN_TYPE_MODEM ) ||
|
|
( GetConnectionType() == vCONN_TYPE_PPPOE ))
|
|
{
|
|
// Now, we have a valid modem. Try to initialize
|
|
//result = snmdm_set_mdm_init( "AT&F S0=0" );
|
|
result = snmdm_set_mdm_init( "AT&F S0=0 W2" );
|
|
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "EE:snmdm_set_mdm_init() failed %d\n", result );
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
|
|
return false;
|
|
}
|
|
|
|
Dbg_Printf( "EE:snmdm_set_mdm_init() worked ok\n" );
|
|
}
|
|
|
|
if( start_stack() == false )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_options_changed = false;
|
|
return true;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
static sn_int32 custom_construct_script( sn_int32 isp_type, sn_char* user_name,
|
|
sn_char* password)
|
|
{
|
|
sn_int32 line_index;
|
|
sn_bool copy_done;
|
|
|
|
copy_done = SN_FALSE;
|
|
line_index = 0;
|
|
|
|
// Copy the preset script to custom_built_script
|
|
while( copy_done == SN_FALSE )
|
|
{
|
|
// Copy this line of the script
|
|
strcpy( custom_built_script[line_index], s_custom_isp_script[line_index] );
|
|
|
|
// If this line was a null string then finished copy
|
|
if( s_custom_isp_script[line_index][0] == 0 )
|
|
{
|
|
copy_done = SN_TRUE;
|
|
}
|
|
else
|
|
{
|
|
line_index++;
|
|
}
|
|
}
|
|
|
|
sn_strcat( custom_built_script[vCUSTOM_USERNAME_LINE], user_name );
|
|
sn_strcat( custom_built_script[vCUSTOM_USERNAME_LINE], "\\r" );
|
|
|
|
// Concatenate password\r on to line index CUSTOM_PASSWORD_LINE
|
|
sn_strcat( custom_built_script[vCUSTOM_PASSWORD_LINE], password );
|
|
sn_strcat( custom_built_script[vCUSTOM_PASSWORD_LINE], "\\r" );
|
|
|
|
return 0; // Success
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
sn_int32 custom_connect_modem( sn_char* phone_no,
|
|
sn_int32 isp_type,
|
|
sn_char* user_name,
|
|
sn_char* password,
|
|
sn_int32 timeout_secs,
|
|
sntc_mdmstate_callback callback )
|
|
{
|
|
sn_int32 result;
|
|
sn_int32 modem_state;
|
|
sn_bool done_script;
|
|
sn_int32 script_index;
|
|
sn_int32 prev_modem_state;
|
|
sn_bool connect_started;
|
|
sn_int32 timeout_ms;
|
|
sn_int32 connect_err;
|
|
|
|
result = snmdm_set_phone_no( phone_no );
|
|
|
|
// Check that the above function call worked ok
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "Failed to set phone number: %d\n", result );
|
|
return SNTC_ERR_MDMAPI;
|
|
}
|
|
|
|
// Construct the log in script file (in custom_built_script)
|
|
result = custom_construct_script( isp_type, user_name, password );
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "Failed to build login script: %d\n", result );
|
|
return SNTC_ERR_BSCRIPT;
|
|
}
|
|
|
|
// Store the log in script file via the modem API
|
|
// Send a null string first, this resets the script write ptr to 0,
|
|
// it should already be at 0, but just being defensive.
|
|
result = snmdm_set_script("");
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "snmdm_set_script() failed: %d\n", result );
|
|
return SNTC_ERR_MDMAPI;
|
|
}
|
|
|
|
// Now send the script file to the modem API
|
|
script_index = 0;
|
|
done_script = SN_FALSE;
|
|
while( done_script == SN_FALSE )
|
|
{
|
|
result = snmdm_set_script( custom_built_script[ script_index ] );
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "snmdm_set_script() failed: %d\n", result );
|
|
return SNTC_ERR_MDMAPI;
|
|
}
|
|
|
|
// Check for null line, which is last line
|
|
if( custom_built_script[script_index][0] == 0 )
|
|
{
|
|
done_script = SN_TRUE;
|
|
}
|
|
else
|
|
{
|
|
script_index++;
|
|
}
|
|
}
|
|
|
|
// Everything is ready, so ask the modem to connect
|
|
result = snmdm_connect();
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "snmdm_connect() failed: %d\n", result );
|
|
return SNTC_ERR_MDMAPI;
|
|
}
|
|
|
|
// Now wait for the modem to become connected
|
|
modem_state = -1; /* Invalid */
|
|
prev_modem_state = -2; /* Ivalid and != modem_state */
|
|
connect_started = SN_FALSE;
|
|
timeout_ms = timeout_secs * 1000;
|
|
|
|
while(( modem_state != SN_MODEM_PPP_UP ) &&
|
|
( s_cancel_dialup_conn == false ))
|
|
{
|
|
|
|
// Get the current state of the modem link
|
|
result = snmdm_get_state(&modem_state);
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "snmdm_get_state() failed: %d\n", result );
|
|
return SNTC_ERR_MDMAPI;
|
|
}
|
|
|
|
// Monitor for modem connection process starting, then if it
|
|
// goes back to ready we know it's failed to connect.
|
|
if( connect_started == SN_FALSE )
|
|
{
|
|
// Any of the following means modem connection started
|
|
if( (modem_state == SN_MODEM_DIALING)
|
|
||(modem_state == SN_MODEM_LOGIN)
|
|
||(modem_state == SN_MODEM_CONNECTED)
|
|
||(modem_state == SN_MODEM_PPP_UP))
|
|
{
|
|
connect_started = SN_TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Having started the connection, then unless it's in
|
|
// one of the following states it's failed to connect
|
|
if( (modem_state != SN_MODEM_DIALING)
|
|
&&(modem_state != SN_MODEM_LOGIN)
|
|
&&(modem_state != SN_MODEM_CONNECTED)
|
|
&&(modem_state != SN_MODEM_PPP_UP))
|
|
{
|
|
// Read the reason why the connect failed.
|
|
result = snmdm_get_connect_err( &connect_err );
|
|
if( result != 0 )
|
|
{
|
|
Dbg_Printf( "snmdm_get_connect_err() failed: %d\n", result );
|
|
return SNTC_ERR_MDMAPI;
|
|
}
|
|
|
|
switch( connect_err )
|
|
{
|
|
case SN_CONERR_BUSY:
|
|
Dbg_Printf( "Busy\n" );
|
|
return SNTC_ERR_BUSY;
|
|
break;
|
|
|
|
case SN_CONERR_NOCARRIER:
|
|
Dbg_Printf( "No carrier\n" );
|
|
return SNTC_ERR_NOCARRIER;
|
|
break;
|
|
|
|
case SN_CONERR_NOANSWER:
|
|
Dbg_Printf( "No answer\n" );
|
|
return SNTC_ERR_NOANSWER;
|
|
break;
|
|
|
|
case SN_CONERR_NODIALTONE:
|
|
Dbg_Printf( "No dialtone\n" );
|
|
return SNTC_ERR_NODIALTONE;
|
|
break;
|
|
|
|
default:
|
|
Dbg_Printf( "connect started then modem state=sntc_str_modem_state(modem_state)\n" );
|
|
return SNTC_ERR_CONNECT;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now check whether the modem state has changed since the
|
|
// previous time round this loop, and if so call the user
|
|
// callback function (unless it's NULL), otherwise check
|
|
// for time-out / do a delay
|
|
if( modem_state != prev_modem_state )
|
|
{
|
|
prev_modem_state = modem_state;
|
|
if( callback != NULL )
|
|
{
|
|
(*callback)(modem_state);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( timeout_ms <= 0 )
|
|
{
|
|
Dbg_Printf( "Connect timed out in modem state %s\n", sntc_str_modem_state(modem_state) );
|
|
return SNTC_ERR_TIMEOUT;
|
|
}
|
|
|
|
sn_delay( 10 );
|
|
timeout_ms -= 10;
|
|
}
|
|
}
|
|
|
|
// If we get to here, the modem has successfully connected
|
|
Dbg_Printf( "Connected!\n" );
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::threaded_modem_conn( void *data )
|
|
{
|
|
|
|
Manager* man = (Manager *) data;
|
|
int result;
|
|
|
|
Dbg_Printf( "Registering modem thread %d with stack\n", GetThreadId());
|
|
|
|
result = sockAPIregthr();
|
|
Dbg_Assert( result == 0 );
|
|
|
|
WaitSema( s_conn_semaphore );
|
|
|
|
Dbg_Printf("EE:Calling sntc_connect_modem()\n");
|
|
|
|
// Set the script write pointer back to zero
|
|
result = snmdm_set_script("");
|
|
|
|
// Set up Authentication parameters.
|
|
sndev_set_chap_type ChapOptions = {0};
|
|
|
|
ChapOptions.accept_chap = man->ShouldUseDialupAuthentication();
|
|
Dbg_Printf( "Setting chap to %d\n", ChapOptions.accept_chap );
|
|
ChapOptions.require_chap = 0;
|
|
strcpy(ChapOptions.locl_name, man->m_isp_user_name );
|
|
strcpy(ChapOptions.locl_secr, man->m_isp_password );
|
|
strcpy(ChapOptions.chal_name,"*"); // Accept any challenge name
|
|
|
|
Dbg_Printf( "Chap username: %s password: %s\n", man->m_isp_user_name, man->m_isp_password );
|
|
result = sndev_set_options( 0, SN_DEV_SET_CHAP, &ChapOptions, sizeof(ChapOptions));
|
|
Dbg_Printf( "EE:sndev_set_options(SN_DEV_SET_CHAP) returned %d\n", result );
|
|
|
|
sndev_set_pap_type PapOptions = {0};
|
|
|
|
PapOptions.accept_pap = man->ShouldUseDialupAuthentication();
|
|
Dbg_Printf( "Setting pap to %d\n", PapOptions.accept_pap );
|
|
PapOptions.require_pap = 0;
|
|
strcpy(PapOptions.locl_name, man->m_isp_user_name );
|
|
strcpy(PapOptions.locl_pass, man->m_isp_password );
|
|
Dbg_Printf( "Pap username: %s password: %s\n", man->m_isp_user_name, man->m_isp_password );
|
|
|
|
result = sndev_set_options( 0, SN_DEV_SET_PAP, &PapOptions, sizeof(PapOptions));
|
|
Dbg_Printf( "EE:sndev_set_options(SN_DEV_SET_PAP) returned %d\n", result );
|
|
|
|
man->m_modem_err = 0;
|
|
if( man->GetConnectionType() == vCONN_TYPE_MODEM )
|
|
{
|
|
Dbg_Printf( "Dialing %s user: %s pass: %s\n", man->m_isp_phone_no, man->m_isp_user_name, man->m_isp_password );
|
|
result = custom_connect_modem
|
|
( man->m_isp_phone_no, // phone_no
|
|
SNTC_ISP_GENERIC, // isp_type
|
|
man->m_isp_user_name, // user_name
|
|
man->m_isp_password, // password
|
|
vMODEM_CONNECT_TIMEOUT, // timeout_secs
|
|
man->conn_modem_state_callback );// callback
|
|
}
|
|
else if( man->GetConnectionType() == vCONN_TYPE_PPPOE )
|
|
{
|
|
result = custom_connect_modem
|
|
( "", // phone_no
|
|
0, // isp_type
|
|
"", // user_name
|
|
"", // password
|
|
vMODEM_CONNECT_TIMEOUT, // timeout_secs
|
|
man->conn_modem_state_callback );// callback
|
|
}
|
|
// Check whether connection succeeded
|
|
if( result == 0 )
|
|
{
|
|
sn_int32 result, statval, statlen;
|
|
|
|
statval = 1234; // so can see it's modified
|
|
statlen = sizeof(statval);
|
|
|
|
result = sndev_get_status(0, SN_DEV_STAT_BAUD, &statval, &statlen);
|
|
man->m_modem_baud_rate = statval;
|
|
|
|
man->m_online = true;
|
|
}
|
|
else
|
|
{
|
|
sntc_disconnect_modem( vMODEM_DISCONNECT_TIMEOUT, // timeout_secs
|
|
NULL, // callback
|
|
NULL ); // error_message
|
|
man->SetModemState( vMODEM_STATE_ERROR );
|
|
man->m_modem_err = result;
|
|
Dbg_Printf( "EE:sntc_connect_modem() failed: %d\n", result );
|
|
man->m_online = false;
|
|
}
|
|
|
|
Dbg_Printf( "DeRegistering modem thread %d with stack\n", GetThreadId());
|
|
sockAPIderegthr();
|
|
SignalSema( s_conn_semaphore );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::threaded_modem_disconn( void *data )
|
|
{
|
|
|
|
Manager* man = (Manager *) data;
|
|
sn_char* err_msg_ptr;
|
|
bool modem_disconnected;
|
|
int result;
|
|
|
|
Dbg_Printf( "Registering modem thread %d with stack\n", GetThreadId());
|
|
|
|
result = sockAPIregthr();
|
|
Dbg_Assert( result == 0 );
|
|
|
|
modem_disconnected = false;
|
|
if( man->m_online )
|
|
{
|
|
Dbg_Printf( "EE:Calling sntc_disconnect_modem()\n" );
|
|
result = sntc_disconnect_modem( vMODEM_DISCONNECT_TIMEOUT, // timeout_secs
|
|
disconn_modem_state_callback, // callback
|
|
&err_msg_ptr ); // error_message
|
|
|
|
// Check whether disconnection succeeded
|
|
if (result == 0)
|
|
{
|
|
Dbg_Printf("EE:sntc_disconnect_modem() worked:%s\n",err_msg_ptr);
|
|
modem_disconnected = true;
|
|
}
|
|
else
|
|
{
|
|
Dbg_Printf("EE:sntc_disconnect_modem() failed:%s\n",err_msg_ptr);
|
|
modem_disconnected = false;
|
|
}
|
|
}
|
|
|
|
// If the modem didn't connect and disconnect ok, then reset it
|
|
if( !modem_disconnected )
|
|
{
|
|
bool modem_reset;
|
|
|
|
do
|
|
{
|
|
Dbg_Printf( "EE:Calling sntc_reset_modem()\n" );
|
|
|
|
result = sntc_reset_modem
|
|
( vMODEM_RESET_TIMEOUT, // timeout_secs
|
|
disconn_modem_state_callback, // callback
|
|
&err_msg_ptr ); // error_message
|
|
|
|
// Check whether reset succeeded
|
|
if( result == 0 )
|
|
{
|
|
Dbg_Printf( "EE:sntc_reset_modem() worked:%s\n", err_msg_ptr );
|
|
modem_reset = true;
|
|
}
|
|
else
|
|
{
|
|
Dbg_Printf( "EE:sntc_reset_modem() failed:%s\n", err_msg_ptr );
|
|
modem_reset = false;
|
|
// If their modem is no longer plugged in, just consider it "hung up"
|
|
if( result == SNTC_ERR_NOMODEM )
|
|
{
|
|
break;
|
|
}
|
|
sn_delay( 1000 ); // avoid excessive printf if unplugged
|
|
}
|
|
} while( !modem_reset );
|
|
}
|
|
|
|
man->SetModemState( vMODEM_STATE_DISCONNECTED );
|
|
man->m_online = false;
|
|
|
|
Dbg_Printf( "DeRegistering modem thread %d with stack\n", GetThreadId());
|
|
sockAPIderegthr();
|
|
}
|
|
|
|
#endif // __PLAT_NGPS__
|
|
|
|
/*****************************************************************************
|
|
** Public Functions **
|
|
*****************************************************************************/
|
|
|
|
/******************************************************************/
|
|
/* Add logic tasks to the current task list */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::AddLogicTasks( App* app )
|
|
{
|
|
Mlp::Manager * mlp_manager = Mlp::Manager::Instance();
|
|
|
|
mlp_manager->AddLogicTask( app->GetReceiveDataTask());
|
|
mlp_manager->AddLogicTask( app->GetSendDataTask());
|
|
mlp_manager->AddLogicTask( app->GetProcessDataTask());
|
|
mlp_manager->AddLogicTask( app->GetNetworkMetricsTask());
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Add logic tasks to the push logic task list */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::AddLogicPushTasks( App* app )
|
|
{
|
|
Mlp::Manager * mlp_manager = Mlp::Manager::Instance();
|
|
|
|
app->GetSendDataTask().Remove();
|
|
app->GetReceiveDataTask().Remove();
|
|
app->GetProcessDataTask().Remove();
|
|
app->GetNetworkMetricsTask().Remove();
|
|
|
|
mlp_manager->AddLogicPushTask( app->GetReceiveDataTask());
|
|
mlp_manager->AddLogicPushTask( app->GetSendDataTask());
|
|
mlp_manager->AddLogicPushTask( app->GetProcessDataTask());
|
|
mlp_manager->AddLogicPushTask( app->GetNetworkMetricsTask());
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Removes network logic tasks */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::RemoveNetworkTasks( App* app )
|
|
{
|
|
app->GetSendDataTask().Remove();
|
|
app->GetReceiveDataTask().Remove();
|
|
app->GetProcessDataTask().Remove();
|
|
app->GetNetworkMetricsTask().Remove();
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Creates a new Server at the given address and port */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
Server* Manager::CreateNewAppServer( int id, char* appName, int max_clients,
|
|
unsigned short port, int address, int flags )
|
|
{
|
|
Server *new_app;
|
|
|
|
|
|
|
|
Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().NetworkHeap());
|
|
|
|
// If we're using DHCP, we should have gotten our real IP address by now
|
|
// from the DHCP server. Use that address from now on
|
|
if( ShouldUseDHCP())
|
|
{
|
|
address = inet_addr( m_local_ip );
|
|
}
|
|
|
|
new_app = new Server( flags );
|
|
new_app->m_net_man = this;
|
|
new_app->init();
|
|
|
|
new_app->m_id = id;
|
|
strncpy( new_app->m_name, appName, MAX_LEN_APP_NAME );
|
|
new_app->m_max_connections = max_clients;
|
|
|
|
m_net_servers.AddToTail( &new_app->m_node );
|
|
if( new_app->IsLocal())
|
|
{
|
|
new_app->m_connected = true;
|
|
}
|
|
else
|
|
{
|
|
new_app->bind_app_socket( address, port );
|
|
if( flags & App::mBROADCAST )
|
|
{
|
|
new_app->m_connected = true;
|
|
}
|
|
}
|
|
|
|
#ifdef USE_ALIASES
|
|
if( flags & App::mALIAS_SUPPORT )
|
|
{
|
|
new_app->AllocateAliasTables();
|
|
new_app->ClearAliasTables();
|
|
}
|
|
#endif
|
|
|
|
AddLogicTasks( new_app );
|
|
|
|
#ifndef __PLAT_NGC__
|
|
Dbg_Printf( "Created new: %s server %p, Max Clients: %d, IP: %s, Port: %d", appName, new_app, max_clients,
|
|
inet_ntoa( *(struct in_addr*) &address ), port );
|
|
#endif // __PLAT_NGC__
|
|
|
|
m_num_apps++;
|
|
|
|
Mem::Manager::sHandle().PopContext();
|
|
return new_app;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Creates a new client socket */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
Client *Manager::CreateNewAppClient( int id, char* appName, unsigned short port, int address,
|
|
int flags )
|
|
{
|
|
Client *new_app;
|
|
|
|
|
|
|
|
Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().NetworkHeap());
|
|
|
|
// If we're using DHCP, we should have gotten our real IP address by now
|
|
// from the DHCP server. Use that address from now on
|
|
if( ShouldUseDHCP())
|
|
{
|
|
address = inet_addr( m_local_ip );
|
|
}
|
|
|
|
new_app = new Client( flags );
|
|
strncpy( new_app->m_name, appName, MAX_LEN_APP_NAME );
|
|
new_app->m_net_man = this;
|
|
new_app->init();
|
|
|
|
new_app->m_id = id;
|
|
new_app->m_max_connections = 1;
|
|
|
|
m_net_clients.AddToTail( &new_app->m_node );
|
|
if( !new_app->IsLocal())
|
|
{
|
|
#ifndef __PLAT_XBOX__
|
|
new_app->bind_app_socket( address, port );
|
|
#endif
|
|
}
|
|
|
|
#ifdef USE_ALIASES
|
|
new_app->ClearAliasTable();
|
|
#endif
|
|
|
|
AddLogicTasks( new_app );
|
|
|
|
Dbg_Printf( "Created new: %s client %p on port %d\n", appName, new_app, port );
|
|
m_num_apps++;
|
|
|
|
Mem::Manager::sHandle().PopContext();
|
|
return new_app;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::DestroyApp( App *app )
|
|
{
|
|
app->m_node.Remove();
|
|
app->ShutDown();
|
|
delete app;
|
|
m_num_apps--;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
Metrics::Metrics( void )
|
|
{
|
|
m_num_packets = 0;
|
|
m_total_bytes = 0;
|
|
m_bytes_per_sec = 0;
|
|
memset( m_num_messages, 0, sizeof( int ) * MAX_MSG_IDS );
|
|
memset( m_size_messages, 0, sizeof( int ) * MAX_MSG_IDS );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Metrics::CalculateBytesPerSec( int cur_time )
|
|
{
|
|
int i, num_bytes;
|
|
|
|
num_bytes = 0;
|
|
// Sum up number of bytes transferred over the last second
|
|
for( i = 0; i < vNUM_BUFFERED_PACKETS; i++ )
|
|
{
|
|
if( i >= m_num_packets )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if(( cur_time - m_packets[i].GetTime()) < (int) Tmr::Seconds( 1 ))
|
|
{
|
|
num_bytes += m_packets[i].GetNumBytes();
|
|
}
|
|
}
|
|
|
|
m_bytes_per_sec = num_bytes;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Metrics::GetBytesPerSec( void )
|
|
{
|
|
return m_bytes_per_sec;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Metrics::GetTotalBytes( void )
|
|
{
|
|
return m_total_bytes;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Metrics::GetTotalMessageData( int msg_id )
|
|
{
|
|
return m_size_messages[ msg_id ];
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Metrics::GetTotalNumMessagesOfId( int msg_id )
|
|
{
|
|
return m_num_messages[ msg_id ];
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Metrics::AddPacket( int size, int time )
|
|
{
|
|
int index;
|
|
|
|
index = m_num_packets % vNUM_BUFFERED_PACKETS;
|
|
|
|
m_packets[ index ].SetNumBytes( size );
|
|
m_packets[ index ].SetTime( time );
|
|
m_total_bytes += size;
|
|
m_num_packets++;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Metrics::AddMessage( int msg_id, int size )
|
|
{
|
|
m_num_messages[ msg_id ]++;
|
|
m_size_messages[ msg_id ] += size;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int PacketInfo::GetNumBytes( void )
|
|
{
|
|
return m_num_bytes;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int PacketInfo::GetTime( void )
|
|
{
|
|
return m_time;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void PacketInfo::SetNumBytes( int size )
|
|
{
|
|
m_num_bytes = size;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void PacketInfo::SetTime( int time )
|
|
{
|
|
m_time = time;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Iterator */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
Server *Manager::FirstServer( Lst::Search< App > *sh )
|
|
{
|
|
|
|
|
|
Dbg_Assert( sh );
|
|
|
|
return((Server*) sh->FirstItem( m_net_servers ));
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Iterator */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
Client *Manager::FirstClient( Lst::Search< App > *sh )
|
|
{
|
|
|
|
|
|
Dbg_Assert( sh );
|
|
|
|
return((Client*) sh->FirstItem( m_net_clients ));
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Iterator */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
App *Manager::NextApp( Lst::Search< App > *sh )
|
|
{
|
|
|
|
|
|
Dbg_Assert( sh );
|
|
|
|
return( sh->NextItem());
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Manager::NumApps( void )
|
|
{
|
|
return m_num_apps;
|
|
}
|
|
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
#ifdef __PLAT_NGC__
|
|
static void* s_so_alloc( u32 name, s32 size )
|
|
{
|
|
return Mem::Malloc( size );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
static void s_so_free( u32 name, void* ptr, s32 size )
|
|
{
|
|
Mem::Free( ptr );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::initialize_ngc( void )
|
|
{
|
|
int result;
|
|
SOConfig config;
|
|
|
|
memset( &config, 0, sizeof( SOConfig ));
|
|
|
|
config.vendor = SO_VENDOR_NINTENDO;
|
|
config.version = SO_VERSION;
|
|
config.alloc = s_so_alloc;
|
|
config.free = s_so_free;
|
|
if( ShouldUseDHCP())
|
|
{
|
|
config.flag = SO_FLAG_DHCP;
|
|
}
|
|
else
|
|
{
|
|
config.flag = 0;
|
|
|
|
inet_aton( GetLocalIP(), (struct in_addr*) &config.addr );
|
|
inet_aton( GetSubnetMask(), (struct in_addr*) &config.netmask );
|
|
inet_aton( GetGateway(), (struct in_addr*) &config.router );
|
|
inet_aton( GetDNSServer( 0 ), (struct in_addr*) &config.dns1 );
|
|
inet_aton( GetDNSServer( 1 ), (struct in_addr*) &config.dns2 );
|
|
}
|
|
|
|
result = SOStartup( &config );
|
|
if( result != 0 )
|
|
{
|
|
SOCleanup();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
#ifdef __PLAT_NGPS__
|
|
|
|
bool Manager::load_irx_files( void )
|
|
{
|
|
|
|
//////////////////////////////
|
|
#if 0 // MOVED TO SIOMAN.CPP
|
|
|
|
int result;
|
|
|
|
// Load the stack IRX file
|
|
#ifdef __NOPT_DEBUG__
|
|
result = SIO::LoadIRX( "SNSTKDBG" );
|
|
#else
|
|
result = SIO::LoadIRX( "SNSTKREL" );
|
|
#endif
|
|
|
|
if( result < 0 )
|
|
{
|
|
Dbg_MsgAssert( 0,( "EE:Can't load module snstkrel/dbg.irx. Error : %d\n", result ));
|
|
SetError( vRES_ERROR_INVALID_IRX );
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
//////////////////////////////
|
|
|
|
|
|
|
|
#ifdef USE_DECI2
|
|
// Load the DECI2 driver IRX file
|
|
SIO::LoadIRX( "sndrv000" );
|
|
#else
|
|
|
|
switch( GetConnectionType())
|
|
{
|
|
case vCONN_TYPE_PPPOE:
|
|
{
|
|
switch( GetDeviceType())
|
|
{
|
|
case vDEV_TYPE_USB_ETHERNET:
|
|
{
|
|
// Load the PPPoE Driver IRX file
|
|
if( SIO::LoadIRX( "sndrv200" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
// Load the USB-Ethernet Driver IRX file
|
|
if( SIO::LoadIRX( "sndrv201" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case vDEV_TYPE_PC_ETHERNET:
|
|
{
|
|
// Load the PPPoE Driver IRX file
|
|
if( SIO::LoadIRX( "sndrv200" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
// Load the SN Wrapper (PPPoE variant) for Sony Ether
|
|
if( SIO::LoadIRX( "sndrv202" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
// Load the Sony pcmcia irx
|
|
if( SIO::LoadIRX( "dev9" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
s_prepare_power_off();
|
|
// Load the Sony Ethernet driver IRX file
|
|
if( SIO::LoadIRX( "smap", 0, NULL, false ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case vCONN_TYPE_ETHERNET:
|
|
{
|
|
switch( GetDeviceType())
|
|
{
|
|
case vDEV_TYPE_USB_ETHERNET:
|
|
{
|
|
// Load the USB-Ethernet Driver IRX file
|
|
if( SIO::LoadIRX( "sndrv001" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case vDEV_TYPE_PC_ETHERNET:
|
|
{
|
|
if( SIO::LoadIRX( "sndrv100" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
// Load the Sony pcmcia irx
|
|
if( SIO::LoadIRX( "dev9" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
s_prepare_power_off();
|
|
// Load the Sony Ethernet driver IRX file
|
|
if( SIO::LoadIRX( "smap", 0, NULL, false ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case vCONN_TYPE_MODEM:
|
|
{
|
|
switch( GetDeviceType())
|
|
{
|
|
case vDEV_TYPE_USB_MODEM:
|
|
{
|
|
// Load the USB-Modem Driver IRX file
|
|
if( SIO::LoadIRX( "sndrv002" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case vDEV_TYPE_SONY_MODEM:
|
|
{
|
|
if (Config::PAL())
|
|
{
|
|
// Sony Modem Not Supported in PAL territories
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
|
|
// Load the SN modem wrapper irx
|
|
if( SIO::LoadIRX( "sndrv101" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
// Load the Sony pcmcia irx
|
|
if( SIO::LoadIRX( "dev9" ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
s_prepare_power_off();
|
|
// Load the Sony modem driver irx
|
|
if( SIO::LoadIRX( "spduart", sizeof(spduartArgs), (char*) spduartArgs ) < 0 )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_NOT_CONNECTED );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
// No valid device specified
|
|
SetError( vRES_ERROR_GENERAL );
|
|
return false;
|
|
}
|
|
|
|
#endif // USE_DECI2
|
|
|
|
return true;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::initialize_ps2( void )
|
|
{
|
|
|
|
|
|
bool result;
|
|
|
|
Dbg_Printf( "initializing PS2\n" );
|
|
|
|
if( m_net_drivers_loaded == false )
|
|
{
|
|
bool success;
|
|
|
|
File::StopStreaming( );
|
|
if ( Pcm::UsingCD( ) )
|
|
{
|
|
Dbg_MsgAssert( 0,( "Can't load IRX modules when CD is busy." ));
|
|
return false;
|
|
}
|
|
|
|
Dbg_Printf( "initializing PS2_2\n" );
|
|
success = load_irx_files();
|
|
m_net_drivers_loaded = true;
|
|
if( success == false )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( m_device_changed )
|
|
{
|
|
SetError( vRES_ERROR_DEVICE_CHANGED );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
result = initialize_device();
|
|
if( result == false )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( !m_stack_setup || m_options_changed )
|
|
{
|
|
m_stack_setup = sn_stack_setup();
|
|
}
|
|
|
|
m_device_changed = false;
|
|
return m_stack_setup;
|
|
}
|
|
|
|
#endif // __PLAT_NGPS__
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
Manager::Manager( void )
|
|
{
|
|
int msg_id, i;
|
|
|
|
#if( defined ( __PLAT_WN32__ ) || defined ( __PLAT_XBOX__ ))
|
|
int err;
|
|
WORD version_required;
|
|
WSADATA wsa_data;
|
|
|
|
#ifdef __PLAT_XBOX__
|
|
XNetStartupParams xnsp;
|
|
ZeroMemory( &xnsp, sizeof(xnsp) );
|
|
xnsp.cfgSizeOfStruct = sizeof(xnsp);
|
|
|
|
#ifdef __NOPT_NOASSERTIONS__
|
|
xnsp.cfgFlags = 0;
|
|
#else
|
|
xnsp.cfgFlags = XNET_STARTUP_BYPASS_SECURITY;// | XNET_STARTUP_BYPASS_DHCP;
|
|
#endif
|
|
|
|
err = XNetStartup( &xnsp );
|
|
if( err )
|
|
{
|
|
XNetCleanup();
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
version_required = MAKEWORD( 2, 2 );
|
|
if( err = WSAStartup ( version_required, &wsa_data ))
|
|
{
|
|
Dbg_MsgAssert( 0,( "Failed to start WinSock\n" ));
|
|
WSACleanup();
|
|
#ifdef __PLAT_XBOX__
|
|
XNetCleanup();
|
|
#endif
|
|
return;
|
|
}
|
|
if ( ( LOBYTE( wsa_data.wVersion ) != 2 ) ||
|
|
( HIBYTE( wsa_data.wVersion ) != 2 ))
|
|
{
|
|
Dbg_MsgAssert( 0,( "Failed to start WinSock\n" ));
|
|
WSACleanup();
|
|
#ifdef __PLAT_XBOX__
|
|
XNetCleanup();
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
#ifdef __PLAT_XBOX__
|
|
# if 0
|
|
HRESULT hr;
|
|
XONLINE_STARTUP_PARAMS xosp = { 0 };
|
|
|
|
hr = XOnlineStartup( &xosp );
|
|
if( FAILED( hr ))
|
|
{
|
|
XOnlineCleanup();
|
|
return;
|
|
}
|
|
# endif
|
|
#endif
|
|
|
|
#else
|
|
#ifdef __PLAT_NGPS__
|
|
ChangeThreadPriority( GetThreadId(), vMAIN_THREAD_PRIORITY );
|
|
m_stack_setup = false;
|
|
m_options_changed = false;
|
|
m_device_changed = false;
|
|
m_net_drivers_loaded = false;
|
|
#endif // __PLAT_NGPS__
|
|
#endif // __PLAT_WN32__
|
|
|
|
for( msg_id = 0; msg_id < 255; msg_id++ )
|
|
{
|
|
SetMessageName( msg_id, "<No Text>" );
|
|
SetMessageFlags( msg_id, 0 );
|
|
}
|
|
|
|
SetMessageName( MSG_ID_PING_TEST, "Ping Test" );
|
|
SetMessageName( MSG_ID_PING_RESPONSE, "Ping Response" );
|
|
SetMessageName( MSG_ID_CONNECTION_REQ, "Connection Request" );
|
|
SetMessageName( MSG_ID_CONNECTION_ACCEPTED, "Connection Accepted" );
|
|
SetMessageName( MSG_ID_CONNECTION_REFUSED, "Connection Refused" );
|
|
SetMessageName( MSG_ID_CONNECTION_TERMINATED, "Connection Terminated" );
|
|
SetMessageName( MSG_ID_SEQUENCED, "Sequenced Message" );
|
|
SetMessageName( MSG_ID_ACK, "Ack" );
|
|
SetMessageName( MSG_ID_FIND_SERVER, "Find Server" );
|
|
SetMessageName( MSG_ID_SERVER_RESPONSE, "Server Find Response" );
|
|
SetMessageName( MSG_ID_TIMESTAMP, "Timestamp" );
|
|
SetMessageName( MSG_ID_ALIAS, "New Alias" );
|
|
SetMessageName( MSG_ID_DISCONN_REQ, "Disconn Request" );
|
|
SetMessageName( MSG_ID_DISCONN_ACCEPTED, "Disconn Accepted" );
|
|
|
|
SetMessageFlags( MSG_ID_TIMESTAMP, mMSG_SIZE_UNKNOWN );
|
|
SetMessageFlags( MSG_ID_ACK, mMSG_SIZE_UNKNOWN );
|
|
|
|
sprintf( m_local_ip, "<Unknown>" );
|
|
sprintf( m_gateway, DEFAULT_SNPS2_GATEWAY );
|
|
sprintf( m_subnet, DEFAULT_SNPS2_SUB_MSK );
|
|
|
|
m_num_apps = 0;
|
|
m_conn_type = vCONN_TYPE_NONE;
|
|
m_use_dhcp = false;
|
|
m_online = false;
|
|
m_use_dialup_auth = false;
|
|
m_last_error = vRES_SUCCESS;
|
|
m_modem_state = vMODEM_STATE_DISCONNECTED;
|
|
m_modem_err = 0;
|
|
|
|
for( i = 0; i < 3; i++ )
|
|
{
|
|
m_dns_servers[i][0] = '\0';
|
|
}
|
|
|
|
#ifdef __PLAT_NGPS__
|
|
m_bandwidth = 4200; // Default to a 33.6kbps modem's approximate payload threshold (i.e. including packet overhead)
|
|
#else
|
|
m_bandwidth = 400000; // On Xbox, just assume broadband
|
|
#endif
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
Manager::~Manager( void )
|
|
{
|
|
|
|
#if( defined ( __PLAT_WN32__ ) || defined ( __PLAT_XBOX__ ))
|
|
WSACleanup();
|
|
#endif
|
|
|
|
#ifdef __PLAT_XBOX__
|
|
XNetCleanup();
|
|
# if 0
|
|
XOnlineCleanup();
|
|
# endif
|
|
#endif
|
|
|
|
#ifdef __PLAT_NGC__
|
|
SOCleanup();
|
|
#endif
|
|
|
|
|
|
#ifdef __PLAT_NGPS__
|
|
sn_int32 stack_state, result;
|
|
|
|
if( m_stack_setup )
|
|
{
|
|
// Stop the stack
|
|
result = sn_stack_state(SN_STACK_STATE_STOP, &stack_state );
|
|
Dbg_MsgAssert( result == 0,( "EE:sn_stack_sate() failed %d\n", result ));
|
|
|
|
// De-Register this thread with the socket API
|
|
Dbg_Printf( "EE:Calling sockAPIderegthr()\n" );
|
|
sockAPIderegthr();
|
|
}
|
|
#endif // __PLAY_NGPS__
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
#ifdef __PLAT_NGPS__
|
|
|
|
void Manager::conn_modem_state_callback( sn_int32 modem_state )
|
|
{
|
|
|
|
Net::Manager * net_man = Net::Manager::Instance();
|
|
|
|
Dbg_Printf(" Modem state %d = %s\n", modem_state, sntc_str_modem_state( modem_state ));
|
|
switch( modem_state )
|
|
{
|
|
case SN_MODEM_READY:
|
|
case SN_MODEM_DIALING:
|
|
net_man->SetModemState( vMODEM_STATE_DIALING );
|
|
|
|
// If we're using PAP/CHAP, clear the login script. We do it here instead of before
|
|
// sntc_connect_modem() because that call resets to the default login script.
|
|
if( net_man->ShouldUseDialupAuthentication())
|
|
{
|
|
sndev_set_null_scrpt_type clr;
|
|
int result;
|
|
|
|
clr.reserved = 0;
|
|
|
|
result = sndev_set_options(0, SN_DEV_SET_NULL_SCRPT, &clr, sizeof(clr));
|
|
Dbg_Printf( "EE:sndev_set_options(clr) returned %d\n", result );
|
|
}
|
|
|
|
Dbg_Printf( "Setting modem state to modem state dialing\n" );
|
|
break;
|
|
case SN_MODEM_LOGIN:
|
|
Dbg_Printf( "Setting modem state to modem state connected\n" );
|
|
net_man->SetModemState( vMODEM_STATE_CONNECTED );
|
|
break;
|
|
case SN_MODEM_PPP_UP:
|
|
Dbg_Printf( "Setting modem state to modem state logged in\n" );
|
|
net_man->SetModemState( vMODEM_STATE_LOGGED_IN );
|
|
break;
|
|
default:
|
|
return;
|
|
};
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::disconn_modem_state_callback( sn_int32 modem_state )
|
|
{
|
|
Net::Manager * net_man = Net::Manager::Instance();
|
|
|
|
Dbg_Printf(" Modem state = %s\n", sntc_str_modem_state( modem_state ));
|
|
switch( modem_state )
|
|
{
|
|
case SN_MODEM_HANGINGUP:
|
|
net_man->SetModemState( vMODEM_STATE_HANGING_UP );
|
|
break;
|
|
default:
|
|
return;
|
|
};
|
|
}
|
|
|
|
#endif
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
|
|
bool Manager::NetworkEnvironmentSetup( void )
|
|
{
|
|
#ifdef __PLAT_NGPS__
|
|
return initialize_ps2();
|
|
#endif
|
|
#ifdef __PLAT_NGC__
|
|
return initialize_ngc();
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::NeedToTestNetworkEnvironment( void )
|
|
{
|
|
#ifdef __PLAT_NGPS__
|
|
if( m_net_drivers_loaded && m_device_changed )
|
|
{
|
|
return true;
|
|
}
|
|
if( !m_stack_setup || m_options_changed )
|
|
{
|
|
return true;
|
|
}
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::ConnectToInternet( void )
|
|
{
|
|
|
|
|
|
#ifdef __PLAT_NGPS__
|
|
|
|
if(( IsOnline() == false ) || m_options_changed )
|
|
{
|
|
if( GetConnectionType() == vCONN_TYPE_ETHERNET )
|
|
{
|
|
m_online = true;
|
|
}
|
|
else if(( GetConnectionType() == vCONN_TYPE_MODEM ) ||
|
|
( GetConnectionType() == vCONN_TYPE_PPPOE ))
|
|
{
|
|
int result, device_type;
|
|
int modem_state;
|
|
|
|
s_cancel_dialup_conn = false;
|
|
result = sndev_get_attached(0, &device_type, NULL, NULL);
|
|
// Check that the above function call worked ok
|
|
if( result != 0 )
|
|
{
|
|
SetModemState( vMODEM_STATE_ERROR );
|
|
m_modem_err = SNTC_ERR_NOMODEM;
|
|
return false;
|
|
}
|
|
|
|
// Check that there is a compatible modem attached
|
|
if( device_type != SN_DEV_TYPE_USB_MODEM )
|
|
{
|
|
SetModemState( vMODEM_STATE_ERROR );
|
|
m_modem_err = SNTC_ERR_NOMODEM;
|
|
return false;
|
|
}
|
|
|
|
result = snmdm_get_state( &modem_state );
|
|
// Check that the above function call worked ok
|
|
if( result != 0 )
|
|
{
|
|
SetModemState( vMODEM_STATE_ERROR );
|
|
m_modem_err = SNTC_ERR_NOMODEM;
|
|
return false;
|
|
}
|
|
|
|
// Make sure that the modem is ready to dial, if not reset it
|
|
if( ( modem_state != SN_MODEM_READY ) &&
|
|
( modem_state != SN_MODEM_READY_AUTOANS ))
|
|
{
|
|
sn_char* err_msg_ptr;
|
|
|
|
Dbg_Printf( "EE:Calling sntc_reset_modem()\n" );
|
|
// Attempt to reset the modem
|
|
result = sntc_reset_modem( vMODEM_RESET_TIMEOUT, // timeout_secs
|
|
disconn_modem_state_callback, // callback
|
|
&err_msg_ptr ); // error_message
|
|
// If failed to reset the modem, then the result, and
|
|
// error_message will have been set up by sntc_reset_modem.
|
|
if( result != 0 )
|
|
{
|
|
SetModemState( vMODEM_STATE_ERROR );
|
|
m_modem_err = SNTC_ERR_NOMODEM;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
struct SemaParam params;
|
|
|
|
params.initCount = 1;
|
|
params.maxCount = 10;
|
|
|
|
s_conn_semaphore = CreateSema( ¶ms );
|
|
|
|
// Clear the modem state before we start
|
|
SetModemState( -1 );
|
|
|
|
m_modem_thread_data.m_pEntry = threaded_modem_conn;
|
|
m_modem_thread_data.m_iInitialPriority = vSOCKET_THREAD_PRIORITY;
|
|
m_modem_thread_data.m_pStackBase = m_modem_thread_stack;
|
|
m_modem_thread_data.m_iStackSize = vMODEM_THREAD_STACK_SIZE;
|
|
m_modem_thread_data.m_utid = 0x150;//vBASE_SOCKET_THREAD_ID + NumApps();
|
|
Thread::CreateThread( &m_modem_thread_data );
|
|
m_modem_thread_id = m_modem_thread_data.m_osId;
|
|
|
|
StartThread( m_modem_thread_id, this );
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
m_online = true;
|
|
#endif
|
|
|
|
return m_online;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::DisconnectFromInternet( void )
|
|
{
|
|
|
|
|
|
#ifdef __PLAT_NGPS__
|
|
if( m_conn_type == vCONN_TYPE_ETHERNET )
|
|
{
|
|
m_online = false;
|
|
}
|
|
else if( ( m_conn_type == vCONN_TYPE_MODEM ) ||
|
|
( m_conn_type == vCONN_TYPE_PPPOE ))
|
|
{
|
|
// Just in case the modem thread is running, stop it
|
|
s_cancel_dialup_conn = true;
|
|
WaitSema( s_conn_semaphore );
|
|
DeleteSema( s_conn_semaphore );
|
|
TerminateThread( m_modem_thread_id );
|
|
DeleteThread( m_modem_thread_id );
|
|
|
|
SetModemState( vMODEM_STATE_DISCONNECTING );
|
|
m_modem_err = 0;
|
|
|
|
m_modem_thread_data.m_pEntry = threaded_modem_disconn;
|
|
m_modem_thread_data.m_iInitialPriority = vSOCKET_THREAD_PRIORITY;
|
|
m_modem_thread_data.m_pStackBase = m_modem_thread_stack;
|
|
m_modem_thread_data.m_iStackSize = vMODEM_THREAD_STACK_SIZE;
|
|
m_modem_thread_data.m_utid = 0x14F;//vBASE_SOCKET_THREAD_ID + NumApps();
|
|
Thread::CreateThread( &m_modem_thread_data );
|
|
m_modem_thread_id = m_modem_thread_data.m_osId;
|
|
|
|
StartThread( m_modem_thread_id, this );
|
|
}
|
|
#else
|
|
m_online = false;
|
|
#endif
|
|
|
|
return ( m_online == false );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Manager::GetModemBaudRate( void )
|
|
{
|
|
return m_modem_baud_rate;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetBandwidth( int bytes_per_sec )
|
|
{
|
|
m_bandwidth = bytes_per_sec;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Manager::GetBandwidth( void )
|
|
{
|
|
return m_bandwidth;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::IsOnline( void )
|
|
{
|
|
#ifdef __PLAT_NGPS__
|
|
if( ( GetConnectionType() == vCONN_TYPE_MODEM ) ||
|
|
( GetConnectionType() == vCONN_TYPE_PPPOE ))
|
|
{
|
|
int modem_state;
|
|
|
|
m_online = false;
|
|
if( snmdm_get_state( &modem_state ) == 0 )
|
|
{
|
|
if( modem_state == SN_MODEM_PPP_UP )
|
|
{
|
|
m_online = true;
|
|
}
|
|
}
|
|
}
|
|
#endif// __PLAT_NGPS__
|
|
|
|
return m_online;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetISPPhoneNumber( char* phone_no )
|
|
{
|
|
|
|
|
|
Dbg_Assert( phone_no );
|
|
|
|
strcpy( m_isp_phone_no, phone_no );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetISPLogin( char* login )
|
|
{
|
|
|
|
|
|
Dbg_Assert( login );
|
|
|
|
strcpy( m_isp_user_name, login );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetISPPassword( char* password )
|
|
{
|
|
|
|
|
|
Dbg_Assert( password );
|
|
|
|
strcpy( m_isp_password, password );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetGateway( char* ip )
|
|
{
|
|
|
|
|
|
if( strcmp( ip, m_gateway ))
|
|
{
|
|
strcpy( m_gateway, ip );
|
|
#ifdef __PLAT_NGPS__
|
|
m_options_changed = true;
|
|
#endif // __PLAT_NGC__
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetSubnetMask( char* ip )
|
|
{
|
|
|
|
|
|
if( strcmp( ip, m_subnet ))
|
|
{
|
|
strcpy( m_subnet, ip );
|
|
#ifdef __PLAT_NGPS__
|
|
m_options_changed = true;
|
|
#endif // __PLAT_NGC__
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetPublicIP( unsigned int ip )
|
|
{
|
|
m_public_ip = ip;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetLocalIP( char* ip )
|
|
{
|
|
|
|
|
|
if( strcmp( ip, m_local_ip ))
|
|
{
|
|
strcpy( m_local_ip, ip );
|
|
#ifdef __PLAT_NGPS__
|
|
m_options_changed = true;
|
|
#endif // __PLAT_NGC__
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetConnectionType( ConnType conn_type )
|
|
{
|
|
if( m_conn_type != conn_type )
|
|
{
|
|
#ifdef __PLAT_NGPS__
|
|
if( m_conn_type != vCONN_TYPE_NONE )
|
|
{
|
|
m_device_changed = true;
|
|
}
|
|
#endif // __PLAT_NGC__
|
|
m_conn_type = conn_type;
|
|
|
|
// Some default values for bandwidth limiting
|
|
switch( m_conn_type )
|
|
{
|
|
case vCONN_TYPE_MODEM:
|
|
SetBandwidth( 4200 );
|
|
break;
|
|
case vCONN_TYPE_ETHERNET:
|
|
SetBandwidth( 400000 );
|
|
break;
|
|
case vCONN_TYPE_PPPOE:
|
|
SetBandwidth( 300000 );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetDeviceType( DeviceType dev_type )
|
|
{
|
|
if( m_device_type != dev_type )
|
|
{
|
|
#ifdef __PLAT_NGPS__
|
|
if( m_device_type != vDEV_TYPE_NONE )
|
|
{
|
|
m_device_changed = true;
|
|
}
|
|
#endif // __PLAT_NGC__
|
|
m_device_type = dev_type;
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetDHCP( bool use_dhcp )
|
|
{
|
|
if( m_use_dhcp != use_dhcp )
|
|
{
|
|
m_use_dhcp = use_dhcp;
|
|
#ifdef __PLAT_NGPS__
|
|
m_options_changed = true;
|
|
#endif // __PLAT_NGC__
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetDialupAuthentication( bool authenticate )
|
|
{
|
|
m_use_dialup_auth = authenticate;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetDNSServer( int index, char* ip )
|
|
{
|
|
|
|
|
|
Dbg_Assert(( index >= 0 ) && ( index < 3 ));
|
|
Dbg_Assert( ip );
|
|
|
|
if( strcmp( ip, m_dns_servers[index] ))
|
|
{
|
|
strcpy( m_dns_servers[index], ip );
|
|
#ifdef __PLAT_NGPS__
|
|
m_options_changed = true;
|
|
#endif // __PLAT_NGC__
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetHostName( char* host )
|
|
{
|
|
|
|
|
|
// Either they pass us NULL or they pass us a value less than 32 chars long
|
|
Dbg_Assert( !host || ( strlen( host ) < 32 ));
|
|
|
|
if( host == NULL )
|
|
{
|
|
m_host_name[0] = '\0';
|
|
}
|
|
|
|
strcpy( m_host_name, host );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetDomainName( char* domain )
|
|
{
|
|
|
|
|
|
// Either they pass us NULL or they pass us a value less than 32 chars long
|
|
Dbg_Assert( !domain || ( strlen( domain ) < 32 ));
|
|
|
|
if( domain == NULL )
|
|
{
|
|
m_domain_name[0] = '\0';
|
|
}
|
|
|
|
strcpy( m_domain_name, domain );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char* Manager::GetDNSServer( int index )
|
|
{
|
|
|
|
|
|
Dbg_Assert(( index >= 0 ) && ( index < 3 ));
|
|
|
|
return m_dns_servers[index];
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char* Manager::GetISPPhoneNumber( void )
|
|
{
|
|
if( GetConnectionType() == vCONN_TYPE_PPPOE )
|
|
{
|
|
return "";
|
|
}
|
|
return m_isp_phone_no;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::ShouldUseDHCP( void )
|
|
{
|
|
if(( GetConnectionType() == vCONN_TYPE_PPPOE ) ||
|
|
( GetConnectionType() == vCONN_TYPE_MODEM ))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return m_use_dhcp;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::ShouldUseDialupAuthentication( void )
|
|
{
|
|
if( GetConnectionType() == vCONN_TYPE_PPPOE )
|
|
{
|
|
return true;
|
|
}
|
|
return m_use_dialup_auth;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char* Manager::GetGateway( void )
|
|
{
|
|
|
|
|
|
return m_gateway;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char* Manager::GetSubnetMask( void )
|
|
{
|
|
|
|
|
|
return m_subnet;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char* Manager::GetHostName( void )
|
|
{
|
|
|
|
|
|
return m_host_name;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char* Manager::GetDomainName( void )
|
|
{
|
|
|
|
|
|
return m_domain_name;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
unsigned int Manager::GetPublicIP( void )
|
|
{
|
|
if( m_public_ip == 0 )
|
|
{
|
|
return inet_addr( m_local_ip );
|
|
}
|
|
|
|
return m_public_ip;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char* Manager::GetLocalIP( void )
|
|
{
|
|
|
|
|
|
#if defined( __PLAT_NGPS__ ) || defined( __PLAT_XBOX__ ) || defined( __PLAT_NGC__ )
|
|
return m_local_ip;
|
|
#else
|
|
struct hostent *host, *local_host;
|
|
struct in_addr address;
|
|
char *ip_str;
|
|
int ip;
|
|
|
|
if(( local_host = gethostbyname( "localhost" )))
|
|
{
|
|
if(( host = gethostbyname( local_host->h_name )))
|
|
{
|
|
ip = *(unsigned long *) host->h_addr_list[0];
|
|
address.s_addr = ip;
|
|
ip_str = inet_ntoa( address );
|
|
return ip_str;
|
|
}
|
|
else
|
|
{
|
|
ip = *(unsigned long *) local_host->h_addr_list[0];
|
|
address.s_addr = ip;
|
|
ip_str = inet_ntoa( address );
|
|
return ip_str;
|
|
}
|
|
}
|
|
|
|
return "<Unknown>";
|
|
#endif
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
ConnType Manager::GetConnectionType( void )
|
|
{
|
|
return m_conn_type;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
DeviceType Manager::GetDeviceType( void )
|
|
{
|
|
#ifdef __PLAT_XBOX__
|
|
return vDEV_TYPE_USB_ETHERNET;
|
|
#else
|
|
return m_device_type;
|
|
#endif
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetError( int error )
|
|
{
|
|
m_last_error = error;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Manager::GetLastError( void )
|
|
{
|
|
return m_last_error;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Get the name associated with a message id */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char* Manager::GetMessageName( unsigned char msg_id )
|
|
{
|
|
#ifdef NET_DEBUG_MESSAGES
|
|
return m_message_names[ msg_id ];
|
|
#else
|
|
return "<Disabled>";
|
|
#endif
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Associate a text name with a message id for debugging purposes */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetMessageName( unsigned char msg_id, char* msg_name )
|
|
{
|
|
#ifdef NET_DEBUG_MESSAGES
|
|
Dbg_Assert( msg_name );
|
|
|
|
strncpy( m_message_names[ msg_id ], msg_name, vMAX_MSG_NAME_LEN - 1 );
|
|
m_message_names[msg_id][vMAX_MSG_NAME_LEN - 1] = '\0';
|
|
#endif
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
char Manager::GetMessageFlags( unsigned char msg_id )
|
|
{
|
|
return m_message_flags[ msg_id ];
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetMessageFlags( unsigned char msg_id, char flags )
|
|
{
|
|
m_message_flags[ msg_id ] = flags;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Manager::GetModemState( void )
|
|
{
|
|
return m_modem_state;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void Manager::SetModemState( int state )
|
|
{
|
|
m_modem_state = state;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int Manager::GetModemError( void )
|
|
{
|
|
return m_modem_err;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
bool Manager::CanChangeDevices( void )
|
|
{
|
|
#ifdef __PLAT_NGPS__
|
|
return !m_net_drivers_loaded;
|
|
#else
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
MsgLink::MsgLink( QueuedMsg *msg )
|
|
: Lst::Node< MsgLink > ( this ), m_QMsg( msg ), m_SendTime( 0 )
|
|
{
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
MsgImpLink::MsgImpLink( QueuedMsg *msg )
|
|
: Lst::Node< MsgImpLink > ( this ), m_QMsg( msg ), m_SendTime( 0 )
|
|
{
|
|
m_NumResends = 0;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
MsgSeqLink::MsgSeqLink( QueuedMsgSeq *msg )
|
|
: Lst::Node< MsgSeqLink > ( this ), m_StreamMessage( 0 ), m_SendTime( 0 ), m_QMsg( msg )
|
|
{
|
|
m_NumResends = 0;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
StreamLink::StreamLink( StreamDesc* desc )
|
|
: Lst::Node< StreamLink > ( this ), m_Desc ( desc )
|
|
{
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
StreamDesc::StreamDesc( void )
|
|
: m_Size( 0 ), m_Data( NULL ), m_DataPtr( NULL ), m_GroupId( 0 ), m_SendInPlace( false )
|
|
{
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
StreamDesc::~StreamDesc( void )
|
|
{
|
|
if( m_Data && !m_SendInPlace )
|
|
{
|
|
delete [] m_Data;
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
MsgDesc::MsgDesc( void )
|
|
: m_Id( 0 ), m_StreamMessage( 0 ), m_Length( 0 ), m_Data( 0 ), m_Priority( NORMAL_PRIORITY ), m_Queue( QUEUE_DEFAULT ), m_GroupId( GROUP_ID_DEFAULT ),
|
|
m_Singular( false ), m_Delay( 0 ), m_ForcedSequenceId( 0 )
|
|
{
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
QueuedMsg::QueuedMsg( unsigned char msg_id, unsigned short msg_len, void* data )
|
|
{
|
|
|
|
|
|
m_Data = NULL;
|
|
if( msg_len > 0 )
|
|
{
|
|
m_Data = new char[ msg_len ];
|
|
memcpy( m_Data, data, msg_len );
|
|
}
|
|
|
|
m_MsgId = msg_id;
|
|
m_MsgLength = msg_len;
|
|
#ifdef __PLAT_NGPS__
|
|
Dbg_MsgAssert(Mem::SameContext(this,Mem::Manager::sHandle().NetworkHeap()),("QueuedMsg not on network heap"));
|
|
#endif // __PLAT_NGPS__
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
QueuedMsg::~QueuedMsg( void )
|
|
{
|
|
|
|
if( m_Data )
|
|
{
|
|
delete [] m_Data;
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
QueuedMsgSeq::QueuedMsgSeq( unsigned char msg_id, unsigned short msg_len, void* data, unsigned char group_id )
|
|
{
|
|
|
|
|
|
m_Data = NULL;
|
|
if( msg_len > 0 )
|
|
{
|
|
m_Data = new char[ msg_len ];
|
|
memcpy( m_Data, data, msg_len );
|
|
}
|
|
|
|
m_MsgId = msg_id;
|
|
m_MsgLength = msg_len;
|
|
m_GroupId = group_id;
|
|
#ifdef __PLAT_NGPS__
|
|
Dbg_MsgAssert(Mem::SameContext(this,Mem::Manager::sHandle().NetworkHeap()),("QueuedMsgSeq not on network heap"));
|
|
#endif // __PLAT_NGPS__
|
|
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
QueuedMsgSeq::~QueuedMsgSeq( void )
|
|
{
|
|
if( m_Data )
|
|
{
|
|
delete [] m_Data;
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
BitStream::BitStream( void )
|
|
{
|
|
m_data = NULL;
|
|
m_bits_left = 32;
|
|
m_size = 0;
|
|
m_cur_val = 0;
|
|
m_bits_processed = 0;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void BitStream::SetInputData( char* data, int size )
|
|
{
|
|
m_data = (unsigned int*) data;
|
|
m_start_data = m_data;
|
|
m_size = size;
|
|
m_bits_left = 0;
|
|
m_bits_processed = 0;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void BitStream::SetOutputData( char* data, int size )
|
|
{
|
|
m_data = (unsigned int*) data;
|
|
m_start_data = m_data;
|
|
m_size = size;
|
|
m_bits_left = 32;
|
|
m_bits_processed = 0;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int BitStream::GetByteLength( void )
|
|
{
|
|
return (( m_bits_processed + 7 ) >> 3 );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void BitStream::WriteValue( int value, int num_bits )
|
|
{
|
|
m_bits_processed += num_bits;
|
|
|
|
// If we cannot fit all bits into our current int, we'll have to span it over
|
|
// two ints
|
|
if( m_bits_left < num_bits )
|
|
{
|
|
// Write out the first portion, then advance to the next int
|
|
|
|
// First clear all top (unwritten) bits
|
|
m_cur_val &= ( 1 << ( 32 - m_bits_left )) - 1;
|
|
|
|
// Now write them (without having to mask low bits off)
|
|
m_cur_val |= value << ( 32 - m_bits_left );
|
|
num_bits -= m_bits_left;
|
|
value >>= m_bits_left;
|
|
memcpy( m_data, &m_cur_val, sizeof( unsigned int ));
|
|
m_data++;
|
|
m_cur_val = 0;
|
|
m_bits_left = 32;
|
|
}
|
|
|
|
// First clear all top (unwritten) bits
|
|
m_cur_val &= ( 1 << ( 32 - m_bits_left )) - 1;
|
|
// Now write them (without having to mask low bits off)
|
|
m_cur_val |= value << ( 32 - m_bits_left );
|
|
m_bits_left -= num_bits;
|
|
|
|
// Flush bits if full
|
|
if( m_bits_left == 0 )
|
|
{
|
|
memcpy((char*) m_data, (char*) &m_cur_val, sizeof( unsigned int ));
|
|
m_data++;
|
|
m_cur_val = 0;
|
|
m_bits_left = 32;
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void BitStream::WriteFloatValue( float value )
|
|
{
|
|
WriteValue( *(int*) &value, sizeof( float ) * 8 );
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void BitStream::Flush( void )
|
|
{
|
|
// Only flush if we have bits to flush
|
|
if( m_bits_left != 32)
|
|
{
|
|
memcpy( m_data, &m_cur_val, sizeof( unsigned int ));
|
|
m_data++;
|
|
m_cur_val = 0;
|
|
m_bits_left = 32;
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
float BitStream::ReadFloatValue( void )
|
|
{
|
|
float res;
|
|
int num_bits;
|
|
|
|
num_bits = 32;
|
|
m_bits_processed += num_bits;
|
|
|
|
// If we're all out of bits (like at start), read a full word
|
|
if( m_bits_left == 0 )
|
|
{
|
|
memcpy( &m_cur_val, m_data, sizeof( unsigned int ));
|
|
m_data++;
|
|
m_bits_left = 32;
|
|
}
|
|
|
|
// Do we hold all bits requested?
|
|
if( m_bits_left >= num_bits )
|
|
{
|
|
// Yes, easy peasy case
|
|
m_bits_left -= num_bits;
|
|
if( num_bits == 32 )
|
|
{
|
|
memcpy( &res, &m_cur_val, sizeof( float ));
|
|
}
|
|
else
|
|
{
|
|
unsigned int int_val;
|
|
|
|
int_val = m_cur_val & ((1 << num_bits) - 1);
|
|
memcpy( &res, &int_val, sizeof( float ));
|
|
}
|
|
|
|
m_cur_val >>= num_bits;
|
|
}
|
|
else
|
|
{
|
|
unsigned int int_val;
|
|
// Nope, grab those we have and fetch more from stream
|
|
|
|
int_val = m_cur_val & (( 1 << m_bits_left ) - 1);
|
|
num_bits -= m_bits_left;
|
|
memcpy( &m_cur_val, m_data, sizeof( unsigned int ));
|
|
m_data++;
|
|
int_val |= ( m_cur_val & (( 1 << num_bits ) - 1)) << m_bits_left;
|
|
m_cur_val >>= num_bits;
|
|
m_bits_left = 32 - num_bits;
|
|
|
|
memcpy( &res, &int_val, sizeof( float ));
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
unsigned int BitStream::ReadUnsignedValue( int num_bits )
|
|
{
|
|
unsigned long res;
|
|
|
|
Dbg_Assert(( num_bits >= 0 ) && ( num_bits <= 32 ));
|
|
|
|
m_bits_processed += num_bits;
|
|
|
|
// If we're all out of bits (like at start), read a full word
|
|
if( m_bits_left == 0 )
|
|
{
|
|
memcpy( &m_cur_val, m_data, sizeof( unsigned int ));
|
|
m_data++;
|
|
m_bits_left = 32;
|
|
}
|
|
|
|
// Do we hold all bits requested?
|
|
if( m_bits_left >= num_bits )
|
|
{
|
|
// Yes, easy peasy case
|
|
m_bits_left -= num_bits;
|
|
if( num_bits == 32 )
|
|
{
|
|
res = m_cur_val;
|
|
}
|
|
else
|
|
{
|
|
res = m_cur_val & ((1 << num_bits) - 1);
|
|
}
|
|
|
|
m_cur_val >>= num_bits;
|
|
}
|
|
else
|
|
{
|
|
// Nope, grab those we have and fetch more from stream
|
|
res = m_cur_val & (( 1 << m_bits_left ) - 1);
|
|
num_bits -= m_bits_left;
|
|
memcpy( &m_cur_val, m_data, sizeof( unsigned int ));
|
|
m_data++;
|
|
res |= ( m_cur_val & (( 1 << num_bits ) - 1)) << m_bits_left;
|
|
m_cur_val >>= num_bits;
|
|
m_bits_left = 32 - num_bits;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
int BitStream::ReadSignedValue( int num_bits )
|
|
{
|
|
long res;
|
|
|
|
Dbg_Assert(( num_bits >= 0 ) && ( num_bits <= 32 ));
|
|
|
|
// Cheasy call to that other function for simplicity
|
|
res = ReadUnsignedValue( num_bits );
|
|
|
|
// Sign extend result if sign bit set
|
|
if( res & ( 1 << ( num_bits - 1 )))
|
|
{
|
|
res |= ~(( 1 << num_bits ) - 1 );
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
} // namespace Net
|