Описание вызовов драйвера сети

 

************************* Общая информация *************************

Определения, описанные в этом документе, объявлены в файле 'sys_h.asm',
который в свою очередь линкует файл 'sysdefs.asm'.

Данный документ подразумевает использование асм-компилятора sjasmplus из репозитория NedoOS.

sjasmplus поставляется в виде исполнияемого файла sjasmplus.exe для OS Windows.
А также в виде исходного кода для самостоятельной сборки под вами используюмую OS.

 

************************* Используемые выражения *************************


байт - минимальня единица хранения данных в ОЗУ ZX-Spectrum, равная 8 битам.

0x - приставка к константе, обозначающая число представленном в шестнадцатиричной системе измерения.

хост(host) - точка подключения

errno - номер ошибки

big-endian - представление числа в ОЗУ. Сначала старший байт, затем младший.
 К примеру 16 битное число 0x1234 располагается в памяти как DEFB 0x12,0x34
little-endian - представление числа в ОЗУ. Это представление использует процессор z80.
 Сначала младший байт, затем старший. В этом документе, по умолчанию, все числа little-endian.
 К примеру 16 битное число 0x1234 располагается в памяти как DEFB 0x34,0x12

SOCKET - дескриптор сокета. Знаковое 8-битное число.

sockaddr_in - структура, размером 15 байт, со следующими полями:
 sin_family - семейство адресов, беззнаковое 8-битное число.
  в текущей реализации допускается только значение 2 (AF_INET).
 sin_port - номер порта, 16-битное беззнаковое big-endian число.
 sin_addr - IP-адрес. Массив из четырёх 8-битных беззнаковых чисел.
  к примеру IP-адрес 1.2.3.4 располагается в памяти как defb 1,2,3,4
 sin_zero - зарезервировано. массив из 8 байт.

************************* Возможные номера ошибок (errno)*************************


SHUT_RDWR   EQU 2
ERR_EAGAIN  EQU 35  ;/* Try again */
ERR_EWOULDBLOCK EQU ERR_EAGAIN ;/* Operation would block */
ERR_INTR   EQU 4
ERR_NFILE   EQU 23
ERR_ALREADY  EQU 37
ERR_NOTSOCK  EQU 38
ERR_EMSGSIZE  EQU 40    ;/* Message too long */
ERR_PROTOTYPE  EQU 41
ERR_AFNOSUPPORT EQU 47
ERR_HOSTUNREACH EQU 65
ERR_ECONNABORTED EQU 53 /* Software caused connection abort */
ERR_CONNRESET  EQU 54
ERR_NOTCONN  EQU 57

************************* Протоколы соединений *************************


SOCK_STREAM EQU 0x01  ;tcp/ip
SOCK_ICMP  EQU 0x02  ;icmp
SOCK_DGRAM  EQU 0x03  ;udp/ip

AF_INET EQU 2


*********************** Вызовы ядра ***********************


При вызове функций ядра считается, что возможна порча всех
регистров(за исключением SP).

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

*********************** OS_NETSOCKET **********************


 Создаёт сокет.
 Макрос вызова функции ядра.
 Все аргументы в регистрах:
  D - семейство адресов, беззнаковое 8-битное число, допускается только значение 2 (AF_INET).
  E - протокол соединения(0x01 tcp/ip, 0x02 icmp, 0x03 udp/ip)
 Возвращаемые значения в регистрах:
  L - SOCKET при положительном значении, при отрицательном значении  - функция завершилась с ошибкой.
  А - errno при ошибке.
  
 Возможные ошибки:
  ERR_AFNOSUPPORT - семейство адресов не поддерживается
  ERR_NFILE  - нет свободных сокетов
  ERR_PROTOTYPE - протокол не поддерживается
  
 Пример создания TCP/IP сокета:
  LD D,AF_INET;2
  LD E,SOCK_STREAM
  OS_NETSOCKET
  BIT 7,L
  JP NZ,ERR_EXIT ;обработка ошибки
  LD A,L
  LD (SOC),A  ;сохраняем дескриптор сокета.
  
 Примечания:
  При закрытии процесса, закрываются все сокеты созданные этим процессом.
  Сокеты защищены от использования другим процессом.
  Номер исходящего порта присваивается автоматически из диапазона 49152...65535


  
*********************** OS_NETSHUTDOWN **********************


 Закрытие сокета.
 Макрос вызова функции ядра.
 Все аргументы в регистрах:
  A - SOCKET
  E - Варианты закрытия, 0 - закрыть немедленно, 1 - закрыть только если буфер отправки пуст.
 Возвращаемые значения в регистрах:
  L - При отрицательном значении  - функция завершилась с ошибкой.
  А - errno при ошибке.
 
 Пример закрытия сокета с ожиданием опустошения буфера отправки:
