Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

Forums:

I have an AnyData DTW200D module.  I am trying to establish a data connection to send/receive http packets to a specific server.  This module is provisioned with Verizon with a static IP address for development.

Does anyone have any sample code to establish a data connection, and then once established how do I send/receive http packets?

Pls use IWeb Api's
sample code:
// 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.

int32 _buffer_offset;

char *m_pXmlBuffer;

;

//*****************************************************************************

// 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;

pApp->m_pXmlBuffer = NULL;

// 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);

}

for (i = 0; i < ARRAY_SIZE(pApp->m_ppszHistory); ++i) {

FREE(pApp->m_ppszHistory[i]);

}

// Release memory buffers

FREE(pApp->m_pszFormData); // FREE(NULL) is okay in BREW

// Release other interfaces

ReleaseObj((void**)&pApp->m_pFileMgr);

ReleaseObj((void**)&pApp->m_pHTMLViewer);

ReleaseObj((void**)&pApp->m_pINetMgr);

ReleaseObj((void**)&pApp->m_pIWeb);

//*****************************************************************************

// EVENT HANDLING FUNCTIONS

//*****************************************************************************

/*===========================================================================

FUNCTION: ND_HandleEvent

DESCRIPTION:

This is the main EventHandler for this app. All events to this app are handled in this

function. All APPs must supply an Event Handler. Key events are passed to specific

event-handers depending on the current state of the application.

PARAMETERS:

pi [in] - Pointer to the AEEApplet structure. This structure contains information specific

to this applet. It was initialized during the AEEClsCreateInstance() function.

eCode [in] - Specifies the Event sent to this applet

wParam [in] - Event specific data.

dwParam [in] - Event specific data.

DEPENDENCIES:

None

RETURN VALUE:

TRUE - If the app has processed the event

FALSE - If the app did not process the event

SIDE EFFECTS:

None

===========================================================================*/

static boolean ND_HandleEvent(CNetDiagnosticsApp* pApp, AEEEvent eCode, uint16 wParam, uint32 dwParam )

