SuperCom - Serial Communication Library
SuperCom is a universal communication library. Using only few functions you already get a complete serial communication program within few lines. SuperCom was from the beginning designed and developed having robustness and portability in mind.
SuperCom ActiveX is a communication ActiveX control. MSComm compatible and much more. Enhance your Visual Basic application easily. Can be used with many compilers like Visual C++, Visual Basic, C#, Delphi, etc.
Easy Handling
The following short program demonstrates how small a data communication program can be when using SuperCom and how fast one can write one:
C/C++
char *Msg = "Hello World";
ComInit(COM_2);
ComSetState(COM_2, 57600, 8, 1, 'N', SIGNAL_CTS);
RS_TXPacket(COM_2, Msg, strlen(Msg), &Result);
ComReset(COM_2);
Delphi
Msg := 'Hello World';
ComInit(COM_2);
ComSetState(COM_2, 57600, 8, 1, 'N', SIGNAL_CTS);
RS_TXPacket(COM_2, Msg, Length(Msg), Result);
ComReset(COM_2);
C#
string Msg = "Hello World";
byte[] Buffer;
SuperCom.ComInit(COM_2);
SuperCom.ComSetState(COM_2, 57600, 8, 1, 'N', SIGNAL_CTS);
Count=StringToBuffer(Msg, Buffer); // custom function
SuperCom.RS_TXPacket(COM_2, Buffer, Count, ref Result);
SuperCom.ComReset(COM_2);
Visual Basic
Msg = "Hello World"
Call ComInit(COM_2)
Call ComSetState(COM_2, 57600, 8, 1, Asc("N"), SIGNAL_CTS)
Call RS_TXPacket(COM_2, Msg, Len(Msg), Result)
Call ComReset(COM_2)
|
What amazes programmers over and over again is that using SuperCom the programming language is of minor interest.
Let's explain the above lines a bit:
The function ComInit configures the second serial port (on Windows "COM2", on Linux "ttyS1"). ComSetState applys the communication parameters and flow control. Now the connection is ready to transfer data. The function RS_TXPacket transmits the data packet Msg through the serial interface and ComReset finaly closes all actions on the serial interface and restores its previous state.
The next small sample shows an elegant solution to a common problem: What serial ports are available in the system (installed and not used).
Available Serial Ports
WORD wPortCount=0;
WORD wPortReady=0;
BYTE i;
printf("scaning hardware...");
for (i=COM_1; i<MAX_COM; i++)
{
switch (ComPortPresent(i))
{
case PORT_AVAILABLE_READY: wPortReady++;
// port is not used by any application
case PORT_AVAILABLE_BUSY: wPortCount++;
// port is used by any application
break;
case PORT_UNAVAILABLE:
// hardware is not installed
break;
}
}
Hint: see also ComPortPresentEx
|
Event Driven
An application using SuperCom can be event driven. Events are reported for: received or transmitted data, modem status, line errors, modem dialup status, file transmit status, plugging or unplugging serial PnP devices (serial comm port insertion/removal), TCP/IP network failures.
The enhanced event reporting mechanism in SuperCom also enables you to receive events on any defined character (e.g. STX, ACK, NAK, EOF).
Type and amount of the events is also related to the used SuperCom software e.g. a SuperCom supporting only serial communications will not report TCP/IP network events.
Event function receiving communications events
C/C++
// optional event function
DWORD COMMAPI OnComm (Com, SComEvent)
{
if (SComEvent & EV_TXCACHE_EMPTY)
// ...
if (SComEvent & EV_RXCHAR)
// ...
if (SComEvent & EV_RI)
// ...
if (SComEvent & EV_TRIGGER)
// ...
:
:
return 0;
}
:
:
// init ...
ComInit(Com);
// activate event reporting ...
ComGetSetEventProc(Com, OnComm);
Visual Basic
' optional event function
Function OnComm(Com, SComEvent) As Long
OnComm = 0
If (SComEvent And EV_RXCHAR) Then
// ...
If (SComEvent And EV_TXEMPTY) Then
// ...
If (SComEvent And EV_RI) Then
// ...
If (SComEvent And EV_TRIGGER) Then
// ...
:
:
End Function
:
:
// init ...
ComInit(Com);
// activate event reporting ...
ComGetSetEventProc(Com, OnComm);
Delphi
// optional event function
Function UserEventProc(Com, SComEvent):DWORD;
Begin
OnComm := 0; { Continue }
If (SComEvent And EV_TXCACHE_EMPTY) Then
// ...
If (SComEvent And EV_RXCHAR) Then
// ...
If (SComEvent And EV_RI) Then
// ...
If (SComEvent And EV_TRIGGER) Then
// ...
:
:
End;
:
:
// init ...
ComInit(Com);
// activate event reporting ...
ComGetSetEventProc(Com, OnComm);
C#
// optional event function
public int OnComm(Com, SComEvent)
{
if ((SComEvent & SuperCom.EV_RXCHAR)==SuperCom.EV_RXCHAR)
// ...
if ((SComEvent & SuperCom.EV_TXCACHE_EMPTY)==SuperCom.EV_TXCACHE_EMPTY)
// ...
if ((SComEvent & SuperCom.EV_RI)==SuperCom.EV_RI)
// ...
if ((SComEvent & SuperCom.EV_TRIGGER)==SuperCom.EV_TRIGGER)
// ...
:
:
return 0;
}
:
:
// init ...
SuperCom.ComInit(Com);
// activate event reporting ...
SuperCom.ComGetSetEventProc(Com, OnComm);
|
Connecting
Establishing connections through a Modem, TAPI, TCP/IP or ISDN is taken care by the common connect functions. The SuperCom functions can establish a connection (dialup) or waiting on an incoming call (server) and execute (on request) completely in background.
The SuperCom functions can trigger events during a connection attempt and provide the application with status information. So, even it executes in background the application stays in touch with the happening.
Modem Connection, OnConnect - InfoProc
C/C++
// optional event function
int OnConnect(Com, Action, TimeLeft, Data)
{
if (Action==acCONNECT_INFO)
{
// Received periodically, while in progress
}
if (Action==acCONNECT_OK)
{
// Connected !
}
if (Action==acCONNECT_FAILED)
{
// A connection attempt failed
}
if (Action==acCONNECT_USERBREAK)
{
// User interrupted
}
return infContinue;
}
:
:
// init ...
ComInit(Com);
// now connect ...
Res = RS_ConnectEx(Com, SEC_60, , DialStr, OnConnect);
Visual Basic
' optional event function
Public Function OnConnect(Com, Action, TimeLeft, Data) As Long
If Action = acCONNECT_INFO Then
'Received periodically, while in progress
End If
If Action = acCONNECT_OK Then
' Connected !
End If
If Action = acCONNECT_FAILED Then
' A connection attempt failed
End If
If (Action=acCONNECT_USERBREAK) Then
' User interrupted
End If
OnConnect = infContinue
End Function
:
:
' init ...
Call ComInit(Com)
' now connect ...
Res = RS_ConnectEx(Com, SEC_60, ,DialStr, OnConnect)
Delphi
// optional event function
Function OnConnect (Com, Action, TimeLeft, Data):Integer;
Begin
OnConnect:=infCONTINUE; { Continue }
If (Action = acCONNECT_INFO) Then
Begin
// Received periodically, while in progress
End;
If (Action = acCONNECT_OK) Then
Begin
// Connected !
End;
If (Action = acCONNECT_FAILED) Then
Begin
// A connection attempt failed
End;
If (Action = acCONNECT_USERBREAK) Then
Begin
// User interrupted
End;
End;
:
:
// init ...
ComInit(Com);
// now connect ...
Res = RS_ConnectEx(Com, SEC_60, ,DialStr, @OnConnect);
C#
// optional event function
public int OnConnect(Com, Action, TimeLeft, Data)
{
switch (Action)
{
case SuperCom.acCONNECT_INFO:
// Received periodically, while in progress
break;
case SuperCom.acCONNECT_FAILED:
// A connection attempt failed
break;
case SuperCom.acCONNECT_OK:
// Connected !
break;
case SuperCom.acUSERBREAK:
// User interrupted
break;
}
return SuperCom.infCONTINUE;
}
:
// init ...
SuperCom.ComInit(Com);
// now connect ...
Res = SuperCom.RS_ConnectEx(Com,SuperCom.SEC_10,,DialStr,cbOnConnectInfoFunc);
|
Seting up a connection can run completely in background. The application receives events about the progress.
Comparing this sample made for a serial Modem with the one for TCP/IP or ISDN shows how effective it is to have a portable API!
File Transfer Protocols
SuperCom provides reliable and high speed file transfer protocols. These protocols are widely used and supported by many third party applications (e.g. ZMODEM, YMODEM/BATCH, YMODEM, YMODEM-G, XMODEM-1K, XMODEM, XMODEM/CRC, KERMIT, Extended XMODEM and ASCII).
One of the most powerful among these protocols is ZMODEM that includes important features like "crash recovery", 32bit CRC, "batch file transfer", File Options, ZMODEM/8k block option and the powerful ADONTEC extension ZMODEM/32k (ZMODEM/64k shipped on request). The SuperCom ZMODEM implementation also includes support for slow communication channels and high latency connections (e.g. Satellite lines).
The KERMIT protocol and the Extended XMODEM are also offering a lot of interesting options.
Autodownload
is a file transfer protocol feature that enables the automated receive of a file transmitted from a remote host machine. Autodownloading is actually supported with the ZMODEM, KERMIT and Extended XMODEM protocol.
A file transfer is very easy started by one function. The protocol then triggers events to inform about status and other usefull protocol information. Events are received by a so called *. The OnFile function is optional but very handy in many situation e.g. to receive progress information, to cancel a file transfer. A protocol like ZMODEM or YMODEM/BATCH can receive many files within on session. The OnFile will provide such information.
File Transfer, OnFile - InfoProc
C/C++ Sample
// optional event function
int COMMAPI OnFile(Com, Action, DataCount, FileData)
{
int Res=infCONTINUE;
if (Action==acSYN)
{
// Synchronization
}
if (Action==acRXING)
{
// A block of data received
}
if (Action==acTXING)
{
// A block of data transmitted
}
if (Action==acTXFIN)
{
// File successfully transmitted
}
:
return Res;
}
:
// Transmit a file ...
RS_TXFile_ZMODEM(Com, FName, , OnFile);
Visual Basic
' optional event function
Public Function OnFile(Com, Action, DataCount, FileData) As Long
If Action = acSYN Then
'Synchronization
End If
If Action = acRXING Then
' A block of data received
End If
If Action = acTXING Then
' A block of data transmitted
End If
If Action = acTXFIN Then
' File successfully transmitted
End If
:
OnFile = infContinue
End Function
:
:
' Transmit a file ...
Res = RS_TXFile_ZMODEM(Com, FName, , OnFile)
Delphi
// optional event function
Function OnFile (Com, Action, DataCount, FileData):Integer;
Begin
OnFile:=infCONTINUE; { Continue }
If (Action = acSYN) Then
Begin
// Synchronization
End;
If (Action = acRXING) Then
Begin
// A block of data received
End;
If (Action = acTXING) Then
Begin
// A block of data transmitted
End;
If (Action = acTXFIN) Then
Begin
// File successfully transmitted
End;
:
End;
:
:
// Transmit a file ...
Res = RS_TXFile_ZMODEM(Com, FName, , @OnFile);
C#
// optional event function
public int OnFile(Com, Action, DataCount, FileData)
{
switch (Action)
{
case SuperCom.acSYN:
// Synchronization
break;
case SuperCom.acRXING:
// A block of data received
break;
case SuperCom.acTXING:
// A block of data transmitted
break;
case SuperCom.acTXFIN:
// File successfully transmitted
break;
:
}
return SuperCom.infCONTINUE;
}
:
:
// Transmit a file ...
Res = SuperCom.RS_TXFile_ZMODEM(Com, FName,,,cbOnFileInfoFunc);
|
With the SuperCom library each protocol can run on any established connection concurrently and in background. Queues of files to transfer are also possible to create and monitor (file-server etc.).
The following samples are using the ActiveX API like class "TSCom" of the SuperCom .NET Class Library. It is the same API used for serial connections, TCP/IP and ISDN.
Establish a serial modem connection and file transfer
C# Sample
using ADONTEC.Comm; // see C# source in SComClass.cs
: // VB Net references the class DLL
:
public class MYSCOM : TSCom
{
public MYSCOM(int CommId, Form frm)
: base(CommId, frm) // pass the window handle to TSCom
{
}
protected override void OnComm(OnCommEventArgs e) [OnComm +-]
{
int SComEvent = (int)e.EventCode;
if (SuperCom.BitsSet(SComEvent, SuperCom.EV_RXCHAR))
if (SuperCom.BitsSet(SComEvent, SuperCom.EV_TXEMPTY))
if (SuperCom.BitsSet(SComEvent, SuperCom.EV_TRIGGER))
if (SuperCom.BitsSet(SComEvent, SuperCom.EV_RING))
:
:
e.RetCode = 0;
}
protected override void OnConnect(OnConnectEventArgs e) [OnConnect +-]
{
switch (e.Action) // handle event
{
case SuperCom.acCONNECT_INFO:
case SuperCom.acCONNECT_DIALING:
case SuperCom.acCONNECT_OK:
:
:
}
}
protected override void OnFile(OnFileEventArgs e) [OnFile +-]
{
switch (e.Action)
{
case SuperCom.acFILENAME:
case SuperCom.acFILEDATA:
case SuperCom.acSYN:
case SuperCom.acRXING:
case SuperCom.acTXING:
case SuperCom.acRXFIN:
case SuperCom.acTXFIN:
:
}
}
protected override void OnDataPacket(OnDataPacketEventArgs e) [OnDataPacket +-]
{
switch (e.Action)
{
case OnDataPacketEventCode.SCOMM_DATAPACKET_OK:
case OnDataPacketEventCode.SCOMM_DATAPACKET_NOK:
:
}
}
} //MYSCOM
SCom = new MYSCOM(Com, frm1);
// Set some comm parameters
SCom.ComType = ComType.COMTYPE_RS232; // *) serial, TAPI, TCP/IP, ISDN
SCom.Settings = "115200,N,8,1";
// or
SCom.BaudRate = 115200;
SCom.DataBits = 8;
SCom.StopBits = StopBits.One;
SCom.Parity = Parity.None;
SCom.Handshaking = Handshaking.SCOMM_HANDSHAKE_CTS;
SCom.PortOpen = true; // Ready to start action...
:
// need some trigger to report when received ?
SCom.Trigger = SuperCom.StringToByteArray("Username");
SCom.TriggerAction = TriggerAction.SCOMM_TRIGGER_ADD;
SCom.Trigger = SuperCom.StringToByteArray("Password");
SCom.TriggerAction = TriggerAction.SCOMM_TRIGGER_ADD;
// now connect to a modem server ..
SCom.ConnectAddress="1234 5678 99"; // phone number
SCom.Connect = true;
:
// transmit a file
SCom.FileName = "sales.doc";
SCom.Protocol = Protocol.PROTOCOL_ZMODEM;
SCom.FileTransmit = true;
:
* One point to select the desired communication type!
The same class can be used for console applications as well.
|
The above sample gives a brief outline on how to use the ActiveX API like class "TSCom" of the SuperCom .NET Class Library.
Now, once we have a working sample as the above how much would it take to switch over to a TCP/IP client ?
Switching ComType from Serial to TCP/IP
C# Sample
In the above sample we've done serial communications. Now we need to send files
to a TCP/IP server. We can create a new class or reuse the one we had in
the previous sample for serial communications.
:
SCom.PortOpen = false; // close that one...
SCom.CommPort = ClientCom; // switch comm index, if needed...
SCom.ComType = ComType.COMTYPE_WINSOCK_CLIENT; // *) serial, TAPI, TCP/IP, ISDN
SCom.PortOpen = true; // Ready to take actions ...
:
// now connect to a TCP/IP server ..
SCom.ConnectAddress = "www.weburl.com:9000";
SCom.Connect = true;
:
// transmit a file
SCom.FileName = "sales.doc";
SCom.Protocol = Protocol.PROTOCOL_ZMODEM;
SCom.FileTransmit = true;
:
* one point to select the desired communication type!
|
Obviously, the SuperCom API not only increases productivity but the code developed once can be reused easily (e.g. from the SuperCom ActiveX, MSComm or PDQComm to SuperCom for NET) and most of the time without changes.
The following sample is using the ActiveX API like class "TSCom" of the SuperCom .NET Class Library within a console application.
Establish a serial file transfer (Tx, Rx)
C# console sample
using ADONTEC.Comm; // see C# source in SComClass.cs
// VB Net references the class DLL
namespace CSharpTxRxFileConsole
{
class Program
{
public class MYSCOM : TSCom
{
public MYSCOM(int CommId) : base(CommId)
{
}
// Optional but handy event functions
protected override void OnComm(OnCommEventArgs e) [OnComm +-]
{
base.OnComm(e); // call base class
int SComEvent = (int)e.EventCode;
if ((SComEvent & SuperCom.EV_RXCHAR) == SuperCom.EV_RXCHAR)
{
// Rx data available, do any further processing here
}
if ((SComEvent & SuperCom.EV_TXEMPTY) == SuperCom.EV_TXEMPTY)
{
// Tx buffer empty, do any further processing here
}
if ((SComEvent & SuperCom.EV_TRIGGER) == SuperCom.EV_TRIGGER)
{
// a file receive (or transmit) request
// or a special user data packet received ?
// Start receiver or handle data packet
TriggerSignaled nTriggerId = this.TriggerSignaled; // which one?
if (nTriggerId == TriggerSignaled.SCOMM_TRIGGER_IS_ZMODEM)
{ // start zmodem receiver to run in background
SCom.FileName = "";
SCom.Protocol = Protocol.PROTOCOL_ZMODEM;
SCom.FileReceive = true; // go get it - no blocking!
}
:
}
:
:
} // OnComm
protected override void OnFile(OnFileEventArgs e) [OnFile +-]
{
base.OnFile(e); // call base class
switch (e.Action)
{
case SuperCom.acFILENAME:
s = "OnFile-Name=" + e.FileName;
break;
case SuperCom.acRXING: // Rxed one data packet
s = "acRXING, at " + (e.Data).ToString();
break;
case SuperCom.acTXING: // Txed one data packet
s = "acTXING, at " + (e.Data).ToString();
break;
case SuperCom.acRXFIN: // Rx complete
s = "acRXFIN" + "(" + TFQFileCount.ToString() + ")";
break;
case SuperCom.acTXFIN: // Tx complete
s = "acTXFIN" + "(" + TFQFileCount.ToString() + ")";
break;
case SuperCom.acUSERBREAK:
s = "acUSERBREAK" + "(" + TFQFileCount.ToString() + ")";
break;
case SuperCom.acQUEUEFIN: // All queued files Txed or Rxed
s = "acQUEUFIN" + "(" + TFQFileCount.ToString() + ")";
break;
:
:
}
Console.WriteLine("OnFile-Event=" + s + Environment.NewLine);
} // OnFile
} // MYSCOM
static void Main(string[] args)
{
Console.WriteLine(" CSharpTxRxFileConsole " + Environment.NewLine);
MYSCOM SCom = new MYSCOM( SuperCom.COM_1); // create instance
// Set some comm parameters
SCom.ComType = ComType.COMTYPE_RS232; // *) serial, TAPI, TCP/IP, ISDN
SCom.Settings = "115200,N,8,1";
SCom.Handshaking = Handshaking.SCOMM_HANDSHAKE_NONE;
Console.WriteLine("Opening port/channel" + Environment.NewLine);
SCom.PortOpen = true; // // Ready to start action...
if (SCom.PortOpen == false)
{
Console.WriteLine(" failed to open port/channel." + Environment.NewLine);
SCom = null;
return;
}
// OK so far we own an open port/channel now prepare environment e.g. DownLoadDir
SCom.FileDownLoadDir = @"c:\adtmp";
// Any Trigger to add for automated receive of files ?
SCom.TriggerAction = TriggerAction.SCOMM_TRIGGER_ADD_ZMODEM;
SCom.TriggerAction = TriggerAction.SCOMM_TRIGGER_ADD_KERMIT;
// prepare for file transmission
SCom.Protocol = Protocol.PROTOCOL_ZMODEM;
SCom.FileName = "c:\\sales*2012.txt";
Console.WriteLine("Starting transmition of " + SCom.FileName + Environment.NewLine);
SCom.FileTransmit = true; // send now
:
:
// Lets assume we want also to receive file(s)
// While we do a simple busy wait here SuperCom may receive files in background
do
{
Console.WriteLine(".. now waiting to receive file(s). ");
Console.WriteLine("Start Sender or press 'E' key to end .. " + Environment.NewLine);
} while (getch()!='E');
:
:
Console.WriteLine(Environment.NewLine + "Closing the port...");
SCom.PortOpen = false; // close port/channel, free communication index
Console.WriteLine(" .. done." + Environment.NewLine);
:
}
}
}
* One point to select the desired communication type!.
|
C++ Sample using high-level class CSuperCom
Using a class library may offer some advantages over pure C functions. SuperCom includes a very complete and easy to handle class library as the following small sample will demonstrate.
A small C++ sample that connects and transmits a file. As one can easily see there is no difference between calls if Serial, ISDN or TCP/IP.
C++ Sample
//-------------------------------------------------------------------
// SuperCom sample using CSuperCom class
//-------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include "supercom.hpp" // CSuperCom
#if defined(_OS_NT_)
// Enable TCP/IP or ISDN, disable both for serial
//#define __USE_TCPIP__
//#define __ISDN__
#endif
#if defined(_OS_LINUX_)
#endif
int bPgmEnd = FALSE;
//-------------------------------------------------------------------
// Class CCMyCOM
//-------------------------------------------------------------------
class CMyCOM : public CSuperCom {
private:
public:
CMyCOM(LPCTSTR pszConfigString, HANDLE hWnd=0);
~CMyCOM(void);
// optional event functions
int OnComm(DWORD SComEvent);
int OnConnect(WORD Action, DWORD TimeLeft);
int OnFile(WORD Action, DWORD Data, PFDATA FileData);
};
CMyCOM::CMyCOM(LPCTSTR pszConfigString, HANDLE hWnd)
:CSuperCom(pszConfigString, hWnd)
{
}
CMyCOM::~CMyCOM(void)
{
}
// Optional Event functions called from SuperCom in background
int CMyCOM::OnComm(DWORD SComEvent)[OnComm +-]
{
int nRes = CSuperCom::OnComm(SComEvent); // base class
if (SComEvent & EV_RXCHAR)
{
}
if (SComEvent & EV_TXEMPTY)
{
}
return nRes;
}
int CMyCOM::OnConnect(WORD Action, DWORD TimeLeft)[OnConnect +-]
{
int Res = CSuperCom::OnConnect(Action, TimeLeft); // base class
// handle any event or none!
switch (Action)
{
case acCONNECT_INFO:
break;
case acCONNECT_OK:
break;
case acCONNECT_FAILED:
break;
case acCONNECT_INIT:
break;
case acCONNECT_DIALING:
break;
case acCONNECT_CONNECTING:
break;
case acCONNECT_TAPI_RING:
break;
default:
break;
}
printf("."); fflush(stdout);
if ( (Action == acUSERBREAK) || bPgmEnd ) // any reason to break ?
return(infBREAK); // Break Task
else
return(Res);
}
int CMyCOM::OnFile(WORD Action, DWORD Data, PFDATA pFileData)[OnFile +-]
{
int Res = CSuperCom::OnFile(Action, Data, pFileData); // base class
// handle any event or none!
switch (Action)
{
case acTXING:
break;
case acRXING:
break;
case acQUEUEFIN:
break;
case acRXFIN:
break;
case acTXFIN:
break;
case acUSERBREAK:
break;
case acRETRY:
break;
case acFILEDATA:
break;
case acFILENAME:
break;
case acSYN:
break;
case acBUFFERSIZE:
break;
default:
break;
}
printf("."); fflush(stdout);
if ( (Action == acUSERBREAK) || bPgmEnd ) // any reason to break ?
return(infBREAK); // Break file transfer
else
return(Res);
}
#if defined(__USE_TCPIP__)
#define SET_CONFIG "SET_IP"=adontec.com:80;"
#elif defined (__ISDN__)
#define SET_CONFIG SET_OWNEXTENSION"=900020;"SET_CONNECTADDRESS"=222333344444;"
SET_CONNECTTIMEOUT"=10;"
#else // Serial
// standard serial port
#define SET_CONFIG "Serial=COM1;BaudRate=9600;"
// or connect through a modem and also trace data
#define SET_CONFIG "Serial=COM18;BaudRate=115200;
ConnectAddress=222333344444;
TRACE=C:\\sc_trace.txt;"
#endif
int main(int argc, char** argv)
{
printf("\nSuperCom Connect sample\nEstablishing connection\n" );
CMyCOM *ThisCOM = new CMyCOM(SET_CONFIG); // create instance
ThisCOM->Connect(TRUE); // now open channel and try to connect
if (ThisCOM->ComValid() == FALSE)
printf("\nFailed to open channel!\n");
else if (ThisCOM->Connected() == FALSE)
printf("\nFailed to connect!\n");
else // port opened, connected, now perform ...
{
int nErrorCode;
char szFileName[SC_MAXPATH]="sales.dat";
printf("\nConnected .. starting transmitting %s\n[", szFileName);
ThisCOM->RS_TXFile (PROTOCOL_ZMODEM, szFileName, &nErrorCode);
if (nErrorCode)
printf("\n Err=%d", nErrorCode);
printf("]\nDone.");
}
printf("\nPress ENTER to end.\n");
getchar();
return 0;
}
|
Pascal / Delphi Sample using high-level class TSuperCom
Using a class library may offer some advantages over pure Pascal functions. SuperCom includes a very complete and easy to handle class library for Delphi / Pascal as the following small sample will demonstrate.
A small Delphi console sample that connects and transmits a file. As one can easily see there is no difference between calls if Serial, ISDN or TCP/IP.
Delphi / Pascal Sample
//-------------------------------------------------------------------
// SuperCom Connect sample using TSuperCom class
//-------------------------------------------------------------------
program Connect;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows, SuperCom;
{$IFDEF _OS_NT_}
// Enable for TCP/IP or ISDN, disable both for serial
{$DEFINE __USE_TCPIP__}
// {$DEFINE __ISDN__}
{$ENDIF}
{$IFDEF _OS_LINUX_}
{$ENDIF}
Var nErrorCode:Integer = 0;
szFileName:Array[0..SC_MAXPATH] Of TSHORTCHAR;
//-------------------------------------------------------------------
// Class CMyCOM
//-------------------------------------------------------------------
Type TMyCOM = class (TSuperCom)
public
Constructor Create (Com:TCOMMID; dwBaud:DWORD); Overload;
Constructor Create(ConfigString:String; hWnd:THANDLE); Overload;
Function OnComm (SComEvent:DWORD):Integer; override;
Function OnConnect (Action:WORD; TimeLeft:DWORD):Integer; override;
Function OnFile (Action:WORD; Data:DWORD; Var FileData:TFDATA):Integer; override;
End;
Constructor TMyCOM.Create (Com:TCOMMID; dwBaud:DWORD);
Begin
Inherited Create(Com, COMTYPE_RS232, 0);
ComSetState (dwBaud, 8, 1, 'N',SIGNAL_NONE);
End;
Constructor TMyCOM.Create (ConfigString:String; hWnd:THANDLE);
Begin
Inherited Create(ConfigString, hWnd);
End;
Function TMyCOM.OnComm (SComEvent:DWORD):Integer;[OnComm +-]
Begin
Result := Inherited OnComm(SComEvent); // base class
// no need to handle any !
If (IsSet(SComEvent,EV_RXCHAR)) Then
Begin
End;
If (IsSet(SComEvent,EV_TXEMPTY)) Then
Begin
End;
End;
Function TMyCOM.OnConnect (Action:WORD; TimeLeft:DWORD):Integer;[OnConnect +-]
Begin
Result := Inherited OnConnect(Action, TimeLeft); // base class
// no need to handle any !
Case (Action) Of
acCONNECT_INFO:
acCONNECT_OK:
acCONNECT_FAILED:
acCONNECT_INIT:
acCONNECT_DIALING:
acCONNECT_CONNECTING:
acCONNECT_TAPI_RING:
End;
If ( (Action = acUSERBREAK) OR bPgmEnd ) Then // any reason to break ?
Result := infBREAK; // Break connect
End;
Function TMyCOM.OnFile (Action:WORD; Data:DWORD; Var FileData:TFDATA):Integer;[OnFile +-]
Begin
Result := Inherited OnFile(Action, Data, FileData); // base class
// Handle any events !
Case (Action) Of
acTXING:
acRXING:
acQUEUEFIN:
acRXFIN:
acTXFIN:
acUSERBREAK:
acRETRY:
acFILEDATA:
acFILENAME:
acSYN:
acBUFFERSIZE:
End;
If ( (Action = acUSERBREAK) OR bPgmEnd ) Then // any reason to break ?
Result := infBREAK; // Break protocol
End;
Const
{$IFDEF __USE_TCPIP__} //---------- TCP/IP -----------
STRX_COMTYPE = 'TCP/IP';
SET_CONFIG = SET_COMTYPE+'='+STR_VAL_COMTYPE_CLIENT+';'+SET_CONNECTADDRESS+'=host;'+SET_CONNECTTIMEOUT+'=10;';
SET_CONFIG = SET_COMTYPE+'='+STR_VAL_COMTYPE_CLIENT+';'+SET_IP+'=host;'+SET_PORT+'=9002;'+SET_CONNECTTIMEOUT+'=10;' ;
{$ELSE}
{$IFDEF __ISDN__} //---------- ISDN -----------
STRX_COMTYPE = 'ISDN';
SET_CONFIG = SET_COMTYPE+'='+STR_VAL_COMTYPE_ISDN+';'+SET_OWNEXTENSION+'=20;'+SET_CONNECTADDRESS+'=22;'+SET_CONNECTTIMEOUT+'=10;';
{$ELSE} //---------- Serial -----------
STRX_COMTYPE = 'Serial';
SET_CONFIG0 = 'Serial=COM4;BaudRate=57600;Handshaking=CTS;';
SET_CONFIG1 = 'CommID=0;ComType=RS232;BaudRate=57600;Handshaking=CTS;TRACE=C:\\sc_trace.txt;' ;
SET_CONFIG2 = 'Serial=COM1;BaudRate=57600;Handshaking=CTS;ConnectAddress=22244444;TRACE=C:\\sc_trace.txt;' ;
SET_CONFIG3 = SET_SERIAL+'=COM1;'+SET_BAUDRATE+'=57600;'+SET_HANDSHAKING+'=CTS;'+SET_CONNECTADDRESS+'=14;'+SET_CONNECTTIMEOUT+'=10;';
SET_CONFIG = SET_CONFIG3; // use this
{$ENDIF}
{$ENDIF}
Var ThisCOM:TMyCOM;
Begin
StrCopy(szFileName, 'sales.dat');
Writeln('SuperCom Connect sample');
Writeln('Establishing connection');
ThisCOM := TMyCOM.Create(SET_CONFIG, 0);
ThisCOM.SetConnectMode(Blocking);
ThisCOM.Connect(TRUE);
// If pure serial nothing to connect to, if not a modem. Port already opened.
// If TCP/IP client it will connect to the Server at IP:Port, as set above
If (ThisCOM.IsValid() = FALSE) Then // failed ?
Writeln('Failed to open channel ', IntToStr(ThisCOM.GetCom()+1), ' ', SET_CONFIG,'..')
Else // OK
Begin
Writeln('COM_',IntToStr(ThisCOM.GetCom()+1),') Starting transmitting ', szFileName);
// transmit file
ThisCOM.RS_TXFile (PROTOCOL_ZMODEM, szFileName, nErrorCode);
If (nErrorCode <> 0) Then WriteLn('Err=', nErrorCode);
WriteLn('done.');
End;
ThisCOM.Free;
Writeln('Press ENTER to end.');
ReadLn;
|
Special Applications
RS-485 Multidrop
Besides supporting RS-232 and RS-422 serial communication, SuperCom also support the RS-485 data communication.
RS-485 connects two or more stations on a two wire half-duplex bus system (network). That is bi-directional, half-duplex, multi-drop serial data communication over a single pair of cable. Each station can only transmit or receive data at a time (half-duplex). The so called "direction" is used to switch from transmit to receiving mode and vice versa. A timed switch of the "direction" is essential to avoid loss in data.
SuperCom handles the RS-485 serial port transparently and offers a very low-latency switch of "direction" (more...). A four wire full-duplex connection may also be used.
:::
The testing samples showed that SuperCom can switch several times within 1 ms.
|
9-Bit serial data
9-Bit serial communication (9-Bit framing) is mainly used to identify address byte within messages running on a RS-485 multidrop network but also on standard RS-232 connections. 9-Bit frames are usually not supported by the standard PC UART but simulated by the SuperCom software. Very fast response timing (low latency) by the software is essential to accomplish reliable 9-bit data communication. SuperCom does provide a very realiable solution here to be used with high level languages.
Many Samples (e.g. C/C++, C#, Delphi, Pascal, Visual Basic net) also included that demonstrate this operating mode.
For example, transmitting a data packet using 9-bit addressing e.g.:
TXPacket9BitCond(Com, cData, nDataCount, SEC0_1);
Intelligent Functions
SuperCom includes additional intelligent functions that solve lengthly or complex operations thus avoiding delaying or blocking of your application (e.g. Data Filtering, Data Monitoring, Data Trigger, Data Packets, File Transmission Queue). The result is a rock-solid solution developed much faster than with regular tools. More samples here.
More info on the SuperCom Serial Library, price list and order form.
Need a TCP/IP library too ? Read more.