Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
Rewriting Service. Priority handling will be done in PacketMag. Service
will set up and insert all packet types. It will also send events to the
packet sources so that they know when they can proceed,
  • Loading branch information
peterkvt80 committed Aug 19, 2017
1 parent 8c84481 commit eaadd3c
Show file tree
Hide file tree
Showing 8 changed files with 269 additions and 51 deletions.
28 changes: 14 additions & 14 deletions configure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ using namespace ttx;

int Configure::DirExists(char *path){
struct stat info;

if(stat(path, &info ) != 0)
return 0;
else if(info.st_mode & S_IFDIR)
Expand All @@ -16,7 +16,7 @@ int Configure::DirExists(char *path){
}

Configure::Configure(int argc, char** argv) :

// settings for generation of packet 8/30
_multiplexedSignalFlag(0),
_initialMag(1),
Expand All @@ -28,15 +28,15 @@ Configure::Configure(int argc, char** argv) :
std::cerr << "[Configure::Configure] Started" << std::endl;
strncpy(_configFile,CONFIGFILE,MAXPATH-1);
#ifdef _WIN32
strncpy(_pageDir,"i:\\temp\\teletext",MAXPATH-1);
strncpy(_pageDir,"j:\\temp\\teletext",MAXPATH-1); // Hard wired for Peter's PC
#else
strcpy(_pageDir,"/home/pi/teletext");
#endif
// This is where the default header template is defined.
_headerTemplate = "TEEFAX 1 %%# %%a %d %%b" "\x03" "%H:%M.%S";

_rowAdaptive = false;

//Scan the command line for overriding the pages file.
//std::cerr << "[Configure::Configure] Parameters=" << argc << " " << std::endl;
if (argc>1)
Expand All @@ -54,7 +54,7 @@ Configure::Configure(int argc, char** argv) :
std::cerr << "[Configure::Configure] " << _pageDir << " does not exist or is not a directory" << std::endl;
exit(EXIT_FAILURE);
}

/// @ scan for overriding the configuration file
std::cerr << "[Configure::Configure] Pages directory is " << _pageDir << std::endl;
std::cerr << "[Configure::Configure] Config file is " << _configFile << std::endl;
Expand All @@ -75,14 +75,14 @@ Configure::~Configure()
int Configure::LoadConfigFile(std::string filename)
{
std::ifstream filein(filename.c_str()); // Open the file

std::vector<std::string>::iterator iter;
// these are all the valid strings for config lines
std::vector<std::string> nameStrings{"header_template", "initial_teletext_page", "row_adaptive_mode"};

if (filein.is_open()){
std::cerr << "[Configure::LoadConfigFile] opened " << filename << std::endl;

std::string line;
std::string name;
std::string value;
Expand All @@ -91,7 +91,7 @@ int Configure::LoadConfigFile(std::string filename)
/// todo: parsing!
std::size_t delim = line.find("=", 0);
int error = 0;

if (delim != std::string::npos){
name = line.substr(0, delim);
value = line.substr(delim + 1);
Expand All @@ -102,7 +102,7 @@ int Configure::LoadConfigFile(std::string filename)
case 0: // header_template
_headerTemplate.assign(value, 0, 32);
break;

case 1: // initial_teletext_page
if (value.size() >= 3){
size_t idx;
Expand Down Expand Up @@ -138,10 +138,10 @@ int Configure::LoadConfigFile(std::string filename)
_initialMag = magpage / 0x100;
_initialPage = magpage % 0x100;
break;
}
}
error = 1;
break;

case 2: // row_adaptive_mode
if (!value.compare("true")){
_rowAdaptive = true;
Expand All @@ -166,4 +166,4 @@ int Configure::LoadConfigFile(std::string filename)
std::cerr << "[Configure::LoadConfigFile] open failed" << std::endl;
return -1;
}
}
}
14 changes: 8 additions & 6 deletions mag.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/// @todo THIS MODULE WILL BE REDUNDANT AUG 2017

#include "mag.h"

using namespace vbit;
Expand Down Expand Up @@ -60,7 +62,7 @@ Packet* Mag::GetPacket(Packet* p)
* 6) However, before iterating in step 2, do this every second: Look at the carousel list and for each page decrement their timers.
* When a page reaches 0 then it is taken as the next page, and its timer reset.
*/

