ESquirt-2 APIs

Version 1.13

February 14, 2001

By:

See Also the ESquirt-2 Specification.


New since version 1.12

New since version 1.11

New since version 1.1


Notice

The C/C++ example headers shown in this specification may not compile. They're essentially pseudo-code. These header files do compile (they're the ones used for the PalmOS C implementation, and are current:) TCoolReference.h, TESquirtOption.h, and CESquirt.h


 

Contents


Description of the API

The following basic types/classes exist:

TCoolBuffer -- a Cooltown buffer of specific length

TCoolBuffer -- This type encapsulates a block of information of a specific length. It is used so that non-ascii data (unicode, etc.) may be described. The members are:
  unsigned char * content; 
  unsigned int length;

Deleting/freeing a TCoolBuffer deletes/frees its content memory.

 

TCoolReference -- a Cooltown Reference

TCoolReference -- This type encapsulates a reference. It is a subclass (C++) or a typedef (C) of a TCoolBuffer and has the same members. Optionally, additional methods may provide means of manipulating or accessing the XML string containing within an TCoolReference.

Deleting/freeing a TCoolReference deletes/frees its content memory.

TESquirtOption  -- the ESquirt-2 options structure

TESquirtOption -- This type encapsulates the options possible for sending/receiving a TCoolReference. The members are:
  unsigned int mode;      // ESQUIRT_SQUIRT | ESQUIRT_BEACON
  unsigned int transport; // ESQUIRT_AUTO | ESQUIRT_ULTRA | ESQUIRT_IRDA |ESQUIRT_BLUETOOTH
  unsigned int protocol;  // ESQUIRT_AUTO | ESQUIRT_RAW | ESQUIRT_OBEX | ESQUIRT_GET

The values are just #defined, and have the following meaning:

  #define ESQUIRT_SQUIRT 1 // Squirting, which means use hp:esquirt as either the IAS name (IRDA) and/or
                           // as the TARGET header value (OBEX) based on protocol and transport settings
  #define ESQUIRT_BEACON 2 // Beaconing, which means use hp:beacon as either the IAS name (IRDA) and/or
			   // as the TARGET header value (OBEX) based on protocol and transport settings
  #define ESQUIRT_AUTO 		0 // Send/receive using any/all available modes/transports/protocols 
				  // (see Send Auto Processing and Receive Auto Processing below)
  #define ESQUIRT_ULTRA		1 // Send/receive using Ultra IR transport
  #define ESQUIRT_IRDA		2 // Send/receive using IrDA TinyTp protocol (ESquirt V1)
  #define ESQUIRT_BLUETOOTH	4 // Send/receive using BlueTooth (not implemented, future support)
  #define ESQUIRT_TCPIP		8 // Send/receive using TCP/IP (not implemented, future support)
  #define ESQUIRT_RAW		1 // Do not use/decode content
  #define ESQUIRT_OBEX		2 // Encode/decode content using Obex / Supports PUT for GetCapabilities()
  #define ESQUIRT_OBEX_GET	4 // Supports GET for GetCapabilities()

ESquirt-2 Obex headers

When using Obex, the following headers are supported:

HI Name Description
0x01 Name File Name
0x42 Type Mime type (text/html, text/wml, etc)
0x46 Target UUID of target for Ultra/Obex
0x48 Body A chunk of the object body
0x49 End of Body The final chunk of the object body
0x4d Auth. Challenge For authentication
0x4e Auth Resp. For authentication

Any correctly encoded Obex header is allowed, but only the above headers are guaranteed to be interpreted. Refer to the Obex 1.2 specification for details. Note that the  ESquirt-2 Specification has additional information on the use of Obex for requests. As of 2/2/2001, that spec was not up to date on the proper means of requesting an interface while passing in a reference in GetControlPage().

Target header

The Target header is used for Ultra/Obex packets. It contains one of two possible values:

If the action is squirting, then Target is this 16  byte sequence:

 {0xb7, 0x7a, 0xdd, 0xa8, 0xf7, 0xd2, 0x11, 0xd4, 0x9c, 0xd9, 0x0, 0x10, 0x83, 0x0, 0xef, 0x7b}

Or as a C string: "\x0b7\x07a\x0dd\x0a8\x0f7\x0d2\x011\x0d4\x09c\x0d9\x000\x010\x083\x000\x0ef\x07b"

