Hi to every one :cheesy:
(I'll say it once: forgive my bad english :sad: )

I have a question!!!

Is there any way to get information aboute Dial-tone PHISICALLY presense without performing a call dail?????!!!!!

I've write a code, in vc++, to make connections over 16 Comm Ports (throw a multiport) using relative modems; Now, while performing a dial, there is no problem to read out events, errors and so on (unsing GetModemSatus, SetCommMask or ClearCommError ect..); but i don't have ALWAYS all 16 lines attached to the front-end of the modem's reck :sad: (athor departements usually uses the same lines swithing some of them before telling my poor code about that) that's mean that my code MUST to know about the LINE presense BEFORE going on and performing a call!!!
NO WAY.........
All functions i've tried returns NO ERRORS even if there is no phone line attached :mad: (that is because there are no problems regarding the rs232 port nor the modem it self they are correctly working) the only way i've find is to MAKE a DIAL or a CONNECTION and wait for the negative responce (waiting for all my own retries :( ) witch is the thing that i'm trying to avoid.

Do some one have an idea to go over this problem??

Here is the part of code regarding the problem mentioned above ....I hope this make it more clear.

const unsigned long sz = 64; //I prefer 'const' compiler instruction to pre-compiler #define one.

void ModemBufCpy(SerialPort* const aSerialModem, char* buf) //SerialPort is a class I wrote
{                                                           //to handle them - works fine.

    BYTE p1=0 , p2=0;               //aux
    for (int i=0; i< sz; i++)
    {
        p1=aSerialModem->read();    // char SerialPort::read(){...} get fist byte in queue from modem buffer
        if (p1==0x0d)               //Only 0x0d + 0x0a means Modem's buffer is empty
        {
            if (p2=aSerialModem->read()==0x0a) 
                break;              //OK Modem buffer is empty! go away.
            else
            {
                buf[i]=p1;
                buf[++i]=p2;        //oops...buffer is not empty yet, get the byte and go ahead.
                continue;
            }
        }
        else
            buf[i]=p1;
    }
    return ;
}


BOOL ModemCheckLine(void) 
{
    BOOL status=TRUE;
    SerialPort aSerialModem ("\\\\.\\COM18");   //this is an example working for a modem attached
                                                //at the last rs232 of a 16 multiport card: usually
                                                //you can use "comN" instead of "\\\\.\\comN" if
                                                //com number is <= 4; After that you will get 
                                                //an error trying to  handle a port using
                                                //CreatFile for numbers over 4.
                                                //Since the OS device name is: \\.\comN you can  
                                                //use a string that takes care of '\' chars doubling them.
                                                // so com18 string become like the one I use.

    char buf[sz]={'\0'};                        //aux
    char at_str[sz]="ATZ\r";                    //AT sequence to reset the modem
    aSerialModem.write(at_str, strlen(at_str)); //RX AT sequence.
    ModemBufCpy(&aPort,buf);                    //need to empty Modem buffer since echo if ON after reset
    at_str[0]='\0';                             //buf now is "ATZ(CR)OK"    
    strcpy(at_str,"ATX4E0S0=0\r");              //initialize Modem in call mode & echo OFF.
    aSerialModem.write(at_str, strlen(at_str)); //RX AT sequence using the SerialPort function member
                                                //int SerialPort::write(const void * sequenza_at, const unsigned long lunghezza){...}
                                                //that uses simply PurgeComm() & WriteFile() functions
    ModemBufCpy(&aPort,buf);                    //echo is still on: OFF mode becoming operative 
                                                //next time: empty modem buffer
    at_str[0]='\0';                             //buf now is "ATX4E0S0=0(CR)OK"
    strcpy(at_str,"ATDT XXXXXXXXXXX\r");        //perform a call    
    aSerialModem.write(at_str, strlen(at_str)); //send it
    ModemBufCpy(&aPort,buf);                    //get modem responce
    //
    //now in base of buf I must be able to 
    //determinate dial-tone status.
    //
    //  if (buf==NO_CARRIER) status=FALSE;
    //
    //  but what I always get is
    //  NO_ANSEWR !!!!
    //  and that could be because XXXXXXXXX phone number is simply not responding!!
    //  and I dont like the idea to MAKE a call at all.
    //
    at_str[0]='\0';                             //de-facto clears at_str
    strcpy(at_str,"ATH0\r");                    //Hang
    aSerialModem.write(at_str, strlen(at_str)); //RX AT sequence
    ModemBufCpy(&aPort,buf);                    //clear modem buffer

    return status;
}

Edited 3 Years Ago by Dani: Formatting fixed

Last week I’ve find the way to resolve my problem: I decide to copy the code from the server to my notebook to take a look at it during last weekend; Now, my old notebook have no multiports nor advanced modems: just a very modest 56K modem!! When I compile the code to work on the notebook I’ve had a surprise: The code worked and I really get a “NO_DIALTONE from the modem and not “NO_ANSWER as I expected!!!!!

Going back to office I tried to use other modems rather the one I usually used tell that moment, and YES: The only modem giving a wrong answer was the one I used before.

At this point I were very curios and I contact the modem supplier (I’m not going to say the brand name: but believe me it is a very important one ), and YES …. BINGO…. They admit that some modems of the model I use have the firmware bug I’ve described to them (They are sending me a new one just right now in substitution )

I make better test version to submit it here hoping to help any one could need it (if any one have observations or better ways to have the same solution, I please him to write them in this thread).

A very old, important and almost forgotten lesson is: “Try it always using a different HW. I’ve forget that lesson and paid a week of headache: Don’t forget it you too.


This function is to read modem's buffer:

const unsigned long sz=32;  //Modem buffer size.

 

void BufCpy(SerialPort* aPort, char* Buf ){

			

			BYTE p1=0 , p2=0;

			char localBuf [sz]= {'\0'};

 

			do

			{

						p1=aPort->read();	   //Eliminate all ESC bytes from header

			} while (p1 < 0x20);

 

			localBuf[0]=p1;					   //First utile byte

			for (int i=1; i< sz; i++)			 // i=1 since the first byte is already in

			{

						p1=aPort->read();  	//get a byte

					    if (p1==0x0d)			  

						{

								   if (p2=aPort->read()==0x0a)  //get another byte

											   break;   //I have the sequence 0x0d+0x0a: job is done go away

								   else

								   {

											   localBuf[i]=p1;	  

											   localBuf[++i]=p2;  //get both bytes, buffer is not empty yet.

											   continue;

								   }

						}

					    else

								   localBuf[i]=p1;  //normal bytes

			}

			strcpy(Buf, localBuf);  //copy result in Buf

			return ;

}

And this is a test function:

void CPModemDlg::OnButton1()  //Test version 

{

 

			SerialPort aPort ("\\\\.\\COM20");

			BOOL LineStatus=FALSE;  			  //Every thing depends on this value 

			CString msg="", caption="Modem Test Message";

			char modem_rs[sz]={'\0'}; 	   		   //Incoming buffer

			char str[sz]="ATZ\r";			   		    //Outgoing buffer = Reset		 

			aPort.write(str, strlen(str));	   		    //Send RESET 

			BufCpy(&aPort,modem_rs);			   //Read modem answer

			

			if (strcmp(modem_rs,"OK") != 0) 

			{

						msg="Modem Reset Error!\n (Modem Check Line Test)";	  

						::MessageBox(NULL,msg,caption,MB_OK | MB_ICONEXCLAMATION);

						return;

			}

 

			strcpy(str,"ATX4E0S0=0S7=30S13=10\r");   		    //Setup Modem : Note S7 and S13 values

			aPort.write(str, strlen(str));										  //Send initialization

			BufCpy(&aPort,modem_rs);									   //Read Modem answer

 

			if (strcmp(modem_rs,"OK") != 0) 

			{

						msg="Modem Initialization Error!\n (Modem Check Line Test)";		 

						::MessageBox(NULL,msg,caption,MB_OK | MB_ICONEXCLAMATION);

						return;

			}

 

						

			strcpy(str,"ATH1\r"); 									  //Hang on J

			aPort.write(str, strlen(str));										  //Send it to Get The Line

			BufCpy(&aPort,modem_rs);									   //Read Modem Answer

 

			if (strcmp(modem_rs,"OK") != 0) 

			{

						msg="Modem Get Line Error!\n (Modem Check Line Test)";

						::MessageBox(NULL,msg,caption,MB_OK | MB_ICONEXCLAMATION);

						return;

			}

 

 

			strcpy(str,"ATDW\r"); //AT “D DIAL &  “W WAIT FOR DIAL TONE

			aPort.write(str, strlen(str));	   //But I’m dialling no number, so NO CALL IS PERFORMED 

			BufCpy(&aPort,modem_rs); //thanks to the two registers S7 and S13 values.

 

			if 		 ((strcmp(modem_rs,"NO ANSWER") != 0) 

						|| (strcmp(modem_rs,"NO DIALTONE") !=0)) 

			{

					    if (strcmp(modem_rs,"NO ANSWER") == 0) LineStatus=TRUE; 

 

						//LINE IS THERE BUT SINCE I’M NOT CALLING ANY NUMBER

						// THEN MODEM ANSWER’S IS “NO_ANSWER

						//OR THERE IS NOT ANY LINE => “NO_DIALTONE EUREKA!!

						

			}

			else 

			{

						msg="Modem Connection Error!\n (Modem Check Line Test)";

						::MessageBox(NULL,msg,caption,MB_OK | MB_ICONEXCLAMATION);

						return;

					    //ELSE I HAVE A HW CONNECTION ERROR (TRY IT J)

			}

			

			strcpy(str,"ATH0\r");						   //Hang off

			aPort.write(str, strlen(str));				   //Do it

			BufCpy(&aPort,modem_rs);			   //Read the answer

 

			if (strcmp(modem_rs,"OK") ==0) 

			{

 

			//Finally, if I’m here means that modem is connected, working and I have the line status

			 

			msg =  (LineStatus) ? "Modem is Ok, Line is present" : "Modem is Ok, No line detected!";

						

			}

			else

			{

						msg= "Modem Error!\n (Modem Check Line Test)";

			

			}

			::MessageBox(NULL,msg,caption,MB_OK | MB_ICONEXCLAMATION);

			return;

}
This article has been dead for over six months. Start a new discussion instead.