// ===================================================
// Листинг 5. Функции IPX.
//
// Файл ipx.c
//
// (C) A. Frolov, 1993
// ===================================================

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include "ipx.h"

/**
* .Name    IntSwap
*
* .Title   Обмен байтов в слове
*
* .Descr   Функция меняет местами байты в слове,
*          которое передается ей в качестве параметра
*
* .Params  unsigned i - преобразуемое слово
*
* .Return  Преобразованное слово
**/

unsigned IntSwap(unsigned i) {
	return((i>>8) | (i & 0xff)<<8);
}

/**
* .Name    IPXOpenSocket
*
* .Title   Открыть сокет
*
* .Descr      Функция открывает сокет, тип которого
*          передается ей через параметр SocketType.
*             Перед вызовом необходимо подготовить в памяти
*          слово и записать в него значение открываемого
*          сокета (или нуль, если нужен динамический сокет).
*          Адрес слова передается через параметр Socket.
*             Если открывается динамический сокет, его
*          значение будет записано по адресу Socket.
*
* .Params  int SocketType - тип сокета:
*                    0x00 - короткоживущий;
*                    0xFF - долгоживущий.
*
*          unsigned *Socket - указатель на слово,
*                    в котором находится номер
*                    открываемого сокета или нуль,
*                    если нужен динамический сокет.
*
* .Return  0 - сокет открыт успешно;
*          0xFE - переполнилась таблица сокетов;
*          0xFF - такой сокет уже открыт.
**/

int IPXOpenSocket(int SocketType, unsigned *Socket) {

	struct IPXSPX_REGS iregs;

	iregs.bx = IPX_CMD_OPEN_SOCKET;
	iregs.dx = IntSwap(*Socket);
	iregs.ax = SocketType;
	ipxspx_entry( (void far *)&iregs );

	*Socket = IntSwap(iregs.dx);
	return(iregs.ax);
}

/**
* .Name    IPXCloseSocket
*
* .Title   Закрыть сокет
*
* .Descr      Функция закрывает сокет.
*             Перед вызовом необходимо подготовить в памяти
*          слово и записать в него значение закрываемого
*          сокета. Адрес слова передается через параметр Socket.
*
* .Params  unsigned *Socket - указатель на слово,
*                    в котором находится номер
*                    закрываемого сокета.
*
* .Return  Ничего
**/

void IPXCloseSocket(unsigned *Socket) {

	struct IPXSPX_REGS iregs;

	iregs.bx = IPX_CMD_CLOSE_SOCKET;
	iregs.dx = IntSwap(*Socket);
	ipxspx_entry( (void far *)&iregs );
}

/**
* .Name    IPXListenForPacket
*
* .Title   Принять пакет
*
* .Descr      Функция подготавливает ECB для приема
*          пакета из сети. Указатель на ECB передается
*          через параметр RxECB.
*
* .Params  struct ECB *RxECB - указатель на ECB,
*                    заполненное для приема пакета.
*
* .Return  Ничего
**/

void IPXListenForPacket(struct ECB *RxECB) {

	struct IPXSPX_REGS iregs;

	iregs.es = FP_SEG((void far*)RxECB);
	iregs.si = FP_OFF((void far*)RxECB);
	iregs.bx = IPX_CMD_LISTEN_FOR_PACKET;
	ipxspx_entry( (void far *)&iregs );
}

/**
* .Name    IPXSendPacket
*
* .Title   Передать пакет
*
* .Descr      Функция подготавливает ECB для передачи
*          пакета. Указатель на ECB передается через
*          параметр TxECB.
*
* .Params  struct ECB *TxECB - указатель на ECB,
*                    заполненное для передачи пакета.
*
* .Return  Ничего
**/

void IPXSendPacket(struct ECB *TxECB) {

	struct IPXSPX_REGS iregs;

	iregs.es = FP_SEG((void far*)TxECB);
	iregs.si = FP_OFF((void far*)TxECB);
	iregs.bx = IPX_CMD_SEND_PACKET;
	ipxspx_entry( (void far *)&iregs );
}

/**
* .Name    IPXRelinquishControl
*
* .Title   Передать управление IPX при ожидании
*
* .Descr      Функция используется при ожидании
*          завершения приема через опрос поля InUse
*          блока ECB.
*
* .Params  Не используются
*
* .Return  Ничего
**/

void IPXRelinquishControl(void) {

	struct IPXSPX_REGS iregs;

	iregs.bx = IPX_CMD_RELINQUISH_CONTROL;
	ipxspx_entry( (void far *)&iregs );
}
