Skip to content

Commit

Permalink
Skeleton of packet source set up
Browse files Browse the repository at this point in the history
Base class for packet generating which will be used to create magazine,
subtitle, packet 830 and databroadcast packet sources.
  • Loading branch information
peterkvt80 committed Aug 10, 2017
1 parent ef6e41b commit 2068d1f
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 40 deletions.
28 changes: 16 additions & 12 deletions TCPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ void TCPClient::command(char* cmd, char* response)
{
switch (cmd[0])
{
case 'T' :;
case 'T' :;
if (response) strcpy(response,"T not implemented\n");
break;
case 'Y' :

case 'Y' :
if (response) strcpy(response,"VBIT620\n");
break;
case 0x0e:
Expand All @@ -51,7 +51,7 @@ void TCPClient::clearCmd(void)
}

/** AddChar
* Add a char to the command buffer and call command when we get CR
* Add a char to the command buffer and call command when we get CR
* There is only a response if a command needs to send something back.
* If the first character is a Newfor character then the data is parsed as Nu4.
* Commands that are not Newfor are MODENORMAL. They are stateless (so far)
Expand Down Expand Up @@ -80,22 +80,22 @@ void TCPClient::addChar(char ch, char* response)
charCount=4;
break;
case 0x0f :
mode=MODEGETROWCOUNT; // n and n*(rowhigh, rowlow, 40 bytes)
mode=MODEGETROWCOUNT; // n and n*(rowhigh, rowlow, 40 bytes)
break;
case 0x10 :
// Put the subtitle on air immediately
_newfor.SubtitleOnair(response);
// std::cerr << "[TCPClient::addChar] On air" << std::endl;
clearCmd();
mode=MODENORMAL;
mode=MODENORMAL;
return;
case 0x18 :
// Remove the subtitle immediately
// std::cerr << "[TCPClient::addChar] Subtitle Off" << std::endl;
_newfor.SubtitleOffair();
strcpy(response, "[addChar]Clear");
clearCmd();
mode=MODENORMAL;
mode=MODENORMAL;
return;
}
} // If first character
Expand All @@ -112,11 +112,11 @@ void TCPClient::addChar(char ch, char* response)
std::cerr << "[TCPClient::addChar] finished cmd=" << _cmd << std::endl;
command(_cmd, response);
clearCmd();
mode=MODENORMAL;
mode=MODENORMAL;
}
break;
// Message type 1 - Set subtitle page.
case MODESOFTELPAGEINIT: // We get four more characters and then the page is set
case MODESOFTELPAGEINIT: // We get four more characters and then the page is set
// @todo If a nybble fails deham or isn't in range we should return nack
// std::cerr << "[TCPClient::addChar] Page init char=" << ((int)ch) << std::endl;
*_pCmd++=ch;
Expand Down Expand Up @@ -176,11 +176,11 @@ void TCPClient::addChar(char ch, char* response)
// Now that we are done, set up for the next command
sprintf(response,"subtitle data complete\n");
mode=MODENORMAL;
clearCmd();
clearCmd();
}
}
break;
} // State machine switch
} // State machine switch
}


Expand All @@ -196,7 +196,7 @@ void TCPClient::Handler(int clntSocket)
int i;
clearCmd();
// std::cerr << "[TCPClient::Handler]" << std::endl;

/* Send received string and receive again until end of transmission */
for (recvMsgSize=1;recvMsgSize > 0;) /* zero indicates end of transmission */
{
Expand All @@ -213,6 +213,10 @@ void TCPClient::Handler(int clntSocket)
// DieWithError("send() failed");
}

#ifdef WIN32
// @todo What is the Windows way?
#else
close(clntSocket); /* Close client socket */
#endif // WIN32
}

24 changes: 12 additions & 12 deletions command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Command::Command(const uint32_t port=5570) :
_portNumber(port)
{
// Constructor
// Start a listener thread
// Start a listener thread
}