It the action is beaconing, then Target is this 16 byte sequence:

 {0xb7, 0x7a, 0xdd, 0xa9, 0xf7, 0xd2, 0x11, 0xd4, 0x9c, 0xd9, 0x0, 0x10, 0x83, 0x0, 0xef, 0x7b}

Or as a C string: "\x0b7\x07a\x0dd\x0a9\x0f7\x0d2\x011\x0d4\x09c\x0d9\x000\x010\x083\x000\x0ef\x07b"

 

AUTO processing:

  When sending, specifying ESQUIRT_AUTO for Transport means the sender does the following:
  1) Attempt a BlueTooth discovery (if BT supported)
	if other BT devices found, look for ESquirt service (*TBD -- need more info on BT)
		if found 
			transport = ESQUIRT_BLUETOOTH
			protocol = ESQUIRT_OBEX??? 
			proceed with connect, send
  2) If no BT, Attempt IrDA Discovery (up to 10 times)
	if other IrDA device found, look for OBEX service
		if OBEX:ESquirt found
			transport = ESQUIRT_IRDA
			protocol = ESQUIRT_OBEX 
			proceed with connect, send
		if OBEX:ESquirt not found, look for OBEX service
		if OBEX found
			transport = ESQUIRT_IRDA
			protocol = ESQUIRT_OBEX 
			proceed with connect, send
		if not found,
			if mode = ESQUIT_AUTO look for hp:esquirt then hp:beacon as per below
			else if mode = ESQUIRT_SQUIRT look for hp:esquirt service
				if hp:esquirt found
				transport = ESQUIRT_IRDA
				protocol = ESQUIRT_RAW
				proceed with connect, send
			else if mode = ESQUIRT_BEACON look for hp:beacon service
				if hp:beacon found
				transport = ESQUIRT_IRDA
				protocol = ESQUIRT_RAW
				proceed with connect, send
  3) If no IrDA device found, or IrDA device found but service not located, send once using Ultra, then using Ultra/Obex
	transport = ESQUIRT_ULTRA
	protocol = ESQUIRT_RAW
	proceed with connect, send
	transport = ESQUIRT_ULTRA
	protocol = ESQUIRT_OBEX
	proceed with connect, send	

CESquirt -- the API

CESquirt -- This class (or library) supports sending/receiving TCoolReferences, and publishing/getting a Control Page.

	// Send()
	int  Send(TCoolReference &data, TESquirtOption &how, AuthCallback auth=0, ...) // send a ref
	int  SendStatus(...); 		// returns status of request made above
	void SendCancel(...); 		// cancels request made above
	// Recv()
	int  Recv(TCoolReference &data, TESquirtOption &how, ...)	// receive a ref
	int  RecvStatus(...); 		// returns status of request made above
	void RecvCancel(...); 		// cancels request made above  
	// Request a Control Page

	// File information structure
	typedef struct _TCoolFileInfo {
		TCoolBuffer* fileName; // A file name, in Unicode
		TCoolBuffer* fileType; // A mime type (such as "text/html") in ascii
	} TCoolFileInfo;

	TCoolBuffer *GetControlPage(TESquirtOption &how, int &error, TCoolReference *data=0, TCoolFileInfo* info=0, AuthCallback auth=0, ...);		// request control page
	int  GetStatus(...); 		// returns status of request made above
	void GetCancel(...); 		// cancels request made above
	// Provide a Control Page
	int ProvideControlPage(TESquirtOption &how, TCoolBuffer* unicodeFileName, ControlPageCallback pageRequest, ...);	// provide control page
	void ProvideCancel(...);		// Stop providing control page
	bool Authenticate(char *passwd);		// authenticate password for pending HandleControlPage()
	// Get capaibilites of this implementation
	void GetCapabilities(TESquirtOption &how)	// see what is supported
	
	// Callback definitions
	typedef bool (*AuthCallback)(char * &userName, char * &passWd); 		// Authentication callback function interface
	typedef int (*ControlPageCallback)(char * &userName, TCoolReference *data=0, TCoolFileInfo* info, TCoolBuffer* &pageContent); 	// Control Page request callback function interface
	

Each method is explained below:


  int CESquirt::Send(TCoolReference &data, TESquirtOption &how, AuthCallback auth=0,...)

