📄 netdiagnostics.c
字号:
/******************************************************************************
FILE: NetDiagnostics.c
SERVICES: Network Diagnostics example application
GENERAL DESCRIPTION:
PUBLIC CLASSES AND STATIC FUNCTIONS:
Uses of INetMgr, ISocket, IHtmlViewer, IWeb, IWebOpts, IWebResp, ISource,
ISourceUtil, IPeek, IGetLine interfaces.
INITIALIZATION & SEQUENCING REQUIREMENTS:
See Exported Routines
Copyright ?1999-2002 QUALCOMM Incorporated.
All Rights Reserved.
QUALCOMM Proprietary/GTDR
******************************************************************************/
//*****************************************************************************
// INCLUDE FILES
//*****************************************************************************
#include "AEEModGen.h"
#include "AEEAppGen.h"
#include "AEEFile.h"
#include "AEEHtmlViewer.h"
#include "AEEMenu.h"
#include "AEEShell.h"
#include "AEEStdLib.h"
#include "AEEText.h"
#include "AEEWeb.h"
#include "netdiagnostics.bid"
#include "netdiagnostics.brh"
#include "nmdef.h"
//*****************************************************************************
// DEFINITIONS
//*****************************************************************************
#define MAX_RES_STRING_BUF_SIZE 200 // Used for allocating resource string buffers
#define SPLASH_TIMER_DURATION 750 // Number of milliseconds the splash screen is displayed
#define MAX_HIST 9
#define IPPORT_ECHO 7
// Special URL bases
#define JUMP_ECHOTEST "test:echo" // starts echo test (expects form data)
#define JUMP_HTTPTEST "test:http" // starts HTTP test (expects form data)
#define JUMP_MAIN "file:///ND_MainMenu.htm"
#define WEBBER_USERAGENT "NetDiagnostics/1.0 (built on "__DATE__")\r\n"
#define STREQ(a,b) (!STRCMP(a,b))
#define FORALL(p,a) for (p = (a) + ARRAY_SIZE(a) - 1; p >= (a); --p)
#define FOR_ALL_WEBACTIONS(pApp, var, exp) {WebAction *var; FORALL(var, (pApp)->m_awa) { exp; } }
//*****************************************************************************
// ENUMERATED TYPE DEFINITIONS
//*****************************************************************************
//*****************************************************************************
// GLOBAL APPLICATION DATA STRUCTURES
//*****************************************************************************
typedef struct _CNetDiagnosticsApp CNetDiagnosticsApp;
typedef void (*PFNCLEANUP)(CNetDiagnosticsApp *);
// A WebAction holds state necessary to perform 1 IWeb transaction
typedef struct WebAction
{
CNetDiagnosticsApp * pParent; // my parent
AEECallback cb; // how to call me back
IWebResp * piWResp; // the answer I get from IWeb
IGetLine * piGetLine; // the body of the response, if any
int nLines; // count of lines in response
int nBytes; // count of bytes in response
uint32 uStart;
uint32 uRecvStart;
IPeek *pipPostData; // POST stream, if any
char *pszPostData; // POST string
} WebAction;
// Applet Struct
struct _CNetDiagnosticsApp
{
AEEApplet a; // Mandatory AEEApplet data member appears first
IFileMgr * m_pFileMgr; // Pointer to the apps IFileMgr object
AEERect m_rc; // Device Screen Rect
IHtmlViewer * m_pHTMLViewer; // The HTMLViewer control used to display HTML text
INetMgr * m_pINetMgr; // Pointer to INetMgr
IStatic * m_pIStatic; // Used for displaying messages
char * m_ppszHistory[MAX_HIST]; // history list
int m_cntHistory; // number of entries currently in the history list
PFNCLEANUP m_pfnViewCleanup; // function to clean up after test (NULL => no test)
// Form data
char * m_pszFormData; // this points to the memory block holding all values
char * m_pszHost; // "HOST" field
char * m_pszURL; // "URL" field
char * m_pszMsg; // "MSG" field
flg m_bRS:1; // "RS" field: Display response if TRUE
flg m_bRT:1; // "RT" field: Display response time if TRUE
flg m_bTCP:1; // "PROTOCOL" field == "1": Use TCP as protocol if TRUE
uint16 m_nDataLength; // length of pszMsg (calculated when set)
// Echoer state
uint16 m_nTCPIdx; // Index used for sending TCP data
uint32 m_nTotalTime; // Total Time
uint32 m_nSendTime; // Time to Send Data
uint32 m_nReceiveTime; // Time to Receive Data
AEEDNSResult m_dnsr; // DNS Result
AEECallback m_cb; // Callback for DNS
ISocket * m_pISocket; // Pointer to socket
// HTTP test state
IWeb * m_pIWeb; // Pointer to IWeb for HTTP Tests
WebAction m_awa[1]; // array of WebActions. By changing the '1' to any
// number, you can attempt to kick off multiple Web
// transactions simultaneously, testing Keep-Alive,
// multiple-POST Keep-Alives, NOWAITCONN, FORCENEW,
// and request queueing.
};
//*****************************************************************************
// FUNCTION DECLARATIONS
//*****************************************************************************
static boolean ND_InitAppData(CNetDiagnosticsApp * pApp);
static void ND_FreeAppData(CNetDiagnosticsApp * pApp);
static boolean ND_HandleEvent(CNetDiagnosticsApp * pApp, AEEEvent eCode, uint16 wParam, uint32 dwParam);
static void ND_NotifyCB( void* pvUser, HViewNotify* pHViewNotify );
static void ND_GoTo(CNetDiagnosticsApp *pApp, const char *pszURL);
static void ND_DisplaySplashScreen(CNetDiagnosticsApp * pApp);
static void ND_DisplaySplashScreenCB(CNetDiagnosticsApp* pApp);
static void ND_DisplayMenu(CNetDiagnosticsApp* pApp, const char *pszURL);
static void ND_EchoCleanup(CNetDiagnosticsApp* pApp);
static void ND_HTTPCleanup(CNetDiagnosticsApp* pApp);
static void ND_StartTest(CNetDiagnosticsApp* pApp, const char* pszURL);
static void Echoer_Start(CNetDiagnosticsApp * pApp);
static void Echoer_TCPConnected(void *p, int nErr);
static void Echoer_TCPConnect(CNetDiagnosticsApp * pApp);
static void Echoer_TCPDNSConnect(void *p);
static void Echoer_TCPWrite(CNetDiagnosticsApp * pApp);
static void Echoer_TCPRead(CNetDiagnosticsApp * pApp);
static void Echoer_UDPWrite(CNetDiagnosticsApp * pApp);
static void Echoer_UDPDNSWrite(void *p);
static void Echoer_UDPRead(CNetDiagnosticsApp * pApp);
static void WebAction_Start(WebAction *pwa, char *pszUrl);
static void WebAction_GotResp(void *p);
static void WebAction_Header(void *p, const char *cpszName, GetLine *pglVal);
static void WebAction_Status(void *p, WebStatus ws, void *pVal);
static void WebAction_Stop(WebAction *pwa);
static void WebAction_ReadLines(void *p);
//*****************************************************************************
// UTILITY FUNCTIONS
//****************************************************************************
// Free the old pointer and fill with STRDUP(pszNew)
//
static void StrReplace(char **ppsz, const char *pszNew)
{
FREE(*ppsz); // FREE(NULL) is okay in BREW
*ppsz = (pszNew ? STRDUP(pszNew) : (char*)pszNew);
}
static void ND_Print(CNetDiagnosticsApp *pApp, char *pszFmt, ...)
{
char buf[512];
va_list argptr;
va_start(argptr, pszFmt);
if( pApp->m_pIStatic )
{
if (VSNPRINTF(buf, sizeof(buf), pszFmt, argptr) >= 0) {
ISTATIC_SetTextEx(pApp->m_pIStatic, (byte*)buf, NULL, TRUE);
ISTATIC_Redraw(pApp->m_pIStatic);
}
}
va_end(argptr);
}
//*****************************************************************************
// APPLICATION-WIDE INITIALIZATION/CLEANUP FUNCTIONS
//****************************************************************************
/*===========================================================================
FUNCTION: AEEClsCreateInstance
DESCRIPTION:
This function is invoked while the app is being loaded. All Modules must provide this
function. Ensure to retain the same name and parameters for this function.
In here, the module must verify the ClassID and then invoke the AEEApplet_New() function
that has been provided in AEEAppGen.c.
After invoking AEEApplet_New(), this function can do app specific initialization. In this
example, a generic structure is provided so that app developers need not change app specific
initialization section every time except for a call to ND_InitAppData().
This is done as follows: ND_InitAppData() is called to initialize AppletData
instance. It is app developers responsibility to fill-in app data initialization
code of ND_InitAppData(). App developer is also responsible to release memory
allocated for data contained in AppletData -- this can be done in
ND_FreeAppData().
PARAMETERS:
clsID [in] - Specifies the ClassID of the applet which is being loaded
pIShell [in] - Contains pointer to the IShell interface.
pIModule [pin] - Contains pointer to the IModule interface to the current module to which
this app belongs
ppObj [out] - On return, *ppObj must point to a valid IApplet structure. Allocation
of memory for this structure and initializing the base data members is done by AEEApplet_New().
DEPENDENCIES:
None
RETURN VALUE:
AEE_SUCCESS - If the app needs to be loaded and if AEEApplet_New() invocation was
successful
EFAILED - If the app does not need to be loaded or if errors occurred in
AEEApplet_New(). If this function returns FALSE, the app will not be loaded.
SIDE EFFECTS:
None
===========================================================================*/
int AEEClsCreateInstance(AEECLSID ClsId,IShell * pIShell,IModule * po,void ** ppObj)
{
CNetDiagnosticsApp * pApp = NULL;
if(!AEEApplet_New(sizeof(CNetDiagnosticsApp), ClsId, pIShell,po,(IApplet**)ppObj,(AEEHANDLER)ND_HandleEvent,(PFNFREEAPPDATA)ND_FreeAppData))
return ENOMEMORY;
pApp = (CNetDiagnosticsApp *)*ppObj;
if (!ND_InitAppData(pApp)) {
*ppObj = NULL;
return EFAILED;
}
return(AEE_SUCCESS);
}
/*===========================================================================
FUNCTION: ND_InitAppData
DESCRIPTION:
This function initializes app specific data allocates memory for app data
(AppletData) and sets it to pAppData of AEEApplet. It also functions to
create all necessary GUI objects.
PARAMETERS:
pi [in] - Pointer to the IApplet structure. This structure contains
information specific to this applet. It was initialized during the
AEEClsCreateInstance().
DEPENDENCIES:
Assumes pi is not NULL
RETURN VALUE:
TRUE: If the app has app data is allocated and initialized successfully
FALSE: Either app data could not be allocated or initialzied
SIDE EFFECTS:
None
===========================================================================*/
static boolean ND_InitAppData(CNetDiagnosticsApp * pApp)
{
AEEDeviceInfo di;
IShell * pIShell = pApp->a.m_pIShell;
// Create each of the controls used by the application.
if((ISHELL_CreateInstance(pIShell, AEECLSID_FILEMGR, (void**)(&pApp->m_pFileMgr)) != SUCCESS) ||
(ISHELL_CreateInstance(pIShell, AEECLSID_HTML, (void**)(&pApp->m_pHTMLViewer)) != SUCCESS) ||
(ISHELL_CreateInstance(pIShell, AEECLSID_NET, (void**)(&pApp->m_pINetMgr)) != SUCCESS) ||
(ISHELL_CreateInstance(pIShell, AEECLSID_WEB, (void **)(&pApp->m_pIWeb)) != SUCCESS))
{
IAPPLET_Release((IApplet*)pApp);
return FALSE;
}
// Set callback for HTML viewer
IHTMLVIEWER_SetNotifyFn(pApp->m_pHTMLViewer, (PFNHVIEWNOTIFY)ND_NotifyCB, pApp);
IHTMLVIEWER_SetProperties(pApp->m_pHTMLViewer, HVP_SCROLLBAR);
// Get device screen rect
ISHELL_GetDeviceInfo(pApp->a.m_pIShell, &di);
SETAEERECT(&pApp->m_rc, 0, 0, di.cxScreen, di.cyScreen);
pApp->m_nTotalTime = pApp->m_nSendTime = pApp->m_nReceiveTime = 0;
// Set Default
pApp->m_bRS = pApp->m_bRT = pApp->m_bTCP = FALSE;
// Initialize the IWeb with a few options
{
int i = 0;
WebOpt awo[10];
// set the IWeb connect timeout to 10 seconds. this also sets the
// failover timeout, if unset, or set to 0, IWeb uses the system
// default (30 seconds unless an OEM changes it)
awo[i].nId = WEBOPT_CONNECTTIMEOUT;
awo[i].pVal = (void *)10000;
i++;
// test user-agent, uncomment this section to ship your own user-agent
// string. if unset, IWeb will send a default. If set to NULL, no
// user agent header will be sent */
// Set TEST_USER_AGENT in the NetDiagnostics project settings to all
// shipping of your own user agent.
#ifdef TEST_USER_AGENT
awo[i].nId = WEBOPT_USERAGENT;
awo[i].pVal = (void *)WEBBER_USERAGENT;
i++;
#endif
// test nowaitconn, this only comes into effect if you build webber
// with multiple WebActions (see the definition of struct Webber)
awo[i].nId = WEBOPT_FLAGS;
awo[i].pVal = (void *)WEBREQUEST_NOWAITCONN;
i++;
// test forcenew, uncomment this section to try multiple simultaneous
// "forced" new connections. Forced new connections are not kept alive
// unless they are the first forced new connection to a host
#ifdef TEST_FORCENEWCONN
awo[i].nId = WEBOPT_FLAGS;
awo[i].pVal = (void *)WEBREQUEST_FORCENEWCONN;
i++;
#endif
// turn off HTTP over HTTP proxying
awo[i].nId = WEBOPT_PROXYSPEC;
awo[i].pVal = (void *)"http:///";
i++;
// turn on ALL proxying. Proxyspecs are examined in WebOpt
// order, so in this list, with the above and below PROXYSPECs,
// everything except HTTP will be proxied through
// http://webproxy.yourdomain.com:8080, (which you'll have to
// set up to test, sorry
awo[i].nId = WEBOPT_PROXYSPEC;
awo[i].pVal = (void *)"*:///http://webproxy.yourdomain.com:8080";
i++;
// Marks the end of the array of WebOpts
awo[i].nId = WEBOPT_END;
// Add Options
IWEB_AddOpt(pApp->m_pIWeb,awo);
}
// Initialize all my WebActions to point to NetDiagnostics applet
FOR_ALL_WEBACTIONS(pApp, p, p->pParent = pApp);
return TRUE;
}
/*===========================================================================
FUNCTION: ND_FreeAppData
DESCRIPTION:
Frees data contained in app data and memory for app data itself.
App developer needs to free data contained in AppletData.
PARAMETERS:
pi [in] - Pointer to the IApplet structure. This structure contains
information specific to this applet. It was initialized during the
AEEClsCreateInstance().
DEPENDENCIES:
Assumes pi is not NULL
RETURN VALUE:
None
SIDE EFFECTS:
None
===========================================================================*/
static void ReleaseObj(void ** ppObj)
{
if (*ppObj) {
(void)IBASE_Release(((IBase *)*ppObj));
*ppObj = NULL;
}
}
static void ND_FreeAppData( CNetDiagnosticsApp* pApp )
{
int i;
// Socket callbacks: Deleting the socket cancels any callbacks. During app
// cleanup, *all* references to the socket must be released, so the socket
// will be deleted and canceling callbacks is not necessary.
if (pApp->m_pfnViewCleanup) {
pApp->m_pfnViewCleanup(pApp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -