Article # 175, added by Geoworks, historical record
| first | previous | index | next | last |

Writing a Socket Link Driver




The following document explains how to write a driver to interface
with TCP/IP and sockets on the Nokia 9000 Communicator.


-----------------------------------------------------------------------------
		     WRITING A SOCKET LINK DRIVER
-----------------------------------------------------------------------------

Include files:

The necessary data structures are in Include/Internal/socketDr.def and
socketInt.def.  There are no GOC equivalents for these files.

Defining entry points:

There are two entry points that must be listed in the
SocketDriverInfoStruct.  The first is the normal driver entry point,
in DIS_entry, the second is the client entry point at
SDIS_clientStrat.

DIS_entry uses the DR_SOCKET_* functions in socketDr.def
SDIS_clientStrat uses the SCO_* functions in socketInt.def
   This field is actually only used for incoming calls.

Configuring the driver:

In the init file, category "[tcpip]" change "link = PPP Driver" to
your own driver.  There is no need to change the linkDomain entry.
Your driver should then know how to load PPP.

At this time, there is no way for your driver to get between PPP and
TCP on incoming calls, since the path to the TCP driver is hard coded
into PPP.  On the other hand, there is also currently no way to
activate PPP's ability to answer incoming calls.

I plan to modify PPP to look up the name of the IP driver from the
init file, probably under "[ppp]"/"ipDriver".  If you cause your
driver to be listed in this key, and set SDIS_clientStrat correctly,
then it will work correctly if and when we enable incoming PPP calls.

General notes:

For most calls (either up or down), you should be able to simply pass
the request through unchanged.  You can do this on the caller's
thread, if you wish, or on your own thread.  However, if TCP calls a
function in your driver, do not call TCP back on the same thread.
Similarly, do not call PPP back with PPP's thread.  Doing so is likely
to cause deadlock.

-----------------------------------------------------------------------------
			     DR functions
-----------------------------------------------------------------------------
These functions are used for calls from TCP into PPP.

DR_INIT/DR_EXIT: the kernel calls this when the driver is loaded/unloaded
DR_SUSPEND/DR_UNSUSPEND: not relevant to the Nokia 9000

DR_SOCKET_REGISTER:
	After loading PPP, TCP will call this to establish certain parameters
	for the call.  
	    domain handle:  this is an ID number that TCP assigns to
	        PPP, which PPP will use to identify itself, in case
	        TCP is using any other link drivers
	    domain name:  PPP ignores this, but pass it through anyway
	    client entry: the address at which PPP will callback to TCP
		(overrides SDIS_clientStrat)
	    SocketDriverType - ignored - should be SDT_LINK
	    client handle:  how TCP will identify itself to PPP, in case
		PPP has any other clients
	    sequenced header size - not relevant
	    datagram header size - the minimum amount of space TCP should
                 reserve in front of any TCP data, so PPP can
		 rewrite the headers in place. 

DR_SOCKET_UNREGISTER:
	When TCP is done with PPP, it will call this to tell PPP to
	clean up and free unneeded resources.

DR_SOCKET_ALLOC_CONNECTION:
	Allocate a connection ID number, which will (presumably) be
	used for a connect request soon.  The ID is allocated before
	connecting so there is a way to identify a particular connect
	request in order to cancel it.

DR_SOCKET_LINK_CONNECT_REQUEST
	Open the serial port, dial the modem, negotiate with the PPP server.

	If there is an immediate error, it will be returned here, otherwise
	the driver will connect asynchronously and call back with the
	result later.

	timeout: the overall time in ticks PPP is allowed to spend connecting
	connection handle:  the ID returned by ALLOC_CONNECTION
	address: the first three fields of a TcpAccpntResolvedAddress
		(link size, link type, and access point ID, but no IP address)

DR_SOCKET_DATA_CONNECT_REQUEST
	Not relevant to PPP

DR_SOCKET_STOP_LINK_CONNECT
	Stop trying to connect.  PPP will call SCO_CONNECTION_CLOSED when
        it has completely shut down the connection.