{

if (pApp->m_pIStatic && ISTATIC_HandleEvent(pApp->m_pIStatic, eCode, wParam, dwParam))

return TRUE;

if (IHTMLVIEWER_HandleEvent(pApp->m_pHTMLViewer, eCode, wParam, dwParam))

return TRUE;

switch(eCode)

{

case EVT_APP_START:

ND_DisplaySplashScreen(pApp);

return TRUE;

case EVT_APP_STOP:

return TRUE;

case EVT_APP_SUSPEND:

// Stop any current network or web access processes. These functions

// also cancel all appropriate callbacks.

ND_EchoCleanup( pApp);

ND_HTTPCleanup( pApp);

// Cleanup all timers

ISHELL_CancelTimer( pApp->a.m_pIShell, (PFNNOTIFY)ND_DisplaySplashScreenCB, pApp);

// Set all controls to the inactive state

if( pApp->m_pHTMLViewer )

IHTMLVIEWER_SetActive( pApp->m_pHTMLViewer, FALSE );

return TRUE;

case EVT_APP_RESUME:

IHTMLVIEWER_SetRect( pApp->m_pHTMLViewer, &pApp->m_rc );

IHTMLVIEWER_SetActive( pApp->m_pHTMLViewer, TRUE );

return TRUE;

case EVT_KEY:

switch (wParam)

{

case AVK_CLR:

// call cleanup function

if( pApp->m_cntHistory > 1 )

{

ND_GoTo(pApp, NULL);

return TRUE;

}

}

break;

}

return FALSE;

//*****************************************************************************

// HTML VIEWER NOTIFICATION CALLBACK FUNCTIONS

//****************************************************************************

static void ND_NotifyCB( void* pvUser, HViewNotify* pNotify )

{

CNetDiagnosticsApp* pApp = (CNetDiagnosticsApp*) pvUser;

switch( pNotify->code )

{

case HVN_REDRAW_SCREEN:

IDISPLAY_ClearScreen(pApp->a.m_pIDisplay);

IHTMLVIEWER_Redraw(pApp->m_pHTMLViewer);

break;

case HVN_JUMP:

case HVN_SUBMIT:

ND_GoTo(pApp, pNotify->u.jump.pszURL);

break;

case HVN_DONE:

IHTMLVIEWER_SetRect(pApp->m_pHTMLViewer, &pApp->m_rc);

IHTMLVIEWER_Redraw( pApp->m_pHTMLViewer );

break;

}

/*===========================================================================

FUNCTION: ND_GoTo

DESCRIPTION:

Activate the appropriate view as described by the given URL. This adds an

entry onto the history list, or returns to the previous history entry.

PARAMETERS:

pszURL = URL describing the view to activate and add to the history,

or NULL to indicate that the previous history entry should be used

pData [in] - The user data pointer that is passed as the only parameter

to the callback.

DEPENDENCIES:

None

RETURN VALUE:

None

SIDE EFFECTS:

Causes the phone display to be updated.

===========================================================================*/

static void ND_GoTo(CNetDiagnosticsApp *pApp, const char *pszURL)

{

int pos = pApp->m_cntHistory; // pos = number of hist entries = next history entry

if (pszURL == NULL) {

// go back

if (pos < 2)

return;

--pos;

pszURL = pApp->m_ppszHistory[pos-1]; // use 'top' entry

} else {

// add new entry to history

if (pos >= MAX_HIST)

return;

++pos;

StrReplace(&pApp->m_ppszHistory[pos-1], pszURL);

}

// Cleanup previous state

if (pApp->m_pfnViewCleanup) {

pApp->m_pfnViewCleanup(pApp);

pApp->m_pfnViewCleanup = NULL;

}

// Activate appropriate state

pApp->m_cntHistory = pos;

if (STRBEGINS("test:", pszURL)) {

// read form data and begin test

ND_StartTest(pApp, pszURL);

} else /*if (STRBEGINS("file:", pszURL))*/ {

// read and display file

ND_DisplayMenu(pApp, pszURL);

}

//*****************************************************************************

// DISPLAY MANIPULATION FUNCTIONS

//****************************************************************************

/*===========================================================================

FUNCTION: ND_DisplaySplashScreen

DESCRIPTION:

This function clears the device screen and displays the application's

splash screen in the center of the display. The function then sets a callback

ND_DisplaySplashScreenCB to start the application's main menu screen.

If the splash image fails to load, then just display the menu and

skip the callback.

PARAMETERS:

pData [in] - The user data pointer that is passed as the only parameter

to the callback.

DEPENDENCIES:

None

RETURN VALUE:

None

SIDE EFFECTS:

Causes the phone display to be updated.

===========================================================================*/

static void ND_DisplaySplashScreenCB(CNetDiagnosticsApp* pApp)

{

// Display main form

ND_GoTo(pApp, JUMP_MAIN);

static void ND_DisplaySplashScreen(CNetDiagnosticsApp* pApp)

{

IImage* pSplash = NULL;

AEEImageInfo rImageInfo;

if((pSplash = ISHELL_LoadResImage( pApp->a.m_pIShell, NETDIAGNOSTICS_RES_FILE, IDB_SPLASH)) != NULL)

{

// Get image information

IIMAGE_GetInfo(pSplash, &rImageInfo);

// Clear Device screen

IDISPLAY_ClearScreen(pApp->a.m_pIDisplay);

// Draw the image in the center of the screen

IIMAGE_Draw(pSplash, (pApp->m_rc.dx/2) - (rImageInfo.cx/2), (pApp->m_rc.dy/2) - (rImageInfo.cy/2));

// The image is no longer needed so release it

IIMAGE_Release(pSplash);

// Set the callback timer

ISHELL_SetTimer( pApp->a.m_pIShell, SPLASH_TIMER_DURATION, (PFNNOTIFY)ND_DisplaySplashScreenCB, pApp);

// Update Display

IDISPLAY_Update(pApp->a.m_pIDisplay);

return;

}

else

{

ND_GoTo( pApp, JUMP_MAIN );

}

/*===========================================================================

FUNCTION: ND_DisplayMenu

DESCRIPTION:

This function clears the device screen and displays the components of

the application's Main Menu screen. This consists of updating the

title bar text at the top of the screen and the HTML Viewer Control in the

remaining space on the screen.

An HTML file is opened via the IFILE interface and its stream is passed

to the HTML Viewer control which reads the text and displays it. This text

includes links which make up the user selectable options of the Main Menu.

PARAMETERS:

pApp [in] - Pointer to the CNetDiagnosticsApp structure. This structure contains

information specific to this applet.

DEPENDENCIES:

Assumes the displayed controls have been previously created and

initialized.

RETURN VALUE:

None

SIDE EFFECTS:

Causes the phone display to be updated.

===========================================================================*/

static void ND_DisplayMenu(CNetDiagnosticsApp* pApp, const char *pszURL)

{

IFile *pf;

const char *pszFileName = pszURL;

if (STRBEGINS("file:", pszFileName))

pszFileName += STRLEN("file:");

if (STRBEGINS("///", pszFileName))

pszFileName += STRLEN("///");

pf = IFILEMGR_OpenFile(pApp->m_pFileMgr, pszFileName, _OFM_READ);

if (pf) {

// Set the file from which the viewer will get its text

IHTMLVIEWER_LoadStream( pApp->m_pHTMLViewer, (IAStream*)pf);

// Release our reference to the file. (The HTML viewer is responsible for

// its own reference count while it uses the stream.)

IFILE_Release(pf);

} else {

// Set the file from which the viewer will get its text

IHTMLVIEWER_SetData( pApp->m_pHTMLViewer, "ErrorFile Not Found", -1);

}

/*===========================================================================

FUNCTION: ND_EchoCleanup

DESCRIPTION:

Cleanup when exiting Network Access test state

PARAMETERS:

pApp [in] - Pointer to the CNetDiagnosticsApp structure. This structure contains

information specific to this applet.

DEPENDENCIES:

RETURN VALUE:

None

SIDE EFFECTS:

Causes the phone display t

Pls use IWeb Api's
sample code:
// 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.

int32 _buffer_offset;

char *m_pXmlBuffer;

;

//*****************************************************************************

// 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;

pApp->m_pXmlBuffer = NULL;

// 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);

}

for (i = 0; i < ARRAY_SIZE(pApp->m_ppszHistory); ++i) {

FREE(pApp->m_ppszHistory[i]);

}

// Release memory buffers

FREE(pApp->m_pszFormData); // FREE(NULL) is okay in BREW

// Release other interfaces

ReleaseObj((void**)&pApp->m_pFileMgr);

ReleaseObj((void**)&pApp->m_pHTMLViewer);

ReleaseObj((void**)&pApp->m_pINetMgr);

ReleaseObj((void**)&pApp->m_pIWeb);

//*****************************************************************************

// EVENT HANDLING FUNCTIONS

//*****************************************************************************

/*===========================================================================

FUNCTION: ND_HandleEvent

DESCRIPTION:

This is the main EventHandler for this app. All events to this app are handled in this

function. All APPs must supply an Event Handler. Key events are passed to specific

event-handers depending on the current state of the application.

PARAMETERS:

pi [in] - Pointer to the AEEApplet structure. This structure contains information specific

to this applet. It was initialized during the AEEClsCreateInstance() function.

eCode [in] - Specifies the Event sent to this applet

wParam [in] - Event specific data.

dwParam [in] - Event specific data.

DEPENDENCIES:

None

RETURN VALUE:

TRUE - If the app has processed the event

FALSE - If the app did not process the event

SIDE EFFECTS:

None

===========================================================================*/

static boolean ND_HandleEvent(CNetDiagnosticsApp* pApp, AEEEvent eCode, uint16 wParam, uint32 dwParam )

{

if (pApp->m_pIStatic && ISTATIC_HandleEvent(pApp->m_pIStatic, eCode, wParam, dwParam))

return TRUE;

if (IHTMLVIEWER_HandleEvent(pApp->m_pHTMLViewer, eCode, wParam, dwParam))

return TRUE;

switch(eCode)

{

case EVT_APP_START:

ND_DisplaySplashScreen(pApp);

return TRUE;

case EVT_APP_STOP:

return TRUE;

case EVT_APP_SUSPEND:

// Stop any current network or web access processes. These functions

// also cancel all appropriate callbacks.

ND_EchoCleanup( pApp);

ND_HTTPCleanup( pApp);

// Cleanup all timers

ISHELL_CancelTimer( pApp->a.m_pIShell, (PFNNOTIFY)ND_DisplaySplashScreenCB, pApp);

// Set all controls to the inactive state

if( pApp->m_pHTMLViewer )

IHTMLVIEWER_SetActive( pApp->m_pHTMLViewer, FALSE );

return TRUE;

case EVT_APP_RESUME:

IHTMLVIEWER_SetRect( pApp->m_pHTMLViewer, &pApp->m_rc );

IHTMLVIEWER_SetActive( pApp->m_pHTMLViewer, TRUE );

return TRUE;

case EVT_KEY:

switch (wParam)

{

case AVK_CLR:

// call cleanup function

if( pApp->m_cntHistory > 1 )

{

ND_GoTo(pApp, NULL);

return TRUE;

}

}

break;

}

return FALSE;

//*****************************************************************************

// HTML VIEWER NOTIFICATION CALLBACK FUNCTIONS

//****************************************************************************

static void ND_NotifyCB( void* pvUser, HViewNotify* pNotify )

{

CNetDiagnosticsApp* pApp = (CNetDiagnosticsApp*) pvUser;

switch( pNotify->code )

{

case HVN_REDRAW_SCREEN:

IDISPLAY_ClearScreen(pApp->a.m_pIDisplay);

IHTMLVIEWER_Redraw(pApp->m_pHTMLViewer);

break;

case HVN_JUMP:

case HVN_SUBMIT:

ND_GoTo(pApp, pNotify->u.jump.pszURL);

break;

case HVN_DONE:

IHTMLVIEWER_SetRect(pApp->m_pHTMLViewer, &pApp->m_rc);

IHTMLVIEWER_Redraw( pApp->m_pHTMLViewer );

break;

}

/*===========================================================================

FUNCTION: ND_GoTo

DESCRIPTION:

Activate the appropriate view as described by the given URL. This adds an

entry onto the history list, or returns to the previous history entry.

PARAMETERS:

pszURL = URL describing the view to activate and add to the history,

or NULL to indicate that the previous history entry should be used

pData [in] - The user data pointer that is passed as the only parameter

to the callback.

DEPENDENCIES:

None

RETURN VALUE:

None

SIDE EFFECTS:

Causes the phone display to be updated.

===========================================================================*/

static void ND_GoTo(CNetDiagnosticsApp *pApp, const char *pszURL)

{

int pos = pApp->m_cntHistory; // pos = number of hist entries = next history entry

if (pszURL == NULL) {

// go back

if (pos < 2)

return;

--pos;

pszURL = pApp->m_ppszHistory[pos-1]; // use 'top' entry

} else {

// add new entry to history

if (pos >= MAX_HIST)

return;

++pos;

StrReplace(&pApp->m_ppszHistory[pos-1], pszURL);

}

// Cleanup previous state

if (pApp->m_pfnViewCleanup) {

pApp->m_pfnViewCleanup(pApp);

pApp->m_pfnViewCleanup = NULL;

}

// Activate appropriate state

pApp->m_cntHistory = pos;

if (STRBEGINS("test:", pszURL)) {

// read form data and begin test

ND_StartTest(pApp, pszURL);

} else /*if (STRBEGINS("file:", pszURL))*/ {

// read and display file

ND_DisplayMenu(pApp, pszURL);

}

//*****************************************************************************

// DISPLAY MANIPULATION FUNCTIONS

//****************************************************************************

/*===========================================================================

FUNCTION: ND_DisplaySplashScreen

DESCRIPTION:

This function clears the device screen and displays the application's

splash screen in the center of the display. The function then sets a callback

ND_DisplaySplashScreenCB to start the application's main menu screen.

If the splash image fails to load, then just display the menu and

skip the callback.

PARAMETERS:

pData [in] - The user data pointer that is passed as the only parameter

to the callback.

DEPENDENCIES:

None

RETURN VALUE:

None

SIDE EFFECTS:

Causes the phone display to be updated.

===========================================================================*/

static void ND_DisplaySplashScreenCB(CNetDiagnosticsApp* pApp)

{

// Display main form

ND_GoTo(pApp, JUMP_MAIN);

static void ND_DisplaySplashScreen(CNetDiagnosticsApp* pApp)

{

IImage* pSplash = NULL;

AEEImageInfo rImageInfo;

if((pSplash = ISHELL_LoadResImage( pApp->a.m_pIShell, NETDIAGNOSTICS_RES_FILE, IDB_SPLASH)) != NULL)

{

// Get image information

IIMAGE_GetInfo(pSplash, &rImageInfo);

// Clear Device screen

IDISPLAY_ClearScreen(pApp->a.m_pIDisplay);

// Draw the image in the center of the screen

IIMAGE_Draw(pSplash, (pApp->m_rc.dx/2) - (rImageInfo.cx/2), (pApp->m_rc.dy/2) - (rImageInfo.cy/2));

// The image is no longer needed so release it

IIMAGE_Release(pSplash);

// Set the callback timer

ISHELL_SetTimer( pApp->a.m_pIShell, SPLASH_TIMER_DURATION, (PFNNOTIFY)ND_DisplaySplashScreenCB, pApp);

// Update Display

IDISPLAY_Update(pApp->a.m_pIDisplay);

return;

}

else

{

ND_GoTo( pApp, JUMP_MAIN );

}

/*===========================================================================

FUNCTION: ND_DisplayMenu

DESCRIPTION:

This function clears the device screen and displays the components of

the application's Main Menu screen. This consists of updating the

title bar text at the top of the screen and the HTML Viewer Control in the

remaining space on the screen.

An HTML file is opened via the IFILE interface and its stream is passed

to the HTML Viewer control which reads the text and displays it. This text

includes links which make up the user selectable options of the Main Menu.

PARAMETERS:

pApp [in] - Pointer to the CNetDiagnosticsApp structure. This structure contains

information specific to this applet.

DEPENDENCIES:

Assumes the displayed controls have been previously created and

initialized.

RETURN VALUE:

None

SIDE EFFECTS:

Causes the phone display to be updated.

===========================================================================*/

static void ND_DisplayMenu(CNetDiagnosticsApp* pApp, const char *pszURL)

{

IFile *pf;

const char *pszFileName = pszURL;

if (STRBEGINS("file:", pszFileName))

pszFileName += STRLEN("file:");

if (STRBEGINS("///", pszFileName))

pszFileName += STRLEN("///");

pf = IFILEMGR_OpenFile(pApp->m_pFileMgr, pszFileName, _OFM_READ);

if (pf) {

// Set the file from which the viewer will get its text

IHTMLVIEWER_LoadStream( pApp->m_pHTMLViewer, (IAStream*)pf);

// Release our reference to the file. (The HTML viewer is responsible for

// its own reference count while it uses the stream.)

IFILE_Release(pf);

} else {

// Set the file from which the viewer will get its text

IHTMLVIEWER_SetData( pApp->m_pHTMLViewer, "ErrorFile Not Found", -1);

}

/*===========================================================================

FUNCTION: ND_EchoCleanup

DESCRIPTION:

Cleanup when exiting Network Access test state

PARAMETERS:

pApp [in] - Pointer to the CNetDiagnosticsApp structure. This structure contains

information specific to this applet.

DEPENDENCIES:

RETURN VALUE:

None

SIDE EFFECTS:

Causes the phone display t