Modem Communication


Samples in VisualBasic

Using Sax Comm

Note: The help file is C:\WINNT\Help\SaxComm8.chm

Here's how to open a COM port, send an AT command, and wait for an answer:

SaxComm1.ShutDown = False
SaxComm1.CommPort = "COM2"
SaxComm1.Settings = "" ' use all default settings
SaxComm1.PortOpen = True
If Not SaxComm1.PortOpen Then
    MsgBox "Error: " & SaxComm1.PortStatus
    Exit Sub
End If
'AutoReceive determines whether you are using event-driven lookup strings, or serial look up strings.
'Serial lookup strings are executed line by line.
SaxComm1.AutoReceive = False
SaxComm1.OutputLine = "atz"
SaxComm1.InputMode = InputMode_Text
SaxComm1.InTimeOut = 2000  ' wait up to 2 seconds
SaxComm1.InputLen = 20     ' read up to 20 characters
Label1.Caption = SaxComm1.Input

Note: Once the modem is installed in Windows (ie. it shows in the Modem section of Control Panel), you can use the following command to have Sax use the default modem through TAPI, so you don't have to specify settings, including the COM port:

SaxComm1.CommPort = ""   ' Select default modem

An alternative way to send a command and wait for an answer that ends with a carriage return, ie. if the modem returns several strings each ending with CRLF, only the first string will be returned:

SaxComm1.AutoReceive = False
SaxComm1.InTimeOut = 30000   ' Wait up to 30 seconds
Password$ = SaxComm1.LineInput

Here's how to send a command, and wait until a given string is returned or a time-out occurs:

SaxComm1.AutoReceive = False
SaxComm1.OutputLine = "atz"
SaxComm1.LookUpTimeOut = 30000   ' Up to 30 seconds
SaxComm1.LookUpInputLen = 120    ' Read up to 120 bytes
SaxComm1.LookUpText = "OK"
MsgBox "Done"

Sax can be either added to a form, or created as an early- or late-binding object. Here's the early binding way:

Dim SaxComm As New SaxComm
SaxComm.SerialNumber = "5555-5555555-55" 'Type your serial number
SaxComm.PortOpen = True

Add "Dim WithEvents" if you want to catch events.

Here's the late-binding way:

Dim SaxComm As Object
Set SaxComm = CreateObject("saxcomm7.commcontrol")
SaxComm.SerialNumber = "5555-5555555-55"
SaxComm.PortOpen = True

Here's how to catch the characters in the input buffer, one by one:

Function ReadOneChar() As Integer ' -1 = timeout
    Dim s As String
    SaxComm1.InTimeOut = 1000
    SaxComm1.Inputlen = 1
    s = SaxComm1.Input
    If s = "" Then
        ReadOneChar = -1
        ReadOneChar = Asc(s)
    End If
End Function

Here's how to feed the list of modems to a combo:

Private Sub Form_Load()
    Dim PortName
    For Each PortName In SaxComm1.CommPorts
        Combo1.AddItem PortName
    Combo1.Text = SaxComm1.CommPort
End Sub
Private Sub btnOK_Click()
    SaxComm1.CommPort = Combo1.Text
End Sub

Here's how to connect out using the default modem installed in Windows, navigate through the menus of a ProWin BBS, and download a file in Zmodem (the form has two pushbuttons, one to connect, one to close the port and close the application, and two textboxes, one for the phone number of the BBS, and one for the file(s) to download):

Private Sub Cancel_Click()
    SaxComm1.PortOpen = False
End Sub
Private Sub Connect_Click()
    Dim sChoice As String
    If Telephone.Text = "" Or File.Text = "" Then
        MsgBox "Phone number or file(s) to download empty."
        Exit Sub
    End If
    SaxComm1.CommPort = "" 'Default modem
    SaxComm1.PhoneNumber = Telephone.Text
    SaxComm1.ShutDown = False
    SaxComm1.XferProtocol = Protocol_ZModem
    SaxComm1.XferStatusDialog = Dialog_Modal
    SaxComm1.PortOpen = True
    If Not SaxComm1.PortOpen Then
        MsgBox "Error: " & SaxComm1.PortStatus
        Exit Sub
    End If
    If Not WaitSend("First name:", "john" & vbCr, 5000) Then
        Exit Sub
    End If
    If Not WaitSend("Last name:", "doe" & vbCr, 3000) Then
        Exit Sub
    End If
    'Correct (Y/N)?
    If Not WaitSend("(Y/N)?", "y", 3000) Then
        Exit Sub
    End If
    If Not WaitSend("Password:", "c" & vbCr, 3000) Then
        Exit Sub
    End If
        'D)ownload ... Your choice?
        If Not WaitSend("Your choice?", "r", 3000) Then
            Exit Sub
        End If
        'Z) Zmodem ... Your choice?
        If Not WaitSend("Your choice?", "z", 3000) Then
            Exit Sub
        End If
        If Not WaitSend("Filename?", File.Text & vbCr, 3000) Then
            Exit Do
        End If
        SaxComm1.Download = ""
        Call WaitUntilTransferFinished
        sChoice = MsgBox("Download other file(s)?", vbYesNo, "New download")
        If sChoice = "" Or sChoice = vbNo Then
            Call WaitSend("uit", "q", 5000)
            Exit Do
            sChoice = InputBox("New file(s) to download?", "Select file(s) to download", "myfile.exe")
            If sChoice = "" Then
                'Looks like buffer doesn't contain menu -> let's close the connection directly
                'SaxComm1.Output = vbCr
                'Call WaitSend("uit", "q", 5000)
                Exit Do
                'File File.txt to keep logic
                File.Text = sChoice
            End If
        End If
    Loop While True
    Exit Sub
