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

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

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

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

/**
* .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 );
}

// Функция для печати содержимого принятого
// пакета конфигурации.

void ECB::PrintDiagnostics(void) {
	int i, j, k, networks, component;

// Печатаем конфигурацию только для тех ECB,
// в поле InUse которых стоит нулевое значение,
// т.е. если был принят пакет.

		if(!_ecb.InUse) {

// Распечатываем версию диагностической
// поддержки, номер сокета для SPX-диагностики и
// количество компонент программного обеспечения,
// работающего на станции.

			printf("\n%d.%d\t%d\t%d\t\t",
				Rep.MajVer, Rep.MinVer,
				Rep.Socket, Rep.NumberOfComponents);

// Распечатываем номер сети, из которой пришел
// пакет конфигурации.

			for(i=0;i<4;i++) {
			  printf("%02.2X",(unsigned char)
				IPXHeader->_ipx_header.SourceNetwork[i]);
			}
			printf("\t");

// Распечатываем сетевой адрес станции, из
// которой пришел пакет конфигурации.

			for(i=0;i<6;i++) {
			  printf("%02.2X",(unsigned char)
				IPXHeader->_ipx_header.SourceNode[i]);
			}
			printf("\n\n");

// Для каждой программной компоненты
// распечатываем ее название.

			for(i=0;i<Rep.NumberOfComponents;) {
				switch(component=Rep.Buffer[i]) {
				case 0:
					printf("\tДрайвер IPX/SPX\n");
					i++;
					break;
				case 1:
					printf("\tДрайвер моста\n");
					i++;
					break;
				case 2:
					printf("\tДрайвер сетевой оболочки\n");
					i++;
					break;
				case 3:
					printf("\tСетевая оболочка\n");
					i++;
					break;
				case 4:
					printf("\tОболочка VAP\n");
					i++;
					break;

// Для мостов и серверов дополнительно выводим
// количество подключенных к ним сетей,
// тип каждой сети, номера подключенных
// сетей и сетевые адреса адаптеров.

				case 5: case 6: case 7:
					switch(component) {
					case 5:
						printf("\tВыделенный мост\n");
						break;
					case 6:
						printf("\tФайл-сервер/внутренний мост\n");
						break;
					case 7:
						printf("\tНевыделенный сервер\n");
						break;
					}
					i++;

// Количество подключенных сетей

					printf("\t\tПодключено сетей: %d",
						(unsigned char)Rep.Buffer[i]);
					networks = Rep.Buffer[i];
					i++;

// Для каждой сети печатаем ее тип,
// номер сети и сетевой адрес адаптера.

					for(j=0;j<networks;j++) {

// Тип сети

						printf("\n\t\t\tТип сети: %d\t",
							(unsigned char)Rep.Buffer[i++]);

// Номер сети

						for(k=0;k<4;k++,i++) {
						  printf("%02.2X",(unsigned char)Rep.Buffer[i]);
						}
						printf("\t");

// Сетевой адрес адаптера

						for(k=0;k<6;k++,i++) {
						  printf("%02.2X",(unsigned char)Rep.Buffer[i]);
						}
					}
					printf("\n");
					break;
				}
			}

		}
}