This method sends the content in TCoolReference, using the options set in how. The default setting of all zeros in how results in ESQUIRT_SQUIRT, ESQUIRT_AUTO, ESQUIRT_AUTO.  Send() is a blocking call, it returns 0 if the TCoolReference was sent, < 0 for any error. Specific error values may be defined for debugging/user feedback, but any non-zero return value means the item was not sent. The how members are updated to indicate exactly what transport and protocol were used to send the TCoolReference, but are undefined if the Send() returns non-zero. If an authentication callback function pointer is provided, it is called if required by the receiver.

  Examples:
	TESquirtOption how;
	how.mode = ESQUIRT_BEACON;
	how.transport = ESQUIRT_ULTRA;
	how.protocol = ESQUIRT_RAW;
	rc = Send(data, how); // sends 1 "hardware style" beacon. rc == 0 means it was broadcast
	how.mode = ESQUIRT_SQUIRT;
	how.transport = ESQUIRT_IRDA;
	how.protocol = ESQUIRT_OBEX;
	rc = Send(data, how); // connect to IrDA OBEX or OBEX:ESquirt serivce, do a PUT, rc == 0 means it was received
	bzero(how);
	rc = Send(data, how); // connect to anything! how.transport and how.protocol will be updated if Send() works

Blocking vs. Non-Blocking Send()

Depending on the Operating System/Language, additional parameters may be added to the end of the Send() method as needed to support a non-blocking Send(). If this is the case, calling Send() will return immediately, with the processing completing at some later time. The following functions (with varying parameters) are available: 

	int SendStatus();   // returns 0 if Send complete, returns non-zero if Send still pending
	void SendCancel();  // aborts Send

Assuming there is a non-blocking version of Send(), the API must supply a blocking version. For example:

  int CESquirt::Send(TCoolReference &data, TESquirtOption &how);	// blocking
  int CESquirt::Send(TCoolReference &data, TESquirtOption &how, Status &stat); // nonblocking, use stat
  int SendStatus(Status stat);	// returns status of request made above
  void SendCancel(Status stat); // cancels request made above

It is not legal to invoke a non-blocking Send() while a previous non-blocking send is still pending.

Authentication during non-Ultra OBEX Send() and GetInterface()

When the protocol is ESQUIRT_OBEX and the transport supports reliable two-way communication (i.e., ESQUIRT_IRDA  or ESQUIRT_BLUETOOTH) then it is possible for the Send() and GetInterface() calls to generate an OBEX authentication challenge. The optional authCallback parameter to these methods is a pointer to an AuthCallback function as defined below:

	typedef bool (*AuthCallback)(char * &userName, char * &passWd);
The AuthCallback() function allocates memory for userName and passWd, fills them in with the desired values, and returns TRUE to attempt to authenticate with the receiver. This call may display a dialog box, fetch the username/password from an application preference, etc. If the application does not want to attempt authentication, then AuthCallback() should return FALSE and the userName and passWd values should not be changed. Here are examples of both Send() and GetInterface() with authentication:
	bool authCallback(char * &userName, char * &passWd) {
		// display dialog allowing user to enter username & passwd
		bool rc = GetUserPass(char * &userName, char * &passWd)
		return rc;  // assumes GetUserPass() allocates memory, returns FALSE if user cancels
	}

	// Send() with Authentication
	TESquirtOption how;
	how.mode = ESQUIRT_SQUIRT;
	how.transport = ESQUIRT_IRDA;
	how.protocol = ESQUIRT_OBEX;
	rc = Send(data, how, authCallback); // connect to IrDA OBEX or OBEX:ESquirt serivce, do a PUT, rc == 0 means it was received

	// Recv() with Authentication
	TCoolReference data;
	data.content = 0;
	data.length = 0;
	bzero(how);
	rc = Recv(data, how, authCallback); // receive anything! how.transport and how.protocol will be updated if Recv() works


  int CESquirt::Recv(TCoolReference &data, TESquirtOption &how, ...)

