Serial communication with Atapi

May 7, 2013 at 2:03 PM
Can i use Atapi with a data modem to recieve a call and handel some serial communication.

I just the monitor demo. I can connect with a modem but how can i stream data from the COMM.

any idea's
Coordinator
May 7, 2013 at 2:36 PM
Edited May 7, 2013 at 2:36 PM
You can, however the TSP needs to support it (Unimodem does). You use TAPI to just dial and connect the call and then TapiCall.GetCommHandle() or TapiCall.GetCommStream() to get the underlying handle or TapiCall.GetCommDevice() to get the ID which you can then open on your own.

Mark Smith
May 7, 2013 at 3:29 PM
Thanks Mark,

Is it to much to ask for a code snippet. This is my first project with this Tapi. The drivers are unimodem or modem specific so that should work.

Any help is welcome
Coordinator
May 7, 2013 at 4:46 PM
Well, I don't have a modem but this is probably close to what you want -- no real error checking and no logic for data is present - it just dials a call, waits for a connect and then sends a CR/LF and prints the response. Give it a shot.

using System;
using JulMar.Atapi;
using System.IO;

namespace SampleComm
{
class Program
{
    static void Main(string[] args)
    {
        string phoneNumber = "2145551212";
        if (args.Length > 0)
            phoneNumber = args[0];

        using (TapiManager mgr = new TapiManager("EnumTapiLines"))
        {
            try
            {
                if (!mgr.Initialize())
                    Console.WriteLine("TAPI failed to find any lines or phones to manage.");

                TapiLine modemLine = null;

                if (mgr.Lines.Length > 0)
                {
                    foreach (TapiLine line in mgr.Lines)
                    {
                        if ((line.Capabilities.MediaModes & MediaModes.DataModem) != 0)
                        {
                            modemLine = line;
                            break;
                        }
                    }
                }
                else
                    Console.WriteLine("No TAPI lines found.");

                if (modemLine == null)
                    Console.WriteLine("No TAPI line capable of data was found.");

                Console.WriteLine("Found: {0}, opening.", modemLine.Name);

                modemLine.Open(MediaModes.DataModem);
                modemLine.CallStateChanged += (s, e) =>
                {
                    Console.WriteLine("{0} is now {1}", e.Call, e.CallState);
                    if (e.CallState == CallState.Connected)
                    {
                        DoCommWork(e.Call);
                    }
                };

                Console.WriteLine("Making call to {0}", phoneNumber);
                TapiCall call = modemLine.MakeCall(phoneNumber);
                Console.WriteLine("Waiting for connection - press any key to terminate.");
                Console.ReadLine();

                modemLine.Close();
            }
            catch (TapiException ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
    }

    private static void DoCommWork(TapiCall call)
    {
        FileStream comm = call.GetCommStream();
        if (comm == null)
        {
            Console.WriteLine("No data stream support found.");
            return;
        }
        using (StreamReader reader = new StreamReader(comm))
        using (StreamWriter writer = new StreamWriter(comm))
        {
            writer.WriteLine("\r\n");
            string line = reader.ReadLine();
            Console.WriteLine("Got: {0}", line);
        }

        // Drop the call when finished
        call.Drop();
    }
}
}
May 30, 2013 at 2:54 PM
Hi all,

I just included the example above into my existing application since I need to add a Modem option to the existing Network and Serial interfaces.

I'm using a US Robotics USB modem which is found correctly by the program. The Open statement appears to work fine too.

However, MakeCall does not actually dial the modem. I'm not using Console.ReadLine or modemLine.Close but instead I'm allowing the code to fall through to the rest of my application.

The first attempt at connecting I do get an ObjectDisposedException at interop.LINEMESSAGE. Subsequent connect attempts do not throw any acceptions but appear to dial (Call 0x100C8 id:0 is now Dialing) and proceed (Call 0x100C8 id:0 is now Proceeding) but the modem does not appear to be getting accessed and doesn't actually dial.

It seems I'm missing something very basic and was hoping someone had an idea.

Thanks,
Paul
Coordinator
May 30, 2013 at 4:30 PM
MakeCall returns a TapiCall which you need to hold onto or it gets collected. Are you keeping the call alive?

mark

Mark Smith

[email removed] | @marksm | 214-774-4749 | www.julmar.com/blog/mark



May 30, 2013 at 8:18 PM
Hi Mark,

Thanks for the reply. That sounds like the problem but I'm not really sure what you mean by "keep the call alive"

Consider me in the "Old Dog, New Trick" category and I'm still learning the new terminology. I started in the "peek" and "poke" era.

Paul
Coordinator
May 30, 2013 at 8:22 PM
The return value from MakeCall is a TapiCall object. You need to hold onto that while you want to interact with the call - i.e. cache it off into a field or property in your class. When you don't keep it, .NET's garbage collection engine will get rid of it.. so something like this:

class Program
{
TapiCall theCall;

void DoMakeCall()
{
theCall = line.MakeCall("555-1212");
theCall.CallStateChanged += OnCallChanged;
...
}

...
}



mark

Mark Smith

[email removed] | @marksm | 214-774-4749 | www.julmar.com/blog/mark



May 30, 2013 at 11:01 PM
Hmmm.

I've got a CallStateChanged event tied-up on TapiLine (exactly like the example) but TapiCall in my version doesn't have any associated events??

Paul
Coordinator
May 31, 2013 at 1:38 AM
My bad, you still need to keep the call alive as you are creating it.

May 31, 2013 at 5:57 AM
Hi,

The fist piece of code snippet works for me. Thx a lot.

Pavalentine. Look at the sample code in de testapplications.zip included in the atap1. You can see how too use the events and what steps you need to connect and exchange data .
May 31, 2013 at 4:39 PM
Hi Roy,

Thanks for the tip. Unfortunately, I can't find the testapplications.zip file. Can you give me another hint as to where to find this particular file?

Thanks,
Paul
May 31, 2013 at 8:40 PM
Edited May 31, 2013 at 8:43 PM
Interesting information.

Instead of embedding this test program into my WPF application, I created a console application solely for this test.

Seems that the MakeCall function still doesn't do a thing. The connection then becomes Idle and Disconnects within a second.

See Below:

15:40:54.1813066 Found: U.S. Robotics V.92 USB Voice Modem, opening.
15:40:54.2413100 Making call to 5551212
Waiting for connection - press any key to terminate.
15:40:55.0603569 Call 0x10098 id:0 is now Idle
15:40:55.0603569 Call 0x10098 id:0 is now Disconnected


Paul
Coordinator
Jun 1, 2013 at 2:34 AM
Seems like it should work. I would try using Hyperterm or some other terminal program to see if the setup is all ok. Is there a specific reason you want to use TAPI for serial communication? If it's just a modem, I would use ATDT commands directly with the serial port - it's far easier IMO.

mark
Coordinator
Jun 2, 2013 at 12:18 PM
Make sure to try with a real phone number. 555-1212 is a fake number which will not result in a call..
Jun 2, 2013 at 12:42 PM
Hi Mark,

I see you're an early riser too. Thanks for all your help on this one.

I've used other dialers on this platform with this modem and they work fine. I've had great success with the US Robotics USB modem in my older app using TAPI directly with C++.

I gave up AT commands decades ago as there is no such thing as "standard" anymore. Too many different manufacturers, too many different setup strings, too many different response code combinations.

My plans for Monday are to stuff an old Conexant "Win Modem" into the PCI slot and see if it acts the same way. The phone number shouldn't matter in my case since I'm using a phone line eliminator which responds to any number.

Thanks again for all your help.
Paul
Coordinator
Jun 2, 2013 at 1:47 PM
Edited Jun 2, 2013 at 2:04 PM
There are a set of sample projects in the source that you can also play with. None of them actually do serial communication, but the phone sample acts as a dialer. I think the relevant code you want is here:

https://atapi.codeplex.com/SourceControl/latest#1946889
Jun 4, 2013 at 5:52 PM
Hi Mark,

Things are now working. I hate to admit it but I had not one, not two, but three different problems with my modems and my phone line eliminator. One modem would pick up the line but not dial and the other wouldn't even pick up the line. One of my two phone line eliminator apparently emits a very weak busy signal that's not detectable by some modems. Strange.

I just bought all new equipment and everything works great.

Thanks again for your help.

Paul
Coordinator
Jun 5, 2013 at 4:55 AM
Sorry you had to get new stuff, but glad it's working for you now!

Mark Smith

[email removed] | @marksm | 214-774-4749 | www.julmar.com/blog/mark