End Sub
'Wait for a string in the BBS menu to show up... and send reply
Public Function WaitSend(sAnswer As String, sCommand As String, lTimeOut As Integer) As Boolean
    SaxComm1.AutoReceive = False
    SaxComm1.LookUpText = sAnswer
    SaxComm1.LookUpInputLen = 2000
    SaxComm1.LookUpTimeOut = lTimeOut
    If SaxComm1.LookUp Then
        MsgBox "Timed out waiting for answer. Closing connection."
        WaitSend = False
        SaxComm1.Pause = 500 'Wait half a second for menu to be displayed
        SaxComm1.Output = sCommand
        'Text1.Text = Text1.Text & SaxComm1.LookUpInput 'LookUpInputLen
        SaxComm1.Pause = 1000
        WaitSend = True
    End If
End Function
Private Sub CloseConnection()
    If SaxComm1.XferStatus > 0 Then
        SaxComm1.AbortTransfer = True
        While SaxComm1.XferStatus > 0
    End If
    SaxComm1.ShutDown = True
    SaxComm1.PortOpen = False
End Sub
' Returns True if transfer was completed successfully
Function WaitUntilTransferFinished() As Boolean
  While SaxComm1.XferStatus > 0
  ' Zero indicates a successful transfer
  WaitUntilTransferFinished = (SaxComm1.XferStatus = 0)
End Function

Determining if more characters are coming


Why can't I use the .CommPort property once the modem has been installed through PnP?

Doesn't work through HyperTerminal either. Looks like you can't access a modem in non-TAPI mode once it's installed in Device Manager.

Controler-based, winmodems and softmodems, DSP, Controller

COM port


The following table shows the version of TAPI shipped with each Windows operating system. (Recent releases, service packs, or updates may not appear on this table.)

Windows OS Installation Default Maximum Version Upgrade
Windows 95 1.4 2.2
Windows 98 2.0 2.2
Windows ME 2.2 2.2
Windows NT 4 2.2 *SP5 2.2
Windows 2000 3.0 3.3
Windows XP 3.3 3.3

The major TAPI function additions are:

TAPI Version Additional Features
1.4 Base version for 32 bit Windows
2.0 Full 32 bit support, support for Unicode - Little effect on TAPI applications
2.1 Major addition of Client/Server functionality
2.2 Specialized call center management added
3.0 COM based API, Media Stream Providers added. 2.1 TSP's can still be used

Microsoft Telephony Overview

Microsoft Telephony Programming Model

TAPI telephony services are divided into Assisted Telephony services and the services provided by the full Telephony API. In general, the full Telephony API is used to implement powerful telephonic applications, and Assisted Telephony is used to add minimal but useful telephonic functionality to non-telephony applications.


Service Providers

TAPI and telephony (article on Allen-Martin site)

ActiveX and DLLs

Here are some tools you can use to access the modem instead of using either the bare-bone MSComm ActiveX control that ships with VB, or the Win32 API:

Tapi & Zmodem/Ymodem/Xmodem etc Protocols

TAPI itself only deals with placing/answering and otherwise manipulating a call (putting it on hold, transferring, conferencing, etc).  TAPI itself does not provide any file transfer or other capabilities.  To deal with a voice call you use the wave API, and for a data call like what you need you use the ReadFile/WriteFile to transfer data over the data connection.

Modems can used to make two different kinds of connections.  The first is a raw data connection.  This raw data connection can then be used for the ZModem protocol.  The second type is that Dial-Up Networking (DUN) can use a modem to connect to a TCP/IP Network.  This network it connects to could be the Internet, or it could be a computer running Dial-Up Server. You can use TAPI to make a raw data connection, so you can use ZModem. You can use the RAS (Remote Access Services) API to make a DUN connection, so you can use FTP.

I'd suggest browsing through and looking at the various custom controls that are available.  There are plenty of development tools available, including Visual Voice, Visual Fax, VBVoice, Fax Plus, to name a few.

