/*
 * The UDS Collection
 * Copyright (C) 2001  Julian v. Bock
 *
 * 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
 *
 *	(See file COPYING for more information)
 */

#ifndef _uds_swanpipe_hh
#define _uds_swanpipe_hh


// includes

#include <linux/if_wanpipe.h>
#include <linux/wanpipe.h>
#include <linux/sdla_x25.h>
#include <uds/packetsocket.hh>
#include <fstream>
#include <string>


namespace uds
{

/** x25api_t wrapper class
	\author Julian v. Bock */
class X25Api_t
{
public:
	/** \param c 'clear data' flag */
	explicit
	X25Api_t( bool c = false );

	/** \param d data
		\param qdm qdm bits */
	explicit
	X25Api_t( const string& d, unsigned char qdm = 0 );

	/** destructor */
	~X25Api_t();

	const x25api_t*
	operator -> () const { return &api; }

	x25api_t*
	operator -> () { return &api; }

	const x25api_t&
	operator * () const { return api; }

	x25api_t&
	operator * () { return api; }

	const x25api_t*
	operator () () const { return &api; }

	x25api_t*
	operator () () { return &api; }

	/** \return packet data */
	string
	Data() const { return string( api.data, api.hdr.length ); }

	/** sets data and length fields
		\param d data
		\param qdm qdm bits */
	void
	SetData( const string& d, unsigned char qdm = 0 );

	/** clears all data (including header) */
	void
	Clear() { memset( &api, 0, sizeof( api ) ); }

	/** sends api data to socket
		\param sock socket
		\param oob 'out of band data' flag */
	void
	Send( int sock, bool oob = false ) const;

private:
	/// wrapped x25api_t
	x25api_t api;
};

ostream&
operator << ( ostream& out, const X25Api_t& api );


/** socket class for X.25 Sangoma Wanpipe cards.
	\author Julian v. Bock */
class X25_SWanpipe : public PacketSocket
{
public:
	/** default constructor */
	X25_SWanpipe();
	
	/** \param fd socket file descriptor */
	explicit
	X25_SWanpipe( int fd );
	
	/** destructor */
	virtual
	~X25_SWanpipe();
	
	/** closes a connection */
	virtual void
	Close();

	/** creates a new socket and enables it tp accept connections
		\param ifc interface
		\param n queue size for pending connection requests */
	virtual void
	Listen( const char* ifc, unsigned n );
	
	/** accepts a conection to a server socket
		\return new socket (file) descriptor */
	virtual int
	Accept();

	/** creates a new socket and connects to a X.25 interface
		\param ifc interface
		\param ps packet size
		\param sn source number
		\param dn destination number */
	virtual void
	Connect( const char* ifc, size_t ps, const char* sn, const char* dn );

	/** fetches one packet from the socket
		\param p packet structure to be filled. All bytes of the structure
			are set to zero before the data is read.
		\param oob 'out of band' data flag */
	virtual void
	Recv( X25Api_t& p, bool oob = false );

	/** fetches data from the socket. If the message was fragmented, all
		packets are read.
		\param data string to be filled with data */
	virtual void
	Recv( string& data );

	/** fetches data from the socket. If the message was fragmented, all
		packets are read.
		\return data */
	virtual string
	Recv() { string ret; Recv( ret ); return ret; }

	/** writes data to the socket
		\param d data
		\param oob 'out of band data' flag */
	virtual void
	Send( const string& d, bool oob = false );

	/** checks whether the link is still up. Only meaningful if the socket
		is connected
		\return true if the link is up */
	bool
	Link() const;

	/** \return packet size */
	size_t
	PacketSize() const { return pack_sz; }

	/** \return link number */
	unsigned short
	LCN() const { return lcn; }

private:
	/// packet size
	size_t pack_sz;
	/// link number
	unsigned short lcn;

	/** Close() helper function */
	void
	priv_close();
};

/** creates a X.25 Sangoma Wanpipe socket
	\param ifc interface
	\param svr 'server socket' flag
	\return socket file descriptor */
int
CrX25_SWanpipeSocket( const char* ifc, bool svr = true );

}

#endif // _uds_swanpipe_hh
