GEOS SDK TechDocs
|
|
3 Sending Data
|
5 Disconnecting
When the modem driver receives notification that data has arrived on the port, it sends a pre-registered message to a specified object. (You specify both the object and the message when you call
ModemConnect()
.)
In the MTalk example, the driver sends MSG_MTALK_PROCESS_READ_DATA to the process object when data has arrived on the port. The handler for this message is shown in Receiving Data Over A Serial Connection .
To receive data, MTalk does the following:
ModemReceive()
(defined in modem.goc) to read incoming dataCode Display 9-3 Receiving Data Over A Serial Connection
@method MTalkProcessClass, MSG_MTALK_PROCESS_READ_DATA
{
/*
* recvDataSize - Amout of data actually read in.
* recvDataPtr - Pointer to data to read in.
* retVal - Return value of ModemReceive().
*/
word revDataSize;
char * recvDataPtr;
StreamError retVal;
/*
* Check to see if connection is still open. Because of message queueing
* delays, we may have received this data notification after the connection
* has been closed.
*
* ConnectionOpen - global flag that keeps track of whether
* the connection is open or closed.
*/
if ( ConnectionOpen == FALSE )
{
return;
}
/*
* Lock the input buffer down on the heap, and obtain a pointer to it.
* (Note: This buffer is a memory block that was allocated in the
* "Connecting" example.)
*/
recvDataPtr = MemLock( recvBuffer );
/*
* A NULL pointer means that the memory manager has gone ahead
* and discarded the buffer block since the last time it was
* unlocked. So we need to reallocate it here. Note that the
* MemHandle is still in use; it just isn't bound to any block of memory.
*/
if ( recvDataPtr == NULL )
{
/*
* Reallocate the block, locking it immediately,
* so it doesn't get discarded again. If the block cannot
* be re-allocated, memory must be low so close the connection.
*/
if (( MemReAlloc( recvBuffer, RECV_BUFFER_SIZE, HAF_LOCK ) == NullHandle)
{
@send self::MSG_MTALK_PROCESS_CLOSE();
return;
}
/*
* After re-allocating the locked block, dereference its handle
* to obtain a pointer to it.
*/
recvDataPtr = MemDeref( recvBuffer );
}
/*
* Read available data up to the size of our buffer then display it.
*/
if ( ModemReceive( RECV_BUFFER_SIZE, (byte*)recvDataPtr, &recvDataSize )
== STREAM_NO_ERROR )
{
@call MTalkOutText::MSG_VIS_TEXT_APPEND_PTR( recvDataPtr,
recvDataSize );
}
/* * If the read data filled the entire buffer, there's a good * chance more data is available so send the message through the * process object's queue again. (We do not want to keep reading * in a loop in case the other side dumped a very large stream * of data; this would keep the process object from handling * other messages in its queue.) */
if ( RECV_BUFFER_SIZE == recvDataSize ) {
@send ,forceQueue self::MSG_MTALK_PROCESS_READ_DATA();
}
/*
* Once all the data has been read, unlock the buffer block.
*/
MemUnlock( recvBuffer );
} /* end of MSG_MTALK_PROCESS_READ_DATA */
Like
ModemSend()
,
ModemReceive()
calls a VirtualSerial routine,
VirtualSerialRead()
, to read incoming data. Because no blocking is specified,
VirtualSerialRead()
reads only data that is currently available in the stream. (If you want the routine to block until there is enough data in the stream to fill the entire buffer, pass STREAM_BLOCK in
VirtualSerialRead()
.)
ModemReceive()
takes three arguments:
ModemReceive()
writes the number of bytes actually read in to this parameter.
ModemReceive()
returns a
StreamError
value:
GEOS SDK TechDocs
|
|
3 Sending Data
|
5 Disconnecting