1

I was wondering if any of you know what I'm doing wrong here? So I have this program in C, that sends AT commands to a modem. These commands have been tested on hyperterminal and work fine, but when sendind them through the modem I get, first, and "OK" for the first "AT" command, which is good, but then, upon sending the next command, the modem answers with "AT+CC"...which I have no idea what it means. Any help is appreciated.

Source:

void sendSMS(const char* port, const char* number, const char* baud)
{
    HANDLE hComm;
    DCB dcb;
    BOOL fSuccess;

    hComm = CreateFile(port,                //port name
        GENERIC_READ | GENERIC_WRITE, //Read/Write
        0,                            // No Sharing
        NULL,                         // No Security
        OPEN_EXISTING,// Open existing port only
        0,            // Non Overlapped I/O
        NULL);        // Null for Comm Devices

    if (hComm == INVALID_HANDLE_VALUE)
    {
        printf("ERROR: Cannot open serial port\r\n");
        return;
    }
    else
        printf("STATUS: Serial port opened\r\n");


    // Configure PORT
    //  Initialize the DCB structure.
    SecureZeroMemory(&dcb, sizeof(DCB));
    dcb.DCBlength = sizeof(DCB);

    //  Build on the current configuration by first retrieving all current
    //  settings.
    fSuccess = GetCommState(hComm, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("GetCommState failed with error %d.\n", GetLastError());
        return;
    }
                               //  Fill in some DCB values and set the com state: 
                               //  57,600 bps, 8 data bits, no parity, and 1 stop bit.
    dcb.BaudRate = atoi(baud);     //  baud rate
    dcb.ByteSize = 8;             //  data size, xmit and rcv
    dcb.Parity = NOPARITY;      //  parity bit
    dcb.StopBits = ONESTOPBIT;    //  stop bit
    dcb.fOutxCtsFlow = FALSE;
    dcb.fOutxDsrFlow = FALSE;
    dcb.fOutX = FALSE;

    fSuccess = SetCommState(hComm, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("SetCommState failed with error %d.\n", GetLastError());
        return;
    }

    //  Get the comm config again.
    fSuccess = GetCommState(hComm, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("GetCommState failed with error %d.\n", GetLastError());
        return;
    }

    // End Config

    sendATCommands(hComm, number, "This is NOT a test.");
    CloseHandle(hComm);//Closing the Serial Port

}

void sendATCommands(HANDLE hComm, const char* number, const char message[])
{
    char str[256];

    if (!writeToPort(hComm, "AT\r\n")) //Hello modem
        return;

    if (!readFromPort(hComm)) // Must be OK
        return;

    if (!writeToPort(hComm, "AT+CMGF=1\r\n")) //Modem, prepare to send text messages
        return;

    if (!readFromPort(hComm)) // Must be OK again
        return;

    memset(str, 0, 256); 
    strcpy_s(str, "AT+CMGS=\"");
    strcat_s(str, 256, number);
    strcat_s(str, 256, "\"\r\n");

    if (!writeToPort(hComm, str)) //Modem, here's the number to send the message to
        return;

    if (!readFromPort(hComm)) // Must be ">" 
        return;

    memset(str, 0, 256); 
    strcpy_s(str, message);
    strcat_s(str, 256, "^Z");

    if (!writeToPort(hComm, str)) //Modem, communicate this to the number I gave you.
        return;

    if (!readFromPort(hComm)) // Must be CMGS: ##
        return;
}


int writeToPort(HANDLE hComm, const char lpBuffer[])
{
    DWORD dNoOFBytestoWrite;         // No of bytes to write into the port
    DWORD dNoOfBytesWritten = 0;     // No of bytes written to the port
    dNoOFBytestoWrite = sizeof(lpBuffer);

    int Status = WriteFile(hComm,        // Handle to the Serial port
                        lpBuffer,     // Data to be written to the port
                dNoOFBytestoWrite,  //No of bytes to write
                &dNoOfBytesWritten, //Bytes written
                            NULL);

    if (Status == FALSE)
    {
        printf("ERROR: Cannot write to serial port\r\n");
    }
    else
        printf("STATUS: Command %s \n written to port.\r\n", lpBuffer); 

    return Status;
}

