Mottek: 2003-02-02

Near Misses

A pretty nasty problem showed up that required going deeper into the endpoint mechanism: Asynchronous data transfer. It is needed because the NewtonScript world works based on the execution of small, non-blocking pieces of code that either return quickly or kick off some sort of background task (such as the whole endpoint infrastructure). One of the central points of data handling in a NewtonScript-based communication application is therefore the InputScript that processes incoming data received by an endpoint. There is no blocking read. This is something to get used to and confuses programmers regularily. For that reason, more "recent" example code from Apple introduced finite state machines which deal with these asynchronous events on the NewtonScript side. In the C++ world, most things are however pretty standard (one reason why a rewrite of parts of NHttpLib, Raissa and MAD Max in C++ could be very promising).

The problem in the IrCOMM case is that data reception is not handled by the nRcv function in the endpoint but in the endpoint's event handler code. I hadn't looked into that mechanism before, but fortunately, the event handling code is part of the TEndpoint protocol interface and can be overridden. In the process of mapping the mechanism, some of the classes and data structures had to be reverse engineered as well. It was not too painful - usually, it is possible to gain some understanding by looking at the C++ constructor and the initialization code. But nevertheless, I think that reverse engineering data structures is more tedious than trying to understand code.

Asynchronous reception of data works now. With one little problem left: sending a packet when handling an incoming packet doesn't seem to work correctly. It is needed to advance TinyTP credits to the peer. The situation becomes critical when a large amount of data is sent from the peer. If the peer doesn't get any credit, it just stops. The solution to this is to either find a way to send data properly in the event handler or set up some sort of idle handler in a different thread that checks the remote credit from time to time and sends a packet if needed. Time to look at more event handler code!