DR_SOCKET_DISCONNECT_REQUEST
	This is the normal way to shut down a PPP connection.  For PPP,
	the close type is ignored.

DR_SOCKET_SEND_DATA
	Not relevant to PPP

DR_SOCKET_SEND_DATAGRAM
	Send one IP segment over the PPP link.

	buffer	- this is a chunk inside of a Huge LMem (see netutils.def)
             If you resize it, use HugeLMemReAlloc, not LMemReAlloc
	buffer size     - the size of the entire chunk, including headers
	client handle   - as above
	address size	- ignored
	address		- ignored

	The data inside the buffer will be in the following form (note
	that the packet contains duplicates of all the parameters
        listed above)
	
	--------------------------------------
        |                                    |
        |  PacketHeader                      |
        |                                    |
        --------------------------------------
        |                                    |
        |  (optional free space)             |
        |                                    |
        --------------------------------------  <-- PH_dataOffset
        |                                    |
        |   TCP header                       |	
        |                                    |
        --------------------------------------
        |                                    |
        |   IP header                        |
        |                                    |
        --------------------------------------
        |                                    |
        |   data                             |
        |                                    |
        --------------------------------------
        |                                    |
        |   (optional free space)            |
        |                                    |
        --------------------------------------

	The SequencedPacketHeader is defined in socketInt.def, the TCP
        and IP headers are per the RFC.


DR_SOCKET_RESET_REQUEST
	In PPP, this is functionally identical to DR_SOCKET_DISCONNECT_REQUEST,
	sans the ignored close type parameter.

DR_SOCKET_GET_INFO
	Retrieves various useful bits of information from the driver.

DR_SOCKET_ATTACH/REJECT - not relevant to PPP

DR_SOCKET_RESOLVE_ADDR
	PPP just copies the source address to the destination address,
	since there is nothing for it to resolve.

DR_SOCKET_SET/GET_OPTION - not relevant to PPP

DR_SOCKET_STOP_RESOLVE
DR_SOCKET_CLOSE_MEDIUM
DR_SOCKET_MEDIUM_CONNECT_REQUEST
	All of these are irrelevant.

DR_SOCKET_MEDIUM_ACTIVATED
	Requests PPP to handle an incoming call.  This is called directly
	by the datarec geode, and does not come from TCP.  PPP will answer
	the call and set up the connection, then notify TCP of the new
	link via SCO_LINK_OPENED. 

-----------------------------------------------------------------------------
			    SCO Functions
-----------------------------------------------------------------------------

These are the calls PPP makes up to TCP, through the entry point specified
in when TCP registerd with PPP for outgoing calls, or through
SDIS_clientStrat for incoming calls.

SCO_GET_PROTOCOL
	If PPP loads TCP, it usese this to check the revision level
	of TCP's downward API.  (as opposed to the offical geode
	protocol, which refers to the upward API)

SCO_ADD_DOMAIN
	Again, if PPP loads TCP, it registers using this function.  The
	data exchanged is the same as for DR_SOCKET_REGISTER.  Note 
	that TCP does not return a new strategy pointer, however; PPP
	just continues to use SDIS_clientStrat.

SCO_LINK_OPENED
	There is an incoming call.  The address is actually the local
	IP address, not the link address.  (size should be 4)

SCO_LINK_CLOSED
	PPP tells TCP that a phone call has been dropped
	close type is ignored
	error parameter indicates why the call was dropped, if known

SCO_RECEIVE_PACKET
	PPP passes a packet of data to TCP.  The data is in the same
	format as for SCO_SEND_DATAGRAM.  There are no oother
	parameters, since all the relevant data is inside the packet.

SCO_CONNECT_REQUESTED
	Not relevant to TCP

SCO_CONNECT_CONFIRMED	
	The connection TCP requested with DR_SOCKET_LINK_CONNECT_REQUEST
	was successful.  TCP will query DR_SOCKET_GET_INFO to find out
	what the local IP address is.

SCO_CONNECT_FAILED
	The connection TCP requested was not successful.  This is 
	functionally identical to SCO_LINK_CLOSED.