Functionality of the Communications Library - libtmcomm.a v1.0

Created: 5/22/1995

"libtmcomm.a" is the most important library out of the three libraries in CSL/SSL v1.0. All Tsimmis programs that uses CSL/SSL v1.0 must link with "libtmcomm.a".

"libtmcomm.a" provides consistent C data structures, communication facilities, and utility functions to all Tsimmis programs.

*******************
* DATA STRUCTURES *
*******************

"libtmcomm.a" provides two major data structures, "TM_Object" and
"TM_Data".

	* TM_Data   - C structure containing some data value
	* TM_Object - C structure representing an OEM object

"TM_Data" is the basic data unit of most "libtmcomm.a" functions.
"TM_Data" is a variable lengthed byte array with a header containing
size information on the array.  "TM_Data" can be used to encode any
data structures such as string, integer, floats, and other C data
structures.  "libtmcomm.a" functions does not care what is encoded
inside a "TM_Data".  The library functions only uses the size
information of the "TM_Data".

"TM_Object" is the only other data structure that "libtmcomm.a"
understands.  "TM_Object" contains a number of pointers pointing to
the label, type, oid, value (or array of child "TM_Object"'s).  Some
functions in "libtmcomm.a" uses the information stored inside a
"TM_Object".

The only other data types understood by "libtmcomm.a" are regular C
data types.  To avoid imcompatiblity, C data types are redefined into
the following types:

	* uint8, int8	- unsigned and signed char (8 bits)
	* uint16, int16	- unsigned and signed short (16 bits)
	* uint32, int32	- unsigned and signed char (32 bits)

"libtmcomm.a" provides functions to convert each one of above data
types to/from "TM_Data".

*****************
* COMMUNICATION *
*****************

The most basic mode of communication in "libtmcomm.a" provides
transmission of "TM_Data".  All data must be encoded into "TM_Data"
format for transmission.  All data received by "libtmcomm.a" are
assumed to be in "TM_Data" format.  "TM_Data" is the basic unit of
transmission.  "libtmcomm.a" provides synchronous and asynchronous of
"TM_Data" without size and number limits.

"libtmcomm.a" uses BSD sockets for communication purposes.
"libtmcomm.a" does not care about the exact network connection
represented by a socket.  As a result, "libtmcomm.a" is not tied to
any particular network type.  Any network supported by BSD socket can
be used as the underlining network for "libtmcomm.a".

Because "TM_Object" is the most commonly transmitted data in a Tsimmis
program, "libtmcomm.a" provides users with functions to send and
receive "TM_Object" without having converting "TM_Object" into and
from "TM_Data".  When sending, these "libtmcomm.a" functions
``virtually'' converts the given "TM_Object" into "TM_Data" format and
then transmit the object.  When receiving, TM_Data received is
converted back into a TM_Object before returning to the user.

To avoid excess amount of copying, the conversion of "TM_Object" into
"TM_Data" format in the send object function does not make a separate
copy of the given "TM_Object".  Instead, the function directly sends
appropriate number of bytes to the network in such way that when the
stream of bytes is received, the bytes are in the correct format of a
"TM_Data" and contains the values of given "TM_Object".

When converting a "TM_Data" to "TM_Object", no additional memory is
allocated either.  Since "TM_Data" contains all the information in a
"TM_Object" includeing all the label, oid, type, and value in one
contiguous block of memory, the pointers in "TM_Object" is swizzled in
such way that the pointers in "TM_Object" all point to the correct
location.

*************
* INTERFACE *
*************

To access the data types and networking functions defined in
libtmcomm.a, the following two header files can be included.

	tmtypes.h    -- contains data structure functions
	tmconnend.h  -- contains networking functions *

* Inclusion of "tmconnend.h" automatically includes "tmtypes.h".

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tmtypes.h -- Including this header file allows access to following
data types and functions.

Data Types:
----------

  uint8, int8   - unsigned, signed char (8 bits)
  uint16, int16 - unsigned, singed short (16 bits)
  uint32, int32 - unsigned, singed int (32 bits)
  TM_Data       - byte array with size header  
  TM_Object     - C struct representing an OEM object
  TM_ArrObjPtr  - varable array of TM_Object pointers

Functions:
---------

## List of functions and macros available in tmtypes.h ##

       TM_NewData        - allocates new TM_Data
       TM_FreeData       - frees TM_Data
       TM_DataDup        - duplicates TM_Data
       TM_DataToString   - converts TM_Data to string
       TM_StringToData   - converts string to TM_Data
       TM_DataToUint8    - converts TM_Data to uint8
       TM_Uint8ToData    - converts uint8 to TM_Data
       TM_DataToUint16   - converts TM_Data to uint16
       TM_Uint16ToData   - converts uint16 to TM_Data
       TM_DataToUint32   - converts TM_Data to uint32
       TM_Uint32ToData   - converts uint32 to TM_Data
       TM_ObjectToData   - converts TM_Object to TM_Data
       TM_DataToObject   - converts TM_Data to TM_Object
 
       TM_NewObject      - allocates new TM_Object
       TM_FreeObject     - frees TM_Object
       TM_FreeAllObject  - frees TM_Object and all its children
       TM_ObjectAppendChild - adds a child to a non-atomic TM_Object
       TM_ObjectGetChildren - gets children array of a non-atomic TM_Object
       TM_ObjectSetValue - sets the value of an atomic TM_Object
       TM_ObjectGetValue - gets the value of an atomic TM_Object
       TM_ObjectSetOid   - sets the oid of TM_Object
       TM_ObjectGetOid   - gets the oid of TM_Object
       TM_ObjectSetFlag  - sets a flag of TM_Object
       TM_ObjectUnsetFlag - unsets a flag of TM_Object
       TM_ObjectTestFlag - tests a flag of TM_Object
       TM_ObjectSetTotal - sets total number of children of TM_Object
       TM_ObjectGetTotal - gets total number of children of TM_Object
       TM_ObjectSetType  - sets type of TM_Object
       TM_ObjectGetType  - gets type of TM_Object
       TM_IsObjectBinary - is it a binary TM_Object?
       TM_IsObjectAtomic - is it an atomic TM_Object?
 
       TM_GetByteOrder   - gets the byte order of the machine (endian)
       TM_Strdup         - duplicate a C string

## More detailed explaination ##

                * Functions for manipulating TM_Data *

--

TM_Data *TM_NewData(uint32 size)

  Allocates space for a TM_Data structure to contain object of given
  size.

  (Use TM_FreeData() to free memory returned from this function.) 
  
  RETURNS:
	 	- pointer to allocated space
	NULL		- memory allocation failed

--

void TM_FreeData(TM_Data *data)

  Frees the space allocated by TM_NewData().
  
  RETURNS:  
  
--

TM_Data *TM_DataDup(TM_Data *src)

  Duplicates a TM_Data.  Space for a new TM_Data is allocated and the
  content of 'src' TM_Data is copied into the newly allocated TM_Data.

  (Use TM_FreeData() to free memory returned from this function.)
  
  RETURNS:
  		- pointer to duplicate TM_Data
 	NULL		- NULL src, or unable to allocate memory

--

char *TM_DataToString(TM_Data *data)

  Converts a TM_Data to a string.  Space for the string is
  dynamically allocated.  Then the string part of the TM_Data is
  copied into the newly allocated string.

  (Use free() to free memory returned from this function.)

  RETURNS:
		- pointer to the string.
	NULL		- TM_Data is NULL, or unable to allocated memory

--

TM_Data *TM_StringToData(char *str)

  Converts a string to TM_Data.  Memory space is dynamically allocated
  for a new TM_Data structure.  Then the content of 'str' is copied
  into the newly allocated TM_Data structure.

  (Use TM_FreeData() to free memory returned from this function.)

  RETURNS:
 		- a pointer to TM_Data structure
        NULL		- str is NULL

--

uint8  TM_DataToUint8(TM_Data *data)
uint16 TM_DataToUint16(TM_Data *data)
uint32 TM_DataToUint32(TM_Data *data)

  Returns the uint8, uint16, or uint32 containted in a TM_Data structure.

--

TM_Data *TM_Uint8ToData(uint8 value)
TM_Data *TM_Uint16ToData(uint16 value)
TM_Data *TM_Uint32ToData(uint32 value)

  Converts a uint8, uint16, or uint32 into a TM_Data.  Memory space
  for TM_Data is first allocated.  Then the content of the 'value' is
  copied into the TM_Data.

  (Use TM_FreeData() to free memory returned from this function.)

  RETURNS:
 		-- pointer to TM_Data structure

--


               * Functions for manipulating TM_Object *

--

TM_Object *TM_NewObject(uint32 flags)

  Allocates memory space for a TM_Object structure.  The valid flags
  are:
  	TM_OBJECT_BINARY	- TM_Object contains binary value
	TM_OBJECT_ATOMIC	- TM_Object contains atomic value
	
  (Use TM_FreeObject() or TM_FreeAllObject() to free memory returned
  by this function.)
  
  RETURNS:
 	 	- pointer to newly allocated space
 	NULL		- memory allocation failed

--

void TM_FreeObject(TM_Object *object)
void TM_FreeAllObject(TM_Object *root)

  Both function can be used to free space allocated by TM_NewObject().
  TM_FreeObject() frees only the object given.  TM_FreeAllObject()
  frees the given object as well as recursively free any child objects
  connected to the given object.

  RETURNS:  

--

int TM_ObjectAppendChild(TM_Object *parent, TM_Object *child)

  Connects TM_Object 'child' to TM_Object 'parent'.  After the
  connection, 'child' becomes a child object of the 'parent'.
  'parent' TM_Object must be non-atomic.

  RETURNS:
  	< 0		- unable to append child object
 	>= 0		- index of the child object

--

           * Functions for manipulating TM_Object and TM_Data *
	   
--

TM_Data	*TM_ObjectToData(TM_Object *object)

  Creates TM_Data from a TM_Object.  Memory space for the return
  TM_Data is allocated.  Then information in 'object' is copied into
  the resulting TM_Data.  The created TM_Data contains an
  representation of TM_Object that is ready to be transmitted over the
  network.  When this TM_Data is received, it can be readily converted
  back to a TM_Object with some minimal amount of work.

  (Use TM_FreeData() to free memory returned from this function.)

  RETURNS:
  		- pointer to newly allocated TM_Data
 	NULL		- NULL object, or unable to allocate memory
  
--

TM_Object *TM_DataToObject(TM_Data *data)

  Casts a TM_Data containing a TM_Object into a TM_Object.  The caller
  must pass in a valid TM_Data to be casted.  Otherwise, horrible
  memory mangling will take place.  Also, do not call TM_DataToObject()
  twice on the same TM_Data.

  * Note that this function does NOT allocate any new memory block.
  The returned TM_Object pointer points to a location within the given
  TM_Data.

  ** The returned pointer can be safely passed as an argument to the
  memory deallocation function TM_FreeObject() and TM_FreeAllObject().
  The given 'data' can also be freed using the function TM_FreeData().
  After any one of the three memory deallocation function is called,
  neither given 'data' nor the returned pointer to TM_Object points
  to valid memory location.
  
  RETURN
	 		- pointer to the TM_Object
	 NULL			- NULL data


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tmconnend.h -- Including this header file allows access to all data types
and functions declared in "tmtypes.h" as well as the following network
related data types and functions.

Data Types:
----------

  TM_ConnEnd    - Data structure representing a network connection end
                  that can send/receive TM_Data.
		  
  TM_EventFlag  - Valid flags used to determine how to handle network
                  events.  Valid values are:

			TM_NONE_BLOCKING
			TM_BLOCK_ONE
			TM_BLOCK_ALL   
  
  TM_Result     - Return results from networking functions.  Valid
                  values are:
		  
			 TM_IN_PROGRESS
			 TM_SUCCESS
			 TM_NET_ERROR
			 TM_BAD_CONNEND

  TM_CommFlag   - Valid flags to determine how to execute a network
                  function.  Valid values are:
		  
			 TM_SYNC
			 TM_ASYNC
			 
  TM_Error      - Error code returned by functions.  Consult
                  "tmerror.h" for detailed listing of all possible
		  error codes.

Functions:
---------

## List of functions and macros available in tmconnend.h ##

 	TM_InitConnEnd		- initializes network code, call once
 	TM_ShutdownConnEnd	- shuts down network code, call once

	TM_CreateConnEnd	- creates a brand new connection end
        TM_DeleteConnEnd	- deletes a connection end

	TM_SendData		- sends TM_Data through a connection end
	TM_SendObject		- sends TM_Object through a connection end
	TM_RecvData		- receives a TM_Data from a connection end
	
	TM_DoOneConnEndEvent	- handles async. network event
        TM_DoOneRecv		- do one receive event
        TM_DoOneSend		- do one send event

## More detailed explaination ##

--

TM_Error TM_InitConnEnd(void)

  Performs initialization code neccessary for proper functioning of
  subsequent network calls.  Call this function once before calling
  any other network functions.

  RETURNS:
  	TM_NO_ERROR		- no error
 	TM_ERR_MEMORY		- unable to allocate memory

--

TM_Error TM_ShutdownConnEnd(void)

  Shuts down all network functions.  This routine deletes all
  outstanding connection ends.  Any outstanding asynchronous send or
  receive calls will return with TM_BAD_CONNEND after this call
  finishes.
  
  RETURNS:
 	TM_NO_ERROR

--

TM_ConnEnd *TM_CreateConnEnd(int16 sock)

  Creates a new connection end on given socket 'sock'.  The given
  'sock' must be a valid BSD socket that has been openned and
  connected.  Ths 'sock' must be opened to send and receive data
  streams.  The actual network that 'sock' is connected with does not
  matter.

  After calling this routine on 'sock', the 'sock' should be
  considered as being surrendered to the libtmcomm.a's network
  interface.  The caller should not explicitly use 'sock' until
  after calling TM_DeleteConnEnd.

  User can make many calls to TM_CreateConnEnd().  Each call returns a
  different TM_ConnEnd allowing user to communicate with many other
  applicates at the same time.  However, do not try to create more
  than one TM_ConnEnd on a single socket.
  
  RETURNS:
  		- pointer to a new ConnEnd
 	NULL		- unable to create a new ConnEnd

--

void TM_DeleteConnEnd(TM_ConnEnd *conn)

  Deletes the given connection end.  The data structure is freed and
  the socket that correspond with the connection is considered
  returned to the caller upon return of this call.  The caller can
  explicitly use the socket after this call returns.  Any outstanding
  asynchronous send/receive requests on this connection end will
  finish with the flag set to TM_BAD_CONNEND.

  RETURNS:    

--

TM_Error TM_SendData(TM_ConnEnd         *conn,
		     TM_Data            *data,
		     TM_Result		*result,
		     TM_CommFlag        flag)

  Sends a TM_Data through a connection end.  This function
  can be called asychronously.  To do so, pass TM_ASYNC as the value
  for 'flag', and pass in a pointer to a TM_Result in 'result'.

  When executing asychronously, the function returns immediately with
  the value TM_NO_ERROR.  The user must check the TM_Result pointed by
  'result' to find out when the data has been completely send over.
  
  When using in the asynchronous mode, many consecutive calls to this
  routine can be made on the same connection end.  The requests are
  processed in FIFO order.  If this function is called synchronously
  (with flag value of 0, or TM_SYNC),  the function returns after the
  data has been send.  The result of sending is placed in 'result'.
  
  The following values can be returned in *result:

      	TM_IN_PROGRESS		- send is in progress (async. mode only)
	TM_SUCCESS		- send completed successfully
	TM_NET_ERROR		- send failed because of an network error
	TM_BAD_CONNEND		- send failed because of bad TM_ConnEnd
	
  RETURNS:
 	TM_NO_ERROR		- no error
	TM_ERR_MEMORY           - memory problem
 	TM_ERR_CONNEND  	- bad TM_ConnEnd
	TM_ERR_RESULT		- result argument is NULL (in async. mode)
 	TM_ERR_SEND		- error during sync. send, check 'result'

--

TM_Error TM_SendObject(TM_ConnEnd     *conn,
		       TM_Object      *object,
		       uint8          net1,
		       uint8          net2,
		       TM_Result      *result,
		       TM_CommFlag    flag)

  Sends a TM_Object through a connection end as a TM_Data.  By using
  this function, no convertion of the TM_Object into a TM_Data is
  needed before a TM_Object is send through a connection end.

  'net1' and 'net2' are flags passed in for partial fetch protocol
  (described in FETCH.DOC).  In TM_SendData(), these two flags are set
  in 'net1' and 'net2' field of the TM_Data structure.  Since
  TM_Object does not contain these fields, the flags must passed in
  directly.
  
  To do so, pass TM_ASYNC as the value  for 'flag', and pass in a
  pointer to a TM_Result in 'result'.  When executing asychronously,
  the function returns immediately with the value TM_NO_ERROR.  The
  user must check the TM_Result pointed by 'result' to find out when
  the data has been completely send over. 
  
  When using in the asynchronous mode, many consecutive calls to this
  routine can be made on the same connection end.  The requests are
  processed in FIFO order.  If this function is called synchronously
  (with flag value of 0, or TM_SYNC),  the function returns after the
  data has been send.  The result of sending is placed in 'result'.
  
  The following values can be returned in *result:

      	TM_IN_PROGRESS		- send is in progress (async. mode only)
	TM_SUCCESS		- send completed successfully
	TM_NET_ERROR		- send failed because of an network error
	TM_BAD_CONNEND		- send failed because of bad TM_ConnEnd
	
  RETURNS:
 	TM_NO_ERROR		- no error
	TM_ERR_MEMORY           - memory problem
 	TM_ERR_CONNEND  	- bad TM_ConnEnd
	TM_ERR_RESULT		- result argument is NULL (in async. mode)
 	TM_ERR_SEND		- error during sync. send, check 'result'

--

TM_Error TM_RecvData(TM_ConnEnd       *conn,
		     TM_Data          **dataPtr,
		     TM_Result	      *result,
		     TM_CommFlag      flag)

  Receives a TM_Data through a connection end.  This function can be
  called asychronously.  To do so, give TM_ASYNC as the 'flag', and
  pass in a pointer to a TM_Result in 'result'.

  When executing asychronously, the function returns immediately with
  the value TM_NO_ERROR.  The user must check the 'result' value to
  find out when the data has been completely received.

  When using in the async. mode, many consecutive calls to this
  routine can be made on the same connection end.  The requests are
  processed in FIFO order.  If calling this function in synchronous
  mode (flag == TM_SYNC), the status of receive is returned in
  'result'.

  The following values can be returned in *result:

      	TM_IN_PROGRESS		- send is in progress (async. mode only)
	TM_SUCCESS		- send completed successfully
	TM_NET_ERROR		- send failed because of an network error
	TM_BAD_CONNEND		- send failed because of bad TM_ConnEnd
	
  RETURNS:
 	TM_NO_ERROR		- no error
	TM_ERR_MEMORY           - memory problem
 	TM_ERR_CONNEND  	- bad TM_ConnEnd
	TM_ERR_RESULT		- result argument is NULL (in async. mode)
 	TM_ERR_RECV		- error during sync. recv, check 'result'
  

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~