Arduino:Примеры/Web Parms

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Передача и анализ параметров[1]

Этот пример демонстрирует, как при помощи библиотеки Webduino сделать осуществить передачу и анализ данных, вводимых пользователем через браузерный интерфейс.

Код

/* Передача и анализ параметров (Webduino) */

/*
 * Этот скетч служит для тестирования и отладки библиотеки, 
 * но может быть и своеобразным шаблоном для нового скетча.
 *
 * Чтобы использовать его, введите в браузер один из URL’ов ниже.
 * Замените «host» на IP-адрес, присвоенный вашей Arduino.
 *
 * http://host/
 * http://host/index.html
 *
 * Эти URL возвращают HTTP-заголовок, сообщающий об успешном 
 * подключении, а также показывают параметры (если они есть), 
 * передавая их в виде одной строки. При этом анализ параметров не 
 * выполняется. Все это осуществляется вызовом команды defaultCmd.
 *  
 * http://host/raw.html
 *
 * Делает примерно то же самое, что и index.html, но выполняется командой rawCmd.
 * 
 * http://host/parsed.html
 *
 * Вызывает команду parsedCmd, которая показывает «сырую» строку с параметрами. Также анализирует отдельные параметры при помощи функции nextURLparam(), а затем показывает их.
 */


#define WEBDUINO_FAIL_MESSAGE "<h1>Request Failed</h1>"
#include "SPI.h"
#include "avr/pgmspace.h"
#include "Ethernet.h"
#include "WebServer.h"

#define VERSION_STRING "0.1"

/* ПОСТАВЬТЕ ЗДЕСЬ СОБСТВЕННОЕ ЗНАЧЕНИЕ. MAC-адрес должен отличаться 
 * от других девайсов в сети. Если MAC-адрес Ethernet-модуля совпадет 
 * с другим MAC-адресом, это повлечет проблемы с получением пакетов.
 */
static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

/* ВЫСТАВЬТЕ ТУТ ЗНАЧЕНИЕ, СООТВЕТСТВУЮЩЕЕ СЕТИ ВАШЕГО ХОСТА. 
 * Большинство сетей находятся в диапазонах 192.168.0.XXX 
 * или 192.168.1.XXX. Выберите адрес, который не используется 
 * и не присваивается автоматически DHCP-сервисом, к которому 
 * подключен ваш роутер. */
static uint8_t ip[] = { 192, 168, 1, 210 };

// ROM-сообщения, используемые скетчем. Они нужны, чтобы сэкономить
// место на RAM-памяти.

P(Page_start) = "<html><head><title>Web_Parms_1 Version "
VERSION_STRING "</title></head><body>\n";
P(Page_end) = "</body></html>";
P(Get_head) = "<h1>GET from ";  //  "запрос GET от "
P(Post_head) = "<h1>POST to ";  //  "запрос POST на "
P(Unknown_head) = "<h1>UNKNOWN request for ";  //  "запрос UNKNOWN для "
P(Default_head) = "unidentified URL requested.</h1><br>\n";  //  "запрошен неопределенный URL."
P(Raw_head) = "raw.html requested.</h1><br>\n";  //  "запрошен raw.html"
P(Parsed_head) = "parsed.html requested.</h1><br>\n";  //  "запрошен parsed.html"
P(Good_tail_begin) = "URL tail = '";  //  "хвостик URL = "
P(Bad_tail_begin) = "INCOMPLETE URL tail = '";  //  "НЕЗАКОНЧЕННЫЙ хвостик URL = "
P(Tail_end) = "'<br>\n";
P(Parsed_tail_begin) = "URL parameters:<br>\n";  //  "параметры URL:"
P(Parsed_item_separator) = " = '";
P(Params_end) = "End of parameters<br>\n";  //  "конец параметров:"
P(Post_params_begin) = "Parameters sent by POST:<br>\n";  //  "параметры, отправленные POST"
P(Line_break) = "<br>\n";

/* Это создает экземпляр веб-сервера. Как PREFIX указываем "",
 * благодаря чему все страницы будут в корне сервера. */
#define PREFIX ""
WebServer webserver(PREFIX, 80);

/* Команды – это функции, вызываемые веб-сервером. Они могут считывать 
// любые данные, опубликованные клиентом, и передавать их обратно от 
// сервера к браузеру. 
void helloCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  /* отправляем стандартное сообщение, что запрос был успешным. */  server.httpSuccess();

  /* Если получили GET или POST, то показываем данные.
     Если получили HEAD request, останавливаемся после 
     показа заголовков */
  if (type == WebServer::HEAD)
    return;

  server.printP(Page_start);
  switch (type)
    {
    case WebServer::GET:
        server.printP(Get_head);
        break;
    case WebServer::POST:
        server.printP(Post_head);
        break;
    default:
        server.printP(Unknown_head);
    }

    server.printP(Default_head);
    server.printP(tail_complete ? Good_tail_begin : Bad_tail_begin);
    server.print(url_tail);
    server.printP(Tail_end);
    server.printP(Page_end);

}


void rawCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  /* эта строчка отправляет браузеру стандартное сообщение, что запрос был успешным.*/
  server.httpSuccess();

  /* эта строчка отправляет браузеру стандартное сообщение, что запрос был успешным.*/
  if (type == WebServer::HEAD)
    return;

  server.printP(Page_start);
  switch (type)
    {
    case WebServer::GET:
        server.printP(Get_head);
        break;
    case WebServer::POST:
        server.printP(Post_head);
        break;
    default:
        server.printP(Unknown_head);
    }

    server.printP(Raw_head);
    server.printP(tail_complete ? Good_tail_begin : Bad_tail_begin);
    server.print(url_tail);
    server.printP(Tail_end);
    server.printP(Page_end);

}

#define NAMELEN 32
#define VALUELEN 32

void parsedCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  URLPARAM_RESULT rc;
  char name[NAMELEN];
  char value[VALUELEN];

  /* эта строчка отправляет браузеру стандартное сообщение, что запрос был успешным.*/
  server.httpSuccess();

  /* Если получили GET или POST, то показываем данные.
     Если получили HEAD request, останавливаемся после 
     показа заголовков */
  if (type == WebServer::HEAD)
    return;

  server.printP(Page_start);
  switch (type)
    {
    case WebServer::GET:
        server.printP(Get_head);
        break;
    case WebServer::POST:
        server.printP(Post_head);
        break;
    default:
        server.printP(Unknown_head);
    }

    server.printP(Parsed_head);
    server.printP(tail_complete ? Good_tail_begin : Bad_tail_begin);
    server.print(url_tail);
    server.printP(Tail_end);

  if (strlen(url_tail))
    {
    server.printP(Parsed_tail_begin);
    while (strlen(url_tail))
      {
      rc = server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN);
      if (rc == URLPARAM_EOS)
        server.printP(Params_end);
       else
        {
        server.print(name);
        server.printP(Parsed_item_separator);
        server.print(value);
        server.printP(Tail_end);
        }
      }
    }
  if (type == WebServer::POST)
  {
    server.printP(Post_params_begin);
    while (server.readPOSTparam(name, NAMELEN, value, VALUELEN))
    {
      server.print(name);
      server.printP(Parsed_item_separator);
      server.print(value);
      server.printP(Tail_end);
    }
  }
  server.printP(Page_end);

}

void my_failCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  /* Эта строчка отправляет браузеру стандартный HTTP-заголовок «HTTP 400 Bad Request» */
  server.httpFail();

  /* Если получили GET или POST, то показываем данные.
     Если получили запрос HEAD, останавливаемся после 
     показа заголовков */ 
  if (type == WebServer::HEAD)
    return;

  server.printP(Page_start);
  switch (type)
    {
    case WebServer::GET:
        server.printP(Get_head);
        break;
    case WebServer::POST:
        server.printP(Post_head);
        break;
    default:
        server.printP(Unknown_head);
    }

    server.printP(Default_head);
    server.printP(tail_complete ? Good_tail_begin : Bad_tail_begin);
    server.print(url_tail);
    server.printP(Tail_end);
    server.printP(Page_end);

}




void setup()
{
  /* Инициализируем Ethernet-модуль */
  Ethernet.begin(mac, ip);

  /* задаем команду, которая будет вызываться по умолчанию, 
  /* когда пользователь будет запрашивать доступ к корню сервера 
  */ 
  webserver.setDefaultCommand(&helloCmd);

  /* задаем команду, которая будет вызываться по умолчанию, 
  /* когда пользователь запросит доступ к несуществующей странице 
  */ 
  webserver.setFailureCommand(&my_failCmd);

  /* запускаем команду indexHTML, если пользователь пытается загрузить страницу /index.html */
  webserver.addCommand("index.html", &helloCmd);

  /* эта команда вызывается, когда пользователь пытается загрузить /raw.html */
  webserver.addCommand("raw.html", &rawCmd);
  webserver.addCommand("parsed.html", &parsedCmd);

  /* Запускаем веб-сервер */
  webserver.begin();
}

void loop()
{
  char buff[64];
  int len = 64;

  /* Вечно обрабатываем входящие соединения (одновременно может обрабатываться только одно соединение) */  
  webserver.processConnection(buff, &len);
}

См.также

Внешние ссылки