Compact, Fast, Robust, Portable Kermit File Transfer for Embedding
Version: 1.51In the News: E-KERMIT ASSISTS IN HURRICANE TRACKING (September 2004)
Date: 23 September 2004
This Page Last Updated: Wed Feb 15 14:22:22 2006
[ Announcement ] [ Kermit Project Home ]
EK (Embedded Kermit, E-Kermit) is an implementation of the Kermit file transfer protocol written in ANSI C and designed for embedding in devices or firmware, use in realtime applications, or for construction of DLLs and libraries.
kermit@columbia.edu
Customers have adapted EK to various environments and platforms, including the Palm Pilot, various kinds of technician equipment (e.g. for diagnosis and maintenance of cell towers), and sometimes they contribute their adaptations or i/o routines, and we can make these available on request at no extra cost on a strictly as-is basis. We are not able to support or maintain customer-contributed code; thus (for example) if a new version of EK is released, customer-contributed modules are not necessarily updated. Customer-contributed code includes:
EK includes the following Kermit Protocol features:
The following Kermit Protocol features are not implemented:
Timeouts would be the responsibility of the Kermit program on the other end of the connection or, if needed in E-Kermit itself, the platform-dependent packet-reading routine which you would write.
As of version 1.5, E-Kermit includes preprocessor constructions to let you exclude various features such as long packets, sliding windows, and higher-order block checks to achieve the smallest possible memory footprint, and can also be built in a Receive-Only configuration.
EK is designed to work in a cooperative multitasking environment but does not require such an environment. The control program takes care of scheduling. Here's what the control program must (and/or can) do:
(When E-Kermit is to receive files, it waits passively for first packet from the file sender; thus it simply enters the packet loop.) In the packet loop, E-Kermit:
Each time the control program calls the kermit() function, this grants it permission to handle one packet; thus one packet = one time slice. If the control program has nothing else to do, it simply processes packets continously, like a regular Kermit program. While in the data-transfer loop, every kermit() call returns a struct containing:
When done, the control program:
The function codes that the control program may call kermit() with are:
K_INIT -- Initialize data structures.
K_SEND -- (Sending only) -- Initiate sending.
K_RUN -- Run the protocol.
K_STATUS -- Return a status report in the k_response struct.
K_QUIT -- Quit immediately and silently.
K_ERROR -- Send Error packet, then quit.
The return codes of the kermit() function are:
X_OK -- OK, protocol active.
X_DONE -- OK, protocol complete.
X_ERROR -- Fatal error.
X_STATUS -- Returning status in response to K_STATUS.
(In fact status is retuned with every call.) Protocol state codes are:
-1 -- Fatal error
0 -- Receiver (protocol not running)
1 -- Receiver waiting for S packet
2 -- Receiver waiting for F or B packet
3 -- Receiver waiting for A or D packet
4 -- Receiver waiting for D or Z packet
10 -- Sender (protocol not running)
11 -- Sender sent S packet (start)
12 -- Sender sent F packet (filename)
13 -- Sender sent A packet (attributes)
14 -- Sender sent D packet (data)
15 -- Sender sent Z packet (EOF)
16 -- Sender sent B packet (EOT)
Because EK is designed primarily for embedding, it does not use streaming or true sliding windows (although much of the sliding windows code is there). This is for the following reasons:
The lack of true sliding windows is compensated by having EK pretend to support them without really doing so. This allows its sending partner to "stream" packets rather than waiting for ACKs after each one, as long as there isn't an error. If there is an error, the recovery strategy is "go back to n" (or perhaps in some cases "error out") rather than "selective repeat".
In any event, since EK is intended primarily for embedding, it is anticipated that round-trip delays won't be a big factor; connections will generally be local, short, relatively fast, and if the connection is effectively flow controlled, error-free. When effective flow control is lacking, the speed and/or packet length and/or window size can be set to a combination of values that maximizes throughput and minimizes data loss.
Should true sliding windows or streaming be required for a particular application, they can be added.
The source files are:
The single entry point for the kermit.c module is the kermit() function:
int kermit(struct k_data * k, struct k_response * r)
The k structure contains all the operating parameters, variables, state information, and buffers; the r struct keeps the caller informed of the current state of the protocol, filename and file info, and transfer progress (bytes so far).
Development of EK takes place on a conventional Unix platform, such as Solaris, HP-UX, or Linux, in which EK is built as a remote-mode Kermit file transfer program, similar to G-Kermit, and tested against a desktop Kermit such as K95 or C-Kermit. NOTE: The Unix version works over stdin/stdout; the "line" is conditioned in the stupidest possible way (system("stty ...")). This gives variable results; e.g. downloads from EK on Solaris might run at 17Kcps, whereas downloads from Linux on the same net to the same PC might run at 1700Kcps. This is not worth worrying about because EK is not intended for production use on Unix, which already has G-Kermit and C-Kermit for production.
The Unix makefile has the following targets (it's easy to add more):
gcc: Build with gcc (default).
cc: Build with cc.
hp: Build for HP-UX.
gccnd: Build with gcc, no debugging.
gprof: Build with gcc, include profiling.
clean: Remove object and core files.
The makefile creates a Unix executable called "ek" (embedded kermit). The sample main() routine provides a simple command-line interface:
$ ./ek -h Usage: ./ek options Options: -r Receive files -s files Send files -p [neoms] Parity: none, even, odd, mark, space -b [123] Block check type: 1, 2, or 3 (default = 3) -k Keep incompletely received files -B Force binary mode -T Force text mode -R Remote mode (vs local) -L Local mode (vs remote) -E number Simulated error rate (0-100) -d Create debug.log -h Help (this message) $
When sending files, if you don't specify Text or Binary, EK scans each file and chooses text or binary mode based on its contents.
Remote vs Local mode is used only to enable the test for keyboard interruption of file transfer.
Version 1.0 of EK was ported to VxWorks by Airvana, Inc, Chelmsford MA. The complete VxWorks EK 1.1 package is included as an example of a production system by Airvana's permission (note that the EK API has changed slightly since then, so before the VxWorks code can be used, it must be updated). To port to a new platform:
#define NODEBUG to build without debugging code.
#define HAVE_UCHAR if UCHAR is already defined or typedef'd to unisgned char.
#define HAVE_ULONG if ULONG is already defined or typedef'd to unisgned long.
#define IBUFLEN to be the desired size for the file input buffer.
#define OBUFLEN to be the desired size for the file output buffer.
#define FN_MAX to be the maximum length for a filename.
#define P_PKTLEN to override the default maximum packet length.
#define P_WSLOTS to override the default maximum window slots.
Here are a few tips for creating an i/o module:
The device i/o routines are expected to handle communications parameters themselves, including communication line speed, parity, and flow control. In particular, Kermit does not handle parity, but still must be told about it. This is done in the setup by main(). Your readpkt() and tx_data() routines should strip and add parity, respectively, if necessary. On serial connections, maybe the UART can be programmed to do this.
Note that calling conventions (argument lists and return values) were changed between version 1.1 to 1.2, mainly to give all routines access to the k struct in a consistent way, and also to provide better feedback to the caller. In each case where a change was made, both the old and the new format are shown.
The device i/o functions are:
Note the F_CTRLC feature. This is enabled by default. It allows EK to be broken out of packet mode by sending it three consecutive Ctrl-C's. You normally would not need to disable this since, even if the sender is "unprefixing" Ctrl-C, three of them in a row would normally be collapsed into a repeat-count sequence.
The file i/o functions are as follows; of course they can be used for reading or writing anything -- not just files: memory, tape, cards, laser beams, instrument controllers, whatever. It doesn't matter what you call these routines, but the argument list and return type must be as shown; also if you give them different names, you'll have to change the prototypes in kermit.h:
The precise calling conventions are shown in the unixio.c file.
If EK was built without NODEBUG defined, then if you include the -d option on the command line, the Unix-based sample version of EK creates a debug.log file in its current directory. In the production version, you would add -DNODEBUG to the C compiler CFLAGS to eliminate the debugging code. The sizes shown above include debugging. You can implement the debug function any way you want in your platform-specific i/o module.
Version | Date | Description |
1.1 | 2002/10/07 | Initial release. |
1.2 | 2003/01/28 | Improved API |
1.3 | 2004/03/04 | Fix file transfer with HyperTerminal. |
1.4 | 2004/03/20 | Fix reception of empty files. |
1.5 | 2004/04/10 | Fix problem with A-packets, allow super-small and/or receive-only configurations. |
1.51 | 2004/09/23 | Adapt to Philips XAG30 (John Dunlap) |
[ Top ] [ Kermit Home ]