This method receives an incomming TCoolReference, using the options set in how. Recv() is a blocking call, it returns 0 if a TCoolReference was received, < 0 for any error. Specific error values may be defined for debugging/user feedback, but any non-zero return value means the item was not received. The how members are updated to indicate exactly what transport and protocol were used to receive the TCoolReference, but are undefined if the Recv() returns non-zero. The TCoolReference content and length members can be zero, in which case memory is allocated to hold the newly received TCoolReference. If the content and length members are non-zero, no memory will be allocated -- if the incomming TCoolReference is larger than the supplied content block, Recv will return a non-zero value.

  Examples:
	TESquirtOption how;
	TCoolReference data;
	data.content = 0;
	data.length = 0;
	how.mode = ESQUIRT_BEACON;
	how.transport = ESQUIRT_ULTRA;
	how.protocol = ESQUIRT_RAW;
	rc = Recv(data, how); // receives 1 "hardware style" beacon. data.content allocated, length updated
	if (rc == 0)
		free(data.content);
	data.content = (unsigned char *) malloc(385);
	data.length = 385;
	how.mode = ESQUIRT_BEACON;
	how.transport = ESQUIRT_ULTRA;
	how.protocol = ESQUIRT_OBEX;
	rc = Recv(data, how); // receives 1 Obex-encoded beacon. No memory allocated, length updated.
	free(data.content);
	data.content = 0;
	data.length = 0;
	bzero(how);
	rc = Recv(data, how); // receive anything! how.transport and how.protocol will be updated if Recv() works

AUTO Processing

When transport is AUTO, Recv() accepts connections on:

	Ultra, 
	IrDA TinyTp service,
	BlueTooth * TBD
When Protocol is AUTO, Recv() accepts connections to these services:
	TinyTP: hp:beacon (BEACON), hp:esquirt (SQUIRT), and either OBEX or OBEX:ESquirt (OBEX) as supported by the OS
	Ultra PID 0x01 (OBEX) and 0x03 (RAW)

Blocking vs. Non-Blocking Recv()

Depending on the Operating System/Language, additional parameters may be added to the end of the Recv() method as needed to support a non-blocking Recv(). If this is the case, calling Recv() will return immediately, with the processing completing at some later time. The following functions (with varying parameters) are available:

	int RecvStatus();   // returns 0 if Recv complete, returns non-zero if Recv still pending
	void RecvCancel();  // aborts Recv
Assuming there is a non-blocking version of Recv(), the API must supply a blocking version. For example:
  int CESquirt::Recv(TCoolReference &data, TESquirtOption &how);	// blocking
  int CESquirt::Recv(TCoolReference &data, TESquirtOption &how, Status &stat); // nonblocking, use stat
  int RecvStatus(stat);		// returns status of request made above
  void RecvCancel(stat);	// cancels request made above

It is not legal to invoke a non-blocking Recv() while a previous non-blocking Recv() is still pending.


  TCoolBuffer *GetControlPage(TESquirtOption &how, int &error, TCoolReference *data=0, TCoolFileInfo* info=0, AuthCallback auth=0, ...);

This method returns a control page from a device, if the device supports control page interfaces. Control pages are only available via OBEX protocols over reliable two-way transports. This means ESQUIRT_IRDA or ESQUIRT_BLUETOOTH. The return value is NULL if no connection is established, the control page is unavailable, or authentication fails. This method requests a control page using the options set in how. GetControlPage() is a blocking call, it returns an allocated TCoolBuffer holding the contents of the received control page, or NULL for any error. The specific Obex reply header code is returned in error. The how members are updated to indicate exactly what transport and protocol were used to receive the control page, but are undefined if the GetControlPage() returns NULL. If a TCoolReference is provided, it is sent as an OBEX BODY_LAST header in the initial interface request. The device handing the request may use this information in tailoring a control page. If a TCoolFileInfo is provided, its non-NULL member values will be used in place of the default Obex Header values for Name (fileName, default is "" in Unicode) and Type (fileType, default is "text/html"). If an authentication callback function pointer is provided, it is called if required by the control page publisher.

  Example:
	TESquirtOption how;
	how.mode = ESQUIRT_AUTO;
	how.transport = ESQUIRT_IRDA;
	how.protocol = ESQUIRT_OBEX;
	char *content = GetInterface(how);
	if (content) {
	  // use content
	  delete content
	}

Blocking vs. Non-Blocking GetControlPage()

Depending on the Operating System/Language, additional parameters may be added to the end of the GetControlPage() method as needed to support a non-blocking GetControlPage(). If this is the case, calling GetControlPage() will return immediately, with the processing completing at some later time. In this case, one of the additional parameters must be a char * reference that is set once the GetControlPage() completes. The following functions (with varying parameters) are available:

	int GetStatus();   // returns 0 if GetControlPage complete, returns non-zero if GetControlPage still pending
	void GetCancel();  // aborts GetControlPage 