close_wait:
  LD A,(SOC)
  LD E,1
  OS_NETSHUTDOWN
  BIT 7,L
  RET Z   ;сокет закрылся
  CP ERR_EAGAIN
  JP NZ,ERR_EXIT  ;обработка ошибки не связанной с ожиданием отправки.
  OS_YIELD  ;не обязательно. Если время не критично,
      ;то отдадим квант времени системе.
  JR close_wait ;ожидаем отправки данных
  
 Возможные ошибки:
  ERR_NOTSOCK - не действительный дескриптор сокета
  ERR_EAGAIN - буфер отправки не пуст
  
 Примечание: Керналь закрывает сокеты процесса при закрытии процесса.
  Но, ввиду ограниченного количества сокетов, рекомендуется закрывать сокет
  как только он становится не нужен.


 
*********************** OS_NETCONNECT **********************


 Подключить TCP/IP сокет к хосту.
 Макрос вызова функции ядра.
 Все аргументы в регистрах:
  A - SOCKET
  DE - указатель на структуру sockaddr_in содержащую IP адрес и порт хоста.
 Возвращаемые значения в регистрах:
  L - При отрицательном значении  - функция завершилась с ошибкой.
  А - errno при ошибке.
 Возможные ошибки:
  ERR_NOTSOCK  - не действительный дескриптор сокета
  ERR_ALREADY  - сокет уже подключен
  ERR_HOSTUNREACH - хост не доступн, либо отверг подключение.
  
 Пример подключения к хосту с IP адресом 1.2.3.4 на порт 80:
  LD A,(SOC)
  LD DE,destination_host
  OS_NETCONNECT
  BIT 7,L
  JP NZ,ERR_EXIT ;обработка ошибки
  ... ;подключились
  
destination_host  
  DEFB AF_INET
  DEFB 0,80    ;порт назначения
  DEFB 1,2,3,4   ;IP адрес назначения
  DEFB 0,0,0,0,0,0,0,0 ;резерв
  
 Примечание: Данная функция применима только к TCP/IP сокетам.

 

*********************** OS_BIND **********************


 Присвоение сокету конкретного номера исходящего порта.
 Макрос вызова функции ядра.
 Все аргументы в регистрах:
  A - SOCKET
  DE - указатель на структуру sockaddr_in содержащую номер исходящего порта.
   (остальные поля структуры не используются, но обязаны присутствовать)
 Возвращаемые значения в регистрах:
  L - При отрицательном значении - функция завершилась с ошибкой.
  А - errno при ошибке.
 Возможные ошибки:
  ERR_NOTSOCK  - не действительный дескриптор сокета
  
 Пример присвоения сокету исходяего порта 433:
  LD A,(SOC)
  LD DE,source_host
  OS_BIND
  BIT 7,L
  JP NZ,ERR_EXIT ;обработка ошибки
  ... ;удачно, продолжаем работу
  
source_host  
  DEFB AF_INET
  DEFB high(433),low(433) ;исходящий порт
  DEFB 0,0,0,0   ;исходящий IP адрес (не используется в текущей реализации)
  DEFB 0,0,0,0,0,0,0,0 ;резерв
 Примечание: В режиме TCP/IP функция вызывается(если нужна) до вызовов OS_NETCONNECT или OS_LISTEN.


 
*********************** OS_LISTEN **********************


 Включить режим прослушивания исходящего порта(режим сервера) TCP/IP сокета.
 Макрос вызова функции ядра.
 Все аргументы в регистрах:
  A - SOCKET
 Возвращаемые значения в регистрах:
  L - При отрицательном значении - функция завершилась с ошибкой.
  А - errno при ошибке.
 Возможные ошибки:
  ERR_NOTSOCK  - не действительный дескриптор сокета
  ERR_ALREADY  - сокет уже подключен
  
 Пример включения режима прослушивания:
  LD A,(SOC)
  OS_LISTEN
  BIT 7,L
  JP NZ,ERR_EXIT ;обработка ошибки
  ... ;удачно, продолжаем работу
  
 Примечание: Данная функция применима только к TCP/IP сокетам.
  Как правило функция вызывается(если нужна) после вызова OS_BIND.
  


*********************** OS_ACCEPT **********************


 Принять входящее TCP/IP подключение.
 Макрос вызова функции ядра.
 Все аргументы в регистрах:
  A - SOCKET
 Возвращаемые значения в регистрах:
  L - SOCKET при положительном значении, при отрицательном значении  - функция завершилась с ошибкой.
  А - errno при ошибке.
 Возможные ошибки:
  ERR_NOTSOCK   - не действительный дескриптор сокета
  ERR_ECONNABORTED - общая ошибка сокета
  ERR_EAGAIN   - входящих подключений пока нет
  
 Пример принятия соединения с ожиданием подключения:
WAIT_CLIENTS
  LD A,(SOC)
  OS_ACCEPT
  BIT 7,L
  JR Z,ESTABLISHED
  CP ERR_EAGAIN
  JP NZ,ERR_EXIT ;обработка ошибки
  OS_YIELD  ;не обязательно. Если время реагирования на подключение не критично,
      ;то отдадим квант времени системе.
  JR WAIT_CLIENTS ;никто не подключился, ждём