Command::~Command()
Expand All @@ -54,16 +54,16 @@ void Command::run()
{
std::cerr << "[Command::run] Newfor subtitle listener started" << std::endl;
int serverSock; /* Socket descriptor for server */
int clientSock; /* Socket descriptor for client */
int clientSock; /* Socket descriptor for client */
struct sockaddr_in echoServAddr; /* Local address */
struct sockaddr_in echoClntAddr; /* Client address */
unsigned short echoServPort; /* Server port */
struct sockaddr_in echoClntAddr; /* Client address */
unsigned short echoServPort; /* Server port */

#ifdef WIN32
int clntLen; /* needs to be signed int for winsock */
WSADATA wsaData;
int iResult;

// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
Expand All @@ -74,7 +74,7 @@ void Command::run()
#endif

echoServPort = _portNumber; /* This is the local port */

// System initialisations
/* Construct local address structure */
std::memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
Expand All @@ -84,27 +84,27 @@ void Command::run()

/* Create socket for incoming connections */
if ((serverSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed\n");
DieWithError("socket() failed\n");

/* Bind to the local address */
if (bind(serverSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
DieWithError("bind() failed");

/* Mark the socket so it will listen for incoming connections */
if (listen(serverSock, MAXPENDING) < 0)
DieWithError("listen() failed");
DieWithError("listen() failed");

/* Set the size of the in-out parameter */
clntLen = sizeof(echoClntAddr);

TCPClient client;

while(1)
{
std::cerr << "[Command::run] Ready for a client to connect" << std::endl;

/* Wait for a client to connect */
if ((clientSock = accept(serverSock, (struct sockaddr *) &echoClntAddr,
if ((clientSock = accept(serverSock, (struct sockaddr *) &echoClntAddr,
&clntLen)) < 0)
DieWithError("accept() failed");
std::cerr << "[Command::run] Connected" << std::endl;
Expand Down
32 changes: 16 additions & 16 deletions command.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Compiler : C++
* @author Peter Kwan
* @date July, 2017
*
*
* Copyright (C) 2017, Peter Kwan
*
* Permission to use, copy, modify, and distribute this software
Expand Down Expand Up @@ -64,36 +64,36 @@ class Command
* @brief Constructor
* @description Listens on port 5570 and accepts connections.
* When connected it can be sent Newfor commands.
*/
*/
Command(const uint32_t port);

/**
* @brief Constructor
* @param port - TCP port number to use
*/
Command(int port);
*/
Command(int port);

/**
* @brief Destructor
*/
*/
~Command();

/**
* @brief Run the listener thread.
*/
* @brief Run the listener thread.
*/
void run();

private:
int _portNumber;

/* Page init and subtitle data can respond with this standard codes */
static const uint8_t ASCII_ACK=0x06;
static const uint8_t ASCII_NACK=0x15;
static const uint8_t MAXPENDING=5; /* Maximum outstanding connection requests */
static const uint8_t MAXPENDING=5; /* Maximum outstanding connection requests */

void DieWithError(std::string errorMessage); /* Error handling function */


}; // Command
} // namespace vbit

Expand Down
31 changes: 31 additions & 0 deletions packetsource.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "packetsource.h"

using namespace vbit;

PacketSource::PacketSource()
{
//ctor
}

PacketSource::~PacketSource()
{
//dtor
}


Packet* PacketSource::GetPacket()
{
Packet* pkt=new Packet(8,25," ");
// Do your stuff
return pkt;
}

bool PacketSource::IsReady()
{
return false; // @todo This will probably just return a member bool
}

void PacketSource::SetEvent(Event event)
{
//@todo Use event to clear the event flags which may have been set by the packet source being in wait.
}
102 changes: 102 additions & 0 deletions packetsource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/** ***************************************************************************
* Description : Interface for sources of packets: mag, subtitles etc.
* Compiler : C++
*
* Copyright (C) 2017, Peter Kwan
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice appear in all
* copies and that both that the copyright notice and this
* permission notice and warranty disclaimer appear in supporting
* documentation, and that the name of the author not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* The author disclaims all warranties with regard to this
* software, including all implied warranties of merchantability
* and fitness. In no event shall the author be liable for any
* special, indirect or consequential damages or any damages
* whatsoever resulting from loss of use, data or profits, whether
* in an action of contract, negligence or other tortious action,
* arising out of or in connection with the use or performance of
* this software.
***************************************************************************
**/
/**
* Anything that generates teletext packets is derived from this interface.
* Functions defined by this interface are
* Constructor - sets up the data required by a particular packet source.
* GetPacket - Gets the next packet in the stream.
* Waiting - The stream is waiting for an event to restart it
* SetEvent - Registers an even with the packet source
*
* Teletext packets come in four broad categories
* 1) Magazines - Rows consisting of headers and body rows.
* 2) Subtitles - Same as magazines but sent at highest priority.
* 3) Packets on magazine 8, row 30 - Timing and control that happen on specific fields.
* 4) Databroadcast - Packets that get sent at low priority and when possible.
*
* Events
* 1) Field
* 2) 10 fields
* 3) Subtitle data in buffer
* 4) All other streams are waiting (so we can now send databroadcast)
**/
#ifndef _PACKETSOURCE_H_
#define _PACKETSOURCE_H_

#include "packet.h"

namespace vbit{

/** @brief Events are used to trigger packet sources so that they may proceed
* @description Different packet sources use different timing schemes.
* Packet sources may put themselves into a waiting state.
* Events are used to start them up again.
* Magazines stop after a header and wait for the next field.
* Subtitles wait until there is data in the subtitle buffer.
* Packet 830 waits for a multiple of 10 fields.
* Databroadcast varies according to the importance of the signal.
* Lowest priority may only jump in only when a filler packet would be sent.
* Highest priority might steal all the packets except for 830.
*/
enum Event
{
EVENT_FIELD,
EVENT_P830_FORMAT_1,
EVENT_P830_FORMAT_2_LABEL_0,
EVENT_P830_FORMAT_2_LABEL_1,
EVENT_P830_FORMAT_2_LABEL_2,
EVENT_P830_FORMAT_2_LABEL_3,
EVENT_SUBTITLE,
EVENT_DATABROADCAST
} ;


class PacketSource
{
public:
/** Default constructor */
PacketSource();
/** Default destructor */
virtual ~PacketSource();

/** Get the next packet
* @return The next packet OR if IsReady() would return false then a filler packet
*/
virtual Packet* GetPacket()=0;

/** Is there a packet ready to go? */
virtual bool IsReady(); // Don't need to Pure this. Just report a member bool

/** Report that an event happened */
virtual void SetEvent(Event event); // Don't need to Pure this. All packet sources can use the same code

protected:
private:
};

} // vbit namespace

#endif // _PACKETSOURCE_H_

0 comments on commit 2068d1f

Please sign in to comment.