Blame tools/extra/mmlink/mmlink_server.h

Packit 534379
// Copyright(c) 2017, Intel Corporation
Packit 534379
//
Packit 534379
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
// modification, are permitted provided that the following conditions are met:
Packit 534379
//
Packit 534379
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer.
Packit 534379
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer in the documentation
Packit 534379
//   and/or other materials provided with the distribution.
Packit 534379
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
//   may be used to  endorse or promote  products derived  from this  software
Packit 534379
//   without specific prior written permission.
Packit 534379
//
Packit 534379
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 534379
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
// POSSIBILITY OF SUCH DAMAGE.
Packit 534379
//****************************************************************************
Packit 534379
/// @file  mmlink_server.h
Packit 534379
/// @brief Basic AFU interaction.
Packit 534379
/// @ingroup SigTap
Packit 534379
/// @verbatim
Packit 534379
//****************************************************************************
Packit 534379
Packit 534379
#ifndef MMLINK_SERVER_H
Packit 534379
#define MMLINK_SERVER_H
Packit 534379
Packit 534379
#include <netinet/in.h>
Packit 534379
#include <string.h>
Packit 534379
#include <sys/param.h>
Packit 534379
Packit 534379
class mmlink_connection;
Packit 534379
class mm_debug_link_interface;
Packit 534379
Packit 534379
class mmlink_server
Packit 534379
{
Packit 534379
public:
Packit 534379
	mmlink_server(struct sockaddr_in *sock, mm_debug_link_interface *driver);
Packit 534379
	~mmlink_server();
Packit 534379
	int run(unsigned char* stpAddr);
Packit 534379
	void stop(void) { m_running = false; }
Packit 534379
	int get_server_id(void) { return m_server_id; }
Packit 534379
	mm_debug_link_interface *get_driver_fd(void) { return m_driver; }
Packit 534379
	void print_stats(void);
Packit 534379
Packit 534379
protected:
Packit 534379
Packit 534379
	mmlink_server(const mmlink_server& mm_server)
Packit 534379
		{
Packit 534379
			m_listen                  = mm_server.m_listen;
Packit 534379
			m_server_id               = mm_server.m_server_id;
Packit 534379
			m_num_bound_connections   = mm_server.m_num_bound_connections;
Packit 534379
			m_num_connections         = mm_server.m_num_connections;
Packit 534379
			m_t2h_pending             = mm_server.m_t2h_pending;
Packit 534379
			m_h2t_pending             = mm_server.m_h2t_pending;
Packit 534379
			m_t2h_stats               = mm_server.m_t2h_stats;
Packit 534379
			m_h2t_stats               = mm_server.m_h2t_stats;
Packit 534379
			m_addr                    = mm_server.m_addr;
Packit 534379
			m_running                 = mm_server.m_running;
Packit 534379
			m_driver                  = mm_server.m_driver;
Packit 534379
Packit 534379
			m_conn = new mmlink_connection*[MAX_CONNECTIONS];
Packit 534379
			for (size_t i = 0; i < MAX_CONNECTIONS; ++i)
Packit 534379
					m_conn[i] = mm_server.m_conn[i];
Packit 534379
		}
Packit 534379
Packit 534379
	mmlink_server& operator=(const mmlink_server& mm_server)
Packit 534379
		{
Packit 534379
			if( this != &mm_server) {
Packit 534379
Packit 534379
				m_listen                  = mm_server.m_listen;
Packit 534379
				m_server_id               = mm_server.m_server_id;
Packit 534379
				m_num_bound_connections   = mm_server.m_num_bound_connections;
Packit 534379
				m_num_connections         = mm_server.m_num_connections;
Packit 534379
				m_t2h_pending             = mm_server.m_t2h_pending;
Packit 534379
				m_h2t_pending             = mm_server.m_h2t_pending;
Packit 534379
				m_t2h_stats               = mm_server.m_t2h_stats;
Packit 534379
				m_h2t_stats               = mm_server.m_h2t_stats;
Packit 534379
				m_addr                    = mm_server.m_addr;
Packit 534379
				m_running                 = mm_server.m_running;
Packit 534379
				m_driver                  = mm_server.m_driver;
Packit 534379
Packit 534379
				if(m_conn) delete[] m_conn;
Packit 534379
				m_conn = new mmlink_connection*[MAX_CONNECTIONS];
Packit 534379
				for (size_t i = 0; i < MAX_CONNECTIONS; ++i)
Packit 534379
						m_conn[i] = mm_server.m_conn[i];
Packit 534379
			}
Packit 534379
			return *this;
Packit 534379
		}
Packit 534379
Packit 534379
private:
Packit 534379
	int m_listen;
Packit 534379
	int m_server_id;
Packit 534379
	static const size_t MAX_CONNECTIONS = 2;
Packit 534379
Packit 534379
	int m_num_bound_connections;
Packit 534379
	int m_num_connections;
Packit 534379
Packit 534379
	bool m_t2h_pending;
Packit 534379
	bool m_h2t_pending;
Packit 534379
	int handle_t2h(mmlink_connection *data_conn, bool can_read_driver, bool can_write_host);
Packit 534379
	int handle_h2t(mmlink_connection *data_conn, bool can_read_host, bool can_write_driver);
Packit 534379
Packit 534379
	struct sockaddr_in m_addr;
Packit 534379
	bool m_running;
Packit 534379
Packit 534379
	mm_debug_link_interface *m_driver;
Packit 534379
Packit 534379
	class mmlink_stats;
Packit 534379
	mmlink_stats *m_t2h_stats;
Packit 534379
	mmlink_stats *m_h2t_stats;
Packit 534379
Packit 534379
	int setup_listen_socket();
Packit 534379
	void get_welcome_message(char *msg, size_t msg_len);
Packit 534379
Packit 534379
	mmlink_connection **m_conn;
Packit 534379
	mmlink_connection *get_unused_connection();
Packit 534379
	mmlink_connection *handle_accept();
Packit 534379
	void close_other_data_connection(mmlink_connection *pc);
Packit 534379
	mmlink_connection *get_data_connection(void);
Packit 534379
Packit 534379
#undef ENABLE_MMLINK_STATS
Packit 534379
// #define ENABLE_MMLINK_STATS
Packit 534379
	class mmlink_stats {
Packit 534379
	public:
Packit 534379
#ifdef ENABLE_MMLINK_STATS
Packit 534379
		mmlink_stats(const char *name) { m_name = name; init(); }
Packit 534379
		void init(void) {
Packit 534379
			m_num_bytes = 0;
Packit 534379
			m_last_count = 0;
Packit 534379
			m_num_packets = 0;
Packit 534379
			m_overflow_size = 0;
Packit 534379
			m_min_count = UINT_MAX;
Packit 534379
			m_max_count = 0;
Packit 534379
			for (int i = 0; i < BUFSIZE; i++)
Packit 534379
				m_histogram[i] = 0;
Packit 534379
		}
Packit 534379
		void print(void) {
Packit 534379
			DPRINT("%s stats:\n", m_name);
Packit 534379
			DPRINT_RAW("total packets transmitted: %u\n", m_num_packets);
Packit 534379
			DPRINT_RAW("total bytes transmitted: %u\n", m_num_bytes);
Packit 534379
			DPRINT_RAW("last transmission: (%u bytes):\n", m_last_count);
Packit 534379
			DPRINT_RAW("min count: %u\n", m_min_count);
Packit 534379
			DPRINT_RAW("max count: %u\n", m_max_count);
Packit 534379
			for (int i = 0; i < m_last_count; ++i)
Packit 534379
				DPRINT_RAW("0x%02X ", m_last_buf[i]);
Packit 534379
			DPRINT_RAW("\n");
Packit 534379
			DPRINT_RAW("histogram of count values:\n");
Packit 534379
			for (int i = 0; i < m_max_count; i++)
Packit 534379
				if (m_histogram[i])
Packit 534379
					DPRINT_RAW("%d: %u\n", i, m_histogram[i]);
Packit 534379
Packit 534379
			if (m_overflow_size)
Packit 534379
			{
Packit 534379
				DPRINT_RAW("Warning: input data was larger than BUFSIZE; packet counts may be inaccurate.\n");
Packit 534379
				DPRINT_RAW("Consider changing BUFSIZE to %u (largest input data seen\n", BUFSIZE);
Packit 534379
			}
Packit 534379
		}
Packit 534379
Packit 534379
		void update(int count, char *buf) {
Packit 534379
			m_num_bytes += count;
Packit 534379
			m_last_count = MIN(count, BUFSIZE);
Packit 534379
			m_histogram[m_last_count]++;
Packit 534379
			memcpy(m_last_buf, buf, m_last_count);
Packit 534379
Packit 534379
			m_min_count = MIN(m_min_count, count);
Packit 534379
			m_max_count = MAX(m_max_count, count);
Packit 534379
Packit 534379
			for (int i = 0; i < count; ++i)
Packit 534379
			{
Packit 534379
				if (count > BUFSIZE)
Packit 534379
				{
Packit 534379
					m_overflow_size = MAX(m_overflow_size, count);
Packit 534379
					break;
Packit 534379
				}
Packit 534379
				if (buf[i] == 0x7B)
Packit 534379
					m_num_packets++;
Packit 534379
			}
Packit 534379
		}
Packit 534379
	private:
Packit 534379
		const char *m_name;
Packit 534379
		unsigned int m_num_bytes;
Packit 534379
		static const size_t BUFSIZE = 1073741824;
Packit 534379
		unsigned char m_last_buf[BUFSIZE];
Packit 534379
		unsigned int m_histogram[BUFSIZE];
Packit 534379
		unsigned char m_last_count;
Packit 534379
		unsigned int m_num_packets;
Packit 534379
		unsigned int m_overflow_size;
Packit 534379
		unsigned m_min_count;
Packit 534379
		unsigned m_max_count;
Packit 534379
#else
Packit 534379
#define UNUSED_PARAM(x) (void)x
Packit 534379
		mmlink_stats(const char *name) { UNUSED_PARAM(name); }
Packit 534379
		void init(void) { }
Packit 534379
		void print(void) { }
Packit 534379
		void update(int count, char *buf) { UNUSED_PARAM(count); UNUSED_PARAM(buf); }
Packit 534379
#endif
Packit 534379
	};
Packit 534379
Packit 534379
};
Packit 534379
Packit 534379
#endif