mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
DirtySDK (EA's Dirty Sockets library) will be used for the LiveAPI implementation, and depends on: EABase, EAThread.
896 lines
26 KiB
C
896 lines
26 KiB
C
/*H********************************************************************************/
|
|
/*!
|
|
\File netconnunix.c
|
|
|
|
\Description
|
|
Provides network setup and teardown support. Does not actually create any
|
|
kind of network connections.
|
|
|
|
\Copyright
|
|
Copyright (c) 2010 Electronic Arts Inc.
|
|
|
|
\Version 04/05/2010 (jbrookes) First version; a vanilla port to Unix from PS3
|
|
*/
|
|
/********************************************************************************H*/
|
|
|
|
|
|
/*** Include files ****************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "DirtySDK/dirtysock.h"
|
|
#include "DirtySDK/dirtyvers.h"
|
|
#include "DirtySDK/dirtysock/dirtyerr.h"
|
|
#include "DirtySDK/dirtysock/dirtymem.h"
|
|
#include "DirtySDK/dirtysock/dirtycert.h"
|
|
#include "DirtySDK/dirtysock/netconn.h"
|
|
#include "DirtySDK/proto/protossl.h"
|
|
#include "DirtySDK/proto/protoupnp.h"
|
|
#include "netconncommon.h"
|
|
|
|
#ifdef DIRTYCODE_APPLEIOS
|
|
|
|
#include "DirtySDK/dirtysock/iphone/netconnios.h"
|
|
|
|
#endif
|
|
|
|
/*** Defines **********************************************************************/
|
|
|
|
//! UPNP port
|
|
#define NETCONN_DEFAULT_UPNP_PORT (3659)
|
|
|
|
/*** Macros ***********************************************************************/
|
|
|
|
/*** Type Definitions *************************************************************/
|
|
|
|
//! private module state
|
|
typedef struct NetConnRefT
|
|
{
|
|
NetConnCommonRefT Common; //!< cross-platform netconn data (must come first!)
|
|
|
|
enum
|
|
{
|
|
ST_INIT, //!< initialization
|
|
ST_CONN, //!< bringing up network interface
|
|
ST_IDLE, //!< active
|
|
} eState; //!< internal connection state
|
|
|
|
uint32_t uConnStatus; //!< connection status (surfaced to user)
|
|
|
|
ProtoUpnpRefT *pProtoUpnp; //!< protoupnp module state
|
|
int32_t iPeerPort; //!< peer port to be opened by upnp; if zero, still find upnp router but don't open a port
|
|
int32_t iNumProcCores; //!< number of processor cores on the system
|
|
int32_t iThreadCpuAffinity; //!< cpu affinity used for our internal threads
|
|
} NetConnRefT;
|
|
|
|
/*** Function Prototypes **********************************************************/
|
|
|
|
/*** Variables ********************************************************************/
|
|
|
|
//! global module ref
|
|
static NetConnRefT *_NetConn_pRef = NULL;
|
|
|
|
/*** Private Functions ************************************************************/
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetConnUpdateConnStatus
|
|
|
|
\Description
|
|
Update the Connection Status and provide logging of status changes
|
|
|
|
\Input *pRef - pointer to net NetConn module ref
|
|
\Input *uNewConnStatus - the new conn status
|
|
|
|
\Version 01/19/2015 (tcho)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static void _NetConnUpdateConnStatus(NetConnRefT *pRef, uint32_t uNewConnStatus)
|
|
{
|
|
#if DIRTYCODE_LOGGING
|
|
int32_t iIndex;
|
|
char strConnStatus[5];
|
|
|
|
for (iIndex = 0; iIndex < 4; ++iIndex)
|
|
{
|
|
strConnStatus[iIndex] = ((char *) &uNewConnStatus)[3 - iIndex];
|
|
}
|
|
|
|
strConnStatus[4] = 0;
|
|
|
|
NetPrintf(("netconnunix: netconn status changed to %s\n", strConnStatus));
|
|
#endif
|
|
|
|
pRef->uConnStatus = uNewConnStatus;
|
|
}
|
|
|
|
#if defined(DIRTYCODE_LINUX)
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetConnGetProcLine
|
|
|
|
\Description
|
|
Parse a single line of the processor entry file.
|
|
|
|
\Input *pLine - pointer to line to parse
|
|
\Input *pName - [out] buffer to store parsed field name
|
|
\Input iNameLen - size of name buffer
|
|
\Input *pData - [out] buffer to store parsed field data
|
|
\Input iDataLen - size of data buffer
|
|
|
|
\Version 04/26/2010 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static void _NetConnGetProcLine(const char *pLine, char *pName, int32_t iNameLen, char *pData, int32_t iDataLen)
|
|
{
|
|
const char *pParse;
|
|
|
|
// skip to end of field name
|
|
for (pParse = pLine; (*pParse != '\t') && (*pParse != ':'); pParse += 1)
|
|
;
|
|
|
|
// copy field name
|
|
ds_strsubzcpy(pName, iNameLen, pLine, pParse - pLine);
|
|
|
|
// skip to field value
|
|
for ( ; (*pParse == ' ') || (*pParse == '\t') || (*pParse == ':'); pParse += 1)
|
|
;
|
|
|
|
// find end of field value
|
|
for (pLine = pParse; (*pParse != '\n') && (*pParse != '\0'); pParse += 1)
|
|
;
|
|
|
|
// copy field value
|
|
ds_strsubzcpy(pData, iDataLen, pLine, pParse - pLine);
|
|
}
|
|
#endif
|
|
|
|
#if defined(DIRTYCODE_LINUX)
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetConnGetProcRecord
|
|
|
|
\Description
|
|
Parse a single proc record.
|
|
|
|
\Input *pProcFile - proc record file pointer
|
|
|
|
\Output
|
|
int32_t - one=success, zero=no more entries
|
|
|
|
\Version 04/26/2010 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static int32_t _NetConnGetProcRecord(FILE *pProcFile)
|
|
{
|
|
char strBuf[1024], strName[32], strValue[128], *pLine;
|
|
while (((pLine = fgets(strBuf, sizeof(strBuf), pProcFile)) != NULL) && (strBuf[0] != '\n'))
|
|
{
|
|
_NetConnGetProcLine(strBuf, strName, sizeof(strName), strValue, sizeof(strValue));
|
|
}
|
|
return(pLine != NULL);
|
|
}
|
|
#endif
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetConnGetNumProcs
|
|
|
|
\Description
|
|
Get the number of processors on the system.
|
|
|
|
\Output
|
|
int32_t - number of processors in system, or <=0 on failure
|
|
|
|
\Version 04/26/2010 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static int32_t _NetConnGetNumProcs(void)
|
|
{
|
|
#if defined(DIRTYCODE_LINUX)
|
|
FILE *pFile = fopen("/proc/cpuinfo", "r");
|
|
int32_t iNumProcs = -1;
|
|
|
|
if (pFile != NULL)
|
|
{
|
|
for (iNumProcs = 0; _NetConnGetProcRecord(pFile) != 0; iNumProcs += 1)
|
|
;
|
|
fclose(pFile);
|
|
|
|
NetPrintf(("netconnunix: parsed %d processor cores from cpuinfo\n", iNumProcs));
|
|
}
|
|
else
|
|
{
|
|
NetPrintf(("netconnunix: could not open proc file\n"));
|
|
}
|
|
return(iNumProcs);
|
|
#else
|
|
return(-1);
|
|
#endif
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetConnGetInterfaceType
|
|
|
|
\Description
|
|
Get interface type and return it to caller.
|
|
|
|
\Input *pRef - module state
|
|
|
|
\Output
|
|
uint32_t - interface type bitfield (NETCONN_IFTYPE_*)
|
|
|
|
\Version 10/08/2009 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static uint32_t _NetConnGetInterfaceType(NetConnRefT *pRef)
|
|
{
|
|
uint32_t uIfType = NETCONN_IFTYPE_ETHER;
|
|
|
|
#if defined(DIRTYCODE_ANDROID)
|
|
|
|
uIfType = NETCONN_IFTYPE_NONE;
|
|
|
|
if (SocketInfo(NULL, 'eth0', 0, NULL, 0) == 0)
|
|
{
|
|
uIfType = NETCONN_IFTYPE_WIRELESS;
|
|
}
|
|
|
|
if (SocketInfo(NULL, 'wan0', 0, NULL, 0) == 0)
|
|
{
|
|
uIfType = NETCONN_IFTYPE_CELL;
|
|
}
|
|
|
|
#elif defined(DIRTYCODE_APPLEIOS)
|
|
|
|
uIfType = NetConnStatusIos(&(_NetConn_pRef->Common), 'type', 0, NULL, 0);
|
|
|
|
#endif
|
|
|
|
return(uIfType);
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetConnUpdate
|
|
|
|
\Description
|
|
Update status of NetConn module. This function is called by NetConnIdle.
|
|
|
|
\Input *pData - pointer to NetConn module ref
|
|
\Input uTick - current tick counter
|
|
|
|
\Version 07/18/2006 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static void _NetConnUpdate(void *pData, uint32_t uTick)
|
|
{
|
|
NetConnRefT *pRef = (NetConnRefT *)pData;
|
|
|
|
// perform idle processing
|
|
SocketControl(NULL, 'idle', uTick, NULL, NULL);
|
|
|
|
// wait for network active status
|
|
if (pRef->eState == ST_CONN)
|
|
{
|
|
uint32_t uSocketConnStatus = SocketInfo(NULL, 'conn', 0, NULL, 0);
|
|
|
|
if (pRef->uConnStatus != uSocketConnStatus)
|
|
{
|
|
_NetConnUpdateConnStatus(pRef, uSocketConnStatus);
|
|
}
|
|
|
|
if (pRef->uConnStatus == '+onl')
|
|
{
|
|
// discover upnp router information
|
|
if (pRef->pProtoUpnp != NULL)
|
|
{
|
|
if (pRef->iPeerPort != 0)
|
|
{
|
|
ProtoUpnpControl(pRef->pProtoUpnp, 'port', pRef->iPeerPort, 0, NULL);
|
|
ProtoUpnpControl(pRef->pProtoUpnp, 'macr', 'upnp', 0, NULL);
|
|
}
|
|
else
|
|
{
|
|
ProtoUpnpControl(pRef->pProtoUpnp, 'macr', 'dscg', 0, NULL);
|
|
}
|
|
}
|
|
|
|
pRef->eState = ST_IDLE;
|
|
}
|
|
}
|
|
|
|
// update connection status while idle
|
|
if (pRef->eState == ST_IDLE)
|
|
{
|
|
// update connection status if not already in an error state
|
|
if ((pRef->uConnStatus >> 24) != '-')
|
|
{
|
|
uint32_t uSocketConnStat = SocketInfo(NULL, 'conn', 0, NULL, 0);
|
|
|
|
if (pRef->uConnStatus != uSocketConnStat)
|
|
{
|
|
_NetConnUpdateConnStatus(pRef, uSocketConnStat);
|
|
}
|
|
}
|
|
}
|
|
|
|
// if error status, go to idle state from any other state
|
|
if ((pRef->eState != ST_IDLE) && (pRef->uConnStatus >> 24 == '-'))
|
|
{
|
|
pRef->eState = ST_IDLE;
|
|
}
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetConnShutdownInternal
|
|
|
|
\Description
|
|
Shutdown the network code and return to idle state for internal use
|
|
|
|
\Input pRef - netconn ref
|
|
\Input uShutdownFlags - shutdown configuration flags
|
|
|
|
\Output
|
|
int32_t - negative=error, else zero
|
|
|
|
\Version 1/13/2020 (tcho)
|
|
*/
|
|
/********************************************************************************F*/
|
|
int32_t _NetConnShutdownInternal(NetConnRefT *pRef, uint32_t uShutdownFlags)
|
|
{
|
|
int32_t iResult = 0;
|
|
|
|
// decrement and check the refcount
|
|
if ((iResult = NetConnCommonCheckRef((NetConnCommonRefT*)pRef)) < 0)
|
|
{
|
|
return(iResult);
|
|
}
|
|
|
|
if (_NetConn_pRef != NULL)
|
|
{
|
|
// disconnect network interfaces
|
|
NetConnDisconnect();
|
|
}
|
|
|
|
// destroy the upnp ref
|
|
if (pRef->pProtoUpnp != NULL)
|
|
{
|
|
ProtoUpnpDestroy(pRef->pProtoUpnp);
|
|
pRef->pProtoUpnp = NULL;
|
|
}
|
|
|
|
// destroy the dirtycert module
|
|
DirtyCertDestroy();
|
|
|
|
// shut down protossl
|
|
ProtoSSLShutdown();
|
|
|
|
// remove netconn idle task
|
|
NetConnIdleDel(_NetConnUpdate, pRef);
|
|
|
|
// shut down Idle handler
|
|
NetConnIdleShutdown();
|
|
|
|
// shutdown the network code
|
|
SocketDestroy(0);
|
|
|
|
#ifdef DIRTYCODE_APPLEIOS
|
|
|
|
//call ios NetConnShutdown
|
|
NetConnShutdownIos(uShutdownFlags);
|
|
|
|
#endif
|
|
|
|
// common shutdown (must come last as this frees the memory)
|
|
NetConnCommonShutdown(&pRef->Common);
|
|
_NetConn_pRef = NULL;
|
|
|
|
return(0);
|
|
}
|
|
|
|
/*** Public functions *************************************************************/
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetConnStartup
|
|
|
|
\Description
|
|
Bring the network connection module to life. Creates connection with IOP
|
|
resources and gets things ready to go. Puts all device drivers into "probe"
|
|
mode so they look for appropriate hardware. Does not actually start any
|
|
network activity.
|
|
|
|
\Input *pParams - startup parameters
|
|
|
|
\Output
|
|
int32_t - zero=success, negative=failure
|
|
|
|
\Notes
|
|
NetConnRefT::iRefCount serves as a counter for the number of times
|
|
NetConnStartup has been called. This allows us to track how many modules
|
|
are using it and how many times we expect NetConnShutdown to the called.
|
|
In the past we only allowed a single call to NetConnStartup but some
|
|
libraries may need to networking without a guarentee that the game has
|
|
already started it.
|
|
|
|
pParams can contain the following terms:
|
|
|
|
\verbatim
|
|
-noupnp - disable upnp support
|
|
-servicename - set servicename <game-year-platform> required for SSL use
|
|
-singlethreaded - start DirtySock in single-threaded mode (typically when used in servers)
|
|
-affinity=<mask as hex> - the cpu affinity for our internal threads
|
|
\endverbatim
|
|
|
|
\Version 10/04/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
int32_t NetConnStartup(const char *pParams)
|
|
{
|
|
NetConnRefT *pRef = _NetConn_pRef;
|
|
int32_t iThreadPrio = 10;
|
|
int32_t iRet = 0;
|
|
int32_t iResult = 0;
|
|
char strThreadCpuAffinity[16];
|
|
|
|
// allow NULL params
|
|
if (pParams == NULL)
|
|
{
|
|
pParams = "";
|
|
}
|
|
|
|
// debug display of input params
|
|
NetPrintf(("netconnunix: startup params='%s'\n", pParams));
|
|
|
|
// common startup
|
|
// pRef shall hold the address of the NetConnRefT after completion if no error occured
|
|
iResult = NetConnCommonStartup(sizeof(*pRef), pParams, (NetConnCommonRefT**)(&pRef));
|
|
|
|
// treat the result of the common startup, if already started simply early out
|
|
if (iResult == NETCONN_ERROR_ALREADY_STARTED)
|
|
{
|
|
return(0);
|
|
}
|
|
// otherwise, if an error occured report it
|
|
else if (iResult < 0)
|
|
{
|
|
return(iResult);
|
|
}
|
|
|
|
pRef->eState = ST_INIT;
|
|
pRef->iPeerPort = NETCONN_DEFAULT_UPNP_PORT;
|
|
|
|
// check for singlethreaded mode
|
|
if (strstr(pParams, "-singlethreaded"))
|
|
{
|
|
iThreadPrio = -1;
|
|
}
|
|
|
|
// get the thread cpu affinity setting from our startup params, defaulting to 0x0
|
|
ds_memclr(strThreadCpuAffinity, sizeof(strThreadCpuAffinity));
|
|
NetConnCopyParam(strThreadCpuAffinity, sizeof(strThreadCpuAffinity), "-affinity=", pParams, "0x0");
|
|
pRef->iThreadCpuAffinity =(int32_t) strtol(strThreadCpuAffinity, NULL, 16);
|
|
|
|
// create network instance
|
|
if (SocketCreate(iThreadPrio, 0, pRef->iThreadCpuAffinity) != 0)
|
|
{
|
|
NetPrintf(("netconnunix: unable to start up dirtysock\n"));
|
|
_NetConnShutdownInternal(pRef, 0);
|
|
return(NETCONN_ERROR_SOCKET_CREATE);
|
|
}
|
|
|
|
// create and configure dirtycert
|
|
if (NetConnDirtyCertCreate(pParams))
|
|
{
|
|
_NetConnShutdownInternal(pRef, 0);
|
|
NetPrintf(("netconnunix: unable to create dirtycert\n"));
|
|
return(NETCONN_ERROR_DIRTYCERT_CREATE);
|
|
}
|
|
|
|
// start up protossl
|
|
if (ProtoSSLStartup() < 0)
|
|
{
|
|
_NetConnShutdownInternal(pRef, 0);
|
|
NetPrintf(("netconnunix: unable to start up protossl\n"));
|
|
return(NETCONN_ERROR_PROTOSSL_CREATE);
|
|
}
|
|
|
|
// create the upnp module
|
|
if (!strstr(pParams, "-noupnp"))
|
|
{
|
|
pRef->pProtoUpnp = ProtoUpnpCreate();
|
|
if (pRef->pProtoUpnp == NULL)
|
|
{
|
|
_NetConnShutdownInternal(pRef, 0);
|
|
NetPrintf(("netconnunix: unable to start up protoupnp\n"));
|
|
return(NETCONN_ERROR_PROTOUPNP_CREATE);
|
|
}
|
|
}
|
|
|
|
// add netconn task handle
|
|
if (NetConnIdleAdd(_NetConnUpdate, pRef) < 0)
|
|
{
|
|
_NetConnShutdownInternal(pRef, 0);
|
|
NetPrintf(("netconnunix: unable to add netconn task handler\n"));
|
|
return(NETCONN_ERROR_INTERNAL);
|
|
}
|
|
|
|
#ifdef DIRTYCODE_APPLEIOS
|
|
//call ios netconn startup
|
|
if ((iRet = NetConnStartupIos(pParams)) < 0)
|
|
{
|
|
_NetConnShutdownInternal(pRef, 0);
|
|
return(iRet);
|
|
}
|
|
#endif
|
|
|
|
// save ref
|
|
_NetConn_pRef = pRef;
|
|
|
|
return(iRet);
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetConnQuery
|
|
|
|
\Description
|
|
Query the list of available connection configurations. This list is loaded
|
|
from the specified device. The list is returned in a simple fixed width
|
|
array with one string per array element. The caller can find the user portion
|
|
of the config name via strchr(item, '#')+1.
|
|
|
|
\Input *pDevice - device to scan (mc0:, mc1:, pfs0:, pfs1:)
|
|
\Input *pList - buffer to store output array in
|
|
\Input iSize - length of buffer in bytes
|
|
|
|
\Output
|
|
int32_t - negative=error, else number of configurations
|
|
|
|
\Version 10/04/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
int32_t NetConnQuery(const char *pDevice, NetConfigRecT *pList, int32_t iSize)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetConnConnect
|
|
|
|
\Description
|
|
Used to bring the networking online with a specific configuration. Uses a
|
|
configuration returned by NetConnQuery.
|
|
|
|
\Input *pConfig - unused
|
|
\Input *pOption - asciiz list of config parameters
|
|
"peerport=<port>" to specify peer port to be opened by upnp.
|
|
\Input iData - platform-specific
|
|
|
|
\Output
|
|
int32_t - negative=error, zero=success
|
|
|
|
\Version 10/04/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
int32_t NetConnConnect(const NetConfigRecT *pConfig, const char *pOption, int32_t iData)
|
|
{
|
|
int32_t iResult = 0;
|
|
NetConnRefT *pRef = _NetConn_pRef;
|
|
|
|
// check connection options, if present
|
|
if (pRef->eState == ST_INIT)
|
|
{
|
|
// check for connect options
|
|
if (pOption != NULL)
|
|
{
|
|
const char *pOpt;
|
|
|
|
// check for specification of peer port
|
|
if ((pOpt = strstr(pOption, "peerport=")) != NULL)
|
|
{
|
|
pRef->iPeerPort = (int32_t)strtol(pOpt+9, NULL, 10);
|
|
}
|
|
}
|
|
NetPrintf(("netconnunix: upnp peerport=%d %s\n",
|
|
pRef->iPeerPort, (pRef->iPeerPort == NETCONN_DEFAULT_UPNP_PORT ? "(default)" : "(selected via netconnconnect param)")));
|
|
|
|
// start up network interface
|
|
SocketControl(NULL, 'conn', 0, NULL, NULL);
|
|
|
|
// transition to connecting state
|
|
pRef->eState = ST_CONN;
|
|
}
|
|
else
|
|
{
|
|
NetPrintf(("netconnunix: NetConnConnect() ignored because already connected!\n"));
|
|
}
|
|
return(iResult);
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetConnDisconnect
|
|
|
|
\Description
|
|
Used to bring down the network connection. After calling this, it would
|
|
be necessary to call NetConnConnect to bring the connection back up or
|
|
NetConnShutdown to completely shutdown all network support.
|
|
|
|
\Output
|
|
int32_t - negative=error, zero=success
|
|
|
|
\Version 10/04/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
int32_t NetConnDisconnect(void)
|
|
{
|
|
NetConnRefT *pRef = _NetConn_pRef;
|
|
|
|
// shut down networking
|
|
if (pRef->eState != ST_INIT)
|
|
{
|
|
// bring down network interface
|
|
SocketControl(NULL, 'disc', 0, NULL, NULL);
|
|
|
|
// reset status
|
|
pRef->eState = ST_INIT;
|
|
pRef->uConnStatus = 0;
|
|
}
|
|
|
|
// abort upnp operations
|
|
if (pRef->pProtoUpnp != NULL)
|
|
{
|
|
ProtoUpnpControl(pRef->pProtoUpnp, 'abrt', 0, 0, NULL);
|
|
}
|
|
|
|
// done
|
|
return(0);
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetConnControl
|
|
|
|
\Description
|
|
Set module behavior based on input selector.
|
|
|
|
\Input iControl - input selector
|
|
\Input iValue - selector input
|
|
\Input iValue2 - selector input
|
|
\Input *pValue - selector input
|
|
\Input *pValue2 - selector input
|
|
|
|
\Output
|
|
int32_t - selector result
|
|
|
|
\Notes
|
|
iControl can be one of the following:
|
|
|
|
\verbatim
|
|
snam: set DirtyCert service name
|
|
\endverbatim
|
|
|
|
Unhandled selectors are passed through to NetConnCommonControl()
|
|
|
|
\Version 1.0 04/27/2006 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
int32_t NetConnControl(int32_t iControl, int32_t iValue, int32_t iValue2, void *pValue, void *pValue2)
|
|
{
|
|
NetConnRefT *pRef = _NetConn_pRef;
|
|
|
|
// make sure module is started before allowing any other control calls
|
|
if (pRef == NULL)
|
|
{
|
|
NetPrintf(("netconnunix: warning - calling NetConnControl() while module is not initialized\n"));
|
|
return(-1);
|
|
}
|
|
|
|
// set dirtycert service name
|
|
if (iControl == 'snam')
|
|
{
|
|
return(DirtyCertControl('snam', 0, 0, pValue));
|
|
}
|
|
|
|
// pass through unhandled selectors to NetConnCommon
|
|
return(NetConnCommonControl(&pRef->Common, iControl, iValue, iValue2, pValue, pValue2));
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetConnStatus
|
|
|
|
\Description
|
|
Check general network connection status. Different selectors return
|
|
different status attributes.
|
|
|
|
\Input iKind - status selector ('open', 'conn', 'onln')
|
|
\Input iData - (optional) selector specific
|
|
\Input *pBuf - (optional) pointer to output buffer
|
|
\Input iBufSize - (optional) size of output buffer
|
|
|
|
\Output
|
|
int32_t - selector specific
|
|
|
|
\Notes
|
|
iKind can be one of the following:
|
|
|
|
\verbatim
|
|
addr: ip address of client
|
|
affn: thread cpu affinity setting
|
|
bbnd: TRUE if broadband, else FALSE
|
|
conn: connection status: +onl=online, ~<code>=in progress, -<err>=NETCONN_ERROR_*
|
|
hwid: (IOS only) This will return the vendor id in pBuf. pBuf must be at least 17 byte.
|
|
macx: MAC address of client (returned in pBuf)
|
|
ncon: returns the network connectivity level (iOS and Android Only)
|
|
onln: true/false indication of whether network is operational
|
|
open: true/false indication of whether network code running
|
|
proc: number of processor cores on the system (Linux only)
|
|
type: connection type: NETCONN_IFTYPE_* bitfield
|
|
upnp: return protoupnp external port info, if available
|
|
vers: return DirtySDK version
|
|
\endverbatim
|
|
|
|
Unhandled selectors are passed through to NetConnCommonStatus()
|
|
|
|
\Version 10/04/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
int32_t NetConnStatus(int32_t iKind, int32_t iData, void *pBuf, int32_t iBufSize)
|
|
{
|
|
NetConnRefT *pRef = _NetConn_pRef;
|
|
|
|
// initialize output buffer
|
|
if (pBuf != NULL)
|
|
{
|
|
ds_memclr(pBuf, iBufSize);
|
|
}
|
|
|
|
// see if network code is initialized
|
|
if (iKind == 'open')
|
|
{
|
|
return(pRef != NULL);
|
|
}
|
|
// return DirtySDK version
|
|
if (iKind == 'vers')
|
|
{
|
|
return(DIRTYSDK_VERSION);
|
|
}
|
|
|
|
// make sure module is started before allowing any other status calls
|
|
if (pRef == NULL)
|
|
{
|
|
NetPrintf(("netconnunix: warning - calling NetConnStatus() while module is not initialized\n"));
|
|
return(-1);
|
|
}
|
|
|
|
// return the thread cpu affinity setting
|
|
if (iKind == 'affn')
|
|
{
|
|
return(pRef->iThreadCpuAffinity);
|
|
}
|
|
|
|
// return broadband (TRUE/FALSE)
|
|
if (iKind == 'bbnd')
|
|
{
|
|
return(TRUE);
|
|
}
|
|
// connection status
|
|
if (iKind == 'conn')
|
|
{
|
|
return(pRef->uConnStatus);
|
|
}
|
|
// see if connected to ISP/LAN
|
|
if (iKind == 'onln')
|
|
{
|
|
return(pRef->uConnStatus == '+onl');
|
|
}
|
|
|
|
// return number of processor cores
|
|
if (iKind == 'proc')
|
|
{
|
|
if (pRef->iNumProcCores == 0)
|
|
{
|
|
pRef->iNumProcCores = _NetConnGetNumProcs();
|
|
}
|
|
return(pRef->iNumProcCores);
|
|
}
|
|
// return interface type (more verbose)
|
|
if (iKind == 'type')
|
|
{
|
|
return(_NetConnGetInterfaceType(pRef));
|
|
}
|
|
// return upnp addportmap info, if available
|
|
if (iKind == 'upnp')
|
|
{
|
|
// if protoupnp is available, and we've added a port map, return the external port for the port mapping
|
|
if ((pRef->pProtoUpnp != NULL) && (ProtoUpnpStatus(pRef->pProtoUpnp, 'stat', NULL, 0) & PROTOUPNP_STATUS_ADDPORTMAP))
|
|
{
|
|
return(ProtoUpnpStatus(pRef->pProtoUpnp, 'extp', NULL, 0));
|
|
}
|
|
}
|
|
#ifdef DIRTYCODE_ANDROID
|
|
|
|
if (iKind == 'ncon')
|
|
{
|
|
if ((SocketInfo(NULL, 'eth0', 0, NULL, 0) == 0) || SocketInfo(NULL, 'wan0', 0, NULL, 0) == 0)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
else
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef DIRTYCODE_APPLEIOS
|
|
|
|
//pass unrecgnized options to NetConnStatusIos and Socket Info
|
|
return(NetConnStatusIos(&pRef->Common, iKind, iData, pBuf, iBufSize));
|
|
|
|
#else
|
|
|
|
// pass unrecognized options to NetConnCommon
|
|
return(NetConnCommonStatus(&pRef->Common, iKind, iData, pBuf, iBufSize));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetConnShutdown
|
|
|
|
\Description
|
|
Shutdown the network code and return to idle state.
|
|
|
|
\Input uShutdownFlags - shutdown configuration flags
|
|
|
|
\Output
|
|
int32_t - negative=error, else zero
|
|
|
|
\Version 10/04/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
int32_t NetConnShutdown(uint32_t uShutdownFlags)
|
|
{
|
|
NetConnRefT *pRef = _NetConn_pRef;
|
|
|
|
// make sure we've been started
|
|
if (pRef == NULL)
|
|
{
|
|
return(NETCONN_ERROR_NOTACTIVE);
|
|
}
|
|
|
|
return(_NetConnShutdownInternal(pRef, uShutdownFlags));
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetConnSleep
|
|
|
|
\Description
|
|
Sleep the application for some number of milliseconds.
|
|
|
|
\Input iMilliSecs - number of milliseconds to block for
|
|
|
|
\Version 10/04/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
void NetConnSleep(int32_t iMilliSecs)
|
|
{
|
|
usleep(iMilliSecs*1000);
|
|
}
|
|
|