Assuming there is a non-blocking version of GetControlPage (), the API must supply a blocking version. For example:

  int CESquirt::GetControlPage (TESquirtOption &how, AuthCallback auth=0);	// blocking
  int CESquirt::GetControlPage (TESquirtOption &how, AuthCallback auth=0, Status &stat); // nonblocking, use stat
  int GetStatus(Status stat);	// returns status of request made above
  void GetCancel(Status stat); // cancels request made above

It is not legal to invoke a non-blocking GetControlPage() while a previous non-blocking GetControlPage() is still pending.


  int *ProvideControlPage(TESquirtOption &how, TCoolBuffer* unicodeFileName, ControlPageCallback pageRequest)
This method indicates the application wishes to provide a control page for the device. Control pages are only available via OBEX protocols over reliable two-way transports. This means ESQUIRT_IRDA or ESQUIRT_BLUETOOTH.

If unicodeFileName is non-null, then pageRequest is called only when a GET request filename matches it.

If unicodeFileName is NULL, then pageRequest is called for all GET requests.

The implementation for a platform may optionally support multiple calls to CESquirt_ProvideControlPage(). If it does, then an application can register several callbacks for different names (and a default callback using a NULL name). If multiple calls to CESquirt_ProvideControlPage() are made with the same unicodeFileName value, only the latest one is retained. CESquirt_ProvideCancel() cancels all registered callbacks.

If the implementation does not support multiple callbacks, then the unicodeFileName parameter is ignored even if it is non-NULL. That means the callback is called for all GET requests.

The return value is non-zero if the implementation does not support providing control pages. When a client establishes a connection, the ControlPageCallback will be called one or more times. This call may be blocking or non-blocking.

The API requires that an implementation support 1 syncronous ProvideControlPage() call, from 1 process, for a machine. It is platform dependent to provide support for multiple processess/threads/apps providing interfaces. In other words, in Win32 the API might support more than one application/thread providing interfaces (differentiated by unicodeFileName of the GET request) while on PalmOS it isn't even possible to implement this.

The actual behavior of this call will differ on the various platforms, check any platform-specific implementation documentation for complete details.

 


  typedef int (*ControlPageCallback)(char * userName, TCoolReference *data, TCoolFileInfo* info, TCoolBuffer * &pageContent)
The ControlPageCallback() method is implemented by the application designer. It is called one or more times when a client requests a control page. When the client makes the initial request, the method is called with userName set to NULL. This represents an unauthenticated request. It should return a standard Obex response value. Standard values are:

0xA0 -- OK, Success. The pageContent pointer is valid.
0xC1 -- Unauthorized. Begin an authentication challenge
0xC4 -- Not Found. Requested file name in info not found
0xCF -- Unsupported media type. Requested file type in info not supported
0xC3 -- Forbidden. Authentication failed.

Only in the case of 0xA0 is the pageContent pointer accessed (and freed). If the client supplied a TCoolReference in the request, it is passed in via the data parameter. If no TCoolReference was supplied, the data parameter will be NULL. The Name (Unicode file Name) and Type (mime type) Obex headers in the request are supplied in info. See ProvideControlPage() above to see when the ControlPageCallback() is called.


  void ProvideCancel(...)
This method cancels all previous calls to ProvideControlPage().

 


  bool Authenticate(char *passwd)
This method allows an application to test (authenticate) a password for a pending ControlPageCallback() call. It returns TRUE if the supplied plain text passwd value, along with the internal information used in the Authentication Request, matches the encrypted password supplied by the client.
  int CESquirt::GetCapabilities(TESquirtOption &how)