int readFromPort(HANDLE hComm)
{
    char TempChar; //Temporary character used for reading
    char SerialBuffer[256];//Buffer for storing Rxed Data
    DWORD NoBytesRead = 0;
    int i = 0;
    int status;

    memset(SerialBuffer, 0, 256);
    printf("STATUS: Waiting response...\r\n");

    do
    {
        status = ReadFile(hComm,           //Handle of the Serial port
            &TempChar,       //Temporary character
            sizeof(TempChar),//Size of TempChar
            &NoBytesRead,    //Number of bytes read
            NULL);

        if (!status)
        {
            printf("ERROR: Cannot read from serial port\r\n");
            break;
        }

        SerialBuffer[i] = TempChar;// Store Tempchar into buffer
        i++;
    }
    while (NoBytesRead > 0);

    if (status)
        printf("PORT RESPONSE: %s \r\n", SerialBuffer);

    return status;
}
Sergio Flores
  • 439
  • 2
  • 8
  • Review `strcpy_s(str, "AT+CMGS=\""); strcpy_s(str, message);` and how safe this code is. Then enable all compiler warnings. – chux - Reinstate Monica Mar 01 '18 at 19:31
  • thanks, however, I get the error, from the 2nd AT command sent, which is hardcoded, the one that reads "AT+CMFG=1\r\n". So the first command, which is a plain "AT\r\n" works all right, and the modem answers "OK", but on the 2nd command, the one I just said, I get back "AT+CC" ... ... I'm going nuts here – Sergio Flores Mar 01 '18 at 19:38
  • I'm not so sure "\r\n" is correct. I believe hitting enter in hyperterminal over this interface just sends "AT". Been a while, but try removing `\r\n`? `^M` or some other character may be necessary, but `\r\n` doesn't seem right. I could be wrong – zzxyz Mar 01 '18 at 19:45
  • What C compiler are you using? – chux - Reinstate Monica Mar 01 '18 at 19:47
  • 1
    Thanks, Yeah, but, if it's wrong, then why do I get the first "OK" back? Also, I tried "AT" (without CR), "AT\r" and those always result in a weird character coming back, ASCII 204... which I think it means "DISCONNECT". Could it be a problem with the readPort function? – Sergio Flores Mar 01 '18 at 19:48
  • I'm using VS community 2017, on multibyte setting – Sergio Flores Mar 01 '18 at 19:49
  • `strcat_s(str, 256, "^Z");` is suspicious. Do you really want to append 2 characters here or 1? – chux - Reinstate Monica Mar 01 '18 at 19:50
  • Good point. I need to send there a . However, again, the error occurs well before we reach this line... – Sergio Flores Mar 01 '18 at 19:54
  • [End of response to an AT command](https://stackoverflow.com/q/13286086/2410359) may be useful. – chux - Reinstate Monica Mar 01 '18 at 20:30
  • What are some sample strings passed to `writeToPort(hComm, str)` right after `strcpy_s(str, "AT+CMGS=\""); strcat_s(str, 256, number); strcat_s(str, 256, "\"\r\n");`? Be sure to not mentally construct the string, but extract via debugging. – chux - Reinstate Monica Mar 01 '18 at 20:37
  • From Memory (I don't have my Laptop to hand to test it), but the second call will echo back the command with it's current setting if you have the device configured to return extended result codes. Check your manual for the device, look for the AT command to turn off extended result codes, then you should find that you just get your "OK" back as expected. – shawty Mar 01 '18 at 20:56
  • Thanks, well, actually I don't care about the modem response as long as it is not an error. I did check the strings and seem ok ex: "AT+CMGS=\"99999999\"\r\n" -> Expected. – Sergio Flores Mar 01 '18 at 21:18
  • And ""This is NOT a test.^Z" -> expected... However, is this the right way to send a CTRL-Z ? Thanks – Sergio Flores Mar 01 '18 at 21:19

0 Answers0