Are you running on NT 2000 beta?  If not then you are out of luck, TAPI 3.0 is only supported on that platform.  You could of course use TAPI 2.1 but there is no COM interface available, only a traditional API.

There are two ways to make calls with TAPI, the assisted TAPI and full TAPI.

Assisted TAPI is a simple option where your application uses a single function (tapiRequestMakeCall) which uses the defined Windows Dialer (typically the MS Phone dialer.)

Full TAPI is a whole lot more complicated and requires your application to initialize TAPI, select one or more TAPI lines, open those lines, make call on the line(s) and monitor and control the calls.

There are two versions of the TAPI interface.  A C function interface (version 2.x) and a COM interface (version 3.x.)  Using the C interface from VB is challenging due to various aspects like variable length data and asynchronous events.  Therefore, you may want to look at the COM interface.  In addition, you may want to look at third party interfaces which use the 2.x interface but are easier to use from VB. If you wish to use the COM (ActiveX) component object  model programming interface then you will need to use  Windows XP and TAPI 3.1  It not only allows capturing  digits, but allows many other features that aren't present  with 3.0.

Get the TAPI Browser test application provided by MS (one for TAPI 3.x and one for 2.x.)

TAPI 3.0 is available on W2k, XP and WS2k3 out of the box. TAPI 3.1 is available on XP and WS2k3 out of the box.

TSP : The term "service provider" is nothing more than a fancy name for a driver. A TAPI service provider (TSP) is a driver that allows TAPI applications to communicate with different types of TAPI hardware.

UnimodemV : Windows 95 and NT come with a built in TSP called Unimodem. Unimodem is a "universal" modem service provider that supports a wide range of commonly used modems. When using telephony hardware other than modems, such as PBX's, voice processing cards, etc. you will typically use a TSP provided by the hardware vendor.

The universal modem driver (Unimodem) provides services for data, fax, and voice modems so that users and program developers will not have to learn or maintain modem AT commands to dial, answer, and configure modems. Unimodem performs these tasks by using files that specify the AT command sets and expected responses for modems. These files usually have an .inf extension. Modem support is provided by the TAPI Unimodem 5 Service Provider in Windows 2000. It enables you to install and use almost any modem available today.

Voice modems are not supported under Windows NT4. Windows NT 4.0 does not support generic UniModem/V voice drivers.

The Unimodem, or Universal Modem Driver, TSP (Unimdm.tsp) provides access to nearly all standard modems. It supports voice modems that allow half-duplex streaming. They are supported by the Wave MSP and stream control is possible. (Note that Unimodem on Windows NT 4.0 or earlier does not support voice modems, so direct stream control is not possible.)

Microsoft wrote a TSP called unimodem (a universal modem driver) and later a voice capable version unimodemV. Unimodem and UnimodemV are configurable with an inf file during modem installation but because Unimodem was designed to work with any modem it has severe limitations.

Because Microsoft wrote this universal modem driver most manufacturers take the easy way out and use it, configure it with an inf file and suffer the inherent limitations of Unimodem rather than writing their own TSP that would be able to use all of the capabilities of their hardware.

A further problem is that Microsoft did not supply a voice enabled version of unimodem for Win NT, meaning that voice modems will not support TAPI under NT4. Most modem manufacturers supply voice software with the modem that does not use TAPI and has been configured specifically for their modems command set and capabilities. So you will find voice capable applications using voice modems, running under NT4, but not via TAPI. Fortunately Microsoft have provided a voice enabled TSP for Windows 2000 called unimodem 5.

MS's Telephony control, the ones that come with the speech sdk.

In addition, you will need hardware that can do what you want.  Most hardware can't detect distinctive rings, at least not inexpensive hardware. :)  Probably your best bet is the Way2Call Hi-Phone, it supports distinctive ring and is under $350.

example from microsoft (vboutgoingcall)


Access from DOS

Some DOS TCP/IP stacks that seem popular:

  * Crynwr Software (only for Ethernet connections, not dial-up?)

  * LSPPP and DOS PPP (both ported from the Linux PPPD driver)

  * WATTCP and Watt32 (unofficial page)

  * KLOS PPP (shareware; very robust)

  * "Net-Tamer is a DOS PPP dial up access program, which requires no TSR packet driver. [..] Can be used to

    replace the complete suite. Has an excellent Web browser. Includes its own TCP/IP stack"

  * Device Logics' TCP/IP Stack ($20 Single User)


PC/TCP Packet Driver Specification

DOS Networking HOWTO

Communications Programs For DOS


DOS TCP/IP connectivity from scratch

How do I run DOS TCP/IP or packet-driver apps in DOS sessions?


NET: Phil Karn's KA9Q for Demon Internet

Samples in PowerBasic

Writing scripts in ProWin Aspect


Location of COM ports and modems in the Registry?




MS Comm Control