#ifndef MB_TCP_SERVER_H
#define MB_TCP_SERVER_H

/***************************************************************************//**
 @defgroup lip_mb_server ModbusTCP Server
 @ingroup  lip_lvl_app
 @brief Модуль стека @c lip, реализующий сервер Modbus TCP.\n
  Зависит от: @ref lip_tcp

  Данный модуль реализует сервер Modbus TCP в соответствии со спецификациями,
  доступными на сайте http://www.modbus.org/specs.php.

  Сервер поддерживает стандартные функции для чтения и записи регистров и битовых полей:
   - Read Discrete Inputs (0x02)
   - Read Coils (0x01)
   - Write Single Coil (0x05)
   - Write Multiple Coils (0x15)
   - Read Input Register (0x04)
   - Read Holding Registers (0x03)
   - Write Single Register (0x06)
   - Write Multiple Registers (0x16)
   - Read/Write Multiple Registers (0x23)
   - Mask Write Register (0x22)

  Протокол Modbus подразумевает, что в сервере хранится 4 блока данных:
   - **Input Registers**. 16-битные регистры, доступные только для чтения.
   - **Holding Registers**. 16-битные регистры, доступные только и для чтения и записи.
   - **Input Discrete**. Дискретные значения (битовые поля), доступные только для чтения.
   - **Coils**. Дискретные значения (битовые поля), доступные для чтения и записи.

  Каждый элемент каждого блока имеет свой адрес. Каждый блок имеет свое адресное
  пространство. Адреса элементов в каждом блоке могут быть от 1 до 65536.
  Максимальное количество регистров и битовых полей определенного типа может быть
  ограничено с помощью настроек #LIP_MB_SERVER_INPUT_REGS_MAX, #LIP_MB_SERVER_HOLDING_REGS_MAX,
  #LIP_MB_SERVER_DISCRETE_INPUTS_MAX и #LIP_MB_SERVER_COILS_MAX файла конфигурации.
  Установка максимального количества в 0 приводит к исключению кода поддержки
  соответствующих функций из стека.

  Сама реализация сервера не определяет, как именно хранятся регистры и битовые поля,
  как и что именно происходит при их чтении или записи. Вместо этого пользователь
  должен реализовать функции обращения к ним и передать их серверу, чтобы он мог
  их вызвать в нужный момент (callback-функции).

  Для этого необходимо:
   - объявить структуру типа #t_lip_mb_server_cbs
   - выполнить ее начальную инициализацию через lip_mb_server_cb_init()
   - назначить полям структуры указатели на функции обработки поддерживаемых запросов
   - вызвать lip_mb_server_cb_set() для назначения указанных функций серверу.

  Как правило данная последовательность выполняется на этапе начальной инициализации
  стека (после вызова lip_init()).

  Для чтения или записи данных в обработчик всегда передается массив байт, в котором
  хранятся записываемые значения или в которые нужно сохранить считываемые значения.
  При этом с этим массивом байт не следует работать напрямую, для доступа к нему
  нужно использовать соответствующие макросы: LIP_MB_GET_REG(), LIP_MB_PUT_REG(),
  LIP_MB_GET_BIT(), LIP_MB_PUT_BIT().

  При работе сервер начинает прослушивать заданный TCP-порт на предмет клиентских
  подключений. По умолчанию используется стандартный для ModbusTCP номер порта
  --- 502, но он может быть изменен функцией lip_mb_server_tcp_port_set().

  Сервер может обрабатывать несколько клиентских подключений в параллель
  (максимальное количество определяется настройкой #LIP_MB_TCP_SERVER_SOCKET_CNT).
  При приходе действительного поддерживаемого запроса от клиента сервер проверяет его
  и, если запрос корректен, то вызывает соответствующую пользовательскую функцию
  (если она назначена) и возвращает ответ клиенту.
 ******************************************************************************/

/***************************************************************************//**
 @addtogroup lip_mb_server
 @{
 @file lip_mb_tcp_server.h
 @brief Файл содержит определения функций и макросов для модуля @ref lip_mb_server,
   которые могут быть использованы в приложении.
 @author Borisov Alexey <borisov@lcard.ru>
*******************************************************************************/

#include "core/lip_mb_server.h"

/***************************************************************************//**
   @brief Назначение TCP-порта для сервера

   Функция устанавливает номер порта, который будет прослушивать ModbusTCP сервер.
   По умолчанию используется порт 502. Если при смене есть установленные активные
   соединения, то они сохраняются и используется старый порт до его закрытия.

   @param[in] port  Номер TCP-порта.
*******************************************************************************/
void lip_mb_server_tcp_port_set(uint16_t port);


/***************************************************************************//**
   @brief Закрытие выбранных клиентских подключений

   Функция выполняет закрытие всех клиентских подключений для которых переданная
   функция обратного вызова вернет значение, отличное от 0.
   @param[in] con_sel_cb    Указатель на функцию обратного вызова для проверки,
                            нужно ли закрывать клиентское соединение.
                            Вызывается на каждое содинение и оно будет закрыто,
                            если функция вертнет значение, отличное от 0.
                            Если будет передан нулевой указатель в качетсве функции,
                            то будут закрыты все клиентские соединения.
   @param[in] cb_ctx        Указатель на контекст, который будет передан в качестве
                            параметра при вызове функции обратного вызова.
   @param[in] tout          Таймаут на закрытие соединения в мс.
*******************************************************************************/
void lip_mb_server_tcp_con_close(t_lip_mb_check_con_cb con_sel_cb, void *cb_ctx, uint32_t tout);


/** @}*/
#endif // MB_TCP_SERVER_H