This method returns the supported capabilities of the implementation in how:
  Examples:
	TESquirtOption how;
	GetCapabilities(&how)
	if ((((how.mode & ESQUIRT_BEACON) == ESQUIRT_BEACON) &&
		((how.transport & ESQUIRT_ULTRA) == ESQUIRT_ULTRA))
		// supports sending "hardware style" Ultra beacons


Example Implementation for header files in C/C++

Remember, these are pseudo-code. They're not going to compile.


//
// TCoolReference header
//

#ifndef __TCOOLREFERENCE__
#define __TCOOLREFERENCE__
#ifdef __cplusplus

class TCoolBuffer {
public:
  TCoolBuffer();				// construct an empty TCoolBuffer
  TCoolBuffer(const TCoolBuffer&);		// construct based on existing TCoolBuffer
  TCoolBuffer& operator=(const TCoolBuffer&);	// copy constructor
    
  TCoolBuffer(const unsigned char *value, unsigned int len);	// construct a TCoolBuffer (allocate & copy in value)
  TCoolBuffer(unsigned int len);		// construct a TCoolBuffer (allocate len size buffer)
  ~TCoolBuffer();				// delete content as well

  const unsigned char * Content();		// get a const * to content
  unsigned int Length();			// get length
private:
  unsigned char * iContent; 
  unsigned int iLength;
};
class TCoolReference : public TCoolBuffer;

#else

// A TCoolBuffer is a content block and a length

typedef struct _TCoolBuffer {
  unsigned char * content; 
  unsigned int length;
} TCoolBuffer;

// This would be the base class for a TCoolReference, in C++ systems
// For C-based code, these two types are interchangable

typedef TCoolBuffer TCoolReference;


// define functions to manipulate a TCoolBuffer struct

// malloc an empty ref, no content memory
TCoolBuffer * TCoolBuffer_Allocate();

// malloc a ref & ref->content, copy in content
TCoolBuffer * TCoolBuffer_Allocate(const TCoolBuffer& ref); 

// malloc ref & ref->content, copy in val
TCoolBuffer * TCoolBuffer_Allocate(const unsigned char *value, unsigned int len); 

// malloc ref & ref->content, unintialized
TCoolBuffer * TCoolBuffer_Allocate(unsigned int len);

// free ref->content and then ref
void TCoolBuffer_Free(TCoolBuffer *ref);

// get a const * to content
#define TCoolBuffer_Content(ref)	((unsigned char *) (ref->content))

// get length
#define TCoolBuffer_Length(ref)	(ref->length)


// inline fns & macros to map TCoolBuffer fns to TCoolReference fns

inline TCoolReference * TCoolReference_Allocate() {return TCoolBuffer_Allocate();}

// malloc a ref & ref->content, copy in content
inline TCoolReference * TCoolReference_Allocate(const TCoolReference& ref) {return TCoolBuffer_Allocate(ref);}

// malloc ref & ref->content, copy in val
inline TCoolReference * TCoolReference_Allocate(const unsigned char *value, unsigned int len) {return TCoolBuffer_Allocate(value, len);}

// malloc ref & ref->content, unintialized
inline TCoolReference * TCoolReference_Allocate(unsigned int len) {return TCoolBuffer_Allocate(len);}


// free ref->content and then ref
#define TCoolReference_Free(ref) TCoolBuffer_Free(ref)

// get a const * to content
#define TCoolReference_Content(ref)	((unsigned char *) (ref->content))

// get length
#define TCoolReference_Length(ref)	(ref->length)

#endif
#endif

//
// TESquirtOption header
//
#ifndef __TESQUIRTOPTION__
#define __TESQUIRTOPTION__

// supported values

// Squirting, which means use hp:esquirt as
// either the IAS name (IRDA) and/or
// as the TARGET header value (OBEX) based on
// protocol and transport settings

#define ESQUIRT_SQUIRT		1

// Beaconing, which means use hp:beacon as either
// the IAS name (IRDA) and/or
// as the TARGET header value (OBEX)
// based on protocol and transport settings

#define ESQUIRT_BEACON		2 


// Send/receive using any/all available
// modes/transports/protocols

#define ESQUIRT_AUTO 		0  

#define ESQUIRT_ULTRA		1 // Send/receive using Ultra IR transport
#define ESQUIRT_IRDA		2 // Send/receive using IrDA TinyTp protocol (ESquirt V1)
#define ESQUIRT_BLUETOOTH	4 // Send/receive using BlueTooth (not implemented, future support)
#define ESQUIRT_TCPIP		8 // Send/receive using TCP/IP (not implemented, future support)

#define ESQUIRT_OBEX		2 // Encode/decode content using Obex / Supports PUT for GetCapabilities()
#define ESQUIRT_OBEX_GET	4 // Supports GET for GetCapabilities()

#ifdef __cplusplus

class TESquirtOption {
public:
	TESquirtOption();
	TESquirtOption(unsigned int aMode, unsigned int aTransport, unsigned int aProtocol);

	unsigned int Mode();
	unsigned int Transport();
	unsigned int Protocol();

	void Mode(unsigned int);
	void Transport(unsigned int);
	void Protocol(unsigned int);
private:
	unsigned int iMode;
	unsigned int iTransport;
	unsigned int iProtocol;
};

#else

typedef struct _TESquirtOption {
	unsigned int mode;
	unsigned int transport;
	unsigned int protocol;
} TESquirtOption;

// define functions to manipulate a TCoolReference struct
#define TESquirtOption_Mode(TESquirtOption a) (a.mode)
#define TESquirtOption_Transport(TESquirtOption a) (a.transport)
#define TESquirtOption_Protocol(TESquirtOption a) (a.protocol)

#endif
#endif
//
// CESquirt header file
//
#ifndef __TCOOLREFERENCE__
#define __TCOOLREFERENCE__

#include "TCoolReference.h"
#include "TESquirtOption.h"

// Authentication callback function interface
typedef bool (*AuthCallback)(char * &userName, char * &passWd);

// Control Page request callback function interface
#define ESQUIRT_REQ_AUTH	1  // to request an authentication
#define ESQUIRT_OK 		0  // to indicate payload is valid and should be returned
#define ESQUIRT_FAIL 		-1 // for either (a) fName not found or (b) auth failed
#define ESQUIRT_OBEX_OK 	0xa0  // Obex "success"   200 ok
#define ESQUIRT_OBEX_NOTFOUND 	0xc4  // Obex "not found" 404 error

typedef int (*ControlPageCallback)(char * userName, TCoolReference *data, TCoolFileInfo* info, TCoolBuffer * &pageContent);

#ifdef __cplusplus

class CESquirt {
public:
	// Send()
	int  Send(TCoolReference &data, TESquirtOption &how, AuthCallback auth=0) // send a ref
	int  SendStatus(); 		// returns status of request made above
	void SendCancel(); 		// cancels request made above
	// Recv()
	int  Recv(TCoolReference &data, TESquirtOption &how)	// receive a ref
	int  RecvStatus(); 		// returns status of request made above
	void RecvCancel(); 		// cancels request made above
	// Request a Control Page
	char *GetControlPage(TESquirtOption &how, int &error, TCoolReference *data=0, TCoolFileInfo* info=0, AuthCallback auth=0);		// request control page
	int  GetStatus(); 		// returns status of request made above
	void GetCancel(); 		// cancels request made above
	// Provide a Control Page
	int ProvideControlPage(TESquirtOption &how, TCoolBuffer* unicodeFileName, ControlPageCallback pageRequest);	// provide control page
	void ProvideCancel();		// Stop providing control page
	bool Authenticate(char *passwd);		// authenticate password for pending HandleControlPage()
	// Get capaibilites of this implementation
	void GetCapabilities(TESquirtOption &how)	// see what is supported

	// there may be private data and/or methods used to support async calls
};

#else

// define functions to send/receive/get/provide

// Send
int  CESquirt_Send(TCoolReference &data, TESquirtOption &how, AuthCallback auth=0) 
int  CESquirt_SendStatus(); // returns status of request made above
void CESquirt_SendCancel(); // cancels request made above

// Receive
int  CESquirt_Recv(TCoolReference &data, TESquirtOption &how, ...)
int  CESquirt_RecvStatus(); // returns status of request made above
void CESquirt_RecvCancel(); // cancels request made above

// Request a Control Page
char *CESquirt_GetControlPage(TESquirtOption &how, int &error, TCoolReference *data=0, TCoolFileInfo* info=0, AuthCallback auth=0);		// request control page
int  CESquirt_GetStatus(); 		// returns status of request made above
void CESquirt_GetCancel(); 		// cancels request made above

// Provide a Control Page
int CESquirt_ProvideControlPage(TESquirtOption &how, TCoolBuffer* unicodeFileName, ControlPageCallback pageRequest);	// provide control page
void CESquirt_ProvideCancel();		// Stop providing control page
bool CESquirt_Authenticate(char *passwd);	// authenticate password for pending HandleControlPage()

// Get Capabilities
void CESquirt_GetCapabilities(TESquirtOption &how)

#endif
#endif