/*
    ncpext.c
    Copyright (C) 2001  Petr Vandrovec

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Revision history:

	1.00  2001, January 27		Petr Vandrovec <vandrove@vc.cvut.cz>
		Initial version.

 */

#include <ncp/nwcalls.h>
#include <ncp/nwnet.h>
#include "ncplib_i.h"
#include "ncpcode.h"

#include <string.h>

#define ncp_array_size(x) (sizeof(x)/sizeof((x)[0]))

NWCCODE
NWScanNCPExtensions(
		NWCONN_HANDLE conn,
		nuint32* iterHandle,
		char* name,
		nuint8* majorVersion,
		nuint8* minorVersion,
		nuint8* revision,
		nuint8 queryData[32]) {
	NWCCODE err;
	
	if (!iterHandle) {
		return NWE_PARAM_INVALID;
	}
	ncp_init_request_s(conn, 0);
	ncp_add_dword_lh(conn, *iterHandle);
	err = ncp_request(conn, 36);
	if (err) {
		ncp_unlock_conn(conn);
		return err;
	}
	if (conn->ncp_reply_size < 72) {
		ncp_unlock_conn(conn);
		return NWE_INVALID_NCP_PACKET_LENGTH;
	}
	*iterHandle = ncp_reply_dword_lh(conn, 0);
	if (majorVersion)
		*majorVersion = ncp_reply_byte(conn, 4);
	if (minorVersion)
		*minorVersion = ncp_reply_byte(conn, 5);
	if (revision)
		*revision = ncp_reply_byte(conn, 6);
	if (queryData)
		memcpy(queryData, ncp_reply_data(conn, 40), 32);
	if (name) {
		size_t namelen;
		
		namelen = ncp_reply_byte(conn, 7);
		if (namelen >= MAX_NCP_EXTENSION_NAME_BYTES) {
			ncp_unlock_conn(conn);
			return NWE_BUFFER_OVERFLOW;
		}
		memcpy(name, ncp_reply_data(conn, 8), namelen);
		name[namelen] = 0;
	}
	ncp_unlock_conn(conn);
	return 0;
}

NWCCODE
NWGetNumberNCPExtensions(
		NWCONN_HANDLE conn,
		nuint* exts) {
	NWCCODE err;
	u_int32_t num;
	NW_FRAGMENT rp;
	u_int32_t iterHandle;
	
	rp.fragAddr.rw = &num;
	rp.fragSize = sizeof(num);
	err = NWRequestSimple(conn, NCPC_SFN(36,3), NULL, 0, &rp);
	if (err) {
		if (err != NWE_NCP_NOT_SUPPORTED) {
			return err;
		}
		iterHandle = ~0;
		num = 0;
		while ((err = NWScanNCPExtensions(conn, &iterHandle, NULL, NULL, NULL, NULL, NULL)) == 0) {
			num++;
		}
		if (err != NWE_SERVER_FAILURE)
			return err;
	} else {
		if (rp.fragSize < 4)
			return NWE_INVALID_NCP_PACKET_LENGTH;
	}
	if (exts)
		*exts = num;
	return 0;	
}