/* pages can be have varying packet codings for X/1 to X/25. Pages using the standard coding we
want to send X/26/0 to X/26/15 first, then X/1 to X/25 afterwards.
For pages which carry data not for display in packets X/1 to X/25 however we must send these first (so the packets including any X/26 are all sent in sequential order of packet and designation code
Expand Down Expand Up @@ -197,16 +199,16 @@ Packet* Mag::GetPacket(Packet* p)

//p->Parity(13); // don't apply parity here it will screw up the template. parity for the header is done by tx() later
assert(p!=NULL);

links=_page->GetLinkSet();
if ((links[0] & links[1] & links[2] & links[3] & links[4] & links[5]) != 0x8FF){ // only create if links were initialised
_state=STATE_FASTEXT; // a non zero FL row will override an OL,27 row
} else {
} else {
_lastTxt=_page->GetTxRow(27); // Get _lastTxt ready for packet 27 processing
_state=STATE_PACKET27;
}
break;

case STATE_FASTEXT:
p->SetMRAG(_magNumber,27);
links=_page->GetLinkSet();
Expand All @@ -231,7 +233,7 @@ Packet* Mag::GetPacket(Packet* p)
{
//std::cerr << "Packet 28 length=" << _lastTxt->GetLine().length() << std::endl;
//_lastTxt->Dump();

p->SetRow(_magNumber, 28, _lastTxt->GetLine(), CODING_13_TRIPLETS);
_lastTxt=_lastTxt->GetNextLine();
break;
Expand All @@ -240,7 +242,7 @@ Packet* Mag::GetPacket(Packet* p)
{
// create X/28/0 packet for pages which have a region set with RE in file
// it is important that pages with X/28/0,2,3,4 packets don't set a region otherwise an extra X/28/0 will be generated. TTXPage::SetRow sets the region to 0 for these packets just in case.

// this could almost certainly be done more efficiently but it's quite confusing and this is more readable for when it all goes wrong.
std::string val = "@@@tGpCuW@twwCpRA`UBWwDsWwuwwwUwWwuWwE@@"; // default X/28/0 packet
int region = _page->GetRegion();
Expand Down
180 changes: 175 additions & 5 deletions packetmag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ PacketMag::PacketMag(uint8_t mag, std::list<TTXPageStream>* pageSet, ttx::Config
_page(NULL),
_magNumber(mag),
_priority(priority),
_priorityCount(priority)
_priorityCount(priority),
_headerFlag(false),
_state(PACKETSTATE_HEADER),
_thisRow(0),
_lastTxt(NULL)
{
//ctor
if (_pageSet->size()>0)
Expand All @@ -32,20 +36,186 @@ PacketMag::~PacketMag()
}

// @todo Invent a packet sequencer similar to mag.cpp which this will replace
Packet* PacketMag::GetPacket()
Packet* PacketMag::GetPacket(Packet* p)
{
int thisPageNum;
unsigned int thisSubcode;
int thisStatus;
int* links=NULL;

static vbit::Packet* filler=new Packet(8,25," "); // filler

// We should only call GetPacket if IsReady has returned true
if (!IsReady())
{
std::cerr << "[PacketMag::GetPacket] Packet not ready. This must not happen" << std::endl;
exit(0);
}

// If there is no page, we should send a filler
if (_pageSet->size()<1)
{
return filler;
}

// If we send a header we go into a wait state
ClearEvent(EVENT_FIELD); // @todo Only when we send the header
return filler; // Dummy return for now
switch (_state)
{
case PACKETSTATE_HEADER: // Start to send out a new page, which may be a simple page or one of a carousel
ClearEvent(EVENT_FIELD); // This will suspend all packets until the next field.

_page=_carousel->nextCarousel(); // The next carousel page

// But before that, do some housekeeping

// Is this page deleted?
if (_page && _page->GetStatusFlag()==TTXPageStream::MARKED)
{
_carousel->deletePage(_page);
_page=NULL;
}

if (_page) // Carousel? Step to the next subpage
{
//_outp("c");
_page->StepNextSubpage();
//std::cerr << "[Mag::GetPacket] Header thisSubcode=" << std::hex << _page->GetCarouselPage()->GetSubCode() << std::endl;

}
else // No carousel? Take the next page in the main sequence
{
if (_it==_pageSet->end())
{
std::cerr << "This can not happen" << std::endl;
exit(0);
}
++_it;
if (_it==_pageSet->end())
{
_it=_pageSet->begin();
}
// Get pointer to the page we are sending
// todo: Find a way to skip carousels without going into an infinite loop
_page=&*_it;
// If it is marked for deletion, then remove it and send a filler instead.
if (_page->GetStatusFlag()==TTXPageStream::MARKED)
{
_pageSet->remove(*(_it++));
_page=NULL;
return filler;
// Stays in HEADER mode so that we run this again
}
if (_page->IsCarousel() && _page->GetCarouselFlag()) // Don't let registered carousel pages into the main page sequence
{
std::cerr << "This can not happen" << std::endl;
exit(0);
// Page is a carousel. This can not happen
//_page=NULL;
//return NULL;
}
}
_thisRow=0;

// When a single page is changed into a carousel
if (_page->IsCarousel() != _page->GetCarouselFlag())
{
_page->SetCarouselFlag(_page->IsCarousel());
if (_page->IsCarousel())
{
// std::cerr << "This page has become a carousel. Add it to the list" << std::endl;
_carousel->addPage(_page);
}
else
{
// @todo Implement this
//std::cerr << "@todo This page has no longer a carousel. Remove it from the list" << std::endl;
//exit(3); //
}
}

// Assemble the header. (we can simplify this code or leave it for the optimiser)
thisPageNum=_page->GetPageNumber();
thisPageNum=(thisPageNum/0x100) % 0x100; // Remove this line for Continuous Random Acquisition of Pages.
if (_page->IsCarousel())
{
thisSubcode=_page->GetCarouselPage()->GetSubCode();
}
else
{
thisSubcode=_page->GetSubCode();
}

thisStatus=_page->GetPageStatus();
// p=new Packet();
p->Header(_magNumber,thisPageNum,thisSubcode,thisStatus);// loads of stuff to do here!

p->HeaderText(_configure->GetHeaderTemplate()); // Placeholder 32 characters. This gets replaced later


//p->Parity(13); // don't apply parity here it will screw up the template. parity for the header is done by tx() later
assert(p!=NULL);

links=_page->GetLinkSet();
if ((links[0] & links[1] & links[2] & links[3] & links[4] & links[5]) != 0x8FF){ // only create if links were initialised
_state=PACKETSTATE_FASTEXT; // a non zero FL row will override an OL,27 row
} else {
_lastTxt=_page->GetTxRow(27); // Get _lastTxt ready for packet 27 processing
_state=PACKETSTATE_PACKET27;
}
break;
case PACKETSTATE_TEXTROW:
// Find the next row that isn't NULL
for (_thisRow++;_thisRow<26;_thisRow++)
{
_lastTxt=_page->GetTxRow(_thisRow);
if (_lastTxt!=NULL)
break;
}
// Didn't find? End of this page.
if (_thisRow>25 || _lastTxt==NULL)
{
if(_page->GetPageCoding() == CODING_7BIT_TEXT){
// if this is a normal page we've finished
p=NULL;
_state=PACKETSTATE_HEADER;
_thisRow=0;
//_outp("H");
} else {
// otherwise go on to X/26
_lastTxt=_page->GetTxRow(26);
_state=PACKETSTATE_PACKET26;
}
}
else
{
//_outp("J");
if (_lastTxt->IsBlank() && _configure->GetRowAdaptive()) // If the row is empty then skip it
{
// std::cerr << "[Mag::GetPacket] Empty row" << std::hex << _page->GetPageNumber() << std::dec << std::endl;
p=NULL;
}
else
{
// Assemble the packet
p->SetRow(_magNumber, _thisRow, _lastTxt->GetLine(), _page->GetPageCoding());
if (_page->GetPageCoding() == CODING_7BIT_TEXT)
p->Parity(); // only set parity for normal text rows
assert(p->IsHeader()!=true);
}
}
break;
case PACKETSTATE_FASTEXT:
p->SetMRAG(_magNumber,27);
links=_page->GetLinkSet();
p->Fastext(links,_magNumber);
_lastTxt=_page->GetTxRow(28); // Get _lastTxt ready for packet 28 processing
_state=PACKETSTATE_PACKET28;
break;
default:
_state=PACKETSTATE_HEADER;// For now, do the next page
// Other packets that Alistair will want implemented go here
}

return p; //
}

/** Is there a packet ready to go?
Expand Down
Loading

0 comments on commit eaadd3c

Please sign in to comment.