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.