Как настроить заголовки HTML при выполнении POST с помощью AT-команд?

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:

Я использую Arduino Nano с библиотекой SoftwareSerial на скорости 9600 бод для связи с модулем GSM2 Click (на базе QUECTEL M95) от Micro Elektronika. Я хочу отправлять данные POST онлайн с пользовательскими заголовками HTML. Мне не удается успешно отправить модуль QUECTEL в POST, когда я пытаюсь добавить пользовательские заголовки с помощью команды QHTTPPOST.

Это первое полуполезное руководство по командам HTTP AT, которое я нашел: /www.quectel.com/UploadImage/Downlad/Quectel_WCDMA_UGxx_HTTP_AT_Commands_Manual_V1.2.pdf

Вот официальное руководство по эксплуатации QUECTEL M95: http://www.quectel.com/product/prodetail.aspx?id=7

Вкратце:

1) Регистрация в сети работает нормально.

2) Публикация данных, когда НЕ используются пользовательские заголовки запросов, работает нормально.

3) Команды QHTTPCFG нет в официальной документации для этого модуля, но она была предложена при обращении в службу поддержки QUECTEL.

4) Полученные коды ошибок AT: CME ERROR: 3804 «HTTP не получает запрос»

  • Мобильный оператор: Vodacom Южная Африка
  • Сила сигнала CSQ: 26

Требуемый формат для AT-команд M95:

Команда ‹ CR >


МОЙ КОД

//Set the correct URL
mySerial.print("AT+QHTTPURL=34,1\r")
mySerial.print("http://posttestserver.com/post.php\r");

ОТКЛИК:

OK

//Set custom request headers
mySerial.print("AT+QHTTPCFG=\"requestheader\",1\r")

ОТКЛИК:

OK

//Initiate post requst (length 187 characters, 60s to write, 7s to read)
mySerial.print("AT+QHTTPPOST=187,60,7\r");

ОТКЛИК:

СОЕДИНЯТЬ

//SEND REQUEST HEADER
mySerial.print("POST/post.php HTTP/1.1\r\n");//25 chars
mySerial.print("HOST: posttestserver.com\r\n");//26 chars
mySerial.print("Accept: */*\r\n");//13 chars
mySerial.print("User-Agent: QUECTEL_MODULE2\r\n");//29 chars
mySerial.print("Connection: Keep-Alive\r\n");//24 chars
mySerial.print("Content-Type: application/x-www-form-urlencoded\r\n");//49 chars
mySerial.print("Content-Length: 0\r\n");//19 chars
mySerial.print("\r\n");//2 chars

... ОТСУТСТВУЕТ: через 60 секунд должен появиться ответ OK, указывающий на успешную отправку.

mySerial.print("AT+QHTTPREAD=5\r");

ОТКЛИК:

+ ОШИБКА CME: 3804


person Jakes23    schedule 14.10.2016    source источник
comment
Откуда взялся issueCommand? Почему после него нет \r (поскольку AT+QHTTPPOST.... раньше включал его)? Кроме того, я почти уверен, что это не имеет ничего общего с c или c++; тега arduino должно быть достаточно.   -  person KevinDTimm    schedule 14.10.2016
comment
@KevinDTimm Мои извинения. Я хотел заменить это на mySerial.print для ясности в вопросе. Я изменил свой первоначальный вопрос. issueCommand — это просто mySerial.print() с \r в конце.   -  person Jakes23    schedule 15.10.2016
comment
Для меня это работает, в POST/post.php отсутствует пробел   -  person Tarion    schedule 02.11.2018


Ответы (2)


Используя команды AT TCPIP вместо команд AT HTTP, я смог решить свою проблему. Теперь я успешно разместил данные вместе с настроенными заголовками.

Вот код, который работает:

mySerial.print("AT+QIOPEN=\"TCP\",\"64.90.48.15\",80\r"); 

ЖДИТЕ ответа "ПОДКЛЮЧИТЬСЯ"

mySerial.print("AT+QISEND\r");//

ЖДИТЕ ответа «>»