ESTABLISHED
  LD A,L    ;удачно
  LD (SOC_CLIENT),A ;сохраняем дескриптор сокета.
  ... ;продолжаем работу
  
 Примечания: Данная функция применима только к TCP/IP сокетам.
  Функция вызывается после вызова OS_LISTEN.
  Возвращает новый дескриптор сокета с принятым соединением. Сокет прослушки продолжает слушать.
  Если дальнейшая прослушка не требуется, то рекомендуется сразу закрывать слушающий сокет.
  При недостатке сокетов, возвращается дескриптор подключенного сокета прослушки,
  в этом случае нет дальнейшего прослушивания.
  Т.е. при закрытии слушающего сокета, необходимо проверить(путем сравнения дескрипторов)
  не является ли он сокетом с принятым соединением.
  


*********************** OS_WIZNETREAD **********************


 Прочитать входящие данные.
 Макрос вызова функции ядра.
 
 При протоколе TCP/IP все аргументы в регистрах:
  A - SOCKET
  DE - указатель на буфер для принятия данных
  HL - размер буфера(в байтах)
 При протоколе отличном от TCP/IP все аргументы в регистрах:
  A - SOCKET
  DE - указатель на структуру sockaddr_in, в неё помещается(ядром) IP-адрес и порт хоста отправившего данные.
  IX - указатель на буфер для принятия данных
  HL - размер буфера(в байтах)
 Возвращаемые значения в регистрах:
  HL - при отрицательном значении функция завершилась с ошибкой,
   про значении больше нуля возвращается действительный размер(в байтах) принятых данных,
   нулевого значения вызов не возвращает.
  А - errno при ошибке.
 Возможные ошибки:
  ERR_NOTSOCK - не действительный дескриптор сокета
  ERR_EAGAIN - входящих данных пока нет
  ERR_NOTCONN - сокет с неустановленным\пропавшем соединением(при протоколе TCP/IP)
  
 Пример принятия данных по протоколу TCP/IP с ожиданием данных:
WAIT_DATA
  LD A,(SOC)
  LD DE,BUF
  LD HL,BUF_SIZE
  OS_WIZNETREAD
  BIT 7,H
  JR Z,RECEIVED ;ошибок нет
  CP ERR_EAGAIN
  JP NZ,ERR_EXIT ;обработка ошибки
  OS_YIELD  ;не обязательно. Если время реагирования на пришедшие данные не критично,
      ;то отдадим квант времени системе.
  JR WAIT_DATA ;данных нет, ждём
RECEIVED
  LD (DATA_SIZE),HL ;удачно. если требуется, то сохраняем количество принятых данных.
  ... ;продолжаем работу

BUF  DEFS 1000
BUF_SIZE EQU $-BUF
 
 Примечания: При протоколе отличном от TCP/IP, необходимо единовременно прочитать весь пакет,
  иначе недовычитанные данные пакета игнорируются.

 

*********************** OS_WIZNETWRITE **********************


 Отправить пакет данных.
 Макрос вызова функции ядра.
 
 При протоколе TCP/IP все аргументы в регистрах:
  A - SOCKET
  DE - указатель на буфер с данными
  HL - размер данных(в байтах), в текущей реализации максимум 8192 байта
 При протоколе отличном от TCP/IP все аргументы в регистрах:
  A - SOCKET
  DE - указатель на структуру sockaddr_in, в неё необходимо поместить IP-адрес и порт хоста получателя
  IX - указатель на буфер с данными
  HL - размер данных(в байтах), в текущей реализации максимум 8192 байта
 Возвращаемые значения в регистрах:
  HL - при отрицательном значении функция завершилась с ошибкой,
   иначе возвращается действительный размер(в байтах) отправленных данных,
  А - errno при ошибке.
 Возможные ошибки:
  ERR_NOTSOCK - не действительный дескриптор сокета
  ERR_NOTCONN - сокет с неустановленным\пропавшем соединением(при протоколе TCP/IP)
  ERR_EMSGSIZE - в буфере отправки нет места, либо пакет слишком большой
  
 Пример отправки данных по протоколу TCP/IP с ожиданием данных:
WAIT_SEND
  LD A,(SOC)
  LD DE,BUF
  LD HL,BUF_SIZE
  OS_WIZNETWRITE
  BIT 7,H
  JR Z,SEND_OK ;ошибок нет
  CP ERR_EMSGSIZE
  JP NZ,ERR_EXIT ;обработка ошибки
  OS_YIELD  ;не обязательно. Если время не критично,
      ;то отдадим квант времени системе.
  JR WAIT_SEND ;буфер отправки переполнен, ждём освобождения
SEND_OK
  LD (DATA_SIZE),HL ;удачно. если требуется, то сохраняем количество отправленных данных.
  ... ;продолжаем работу
 
BUF  DEFB "Hello World!"
BUF_SIZE EQU $-BUF
    

You have no rights to post comments

Комментарии   
#1 Dimkama 05.10.2020 13:43
Надо такую же статью про остальное