Отправка AT-команд на модем USR в C

Мне было интересно, если кто-нибудь из вас знает, что я делаю неправильно здесь? Итак, у меня есть эта программа на C, которая отправляет AT-команды на модем. Эти команды проверены на гипертерминале и работают нормально, но при отправке их через модем я получаю сначала и "ОК" на первую "АТ" команду, что хорошо, но потом при отправке следующей команды модем отвечает "AT+CC"... что я понятия не имею, что это значит. Любая помощь приветствуется.

Источник:

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;
}

person Sergio Flores    schedule 01.03.2018    source источник
comment
Просмотрите strcpy_s(str, "AT+CMGS=\""); strcpy_s(str, message); и узнайте, насколько безопасен этот код. Затем включите все предупреждения компилятора.   -  person chux - Reinstate Monica    schedule 01.03.2018
comment
спасибо, однако, я получаю сообщение об ошибке из 2-й отправленной AT-команды, которая жестко закодирована, та, которая читает AT+CMFG=1\r\n. Таким образом, первая команда, которая является простой AT\r\n, работает нормально, и модем отвечает OK, но на вторую команду, которую я только что сказал, я получаю ответ AT+CC ... ... I' я схожу с ума здесь   -  person Sergio Flores    schedule 01.03.2018
comment
Я не уверен, что \r\n правильно. Я считаю, что нажатие ввода в гипертерминале через этот интерфейс просто отправляет AT. Прошло некоторое время, но попробуйте удалить \r\n? ^M или какой-то другой символ может быть необходим, но \r\n кажется неправильным. Я могу ошибаться   -  person zzxyz    schedule 01.03.2018
comment
Какой компилятор C вы используете?   -  person chux - Reinstate Monica    schedule 01.03.2018
comment
Спасибо, да, но если это неправильно, то почему я получаю первое ОК обратно? Кроме того, я попробовал AT (без CR), AT\r, и они всегда приводят к возвращению странного символа, ASCII 204 ... что, я думаю, означает ОТКЛЮЧЕНИЕ. Может ли быть проблема с функцией readPort?   -  person Sergio Flores    schedule 01.03.2018
comment
Я использую VS Community 2017 с многобайтовой настройкой.   -  person Sergio Flores    schedule 01.03.2018
comment
strcat_s(str, 256, "^Z"); подозрительно. Вы действительно хотите добавить сюда 2 символа или 1?   -  person chux - Reinstate Monica    schedule 01.03.2018
comment
Хорошая точка зрения. Мне нужно отправить туда ‹CTRL-Z›. Однако, опять же, ошибка возникает задолго до того, как мы доходим до этой строки...   -  person Sergio Flores    schedule 01.03.2018
comment
Конец ответа на AT-команду может быть полезен.   -  person chux - Reinstate Monica    schedule 01.03.2018
comment
Какие примеры строк передаются writeToPort(hComm, str) сразу после strcpy_s(str, "AT+CMGS=\""); strcat_s(str, 256, number); strcat_s(str, 256, "\"\r\n");? Обязательно не мысленно создавайте строку, а извлекайте ее с помощью отладки.   -  person chux - Reinstate Monica    schedule 01.03.2018
comment
Из памяти (у меня нет ноутбука, чтобы протестировать его), но второй вызов вернет команду с текущими настройками, если ваше устройство настроено на возврат расширенных кодов результатов. Проверьте свое руководство для устройства, найдите AT-команду для отключения расширенных кодов результатов, после чего вы обнаружите, что вы просто получаете свое «ОК», как и ожидалось.   -  person shawty    schedule 01.03.2018
comment
Спасибо, ну на самом деле мне плевать на ответ модема, если это не ошибка. Я проверил строки и вроде все в порядке, например: AT+CMGS=\99999999\\r\n -> Ожидается.   -  person Sergio Flores    schedule 02.03.2018
comment
И это НЕ тест. ^Z -> ожидается... Однако, это правильный способ отправить CTRL-Z ? Спасибо   -  person Sergio Flores    schedule 02.03.2018