//The HTML Header
mySerial.print("POST /post.php?dir=WPCN HTTP/1.1\r\n");
mySerial.print("HOST: posttestserver.com\r\n");
mySerial.print("Accept: application/json\"\r\n");
mySerial.print("User-Agent: QUECTEL_MODULE2\r\n");
mySerial.print("Content-Length: 7\r\n");
//Signifies end of Header
mySerial.print("\r\n");
//Data:
mySerial.print(“[hello]\r”);
//This is the <CTRL+Z> character which signifies end of transmission
mySerial.print("\x1A");

Ответ "ОТПРАВИТЬ ОК"

//End Data Mode
delay(1000);
mySerial.print("+++");
delay(1000);
//Close connection
mySerial.print("AT+QCLOSE\r");
person Jakes23    schedule 19.10.2016

Несколько вещей, которые могут помочь:

  1. Вам следует дождаться, пока GSM-модуль вернет Connect в команду mySerial.print("AT+QHTTPPOST=187,60,7\r");. После этого вы должны отправить данные поста.

  2. Когда вы используете команды AT+QHTTP, вы используете уровень HTTP, реализованный в модуле Quectel. Таким образом, вам нужно отправить только данные сообщения, а не все сообщение TCP для POST HTTP. Сообщение, которое вы отправляете, представляет собой пакет TCP, реализующий протокол HTTP. Для получения дополнительной информации вы можете посмотреть это.

Из 2 вам нужно отправить только те данные, которые вы хотите опубликовать. По ссылке, которую я добавил, вы можете увидеть этот пример пакета HTTP POST:

POST /bin/login HTTP/1.1
Host: 127.0.0.1:8000
Accept: image/gif, image/jpeg, */*
Referer: http://127.0.0.1:8000/login.html
Accept-Language: en-us
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Length: 37
Connection: Keep-Alive
Cache-Control: no-cache

User=Peter+Lee&pw=123456&action=login

Если вы хотите сделать этот POST, вы должны сделать что-то вроде:

mySerial.print("AT+QHTTPPOST=37,60,7\r");

СОЕДИНЯТЬ

mySerial.print("User=Peter+Lee&pw=123456&action=login");

А потом прочитайте ответ или что-то в этом роде.

person dubafek    schedule 15.10.2016
comment
Ваш ответ очень полезен, спасибо. Некоторые комментарии: 1) Заголовки в моем вопросе произвольны. Это просто фиктивный пост для проверки. Для реального приложения мне нужно изменить заголовок Accept и добавить заголовок X-Session_ID. Итак, мне нужно настроить заголовки. 2) Мне удалось опубликовать, не настраивая заголовки. При задержке после почтового запроса на ожидание ответа CONNECT результат тот же: почта не проходит. - person Jakes23; 15.10.2016
comment
Ваш ответ полезен, спасибо, но он еще не решает проблему. Некоторые дополнительные комментарии: 1) Заголовки в моем вопросе произвольны. Это просто фиктивный пост для проверки. Для реального приложения мне нужно изменить заголовок Accept и добавить заголовок X-Session_ID. Итак, мне нужно настроить заголовки. 2) Мне удалось опубликовать, не настраивая заголовки. 3) При задержке после QHTTP POST на ожидание ответа CONNECT результат аналогичен: сообщение не выполняется. Теперь я получаю +CME ERROR: 3825 InputTimeout +CME ERROR: 3804 - person Jakes23; 15.10.2016
comment
Дело в том, что вам не нужно помещать заголовки. Заголовки идут, когда вы используете TCP-соединение. При использовании QHTTPPOST модуль Quectel должен создавать HTTP-пакет и добавлять заголовки. - person dubafek; 15.10.2016
comment
Итак, вы предлагаете использовать команду TCP вместо установки заголовков? У меня сложилось впечатление, что установка пользовательских заголовков означает возможность использовать команду post для изменения заголовков, но я понимаю, о чем вы говорите. - person Jakes23; 15.10.2016
comment
В разделе 3.1.2.1. из присланной вами документации есть пример использования QHTTPPOST, в нем заголовки не ставятся. Я думаю, что если вам нужно установить заголовки, вам нужно открыть TCP-соединение и отправить по нему пакет POST. - person dubafek; 16.10.2016
comment
Вы действительно правы. Парень из Quectel направил меня не в ту сторону, но мне удалось решить проблему так, как вы сейчас предложили. Я опубликую решение, которое сработало позже. - person Jakes23; 18.10.2016