11/3
11/4
11/5
Thread Basics
11/7
11/10
Overview of the Initialization of the AntennaControl
[Aside] Simulate Data
11/11
11/12
11/13
Create new KyleWave2 board
11/14
GCP compiling error 11.14
11/17
readline error on bicep0
11/19
KyleWave2 is working!!!
11/20
Check out gcp code to find.uchicago
11/21
Fluxbox
11/24
Checkout brand new version of gcp onto Find:
Create svnRepos on Find for my gcp code.
Fix stat page:
Make KyleWave2 work on Find.
How Antenna connects to the Mediator
Look at how Antenna layer connects to the Mediator layer and how frames are packed, queued, and sent / received.
11/25
Check out new copy of gcp onto spudws2:
AntennaMonitor packing frames
11/25
12/1
Work backwords from AntennaMonitor::packNextFrame()
Pack Data
Doxygen
12/2
12/3
12/5
Description of packing a Data Frame in the Antenna Layer.
12/8
Mediator Layer : Detailed Description of Classes
Master class of Mediator
Scanner class of Mediator
Mediator Msg types
Mediator startup function: bin_Mediator.cc
Master Thread
Mediator - Control Thread
Mediator - Scanner Thread
Mediator - Signal Thread
12/11
GenericTask.h
GenericMasterTask.h
GenericTaskMsg.h
GenericMasterTaskMsg.h
SignalTask
TimerInfo
SignalHandler
Thread of gcp/util/common/
AbsTimer of gcp/util/common/
NetHandler of gcp/util/common
NetMsgHandler of gcp/util/common
AntNum of gcp/util/common
RegMap definitions
12/12
Connection from Antenna to Monitor
Read DataFrame from Antenna in Monitor
Write New MceConsumer class
Off to Caltech!!
12/15
At Caltech!!
Modify mediator layer to accomidate MceConsumer.
gcp/mediator/util/MceConsumer
gcp/util/common/NetMceDataFrameHandler
gcp/util/common/MceDataFrameManager
gcp/util/common/MceDataFrame
/gcp/mediator/specific/Scanner
Other changes
Deal with makefiles
Compile #1
12/16
Email from Steve Benton on PCI connection from Sync Box
Initial commit to Subversion on spudwsw
Edit Scanner more.
12/17
Talking with Walt
12/18
Understand Register Maps
Antenna0 register
Compile:
Run:
Check into subversion:
Start MASD code
12/19
Notes
Notes from Walt

11/3

Looking for main() in Antenna that is being run.
Run Antenna program:
It seems to be running when all sim flags are set to "t".
The only one it fails to run on is when simgps=f.

On Antenna xterm:
kstory@bicep0:~/gcp/$ /home/bicep/gcp/bin/bicepAntennaControl host=localhost antenna=0 dataport=1500 cmdport=1600 simpmac=t simdata=t simgps=t sim1pps=t logd=/home/bicep0/kstory/gcp/runlogs logf=bicepTestAntennaControl debuglevel=0
03-NOV-2008 18:08:38.812: In void gcp::util::LogFile::open(): Opened logfile: /home/bicep0/kstory/gcp/runlogs/bicepTestAntennaControl38 on Mon Nov  3 10:08:38 2008

(obviously something is running, but nothing is printing out)

On another terminal:
kstory@bicep0:~/gcp/$ /home/bicep0/kstory/gcp/misc/scripts/common/killAll bicepAntenna
killing  7380
killing

On Antenna xterm:
kstory@bicep0:~/gcp/$ /home/bicep/gcp/bin/bicepAntennaControl host=localhost antenna=0 dataport=1500 cmdport=1600 simpmac=t simdata=t simgps=f sim1pps=t logd=/home/bicep0/kstory/gcp/runlogs logf=bicepTestAntennaControl debuglevel=0
03-NOV-2008 18:10:09.898: In void gcp::util::LogFile::open(): Opened logfile: /home/bicep0/kstory/gcp/runlogs/bicepTestAntennaControl39 on Mon Nov  3 10:10:09 2008
Caught exception: In void gcp::antenna::control::Tfp::open(): In void gcp::antenna::control::Tfp::open(): In open(): No such file or directory.

I put print statements in all of the main() programs in the entire gcp. However, when I run the Antenna control code, none of them print out. I really don't understand what code is being run the!!

Search for simgps. Only found in two files that I already have print statements for.

New thought; what I am compiling is not actually showing up in the binary directory.
Rename lib/libGcpAntennaControlSpecific.so to mylibGcpAntennaControlSpecific.so.
Run:
Kills Mediator level, Antenna is still the same.

Mediator Requires:
libGcpAntennaControlSpecific.so
libGcpControlCommon.so
libGcpControlSpecific.so
libGcpGrabberCommon.so
libGcpMediatorSpecific.so
libGcpMonitor.so
libGcpMonitor.so
libGcpProgramCommon.so
libGcpUtilCommon.so
etc.
Antenna Does NOT require:
libGcpAntennaControlSpecific.so
libGcpControlCommon.so
libGcpControlSpecific.so
libGcpGrabberCommon.so
libGcpMediatorSpecific.so
libGcpMonitor.so
libGcpMonitor.so
libGcpProgramCommon.so
libGcpUtilCommon.so

Thus I am convinced that the binary /home/bicep/gcp/bim/bicepAntennaControl is not running any of the code that is in my directories. Where is the code I am compiling going?

11/4

Code Mystery Solved!!
I was running the antenna code from /home/bicep/gcp/, when to run my version I need /home/bicep0/kstory/gcp.

It works!!
Now figure out where the code is resting, and try to find out why the data simulation is not working.

Current Antenna code does the following:

In Program::initialize()
program name = bicepAntennaControl
Leave Program::initialize()
In Program::run(), after initialize(), returnValue = 0
In Program::run() after initialize(), return 0

  In try this->main()

In Antenna::main()
 in Antenna::main(), after sigfillset() and pthread_sigmask().
 in Antenna::main(), about to initialize AntennaMaster.
 in Antenna::main(), in try.
04-NOV-2008 22:53:05.413: In void gcp::util::LogFile::open(): Opened logfile: /home/bicep0/kstory/gcp/runlogs/bicepTestAntennaControl54 on Tue Nov  4 14:53:05 2008
In Antenna::main(), about to create AntennaMaster.
In AntennaMaster::constructor.
In AntennaMaster::constructor, about to initialize AntennaControl thread.
In AntennaMaster::constructor, about to initialize AntennaRx thread.
In AntennaMaster::constructor, about to initialize thread.
In AntennaMaster::constructor, about to initialize AntennaMonitor thread.
In AntennaMaster::constructor, about to initialize AntennaSignal thread.
In AntennaMaster::constructor, done with threads.
In Tfp constructor, simulate = 1
In AntennaMaster::constructor, about to installSignals().
In AntennaMaster::constructor, about to installTimers().
In AntennaMaster::constructor, about to startThreads().
In AntennaMaster::THREAD_START(startAntennaControl())
In AntennaMaster::THREAD_START(startAntennaRx())
In AntennaMaster::THREAD_START(startAntennaRx()), call parent->getThread(AntennaRx)
In AntennaMaster::THREAD_START(startAntennaRx()), define parent->rxTask_

For tomorrow, keep working...

11/5

Working through Antenna running process.

Function startThreads():
Defined in GenericTask. Calls the run() method of all Threads managed by this task, which calls pthread_create() for each thread.

AntennaRx threads:
To see which threads we are instantiating, need to understand Antennamaster private field prio.
Called with Program::getbParameter("prio").
Calls Program::getParameter("prio").
  int i = findKey("prio") // returns index for keyname "prio". Here, "prio" = t.
  return keys_[i].val

keys_ of type Keyword.
KeyWord:
Program object has struct keyword
field keys_
  string key, val, help
  int count // reference count
  int upd // 0=read, 1=unread original 2=unread updated
  int system // system key word, 0=no, 1=yes
This gets instantiated in bin_AntennaControl.cc, or anywhere where there is a main function.

Once I turn off priority, the antenna actually looks like it is running something!!!

For tomorrow, keep working through details of how Antenna runs, starting with AntennaMaster constructor.

Thread Basics

pthread tutorial

Thread operations: creation, termination, synchronization, scheduling, data management, process installation.
A thread does not know who created it or who it has created.
Thread has:
  - Thread ID
  - set of registers, stack pointer
  - stack for local variables, return addresses
  - signal mask
  - priority
  - return value: errno

Thread Creation
created with pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (start_routine)(void ), void arg);
  - thread: returns the thread id.
  - attr: set to NULL if default thread attributes are used.
  - void
(*start_routine): pointer to the function to be threaded. Function has a single argument: pointer to void.
  - \*arg: pointer to argument of function.

Thread Synchronization
mutexes: Mutual exclusion lock: Block access to variables by other theads. This enforces exclusive access by a thread to a variable or set of variables.
join: Make a thread wait till others are complete (terminated).
condition variables: data type pthread_cond_t

Thread Scheduling
When this option is enabled, each thread may have its own scheduling properties.

11/7

DataBase.cc has a simulation constructor that is not being called currently.
Working through Antenna code; I will type up my findings next week.

11/10

Working through Antenna code.

I know that the GpsTimer simulate mode is working.

Overview of the Initialization of the AntennaControl

kstory@bicep0:~/gcp/$ /home/bicep0/kstory/gcp/bin/bicepAntennaControl host=localhost antenna=0 dataport=1500 cmdport=1600
 simpmac=t simdata=t simgps=t sim1pps=t logd=/home/bicep0/kstory/gcp/runlogs logf=bicepTestAntennaControl debuglevel=0 pr
io=f
In Program::main(antenna=0)
In Program::run(13)
In Program::initialize()
program name = bicepAntennaControl
Leave Program::initialize()
In Program::run(), after initialize(), returnValue = 0
In Program::run() after initialize(), return 0
  In try this->main()

In Antenna::main()
 in Antenna::main(), after sigfillset() and pthread_sigmask().
 in Antenna::main(), about to initialize AntennaMaster.
 in Antenna::main(), in try.
10-NOV-2008 20:17:39.034: In void gcp::util::LogFile::open(): Opened logfile: /home/bicep0/kstory/gcp/runlogs/bicepTestAn
tennaControl78 on Mon Nov 10 12:17:39 2008
In Antenna::main(), about to create AntennaMaster.
In AntennaMaster::constructor.
In AntennaMaster::constructor, about to initialize AntennaControl thread.
In AntennaMaster::constructor, about to initialize AntennaRx thread.
In AntennaMaster::constructor, about to initialize AntennaDrive thread.
In AntennaMaster::constructor, about to initialize AntennaMonitor thread.
In AntennaMaster::constructor, about to initialize AntennaSignal thread.
In AntennaMaster::constructor, done with threads.
In AntennaMaster::constructor, about to initialize share_.
In Tfp constructor, simulate = 1
In AntennaMaster::constructor, about to installSignals().
In AntennaMaster::constructor, about to installTimers().
In AntennaMaster::constructor, about to startThreads().
In AntennaMaster::THREAD_START(startAntennaControl())
In AntennaControl::constructor()
In AntennaControl::constructor(), About to call startThreads().
Leaving AntennaControl::constructor() ...
In AntennaControl::serviceMsgQ().
In AntennaMaster::THREAD_START(startAntennaRx)
In AntennaMaster::THREAD_START(startAntennaRx), call parent->getThread(AntennaRx)
In AntennaMaster::THREAD_START(startAntennaRx), define parent->rxTask_
In AntennaRx::constructor.
In AntennaRx::constructor, calling parent_->prio(), start Data thread.
In AntennaRx::constructor, parent_->prio() == false.
In AntennaRx::constructor, start Command thread.
In AntennaRx::constructor, call startThreads().
In THREAD_START(AntennaRx::startData)
In THREAD_START(AntennaRx::startData), call rx->getThread(Data).
In THREAD_START(AntennaRx::startData), instantiate DataNew object with DataBase constructor.
In DataBase::constructor().
In DataBase::constructor(), simData_ = 1.
In DataBase::constructor(), create new NetDataBoard at dataport 1500.
In DataBase::constructor(), creating new PmacBoard, simPmac= 1.
In DataBase::constructor(), initialize NetDataParse objects.
In DataBase::constructor(), add fast registers.
Leaving DataBase::constructor().
In DataNew::constructor(), simData_ = 1.
In DataNew::constructor(), dumpData = 0.
Leaving DataNew::constructor().
In THREAD_START(AntennaRx::startData), let others know data thread is ready.
In THREAD_START(AntennaRx::startData), call DataNew::run().
In DataNew::run(), call serviceMsgQ().
In DataNew::serviceMsgQ().
In DataNew::serviceMsgQ(), simData_ = true.
In DataNew::serviceMsgQ(), About to drop into while().
In THREAD_START(AntennaRx::startCommand).
In THREAD_START(AntennaRx::startCommand), instantiate new CommandTask().
In THREAD_START(AntennaRx::startCommand), broadcastReady().
In THREAD_START(AntennaRx::startCommand), call commandTask_->run().
In CommandTask::serviceMsgQ().
In AntennaMaster::THREAD_START(startAntennaRx), set internal thread pointer pointing to AntennaRx thread.
In AntennaMaster::THREAD_START(startAntennaRx), thread->broadcastReady()
In CommandTask::serviceMsgQ(), about to drop into while().
In AntennaMaster::THREAD_START(startAntennaRx), call rxTask_->run()
In AntennaMaster::THREAD_START(startAntennaDrive).
In AntennaMaster::THREAD_START(startAntennaDrive), call AntennaDrive constructor.
In AntennaDrive::constructor().
Unsing no prio for AntennaDrive
In AntennaDrive::constructor(), create Tracker thread.
In AntennaDrive::constructor(), startThreads().
In AntennaDrive::THREAD_START(AntennaDrive::startTracker).
About to start tracker
Using no prio
In Tfp constructor, simulate = 1
In GPSTimer::RUN_RN(Gpstimer::runFn).
In GPSTimer::run(), simulatetimer_ = 1.
In GpsTimer::runSim(), about to enter while().
In Tracker::privateConstructor().
In Tracker::privateConstructor(), instantiate PmacBoard.
In Tracker::privateConstructor(), instantiate TrackerBoard.
In Tracker::privateConstructor(), instantiate WeatherMonitor.
Leaving QuaMonitor constructor: spawn = 1
Inside connect
In Tracker::privateConstructor(), call initialize().
In Tracker::initialize().
In Tracker::initialize, call gps_.registerCallback().
In Tracker::initialize, halt Telescope.
Just executed setupForHalt
Leaving Tracker::initialize.
Leaving Tracker::privateConstructor().
Leaving AntennaDrive::constructor().
In AntennaDrive::THREAD_START(AntennaDrive::startTracker), call trackertask_->run().
In AntennaMaster::THREAD_START(startAntennaMonitor())
Unknown TCP/IP host: "omega0.southpole.usap.gov".
In AntennaMonitor::connect().

Attempting to connect to host: localhost on port 5467
AntennaMonitor Successfully connected
In AntennaMaster::THREAD_START(startAntennaSignal())
In AntennaMaster::constructor, about to run().
In AntennaMaster::THREAD_START(startAntennaSignal()), About to call signalTask::run().
In SignalTask::run().

In AntennaControl::processMsg() from MsgQ.
In AntennaControl::connectControl(), client is: not connected.
In AntennaControl::connect().
In AntennaControl::connect(), call client_.connectToServer(antMaster->host(),...).
In AntennaControl::connect(), successfully connected to server.
In AntennaControl::sendAntennaIdMsg().
Got a collimation command
Got a collimation command
  In DataNew::serviceMsgQ() while, nready = 1.
  In DataNew::serviceMsgQ() while, iterate over Boxes:    fdSet_.isSerInRead(iBox) = [0, 0, 0, 0, 0, 0, 0, 0, 0,  ]
  In GpsTimer::runSim(), in while(), TimeVal = 1226348260 sec.
In GpsTimer::callHandlers().

In Tracker::GPS_CALLBACK_FN(Tracker::sendTickMsg).
Tracker thinks clock has jumped: diff = 1.22635e+09
  In GpsTimer::runSim(), in while(), TimeVal = 1226348261 sec.
In GpsTimer::callHandlers().

In Tracker::GPS_CALLBACK_FN(Tracker::sendTickMsg).
  In GpsTimer::runSim(), in while(), TimeVal = 1226348262 sec.
In GpsTimer::callHandlers().

In Tracker::GPS_CALLBACK_FN(Tracker::sendTickMsg).
10-NOV-2008 20:17:42.050: The telescope is halted
In AntennaControl::processMsg() from MsgQ.
In AntennaControl::processMsg() from MsgQ.
  In GpsTimer::runSim(), in while(), TimeVal = 1226348263 sec.
In GpsTimer::callHandlers().

In Tracker::GPS_CALLBACK_FN(Tracker::sendTickMsg).
  In GpsTimer::runSim(), in while(), TimeVal = 1226348264 sec.
In GpsTimer::callHandlers().

In Tracker::GPS_CALLBACK_FN(Tracker::sendTickMsg).
  In GpsTimer::runSim(), in while(), TimeVal = 1226348265 sec.
In GpsTimer::callHandlers().

In Tracker::GPS_CALLBACK_FN(Tracker::sendTickMsg).
Killed
kstory@bicep0:~/gcp/$

Start with ./bin/bicepAntennaControl
Program::main() name bicepAntennaControl
  Program::getProgram() to initialize Program* object.
    calls devault constructor of Program object.
  call program->run(argc, argv)
  delete calling instance of program after run() is finished (which is indefinitely long.

Program::run(argc, argv)
  try{ initialize(); } -> catch error
  try{ this->main(); } -> catch error // main() defined in bin_AntennaControl.cc
  try {Program:: terminate(); } -> catch error

Program::initialize(void)
  call initializeUsage() -> defined in bin_AntennaControl.cc, empty function.
  store program name in progName_ field.
  deal with program keys:
    npkeys_ // # program keys
    nskeys_ // # system keys

bin_AntennaControl.cc
Program::main(void)
  sigfillset(&allSignals) // standard c++ function in signal.h library, initializes a signal set so that it includes all supported signals.
  pthread_sigmask(...)
  AntNum antNum
  set Id for antNum
  open log files
  //create new instance of AntennaMaster:
  AntennaMaster master(args from keywords)

AntennaMaster
Threads:
  - AntennaControl
  - AntennaRx
  - AntennaDrive
  - AntennaMonitor
  - AntennaSignal

AntennaMaster::constructor
  Create threads for:
    - AntennaControl
    - AntennaRx
    - AntennaDrive
    - AntennaMonitor
    - AntennaSignal
  antNum_ = new AntNum()
  initialize BicepShare share_
  installSignals() // call sendInstallSignalMsg(...)
  installTimers() // see below
  startThreads() // calls THREAD_START() function for each thread. See below:

AntennaMaster::installTimers()
  install "heartbeat" timer
  # if BICEP_DATA // if we ahve a data source, let it drive the dataframe sending
    sendInstallTimerMsg("monitor", ANTENNA_MONITOR_SIGNAL,
                      0, ANTENNA_MONITOR_NSEC,
                      &sendDataStrobeMsg);
  # else
    sendInstallTimerMsg("monitor", ANTENNA_MONITOR_SIGNAL,
                      0, ANTENNA_MONITOR_NSEC,
                      &sendPackDataFrameMsg);
    //sendPackDataFrameMsg is of type SIGNALTASK_HANDLER_FN(* handler), defined in AntennaMaster
    // tells AntennaMonitor to send a data frame back to the ACC.
  # endif
  install "pmac" timer
  install "connect" timer


AntennaControl
Threads: none

_THREAD_START(AntennaMaster::startAntennaControl)_
  AntennaMaster* ant = (AntennaMaster*) arg;
  ant->controlTask_ = new AntennaControl(ant); // see below
  controlTask_->thread_ = ant->getThread("AntennaControl");
  thread->broadcastReady()
  controlTask_->run() // calls ?? which calls AntennaControl::serviceMsgQ()
  // stays in MessageQ, waiting for messages from above or below.

AntennaControl::constructor
  class derived from BicepTask, GenericTask
  forwarder_ = new AntNetCmdForwarder(parent);
  startThreads(this); // No threads to start here.

AntennaControl::connect
  connect to AntennaMaster
  register handlers.


AntennaRx
Threads:
  - data
  - command

_THREAD_START(AntennaMaster::startAntennaRx)_
  parent is type AntennaMaster*.
  thread = parent->getThread("AntennaRx");
  parent->rxTask_ = new AntennaRx(parent); // instantiate new AntennaRx object. See below.
  rxTask_->thread_ - thread; // set internal pointer pointing to Rx thread.
  thread->broadcastReady();
  rxTask_->run(); // calls ??

AntennaRx::constructor
  instantiate threads:
  - data // call different constructors depending on whether or not we have priority.
  - command
  startThreads(this); // calls THREAD_START(AntennaRx::type).

_THREAD_START(AntennaRx::startData)_ in AntennaRx.cc
  Thread* thread = rx->getThread("Data") // get thread object which will manage this thread.
  have field DataBase* dataTask_
  rx->dataTask_ = new DataNew(rx) // calls DataBase constructor
  dataTask_->thread_ = thread; // set internal thread
  thread->broadcastReady()
  dataTask_->run() // calls DataNew::run(), which calls DataNew::serviceMsgQ().

_THREAD_START(AntennaRx::startCommand)_ in AntennaRx.cc
  rx->commandTask_ = new CommandTask(rx) // see below
  rx->commandTask_->thread_ = rx->getThread("Command");
  thread->broadcastReady();
  commandTask_->run(); // calls ?? which ends up at CommandTask::serviceMsgQ

DataNew
Fields:
  - TimeVal timeOut_
  - FdSet fdSet_
  - std::ofstream* fout_
Methods:
  - run() -> calls serviceMsgQ()
  - serviceMsgQ()

DataNew::constructor : DataBase(parent)
  This first calls the DataBase constructor.
  if !simData_
    fdSet_.registerReadFd( data_->fd(i) ); where (i) is the box number up to NBOX

DataNew::run()
  call serviceMsgQ()

DataNew::serviceMsgQ()
    Wait for data to arrive
  Once a message has arrived:
    - processTaskMsg
    - Loop over boxes:
      > read box with NetDataBoard::read(unsigned iBox)
        deal with time stuff
        - update seq number if necessary
        - update time and calculate dTime between current and time last packet arrived
        case: data is in current set i.e. seq==currSeq
          - note that the box data for that sequence number has arrived, and keep waiting for all boxes
          - if all boxes have arrived, call incrimentSampleCount() to buffer the data
        case new sequence number i.e. seq > currSeq
          if dCurrSeq != 1, log a message. If dCurrSeq > seqJumpThreshold, do not read new data
          Usually, dCurrSeq == 1.
          Calculate change in seq number and time between most recent packets.
          bufferTimeData(iSamp, )
          bufferPmacData(iSamp)
  Wait for more data to arrive.

DataBase
Fields:
  - NetDataBoard data_
  - PmacBoard pmac_
  - ThermalControl thermalControl_
  - NetDataParse bolo_, fridge_, rot_, dewar_, timep_, datasys_, aux_, level_, cal_
  - vector fastRegs_, where FastReg is a struct defined in DataBase.h
Methods:
  - addFastPmacRegs()
  - writeBoxData(), writePmacData(), writeTimeData(), writeData()
  - bufferBoxData(), bufferPmacData(), bufferTimeData(), bufferData()
  - run() -> virtual, does nothing.

DataBase::constructor
  data_ = new NetDataBoard(parent_->dataport_, NBOX);
  pmac_ = new PmacBoard(share_, "pmac", parent_->simPmac());
  initParsers(); // initialize NetDataParse() for:
    bolo, fridge, rotator, time, datasystem, dewar, auxiliary, level, cal
  addFastPmacRegs(); // add pmac registers we want to monitor at the fast rate:
    az_pos, el_pos, dk_pos, mtr_pos, mtr_com_pos, mtr_mean_err, mtr_vel, mtr_com_vel, mtr_com_i, aux_input, new_position.

NetDataBoard : class for reading/writing data and messages to and from BICEP's UDP-based data acquisition system.
NetDataBoard::constructor(int port, int n)
  init(port, n);
  for(i < nBox)
    socket[i].configure(port+i); // sockets are UDPSocket[] objects.

NetDataParse :
Fields:
  - float* cosine, sine, quadsum, cAvg, sAvg, phase, voltage, current, frequency, etc.
  - RegMapBlock* received_, cosine_, sine_, quandsum_, phase_, sequence_, etc.
Methods:
  - fake_bolo_sample()
  - init_bolo_registers()
  - read_bolo_sample()
  - pack_bolo_frame()

  - [init, read, pack] bolo, fridge, rotator, time, datasys, auxiliary, dewar, level, cal

_NetDataParse::read_bolo_sample(unsigned nsample, NetDataBoard* data, unsigned rcvd, double* thermalcontrolVals)_
  char* word1=data->box[BOLO_BIAS_OFFSET].sdata[BOLO_BIAS_CHAN_SEND]
  int freq = word11;
  for(bindex) //box index
    for(cindex) // channel index
      data->words2components2( data->box[bindex+BOLO_DATA_SET].sdata[cindex], &s, &c, VMAX );
      index=bindex*NCHAN + cindex;
    cosine[...] =
    sine[...]=
    sAvg[], cAvg[], quadsum[], thermalControlVals[], phase[]

[Aside] Simulate Data

_fake_bolo_sample(nsample, NetDataBoard* data, rcvd, double* thermalControlVals)_
  for(bindex) // box index
    for(cindex) // channel index
      index=bindex*NCHAN + cindex;
      c = 10.*cos(2*M_PI*(double)(count)/(100 + index)) + index;
      s = 10.*sin(2*M_PI*(double)(count)/(100 + index)) + index;
      fill in everything else based on index number.

UDPSocket
Fields:
  - int sockfd
  - int portno
  - int clilen
  - double timeout
  - fd_set read_set
  - struct timeval select_timeout, tmp_timeout
  - struct sockaddr_in serv_addr, cli_addr
  - struct hostent* server
  - unsigned nByte
Methods:
  - int socket_init( int portno )
  - void initialize()
  - void configure (int portno)
  - void configure(int portno, char server_name[])
  - int read(char* buffer, int maxlen)
  - int read2( char* buffer, intmaxlen)
  - void settimeout( double t)
  - void arm_for_wait()
  - int wait()
  - int fd()

_UDPSocket::arm_for_wait()_
  FD_ZERO(&read_set);
  FD_SET(sockfd, &read_set);

UDPSocket::wait()
  if(timeout < 0. ) // no timeout
    ret=select(sockfd+1, &read_set, NULL, NULL, NULL)
  else
    bcopy(time stuff)
  if(ret<0) error("waiting on select()\n")
  else if (ret==0) arm_for_wait()

CommandTask Still in AntennaRx, looking at command thread.
Fields: AntennaRx* parent_, NetDataBoard cmdBrd_
Method: serviceMsgQ().

CommandTask::constructor
  create instances of:
  - PeriodicHeLevelCommand
  - ContinuousHeLevelCommand
  - AutoResetCommand
  - FridgeCommand
  simData_ = parent->simData().


AntennaDrive
Threads:
  - Tracker

AntennaDrive::constructor
  instantiate Tracker thread, depending on whether or not we have thread prioritization.
  startThreads() -> start Tracker.

_THREAD_START(AntennaDrive::startTracker)_
  Thread* thread = drive->getThread("Tracker") // get thread object which will manage this thread.
  drive->trackertask_ = new Tracker() // which constructor depends on prio
  trackertask_->thread_ = thread; // set internal thread
  thread->broadcastReady()
  trackertaskask_->run() // calls ??

Tracker
Fields:
  - CameraBoard* camera_
  - PmacBoard* pmac_
  - TrackerBoard* tracker_
  - Scan scan_
  - GpsTimer gps_
  - WeatherMonitor* wx_
Methods:
  - serviceMsgQ() // defined only if we have areal GPSTracker
  - Many Pmac control commands.

Tracker::constructor
  instantiate GpsTimer gps_
  create instances of:
    - PmacBoard
    - TrackerBoard
    - Weathermonitor
  initialize()

Tracker::initialize
  pmac_->connect();
  gps_.registerCallback()
  haltTelescope(NULL)

_GPS_CALLBACK_FN(Tracker::sendTickMsg)_
  TrackerMsg msg
  msg.packTickMsg()
  tracker->sendTaskmsg(&msg)

CameraBoard derrived class of Board
Fields: RegMapBlock* angle_
Methods: recordAngle()

CameraBoard::constructr
  instantiate Board(share, name)
  angle_ = findReg("angle"); // calls writeReg(angle_,0,1,value)

Board
Fields:
  - BicepShare* share_
  - RegMapBoard* board_
Methods:
  - RegMapBlock* findReg(char* name)
  - readReg()
  - writeReg()

Board::constructor
  board_ = share_->findRegMapBoard(name)

Board::findReg(name)
  RebMapBlock8 block = find_RegMapBoard_Block()
  return block

Board::readReg()
  share_->readReg()

Board::writeReg()
  share_->writeReg()

PmacBoard
Fields:
  - PmacComms* comms_
  - RegMapBlock* hostRead_, pmacWrite_, newPosition_, positionFault_, newMode_, scanMode_, newAz_, newAl_, newDk_, newAcRate_, newElRate_, azPos_, elPos_, dkPos_, driveStatus_, statusMask_
Methods:
  - readReg()
  - writeReg()
  - connect() // connect to the pmac
  - computeDparmStats() // determine size of used portion of the DPRAM


PmacBoard::constructor
  set all variables to 0
  use findReg() to look up relevant registers
  computeDpramStats()
  if(!simPmac-) comms_ = new PmaccommsPci
  share_->writeReg(newPosition)
  share_->writeReg(hostRead)

PmacBoard::readReg()
  if(!simPmac_) comms_->readReg(...)

PmacBoard::writeReg()
  if(!simPmac_) comms_->writeReg(...)

PmacBoard::connect()
  if(simPmac_)
    return true
  bool connected = comms_->connect()

TrackerBoard
Fields:
  - RegMapBlock* lacking_, utc_, 1st_, ut1utc_, eqneqx_, mode_, deck_mode_, refraction_, encoder_off_, encoder_mul_, az_limits_, el_limits_, dk_limits_, tilts_, flexure_, axis_, fixedCollimation_,
                polarCollimation_, siteActual_, siteFiducial_, location_, source_, scanState_, scanName_, scanOff_, scanInd_, scanRep_, equat_geoc_, equat_off_, horiz_geoc_, horiz_topo_, horiz_mount_,
                horiz_off_, sky_xy_off_, counts_, rates_, actual_, expected_, errors_, state_, stateMask_, off_source_
Methods:
  - packLst()
  - packUt1Utc()
  - packEqnEqx()
  - archivePointing()
  - archiveStatus()


TrackerBoard::constructor
  set all variables to 0
  use findReg() to look up relevant registers


GpsTimer
Fields:
  - Tfp gps_ // the Gps card itself
Methods:
  - RUN_FN() // calls run()
  - run()
  - runReal()
  - runSim()
  - runTest()
  - getDate()

GpsTimer::constructor
  instantiate gcp::util::Runnable() object
  instantiate Tfp gps_(simulateGpsCard)
  set simulateTimer_
  set simulateGpsCard_

GpsTimer::run()
  if(simulateTimer_)
    runSim();
  else runReal();

GpsTimer::runSim()
  Sit in while(true).
  Every 1 sec, call
  gps_.getDate(lastTick_)
  callHandlers()

Gpstimer::getDate()



GpsTimer::runReal()
  open() // open device
  sit in select(), watching for the file descriptor to become readable
  When it does, get the date.
  When told to stop, close connection with Gps.


Tfp
Fields:
Methods:
  - getDate()

Tfp::getDate()
  if(simulate_)
    tVal.settoCurrentTime()
    return;
  else
    readUnixTime(TimeVal)

WeatherMonitor derrived class of QuadMonitor
Fields:
  - Tracker* parent_
  - BicepShare* share_
  - TipperClient* tipper_
  - airTemp_, pressure_, humidity_, windSpeed_, windDir_, utc_,
  - RegMapBlock* airTempBlock_, pressureBlock_, humidityBlock_, windSpeedblock_, windDirBlock_, utcBlock_
Methods:
  - readdoneAction()
  - sendWeatherUpdate()

WeatherMonitor::constructor
  call QuadMonitor(spawnThread, "omega0.southpole.usap.gov", "/dev/null") constructor
  set all registers to 0
  selections_.push_back(gcp::quad::MonitorSelection("weather", "regName", selections_.size()))
    do this for all registers
  use findReg() to look up relevant registers.
  instantiate TipperClient

WeatherMonitor::sendWeatherUpdate()
  if we have passed the updateInterval_,
    TrackerMsg msg;
    msg.packWeatherMsg(...)
    parent_->forwardTrackerMsg(&msg)

QuadMonitor location: gcp/util/common/QuadMonitor.h
Fields:
  - vector selections_
  - vector selectedRegs_
  - gcp::quad::MonitorStream* ms_
Methods:
  - RUN_FN()
  - run()
  - readRegs()
  - connect()
  - gcp::quad::MsReadState readNextFrame()

QuadMonitor::constructor
  call gcp::util::Runnable(spawnThread, runFn)
  call privateConstructor()
    setMonitoringInterval(1)
    tioeOut_.setSeconds(0)

MonitorSelection in control/code/unix/libquad_src/monitor_stream.h
This is a struct in this file
Fields:
  - int id // index of this MonitorSelection in its parent array
  - string board_name
  - string block_name
  - unsigned regIndex // first element of the register to select
  - unsigned nreg // number of elements to select
  and others

TipperClient
Fields:
  - TipperData tipperData_
  - vector bytes_
  - BicepShare share_
  - RegMapBlock* utcBlock_, tauBlock_, tAtmBlock_
Methods:
  - readServerData(NetHandler&)

TipperClient::constructor
  call gcp::util::TipperClient::constructor
    call Client(spawnThread, host, TIPPER_SERVER_PORT) constructor
    setReadBufSize()
    setSendbufSize()
  use findReg() to look up relevant regs.

TipperClient::readServerData(NetHandler& handler)
  handler.getReadStr()->getChar()
  handler.getReadStr()->endGet()
  tipperData_.deserialize(bytes_)
  share->write()


AntennaMonitor
Threads: none
Fields:
  - Scanner* scanner_
  - AntennaMaster* parent_
  - FrameSender* sender_
  - string host_ // IP address of the control host
  - TcpClient client_ // object to manage connection to the control program
  - NetHandler netDataFrameHandler_ // TCP network handler for sending data frames
  - NetMsgHandler netMsgHandler_ // network stream handler for sending a greeting to the archiver program
Methods:
  - connect(), disconnect() // connect to control host
  - connectScanner()
  - serviceMsgQ()
  - packNextFrame()
  - packFrame()
  - NET_READ_HANDLER(), NET_SEND_HANDLER()

_THREAD_START(AntennaMaster::startAntennaMonitor)_
  Thread* thread = ant->getThread("AntennaMonitor")
  ant->monitorTask_ = new AntennaMonitor(ant)
  monitorTask_->thread_ = thread;
  thread->broadcastReady()
  ant->monitorTask_->run(); // calls ??

AntennaMonitor::constructor
  call BicepTask() generic constructor
  call GenericTask() generic constructor
  share_ = parent_->getShare()
  scanner_ = new Scanner(share_, parent_->getAnt())
  connectScanner(true)

AntennaMonitor::connectScanner()
  call connect()
  sendScannerconnectedMsg() to report result.

AntennaMonitor::connect()
  client_.connectToServer(parent_->host(), TRANS_ANT_SCANNER_PORT, true) // connect to control program
  netMsgHandler_.attach(client_.getFd()) // Attach send stream of the msg handler to the new client socket.
  netMsgHandler_.installSendHandler() // install handler to be called when msg is sent
  netMsgHandler_.installReadHandler() // install handler to be called when msg is read
  netMsgHandler_.installErrorHandler()// install handler to be called when error occurs
  fdSet_.registerReadFd(client_.getFd()) // Register the socket to be watched for input
  sendAntennaIdMsg() // send greeting message to controller.

AntennaMonitor::serviceMsgQ()
  fdSet_.registerReadFd()
  while(!stop)
    nready=select() // deal with messages depending on their type
    if(fdSet_.isSetInRead(msgqFd))
      processTaskMsg()
    if(isSetInWrite(netDataFrameHandler )
      netDataFrameHandler_.send()
    if(isSetInWrite(netMsgHandler )
      netMsgHandler_.send()
    if(isSetInRead(netMsgHandler )
      netMsgHandler_.read()

Scanner
Fields:
  - BicepShare* share_
  - AntennaFrameBuffer fb_
  - FrameBoard* frame_
  - struct Features // manage details of feature bits received from control program
  - struct Walsh // store current bit mask of receiver walsh states
Methods:
  - packNextFrame()
  - dispatchNextFrame()
  - listBoards()

Scanner::constructor
  set fb_(ant), share_(share)
  frame_ = new FrameBoard(share, "frame")
  call initialize()
    features_.reset()
    recordWalshState()

Scanner::packNextFrame()
  setTime()
  recordRecordNumber()
  recordTime()
  recordFeatures()
  recordWalshState()
  share_->packFrame(fb_.getNextFrame())

FrameBoard
A class that encapsulates details of the frame software board.
Fields:
  - RegMapBlock* nsnap_, record_, utc_, lst_, features_, markSeq_, walshstate_
Methods:
  - setTime(),
  - archiveTime(), archiveFeatures(), archiveWalshState(), archiveNsnap()

AntennaFrameBuffer derrived class of FrameBuffer
Fields:
  - struct FrameBufferSlot{
    unsigned int id_
    DataFrameManager* frame_
    struct FrameBufferSlot* next_ }
  - vector slots_
  - Mutex guard_
  - std::map frameMap_
Methods:
  - getFrame()
  - getNextFrame()
  - dispatchNextFrame()
  - findSlot()
  - getNextSlot()
  - clearSlot()


AntennaSignal
Threads:
Fields:
Methods:

_THREAD_START(AntennaMaster::startAntennaSignal)_
  Thread* thread = ant->getThread("AntennaSignal")
  ant->signal_ = new gcp::util::SignalTask()
  thread->broadcastReady()
  ant->signal_->run(); // calls ??

gcp::util::SignalTask
Classes:
  - TimerInfo
  - SignalHandler

Fields:
  - struct HandlerPair
  - vector timers_
  -
Methods:
  - sendInstallTimerMsg()
  - sendAddHandlerMsg()
  - sendEnabletimerMsg()
  - stopTimers()
  - getIoSig()
  - run()
  - serviceMsgQ()

SignalTask::constructor
  id_ = pthread_self()
  sigIo_ = SIGNALTASK_IO_SIGNAL
  installSignal(sigIo_, &checkMsgQ)

For after lunch
1) Figure out why I can't type into bicepViewer
2) Plug KyleWave into Tracker.
3) Where is Data coming from??


For Tomorrow

11/11

Continue above.

How Things Simulate:
GpsTimer: gets current time from localhost.
Pmac: does not connect, does not read or write anything.
Data: ????(#$*(&^#?

SOMETHING SIMULATE IS WORKING!!!!!
I got bolometer cosine data (simulated, obviously) to show up on a viewer page!!!

11/12

Continue within 11/10.

11/13

Bicep viewer is not working; I cannot type into the browser.
Try using 8.08_gcp -> does not work either.

Try checking out a completely new version of the gcp:
It compiles.
Everything runs, but I still can't type into the Viewer.
Hypothesis; it is too slow coming from caltech. But then why could I type into it before?

Create new KyleWave2 board

Model after TrackerBoard.
  Ease; Only added two files.

Plug into Tracker.
  Time to break stuff...

11/14

Now no numbers from bolo.
Try re-running 11.12_gcp -> ok.
Go back to current version and remove anything that calls KyleWave. -> segfault in addTick().
Remove calls to KyleWave -> no more segfault, bolo numbers show up again.

Try again.
Follow example of TrackerBoard.
Looking at 3 RegMapBlocks, lst_, eqneqx_, and scanState_
It seems that lst_ and eqneqx_ are not being updated.
Try to match scanState_.

Seg faulting. Compiled, and it didn't work. make clean all -> fail;
Can't find libGcpUtilCommon
Try checking out new file and compiling.
This is also failing.
Try adding back in Makefile.rules that they were telling me to delete before.
Remove the MakeFile.rules, and the freshly copied version compiles. Good.

Now my 11.14_gcp compiles. ??
Try running.
Same Segmentation fault.

Try 'make clean all'

Compiling library:  /export/home/bicep0/kstory/gcp/lib/libGcpControlCommon.so

g++ -shared -o /export/home/bicep0/kstory/gcp/lib/libGcpControlCommon.so archiver.o ArchiverWriterDirfile.o ArchiverWriterFrame.o controlscript.o fitsio.o genericcontrol.o genericscheduler.o genericscript.o generictypes.o grabber.o InitScript.o logger.o navigator.o NewNetCmd.o NewNetMsg.o NewRtcNetMsg.o pipe.o terminal.o TransactionStatus.o
make[5]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code/unix/control_src/common'
g++ -o /export/home/bicep0/kstory/gcp/bin/bicepControl genericcontrol.o -L /export/home/bicep0/kstory/gcp/lib -L /export/home/bicep0/kstory/gcp/control/code/unix/lib -Xlinker -R -Xlinker /export/home/bicep0/kstory/gcp/lib -Xlinker -R -Xlinker /export/home/bicep0/kstory/gcp/control/code/unix/lib \
-lGcpControlCommon -lGcpControlSpecific -lGcpProgramCommon \
-lGcpShareCommon -lGcpShareSpecific \
-lGcpUtilCommon -lGcpUtilSpecific \
-lGcpScript -lGcpSla -lGcpSrc -lGcpScan -lGcpMonitor \
-lGcpTransaction -lGcpQuadSrc \
-lrt -lreadline -ltermcap -lpthread -lnsl -lm
/usr/lib64/gcc/x86_64-suse-linux/4.0.2/../../../../x86_64-suse-linux/bin/ld: cannot find -lGcpUtilCommon
collect2: ld returned 1 exit status
make[4]: *** [/export/home/bicep0/kstory/gcp/bin/bicepControl] Error 1
make[4]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code/unix/control_src/common'
make[3]: *** [make_control] Error 2
make[3]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code/unix'
make[2]: *** [bins] Error 2
make[2]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code'
make[1]: *** [bins] Error 2
make[1]: Leaving directory `/export/home/bicep0/kstory/gcp/control'
make: *** [make_control] Error 2

Check out new version and compile with make clean all:

cvs -d bicep0.caltech.edu:/home/bicep0/cvsroot checkout -r working14Feb gcp
kstory@bicep0:~$ cd gcp/control/code/unix/libscan_src/
kstory@bicep0:libscan_src$ mv Makefile.rules BKMakefile_rules
kstory@bicep0:libscan_src$ cd
kstory@bicep0:~$ cd gcp/
kstory@bicep0:gcp$ make clean all
...
make[2]: *** [clean_depend] Error 2
make[1]: *** [clean_code] Error 2

make: *** [make_control] Error 2
kstory@bicep0:gcp$ make
/usr/lib64/gcc/x86_64-suse-linux/4.0.2/../../../../x86_64-suse-linux/bin/ld: cannot find -lGcpUtilCommon
collect2: ld returned 1 exit status
make[4]: *** [/export/home/bicep0/kstory/gcp/bin/bicepControl] Error 1
make[4]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code/unix/control_src/common'
make[3]: *** [make_control] Error 2
make[3]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code/unix'
make[2]: *** [bins] Error 2
make[2]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code'
make[1]: *** [bins] Error 2
make[1]: Leaving directory `/export/home/bicep0/kstory/gcp/control'
make: *** [make_control] Error 2

GCP compiling error 11.14

makeErrors11-14.html

11/17

Looking for compiler errors.
Erik Leitch emailed back:

Kyle --

The makefiles are set up to keep going even if errors occur, so you
might not see the initial error that's preventing GcpUtilCommon to
compile if you just let all the output blitz past you.

Capture and look at the output, or do 'make |& less' (tcsh) and watch
for the first error.

readline error on bicep0

Found error:
In gcp/util/common/pmacterm.cc,
-> can't find file.
change to:



Files containing readline:
gcp/control/code/unix/misc_src/command_interp.c : L14
gcp/control/code/unix/misc_src/pmacterm.c : L20
gcp/util/common/Control.cc : L3
gcp/util/common/pmacterm.cc : L20

11/19

KyleWave2 is working!!!

I have successfully added a board to the gcp called KyleWave2, which prints out a triangle wave with values from 0-10, which update every second along with the Tracker register information.

Questions:
Antenna0: keeps trying to connect to bicep3.
This is in the line
antenna/control/bicep/bin_AntennaControl.cc:25: { "tipperhost", "bicep3", "s", "Tipper host"},

I still cannot type into the Viewer


Next:
  - How to type into the Viewer -> ?? Try on laptop.
  - Get it compiling on find. -> Done
  - Subversion

11/20

Check out gcp code to find.uchicago

Check out the code

kstory@find:~/$ cvs -d bicep0.caltech.edu:/home/bicep0/cvsroot checkout -r working14Feb gcp

remove gcp/control/code/unix/libscan_src/Makefile.rules:

kstory@find:~/gcp/$ mv control/code/unix/libscan_src/Makefile.rules control/code/unix/libscan_src/BadMakefile_rules

make -> ok.

Now run: -> ok.

Still can't type into BicepViewer. ??
The problem is not the readline stuff.
Idea: try on my laptop at home.

Subversion:

11/21

Clem changed my desktop environment to Fluxbox. Grr!!

edit things in .fluxbox/init
Set up .tcshrc file.
http://www.over-yonder.net/~fullermd/projects/tcshrc/

change xterm to have white background:
http://mail.afterstep.org/pipermail/as-users/2003-November/001142.html

I want all open things to show up on the tool bar, not just when I minimize them.
right-click on tool bar:
  Iconbar mode -> Workspace

I want 'tab tab' to show a list of possibilities.
add to .tcshrc:
  set autolist = ambiguous

syntax highlighting of shell script:
Need to include the following at the beginning of the .tcshrc.local file:


I want to enable ctrl-alt left (right) to switch windows.
edit .fluxbox/keys
add:
Control Mod1 Left :PrevWorkspace
Control Mod1 Right :NextWorkspace

http://www.math.colostate.edu/~reinholz/freebsd/fluxconfig.html

Wow, Leo updated my fluxbox version, and everything broke. I couldn't even log in!

Here we go again...

Fluxbox

clock:
right click,
  choose 12h

toolbar:
right click
  bottom left, width = 90%
  Iconbar Mode -> Workspace = > places all current items on the bar.

menu: open .fluxbox/menu
In
[submenu] (Window)
add
      [restart] (kde) {startkde}

Add the following in [begin] (Fluxbox) and [submenu] (Terminals):
      [exec] (gnome-terminal) {gnome-terminal}

.fluxbox/init
number of windows:
session.screen0.workspaces: 6

background:
session.screen1.rootCommand: fbsetbg -f /home/kstory/pictures/wallpaper.JPG

fonts:
session.screen1.toolbar.font: misc-12:bold
This doesn't seem to be working.

.fluxbox/keys
add:
Control Mod1 Left :PrevWorkspace
Control Mod1 Right :NextWorkspace

.fluxbox/overlay
menu.title.font: sans-16:bold
menu.frame.font: sans-14
toolbar.clock.font: sans-16:bold
toolbar.workspace.font: sans-16:bold
.font: sans-16


Problems:
  - Toolbar and all fonts are tiny.

background:
Must have feh installed.
kstory@spudws2:~> fbsetbg -f personal/MtHooker8-08.JPG
Set this up automatically:
In .fluxbox/startup,
  fbsetbg -f /home/kstory/pictures/wallpaper.JPG
Now as long as wallpaper.JPG is defined, this should work.
Nope.

startup is not working.
I tried putting the fbsetbg command in the .tcshrc. this produced the background, but got rid of the title bar and all right-click options.

Try adding Fluxbox to GDM:
http://fluxbox-wiki.org/index.php?title=GDM
create new file ~/.Xsession
add:
exec /usr/bin/startfluxbox
-> changed nothing.

Try creating:
/usr/share/xsessions/fluxbox.desktop
add:
[Desktop Entry]
  Encoding=UTF-8
  Name=Fluxbox
  Comment=Highly configureable low resource X11 Window Manager
  Exec=/usr/local/bin/startfluxbox
  Terminal=False
  TryExec=/usr/local/bin/startfluxbox
  Type=Application
Please don't die...
-> changed nothing.
Remove /usr/share/xsessions/fluxbox.desktop

call /usr/local/bin/startfluxbox -> works!!
add this to .tcshrc:
  exec /usr/local/bin/startfluxbox
BAD BAD
this made it such that I could not login as kstory anymore.
Errors:
/home/kstory/.fluxbox/startup: line 45: /usr/bin/fluxbox: No such file or directory.

Try this later:
Try editing .fluxbox/startup:
change:
  exec /usr/bin/fluxbox
to:
  exec /usr/local/bin/fluxbox

Try adding the following to .tcshrc.local
fbsetbg -f /home/kstory/pictures/wallpaper.JPG
-> crashes immediately.

Add to .tcshrc.local:
  exec /usr/local/bin/startfluxbox
and change .fluxbox/startup to
  exec /usr/local/bin/fluxbox
Close, logs in, tool bar, but can't open terminal.

add:
session.screen1.rootCommand: fbsetbg -f /home/kstory/pictures/wallpaper.JPG
Previously just
session.screen1.rootCommand:

Nope.

Here is what worked:

in .fluxbox/init, add the line
session.screen1.rootCommand:    fbsetbg -f /home/kstory/pictures/wallpaper.JPG

11/24

Look for calendar later. Time to work now.

To do:
  - subversion of gcp on find.
  - Make KyleWave2 work on find. -> Done
  - Look at Grabber and figure out how to add new GCP board.

Checkout brand new version of gcp onto Find:

kstory@find:~/$ cvs -d bicep0.caltech.edu:/home/bicep0/cvsroot checkout -r working14Feb gcp
kstory@find:~/$ mv gcp/control/code/unix/libscan_src/Makefile.rules gcp/control/code/unix/libscan_src/BADMakefile.rules
kstory@find:~/$ cd gcp
kstory@find:~/gcp/$ make > & compileLog-11.24
kstory@find:~/gcp/$ mkdir runlogs

Run. It is all working:
  - I can type into the bicepViewer
  - I can plot the bolo->cosine11 which produces a cool star parttern.

- Try to check into subversion. -> no subversion on Find.
- Fix stat page. -> Done.

Create svnRepos on Find for my gcp code.

Create a new subversion directory:

kstory@find:~/$ svnadmin create /home/kstory/svnRepos
svnadmin: Command not found.
kstory@find:~/$ which svn
svn: Command not found.
kstory@find:~/$

Grr...

Fix stat page:

kstory@find:~/gcp/$ en control/code/unix/viewer_src/viewer.tcl
  comment out line 2396:
#  set ::viewer(conf_file) {stat.page}         ;# The configuration file.

in viewer.tcl

Edit L:2395
   set ::viewer(conf_dir) $::env(GCP_DIR)/conf/bicep          ;# The directory containing configuration files.
   set ::viewer(conf_file) {viewer_conf.page}         ;# The configuration file.

and write a file called viewer_conf.page.
Works.

Make KyleWave2 work on Find.

Here we go...

1) create gcp/antenna/control/bicep/KyleWave2.cc, .h

2) edit gcp/antenna/control/bicep/Makefile.rules
  - AntennaDrive -> yes
  - AntennaMaster -> yes
  - KyleWave2 -> yes
  - PmacComms -> no
  - PmacCommsPci -> no
  - Tracker -> yes
  - WeatherMonitor-> yes

3) Add KyleWave2 board to Tracker.h

4) Add read functions to Tracker.cc
  a) Instantiate KyleWave2 board in the Tracker::privateConstructor().
  b) Add to destructor.
  c) call kyleWave2_->recordWaveVal() from Tracker::addTick()

5) Add KyleWave to the registers: gcp/control/code/unix/libunix_src/bicep/specificregs.c
  - Add RegBlockTemp bicepKyleWave2[]
  - Add the kyleWave2 block to the bicep_antenna_boards[] RegBoardTemp.

Compile. -> Ok.

Run. -> Ok.

How Antenna connects to the Mediator

AntennaMonitor
Fields:
  - Scanner* scanner_
  - AntennaMaster* parent_
  - FrameSender* sender_
  - string host_ // IP address of the control host
  - TcpClient client_ // object to manage connection to the Mediator.
  - NetMsgHandler netMsgHandler_ // network stream handler for sending a greeting to the archiver program.
  - NetHandler netDataFrameHandler_ // TCP network handler for sending data frames
  From GenericTask:
  - Thread* thread_ // pointer to the thread that sponed the AntennaMonitor
  - PipeQ mstq_ // A message queue, implimented as a pipe, by which we can communicate with this task.
  - FdSet fdSet_
  - vector commands_ // a vector of comands used by this task.

Methods:
  - connect(), disconnect() // control host i.e. Mediator.
  - connectScanner(), disconnectScanner()
  - serviceMsgQ()
  - packNextFrame()
  - packFrame()
  - NET_READ_HANDLER(netMsgReadHandler)
  - NET_SEND_HANDLER(netMsgSentHandler)
  - NET_SEND_HANDLER(netDataFrameSentHandler)
  - packNextFrame() // If there is room in the circular frame buffer, record another data frame and push it onto the event channel.
  - dispatchNextFrame() // Send data frame.
  - packFrame() // Install the frame buffer as teh network buffer and pre-format the register frame output message.
  - sendScannerConnectedMsg() // sent to parent (AntennaMaster)
  - sendAntennaIdMst() // Pack a greeting message to be sent to the controller
  - pareseGreetingMsg() // from control program



Look at how Antenna layer connects to the Mediator layer and how frames are packed, queued, and sent / received.

AntennaMaster has thread AntennaMonitor which takes care of this stuff.

AntennaMonitor
TcpClient client_ maintains connection to Mediator layer.
serviceMsgQ has 4 message type options:
  - fdSet_.isSetInRead(msgqFd) -> processTaskMsg()
  - fdSet_.isSetInWrite(netDataFrameHandler_.getSendFd()) -> netDataFrameHandler_.send()
  - fdSet_.isSetInWrite(netMessageHandler_.getSendFd()) -> netMessageHandler_.send()
  - fdSet_.isSetInRead(netMessageHandler_.getReadFd()) -> netMessageHandler_.read()

send is NetHandler::send()

AntennaMaster::packNextFrame
  scanner_->packNextFrame()
  sendDispatchDataFrameMsg();


For tomorrow:
  - Look at how AntennaMonitor packs frames, starting with scanner::packNextFrame
  - How does polling of Antenna (pmac etc) stuff work?
  - How does the Mediator maintain a connection to the Antenna layer?
  - Look at Grabber.

11/25

Trying to get screensave to run automatically.

1) In .Xsession, add

/bin/tcsh

2) remove from .fluxbox/init:
session.screen0.rootCommand: fbsetbg -f /home/kstory/pictures/wallpaper.JPG
--> nope.

to .fluxbox/startup, add
exec /usr/bin/gnome-screensaver

In .Xsession
change line to
/usr/local/bin/startfluxbox

this works in the command line:
/usr/local/bin/startfluxbox

In .tcshrc.local, Add
exec /usr/local/bin/startfluxbox -> BAD

Change .Xsession to executable -> nothing.

create .xsession and .xinitrc -> BAD

Create .xsession:
#!/bin/sh
xsetroot -solid steelblue

kstory@spudws2:~> chmod 700 .xsession
kstory@spudws2:~> ln -s .xsession .xinitrc

Can't log in anymore. Login with root and remove these files.

Change permissions on my home file:

cd /home
chmod g+rx kstory/
chmod a+x kstory

put .xsession back in. -> BAD

I give up. Just run command
gnome-screensaver
from a terminal every time I log in.

Check out new copy of gcp onto spudws2:

1) checkout
2) move Makefile.rules
3) mkdir runlogs
4) compile -> failure

Copy over pgplot directory from find
compile -> ok.

Fix stat page:

Edit /gcp/control/code/unix/viewer_src/viewer.tcl
set ::viewer(conf_dir) $::env(GCP_DIR)/conf/bicep
set ::viewer(conf_file) {viewer_conf.page}

and write viewer_conf.page file.

Run: Fix mysimpleStartup, myclose, viewer_conf.page. -> OK.

AntennaMonitor packing frames

AntennaMonitor::packNextFrame()
  calls scanner_->packNextFrame()

Scanner::packNextFrame()
  setTime() // Set the current time in the database.
  recordRecordNumber(recordNumber_ + 1); // incrimented whenever a frame is recorded.
  recordTime()
  recordFeatures()
  recordWalshState() // empty ??
  share_->packFrame(fb_.getNextFrame()) // copy the shared-memory object into the next frame in the frame buffer
  features_.transient_ = 0; // clear the transient feature mask.

Scanner::setTime() -> frame_->setTime(); -> share_->setClock()

BicepShare::setTime(void)
  LogStream ls;
  INSTALL_MUTEX_CLEANUP(guard_, ls); // pthread_mutex_t guard_
  if(pthread_mutex_lock(&guard_) != 0)
    // log error
  time_.setToCurrentTime(); // gcp::util::TimeVal time_
  if(pthread_mutex_unlock(&guard_) != 0)
  UNINSTALL_MUTEX_CLEANUP(ls);

Scanner::recordRecordNumber(unsigned record)
  frame_->archiveRecordNumber(record); -> writeReg(redord_,0,1,&record);
  recordNumber_ = record;

Scanner::recordTime() -> frame_->archiveTime()

FrameBoard::archiveTime()
  double mjd = share->getUtc(); -> time_.getTimeInMjdDays()
  gcp::util::RegDate date(utc[0], utc[1\])
  unsigned lst = share->getLst(mjd)* (daysec/twopi)*1000.
  share->writeReg(utc_, date.data());
  writeReg(lst_, 0, 1, &lst);

Scanner::recordFeatures()
  unsigned features = features_.transient_ (or) features_.persistent_;
  frame_->archiveFeatures(features, features_.seq_);

Scanner:: struct Features{
  unsigned seq_ // sequence number of the last feature marker command received from the control program
  unsitned transient_ // Bit-mask union of persistent feature markers received from the last control program since last frame
  unsigned persistent_; // bitmask union of persistent features previously received from the control program but not cancelled.
  void reset()

FrameBoard::archiveFeatures(unsigned features, unsigned seq)
  writeReg(features_, 0, 1, &features)
  writeReg(markSeq_, 0, 1, &seq)

BicepShare::packFrame(DataFrameManager* frame)
  for(unsigned int iboard=0; iboard < regmap_->nboard_; iboard++) {
    RegMapBoard* brd = regmap_->boards_[iboard];
Field RegMap* regmap_
    // if the board is marked as reachable, attempt to copy the contents of the board's registers into the frame buffer.
    if(brd->nbyteArchive_ > 0) {
      if(verifyBoard(iboard) {
        try{ packRegBoard(brd, frame) } catch(...){
          frame->fillBuffer(0, brd->nByteArchive_)
          flagBoard(iboard);
        }


RegMap:: defined in control/code/unix/libunix_src/common/regmap.h
  std::vector boards_

RegMapBoard::
  std::vector

RegMapBlock::
  char name_
  unsigned flags_ // I think this denotes the type
  unsigned ireg_ // the sequential number of the first register
  unsigned nreg_ // total number of elements in the block
  int slot_ // The start index of the block in the archive array
  int iSlot_ // The sequential slot index of the first register in parent slot array
  int iArcSlot_ // The sequential slot index of the first register in parent archived slot array
  int iByte_ // The sequential byte index of the first register in the parent register map
  int iArcByte_ // The starting index of this block in the archive byte array, or -1 if this register is not archived
  unsigned nBytePerEl_ // The number of bytes in each element of this register

BicepShare::BicepRegDb::verifyBoard(int board)
  INSTALL_MUTEX_CLEANUP(guard_, ls);
  grabRegs(WAIT_FOREVER); // don't time out
  status \* boardStatusReg(board);
  ungrabRegs();
  UNINSTALL_MUTEX_CLEANUP(ls);

BicepShare::grabRegs(TimeOut timeout)
  regdb_-> grabRegs(timeout)

BicepShare::BicepRegDb::grabRegs(TimeOut timeout)
  if(timeout==WAIT_FOREVER)
    status = pthread_mutex_lock(&guard_);

BicepRegDb class defined in BicepShare.h
Fields:
  friend class BicepShare
  RegMap* regmap_
  pthread_mutex_t guard_
  unsigned* shadnw) // shadow and local register buffer
  int nshadow_ // dimension of shadow[]
Methods:
  void grabRegs(TimeOut timeout);
  void ungrabRegs()
  RegMapBoard* findRegMapBoard(string boardName)
  void flagBoard(int board) // flag board as unreachable

AntennaDataFrameManager class defined in gcp/util/common/AntennaDataFrameManager.h
Fields:
  AntennaDataFrame* antFrame_
Methods:
  SetAnt(gcp::util::AntNum::Id) // set teh antenna number associated with this dataframe.
  getAntIntId() // return the antenna number associated with this dataframe.
  AntNum getAnt() // Return the antenna descriptor associated with this dataframe.
  void initialize()

AntennaDataFrame class defined in gcp/util/common/AntennaDataFrame.h
Fields:
  AntNum antNum_
Methods:
  setAnt()
  getAnt()
  unsigned char* data() // Get a pointer to our interna data suitable for using an external network buffer.

Questions:
  - where is AntennaMonitor::packNextFrame() called from?
  - Where is Share::packRegBoard(brd, frame) defined?


For Tomorrow:
  - Start with BicepShare::packFrame()
  - Figure out where data is getting polled from.
  - How does polling of Antenna (pmac etc) stuff work?
  - How does the Mediator maintain a connection to the Antenna layer?
  - Look at Grabber.

11/25

continue above.

For next week:
  - work backwords from AntennaMonitor::packNextFrame()
    - where do the boards get put into the BicepShare object?
    - where does data, Antenna stuff get polled from?
    - How does the Mediator maintain a connection to the Antenn lyer?
      ~ are there multiple connections for data and commands?
  - Look at Grabber.
  - Diagram out how data is polled and flows up from Antenna to Mediator to archive.

12/1

Trying to add new monitor.
Twin view does not work well.

Look at:
http://jbopensrc.wordpress.com/2008/04/29/quickfix-ubuntu-hardy-dual-monitor-with-intel-945gm-troubles-cant-escape-clone-mode/

edit /etc/X11/xorg.conf
Add:
Section "Screen"
  SubSection "Display"
      Virtual 1024 768
Failure.

Try again later.

Work backwords from AntennaMonitor::packNextFrame()

called in
AntennaMonitorMsg::processMsg(AntennaMonitorMsg* msg)
switch (msg->type)
case AntennaMonitorMsg::PACK_DATAFRAME:
  packNextFrame();
case AntennaMonitorMsg::DISPATCH_DATAFRAME:
  dispatchNextFrame();
case AntennaMonitorMsg::CONNECT:
  if(connect())
    sendScannerconnectMsg(true);

AntennaMonitor::serviceMsgQ()
  if(fdSet_.isSetInRead(msgqFd))
    processTaskMsg(&stop);
I think this somehow calls processMsg??

Pack Data

Done from AntennaRx thread.
run() calls serviceMsgQ()

DataNew::serviceMsgQ()
Wait for data to arrive
Once a message has arrived:
  - processTaskMsg()
  - Loop over boxes:
  >read box with NetDataBoard::read(iBox) -> reads socket to boxes.
    update sequence number if necessary
    deal with time stuff
    >case: seq == currSeq
      if(received == DataBase::BOX_ALL) // If the packet has now been received from all boxes, buffer box data
        incrementSamplecount(iSamp, received) // calls bufferBoxData()
    >case: seq > currSeq // new sequence number means all data have arrived, or some packets are missing. In either case, buffer data for current seq and start acquiring new data.
      deal with sequence number stuff, i.e. large jumps in seq
      if(received != DataBase::BOX_NONE) // if we have received any data packets, buffer
        incrimentSampleCount()
      bufferTimeData()
      bufferPmacData()
else //we have timed out
  bufferTimeData()
  bufferPmacData()
  incrimentSampleCount(iSamp, DataBase::BOX_NONE)

DataNew::incrimentSampleCount() -> calls bufferBoxData()
  bufferBoxData() -> method of DataBase
  if(iSamp == NSAMPLESPERFRAME)
    writeData() -> calls writeBoxData(), writePmacData(), writeTimeData()
    parent_->sendPackDataFrameMsg() -> AntennaMaster::sendPackDataFrameMsg()

DataBase::bufferBoxData()
  if(!simData)
    bolo_->read_bolo_sample(...) -> NetDataParse::read_bolo_sample() -> reads socket.
    same for all NetDataParse objects
  else
    bolo_->fake_bolo_sample() -> make up values based on index

DataBase::writeData()
  writeBoxData()
  writePmacData()
  writeTimeData()

DataBase::writeBoxData()
  bolo_->pack_bolo_frame()
  x_->pack_x_frame() for x = all NetDataParse objects of DataBase.
  calls share_->writeReg(...)


AntennaMaster::sendPackDataFrameMsg()
  sendStrobePmacMsg() -> TrackerMsg::packStrobePmacMsg(); forwardDriveMsg(&masterMsg);
  AntennaMasterMsg masterMsg;
  AntennaMonitorMsg* monitorMsg = masterMsg.getMonitorMsg()
                                  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC;
                                  type = MONITOR_MSG;
                                  return &body.monitorMsg;
  monitorMsg-> packPackDataFrameMsg()
                  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC;
                  type = PACK_DATAFRAME;
  forwardMonitorMsg(&masterMsg)
    _ANTENNAMASTER_TASK_FWD_FN(AntennaMaster::forwardMonitorMsg(AntennaMasterMsg* msg)_
      AntennaMonitor->sendTaskMsg(AntennaMonitorMsg* msg->getMonitorMsg());
After this we have the following:
masterMsg:
  - genericMstType_ = TASK_SPECIFIC
  - MstType type = MONITOR_MSG
  - body.monitorMsg = monitorMsg
monitorMsg:
  - genericMsgType_ = TASK_SPECIFIC
  - type = PACK_DATAFRAME

AntennaMasterMsg : derrived from GenericMasterTaskMsg
Fields:
  - enum MsgType{} type
  - union{
    - AntennaControlMsg controlMsg;
    - AntennaDriveMsg driveMsg
    - AntennaMonitorMsg monitorMsg
    - AntennaRxMsg rxMsg
    - UmacControlMsg umacControlMsg
    } body
Methods:
  - getControlMsg()
  - get[Type]Msg(), Control, Drive, Monitor, Rx, UmacControl
  - packSendHeartBeatMsg()
  - pack[Type]Connected Msg, Control, Scanner, Pmac

AntennaMonitorMsg
Fields:
  - enum MsgType{} type
  - union{
    - struct flagBoard
    } body
Methods:
  - pack[Type]Msg(), FlagBoard, PackDataFrame, DispatchDataFrame, Connect

AntennaMonitor::serviceMsgQ()
  receive message
  processTaskMsg() : GenericTask::processTaskMsg(bool* stop)
                      deal with cases HEARTBEAT, RESTART, STOP
                      case TASK_SPECIFIC:
                        call local processMsg()
    AntennaMonitor::processMsg()
      case PACK_DATAFRAME:
        packNextFrame()
      case DISPATCH_DATAFRAME:
        dispatchNextFrame()
      case CONNECT
        if( connect() )
          sendScannerConnectedMsg(true)

AntennaMonitor::packNextFrame()
  scanner_-> packNextFrame()
              setTime()
              recordRecordNumber(recordNumber+1)_
              recordTime()
              recordFeatures()
              share_->packFrame(fb_.getNextFrame()) // for all reachable boards, copy contents of board's registers into frame buffer.
              features_.transient_ = 0;
  sendDispatchDataFrameMsg()
    AntennaMonitorMsg msg;
    msg.packDispatchDataFrameMsg()
      genericMstType_ = TASK_SPECIFIC;
      type = DISPATCH_DATAFRAME
    sendTaskMsg(&msg) -> back to AntennaMonitor::serviceMsgQ(), case DISPATCH_DATAFRAME

AntennaMonitor::dispatchNextFrame()
  check for connection to monitor.
  // Get the next frame (if any) to be dispatched
  DataFrameManager* frame =
    scanner_-> dispatchNextFrame()
                return fb_. dispatchNextFrame() // AntennaFrameBuffer fb_
                              calls FrameBuffer::dispatchNextFrame()
  // Pack the frame into our network buffer.
  packFrame(frame->frame()) // Install the frame buffer as the network buffer and pre-format th register frame output message.
    NetSendStr* nss = netDataFrameHandler_.getSendStr();
    nss-> setBuffer(frame->data(), frame->nByte());
    nss-> startPut(0);
    nss->incNput(frame->nByte(0 - NET_PREFIX_LEN);
    nss->endPut();
  // Add register to the archiver file descriptor to be watched for writability
  fdSet_.registerWriteFd(client_.getFd())
  dispatchPending_ = true;

FrameBuffer::dispatchNextFrame()
  DataFrameManager* dfm = nextSendSlot_->frame_
  frameMap_.erase(nextSendSlot_->id_); // FrameBuffer::nextSendSlot(FrameBufferSlot* slot)
  dfm->lock(); // Lock the frame. This protects against writers trying to modify the frame while the calling thread is attempting to send it.
  if(lastSentSlot_ != 0) // Only decrement the count of frames waiting to be sent if this call means we just finished sending a frame.
    clearSlot(lastSentSlot) // FrameBuffer::clearSlot(FrameBufferSlot* slot)
      frameMap_.erase(slot->id_) // Delete this slot's entry in the map
      slot->frame_->unlock() // Make sure this frame is unlocked
      slot->frame_->reinitialize() // And reinitialize its contents.
    nUsed_--
  lastSentSlot_ = nextSendSlot_ // Set the last sent frame pointint to the one we are currently dispatching.
  nextSendSlot_ = nextSendSlot_->next_
  return dfm; // return the pointer to the frame of the slot to be sent.




DataFrameManager : util/common/
Fields:
  - bool dataIsInitialized_
  - unsigned currentIndex_
  - unsigned nBuffer_
  - unsigned nUsed_
Methods:
  - pack() // many varieties
  - fillBuffer() // many varieties
  - DataFrame* frame() // return a handle to the raw data frame managed by this object
  - unpack()
  - advance(unsigned ndata) // Adnvance the internal buffer ndata elements
  - virtual reinitialize()
  - virtual lock()
  - virtual unlock()
  - virtual getId()
  - byteOffsetInFrameOfData()
  - sizeInBytes()
  - unsigned sizeInBytesOfData()

DataFrame : util/common/
Fields:
  - unsigned nAvg_ // a counter for running averages
  - Mutex guard_
  - AxisRange axisRange_ // a utility member
Methods:
  - resize()
  - size()
  - nReg()
  - nByte
  - char* data() // Get a pointer to our internal data suitable for using as an external network buffer
  - pack() // 4 functions
  - add[stuff]
  - unpack()
  - getPtr(DataType::Type) // return an arbitrary pointer to our internal data, cast as the requested type
  - get[Type]Ptr()
  - RegDate() // return a pointer to our internal data, cast as a Date pointer.
  - lock()
  - unlock()

FrameBuffer : util/common/
Fields:
  - struct FrameBufferSlot{}
  - vector slots_
  - unsigned int nSlot_
  - Mutex guard_
  - std::map frameMap_
  - struct FrameBufferSlot* nextFreeSlot_
  - struct FramebufferSlot* nextSendSlot_
  - struct FramebufferSlot* lastSentSlot_
  - unsigned int nUsed_ // number of slots currently in use
Methods:
  - DataFrameManager* getFrame()
  - DataFrameManager* dispatchNextFrame()
  - getNframesInQueue()
  - struct FrameBufferSlot* findSlot()
  - struct FrameBufferSlot* getNextSlot()
  - void clearSlot(FrameBufferSlot* slot)

NetSendStr : gcp/util/common/
Fields:
  - enum NetSendId ( NET_SEND_[ DATA, DONE, CLOSED, ERROR ] )
  - gcp::control::NetSendStr* netStream_
  - bool netBufAllocated_
  - bool attached_
Methods:
  - attach(fd) // Attach this network buffer to a file descriptor
  - setBuffer(buffer, size) // Set the network buffer pointint to an external buffer
  - NetSendId send() // Send a message packed into out network buffer to a socket described by previously attached fd.
  - NetSendId state() // Return the last send state
  - getFd()
  - startPut(int opcode) // Start packing a message into a network buffer
  - endPut()
  - putChar(int ndata, unsigned char* data) // Pack a byte into a network buffer.
  - put[Type]() // Type = [Char, Short, Int, Float, Double, Obj]
  - incNput(nbytes) // Incrementally put bytes into a network buffer
  - installSendHandler(NET_SEND_HANDLER(* handler), void* arg) // Install a send handler.
  - installErrorHandler(NET_ERROR_HANDLER(* handler), void* arg)
  - NetSendId privateSend(fd) // Send a message in our network buffer to the specified socket.
  - NET_SEND_HANDLER(* sendHandler_)
  - NET_SEND_HANDLER(* errorHandler_)

netbuf.h : controle/code/unix/libunix_src/common/netbuf.h
Fields:
  - enum NetTypeSize
  - struct NetBuf{
    char* buf // The network I/O buffer
    int size // The allocated size of buf[]
    int nget // The number of bytes extracted from the buffer
    int nput // The number of bytes added to the buffer
    int external // True if buf[] is an externally provided buffer
    }
  - struct gcp::control::NetReadStr {
    NetBuf* net
    unsigned int msglen
    int fd
    enum NetReadId{...} state
    }
  - struct gcp::control::NetSendStr {
    NetBuf* net
    int fd
    enum NetSendId{...} state
    }

Methods:
  - gcp::control::NetBuf* new_netBuf(int size) // NetBuf constructor
  - gcp::control::NetBuf* del_NetBuf(NetBuf* net) // NetBuf destructor
  - size_NetBuf(NetBuf)
  - net_set_buffer(NetBuf* net, void* buf, size_t length) // NetBuf containers created with a buffer 'size' of zero must have an external buffer supplied before use.
    // When an external buffer is being used to format messages for output,
    // net_inc_nput can be used to increment the record length of the message
    // to account for externally formatted data in the proviced buffer.
  - net_inc_nput(NetBuf* net, int nbytes)
  - net_start_get()
  - net_end_get()
  - net_get_[type](), type = [char, short, int float, double, nget]
  - net_start_put()
  - net_end_put
  - net_put_[type], type = [char, short, int float, double]
  - attach_NetReadStr()
  - nrs_read_msg()
  - attach_NetReadStr()
  - attach_NetSendStr()
  - nss_send_msg()

FdSet
Fields:
  - fd_set readFdSet_
  - fd_set readFdSetSave_
  - fd_set writeFdSetSave_
  - int fdSetSize_
Methods:
  - zeroReadFdSet()
  - zeroWriteFdSet()
  - registerReadFd()
  - registerWriteFd()
  - clearFromReadFdSet()
  - fd_set* readFdSet() // Return a pointer to the set of read file descriptors
  - fd_set* writeFdSet()
  - size() // size of largest file descriptor in the set
  - bool isSetInRead()
  - bool isSetInWrite
  - clear()
  - print() // for debugging

NetHandler : gcp/util/common/NetHandler.h
Fields:
  - int fd_
  - NetReadStr* nrs_
  - NetSendStr* nss_
  - unsigned readBufSize_
  - unsigned sendbufSize_
Methods:
  - attachReadStream(fd) // Attach the network I/O stream to a socket.
  - attachSendStream(fd) // Attach the network I/O stream to a socket.
  - attach(fd) // Attach all streams to the same socket.
  - getReadFd() // Overwritable method for returning the read fd.
  - getSendFd() // Overwritable method for returning the send fd.
  - getFd() // Method for returning a single fd.
  - setReadBuffer(buffer, size) // Set the network buffer pointing to an external buffer
  - setSendBuffer(buffer, size) // Set the network buffer pointing to an external buffer
  - gcp::util::NetSendStr::NetSendId send()
  - gcp::util::NetReadStr::NetReadId read()
  - NetReadStr* getReadStr() // Return a pointer to our read stream
  - netSendStr* getSendStr() // Return a pointer to our send stream
  - initialize() // private

Doxygen

Create configuration file

kstory@spudws2:gcp> doxygen -g myConfig-file

Run doxygen: to generate the documentation you can now enter:

kstory@spudws2:gcp> doxygen Doxyfile

Output:
file:///home/kstory/work/gcp/gcp/html/index.html
This shows up, but nothing is there. ??

For Tomorrow:
start with FrameBuffer::dispatchNextFrame().

12/2

work on Double screen stuff.

kstory@spudws2:~> nvidia-settings &
  -> "you do not appear to be using the NVIDIA X driver."
kstory@spudws2:~> sudo nvidia-xconfig
Using X configuration file: "/etc/X11/xorg.conf".

WARNING: Unable to find CorePointer in X configuration; attempting to add new CorePointer
         section.


WARNING: The CorePointer device was not specified explicitly in the layout; using the first
         mouse device.

Backed up file '/etc/X11/xorg.conf' as '/etc/X11/xorg.conf.backup'
New X configuration file written to '/etc/X11/xorg.conf'

[root@spudws2 ~]# nvidia-xconfig

Using X configuration file: "/etc/X11/xorg.conf".
Backed up file '/etc/X11/xorg.conf' as '/etc/X11/xorg.conf.backup'
New X configuration file written to '/etc/X11/xorg.conf'

Make x-fig sketch of computer program.
http://find.uchicago.edu/~kstory/notebook/projects.html#sec7

12/3

start with FrameBuffer::dispatchNextFrame within 12/1.

12/5

Description of packing a Data Frame in the Antenna Layer.


> Something sends a message to DataNew::ServiceMsgQ(), perhaps a Timer. > **DataNew::ServiceMsgQ()** > fdSet_.registerReadFd(msgq_.fd()) // reads message type > //Loop over boxes. For each box, check if it has data with fdSet_.isSetInRead(data_->fd(iBox)) > **NetDataBoard::read(iBox)** // read the socket, storing the data. > // This function calls socket[].read(...), which actually reads the data from the socket, filling structure DataSystemBox::box[]. > update sequence number if necessary > > case( seq==currSeq ) // > received |= DataBase:boxId(iBox) > if(received == BOX_ALL) // If this packet has now been received from all boxes, buffer box data > **incrementSampleCount()** // read data boxes, pack a frame, and incriment to next sample. > **bufferBoxData()** // method of DataBase > bolo_->read_bolo_sample(...) > [type]_->read_[type]_sample(...) // type = [fridge, rot, datasys, aux, dewar, level, cal] > **read_[bolo]_sample()** // move info from struct box[] to specific arrays. > //fill arrays of values that will be written to registers later. > // bindex = > bin index, cindex = > channel index > data->words2components2( data->box[ bindex+BOLO_DATA_OFFSET].sdata[cindex], ... ) > //fill cosine[], sine[], quadsum[], etc. > > if(iSamp == NSAMPLESPERFRAME) // if we have data from all boxes, send message to pack frame. > **writeData()** > **writeBoxData()** > bolo_->pack_bolo_frame() > [type]_->pack_[type]_frame(), type = [fridge, rot, datasys, aux, dewar, level, cal] > **pack_[type]_frame()** > share_->writeReg(...) > **writePmacData()** > **writeTimeData()** > > parent_-> **sendPackDataFrameMsg()** > **AntennaMaster::sendPackDataFrameMsg()** > **sendStrobePmacMsg()** > AntennaMasterMsg masterMsg; > AntennaMonitorMsg* monitorMsg = masterMsg.getMonitorMsg() > **AntennaMasterMsg::getMonitorMsg()** > genericMsgType_ = TASK_SPECIFIC > type = MONITOR_MSG > monitorMsg-> **packPackDataFrameMsg()** > genericMsgType_ = TASK_SPECIFIC > type = PACK_DATAFRAME > **forwardMonitorMsg(&masterMsg)** // calls ANTENNAMASTER_TASK_FWD_FN(AntennaMaster::forwardMonitorMsg) > AntennaMonitorMsg* monitorMsg = msg->getMonitorMsg() > master_->monitorTask_->sendTaskMsg(monitorMsg) > **GenericTask < Msg >::sendTaskMsg(Msg* msg)** > msgq_.sendMsg(msg) > **PipeQ< Msg >::sendMst(Msg* msg)** > pipe_.writePipe(...) > **Pipe::writePipe(buffer, nbyte, timeout)** // write the message to the pipe, which goes to AntennaMaster::ServiceMsgQ(). > > //End parent_->sendPackDataFrameMsg() > deal with time stuff. > rcvdLast = received; > //End incrementSampleCount() > received = DataBase::BOX_NONE > //End if(received==BOX_ALL) > > case( seq > currSeq ) // buffer now > // deal with large seq number jumps > if(received != if we have received any data packets > incrementSampleCount() // calls read_[x]_sample() > currWeq = seq; > received = DataBase::boxId(iBox) > **bufferTimeData()** > timep_->readGpsTimeSample() > timep_->setDeltaT(...) > **bufferPmacData()** > // Read all fast regs. > pmac_->readRegNoWrite(...) > //End case(seq==currSeq) > > **AntennaMonitor::serviceMsgQ()** // Message from forwardMonitorMsg() to PACK_DATAFRAME > receive message > **processTaskMsg()** > **GenericTask< Msg >::processTaskMsg(bool* stop)** > case Msg::TASK_SPECIFIC > **AntennaMonitor::processMsg(AntennaMonitorMsg* msg)** > case PACK_DATAFRAME > **packNextFrame()** > scanner_-> **packNextFrame()** > setTime() > recordRecoredNumber() > recordTime() > recordFeatures() > recordWalshState() > share_-> **packFrame( fb_.getNextFrame() )** > // copy contents of board's registers into a frame buffer, i.e. DataFrame object. > // use verifyBoard(), packRegBoard(RegMapBoard, DataFrameManager) > > **sendDispatchDataFrameMsg()** > AntennaMonitorMsg msg > **msg.packDispatchDataFrameMsg()** > genericMsgType_ = TASK_SPECIFIC > type = DISPATCH_DATAFRAME > sendTaskMsg(&msg) > //End packNextFrame() > //End AnM::processMsg() > //End processTaskMsg() > > **AntennaMonitor::serviceMsgQ()** // case PACK_DATAFRAME > receive message > **processMsg()** : case DISPATCH_DATAFRAME > **dispatchNextFrame()** > make sure we are connected to control program. > DataFrameManager* frame = scanner_->dispatchNextFrame() > **Scanner::dispatchNextFrame()** > return fb_.dispatchNextFrame() > **FrameBuffer::dispatchNextFrame()** > // Return a pointer to the next slot to be dispatched to the outside world. > **packFrame( frame->frame() )** // Pack the frame into our network buffer. > NetSendStr* nss = netDataFrameHandler_.getSendStr() // calls NetHandler::getSendStr(){ return nss_ } > nss->setBuffer( frame->data(), frame->nByte ) > nss->startPut(0) > nss->incNput( frame->nByte(0-NET_PREFIX_LEN ) > nss->endPut() > fdSet_.registerWriteFd( client_.getFd() ) > dispatchPending_ = true > //End dispatchNextFrame() > > **AntennaMonitor::serviceMsgQ()** // case NetHandler::send() > case fdSet_.isSetInWrite( netDataFramehandler_.getSendFd() ) == 1 > netDataFrameHandler_.send() > **NetSendStr::NetSendId NetHandler::send()** > return nss_->send() > **NetSendStr::send()** > return **privateSend(fd)** > case state() == NET_SEND_DATA > sendState == privateState( nss_send_msg(netStream_) ) > **netbuf::nss_send_msg()** // write previously composed network message > case nss->state == NET_SEND_DATA > while(net->nget < net->nput) > int nnew = write(nss->fd, buf+nget, nput-nget) > handle errors > return nss_state(nss, NetSendStr::NET_SEND_DONE) > //End nss_send_msg() > handle errors > if( sendState == NET_SEND_DONE) > if(sendHandler_ != 0) > sendHandler_( sendArg_ ) > //end privateSend() > //End NetSendStr::send() > //End NetHandler::send() > >

12/8

Mediator Layer : Detailed Description of Classes

AntennaConsumer : gcp/monitor/AntennaConsumer
derrived from GenericTask< ScannerMsg >
friend class Scanner
Fields:
  - Scanner* parent_

AntennaConsumerNormal : gcp/monitor/AntennaConsumerNormal
derrived from AntennaConsumer
Fields:
  - Scanner* parent_
  - static AntennaconsumerNormal* consumer_
  - int nAntenna_
  - gcp::util::TcpListener* listener_
  - gcp::util::NetCommHandler temporaryHandler_
  - vector< gcp::util::NetAntennaDataFrameHandler* > connectedHandlers_
  - TimeVal startTime_
  - TimeVal timer_
  - struct timeval* timeOut_
Methods:
  - connectTcpIp()
  - serviceMsgQ()
  - listen(bool listenVar)
  - void initializeConnection()
  - terminateConnection(NetHandler* str)
  - finalizeConnection()
  - sendGreetingMsg()
  - bool timedOut()
  - static NET_READ_HANDLER(netMsgReadhandler)
  - static NET_SEND_HANDLER(netMsgSentHandler)
  - static NET_ERROR_HANDLER(netMsgErrorHandler)
  - static NET_READ_HANDLER(netantennaDataFrameReadHandler)
  - static NET_ERROR_HANDLER(netAntennaDataFrameErrorhandler)

AntennaConsumerNormal::constructor(Scanner* parent) : Antennaconsumer(parent), parent_(parent), listener_(0)
  consumer_ = this
  AntNum antnum
  nAntenna_ = antnum.getAntMax()
  listener_ = new Tcplistener(TRANS_ANT_SCANNER_PORT, nAntenna_)
  connectedHandlers_.reserve(nAntenna_)
  for( antennas iant )
    connectedHandlers_.push_back(new NetAntennaDataFrameHandler() )

AntennaConsumerNormal::serviceMsgQ()
  bool stop = false
  int nready = 0
  int msgqFd = msgq_.fd()
  wait for messages to arrive
    if(fdSet_.isSetInRead(msgqFd))
      processTaskMsg(&stop)
    if(fdSet_.isSetInRead(listener_->getFd())) // Connection request from an antenna
      initializeConnection()
    // waiting for response from newly connected antenna
    if(temporaryHandler_.getNetMsgHandler()->getReadFd() >= 0)
      //Waiting for an initialization message
      if(fdSet_.isSetInRead(temporaryHandler_.getNetMsgHandler()->getReadFd()))
        temporaryHandler_.readNetMsg()
      else if(timedOut() )
        terminateConnection(&temporaryHandler_)
        listen(true)
    // Established connections
    for( antennas iant )
      if(fdSet_.isSetInRead(str->getReadFd())) // Check for partially read data frames from established antennas
        str->read()

AntennaConsumerNormal::initializeConnection()
  fd = listener_->acceptConnection(() // Allow the caller to connect.
  temporaryhandler_.getNetMsgHandler()->attach(fd) // Attach this fd to teh temp connection handlr
  temporaryHandler_.getNetMsghaneler()-> // Register a handler to be called when a network message is rcvd
    installReadhandler( netMsgReadHandler, 0)
  temporaryHandler_.getNetMsgHandler(0->
    installErrorHandler( netMsgErrorHandler, 0 )
  fdSet_.registerReadFd(fd) // Register the descriptor to be watched for input.
  listen(false)

AntennaConsumerNormal::NET_READ_HANDLER(AntennaconsumerNorman::netMsgReadHandler)

AntennaConsumerNormal::finalizeConnection()
  NetMsg* netMsg = temporaryHandler_.getLastReadNetMsg()
  unsigned int antennaId = netMsg->body.antenna
  AntNum antNum(antennaId)
  int fd = temporaryhandler_.getFd()
  if( antnum.isValidsingleAnt() ) // Only proceed if the response was valid
    temporaryHandler_.getNetMsgHandler()->
      installSendHandler(netMsgSenthandler, 0)
    sendGreetingMsg()
  else // Terminate the temporary connection
    terminateconnection( &temporaryHandker_ )

gcp::util::NetAntennaDataFrameHandler
derrived from NetHandler
Fields:
  - AntennaDataFrameManager frame_
Methods:
  - getFrame()
  - setAnt(AntNum::Id antennaId)
  - unsigned int getAnt()

AntennaControl : Thread of Master - Control gcp/mediator/specific/AntennaControl.h, cc
derrived from GenericTask< AntennaControlMsg >
friend class Control
Fields:
  - Control* parent_
  - int nAntenna_
  - gcp::util::TcpListener* listener_ // The server socket on which to listen for connection requests fromt the antennaComputers.
  - gcp::util::NetCommHandler temporaryHandler_ // A network buffer associated with antennas whose connections we have accepted,
                                                // but for which a greeting-response cycle is not yet complete.
  - std::vector connectedHandlers_ // A vector of network buffers associated with established antenna connections.
  - std::list initScript_
  - std::list< AntennaControlMsg >:: iterator initScriptIter_ // A pointer to the current element of the list
  - bool recordingInitScript_ // True when we are recording an initialization script
  - bool initInProgress_
  - enum InitState{ UNINITIALIZED, INITIALIZING, INITIALIZED}
  - std::vector< InitState > antennaInitState
  - enum ConnectState{ DISCONNECTED, PENDING, CONNECTED}
  - std::vector< ConnectedState > antennaConnectedState_
  - std::vector< bool > sendPending_
  - int nConnected_
  - timeVal startTime_
  - TimeVal timer_
  - timeval* timeOut_
  - int pending_
Methods:
  - setPending(iant, bool pending) // Decrement/Increment the count of commands pending to antennas.
  - connectTcpIp() // Set up for TCP/IP communications
  - void processMsg(AntennaControlMsg* taskMsg) // process a message received on our message queue
  - sendRtcnetCmd(AntennaControlMsg* msg) // Respond to a message to send a network command to the antenna control socket.
  - void decrementPending() // Decrement the count of commands pending to antennas
  - static NET_SEND_HANDLER(netMsgSentHandler)
  - static NET_SEND_HANDLER(netCmdSentHandler)
  - static NET_ERROR_HANDLER(netErrorHandler)
  - void setInitState()
  - recordInitMsg(AntennaControlMsg* msg) // Record the next command in an intitialization script
  - void beginInitScript() // Start an initialization script
  - void sendNextInitMsg() // Send the next initialization script command
  - void endInitScript()
  - void sendNavUpdateMsg() // Send a request for an update of ephemeris data from the ACC.
  - bool haveAntennasReady() // Return true if any antennas are ready to be initialized
  - void flagAntenna(AntennaControlMsg* msg) // Respond to a message that an antenna changed state
  - bool listening() // Return true if we are currently listening for connection requests.
  - void serviceMsgQ() // Overwrite the base-class event loop
  - void initializeConnection() //Initialize a connection to an antenna.
  - void finalizeConnection() // Finalize a connection to an antenna
  - void terminateConnection(gcp::util::NetCommHandler* str, bool shutdown=true) // Terminate a socket connection
  - void forwardNetMsg(gcp::util::NetMsg* msg) // Forward a net message to the control task.
  - void sendGreetingMsg(gcp::util::NetCommHandler* netHandler) // Send a greeting message to an antenna
  - static NET_READ_HANDLER(processTemporaryNetMsg) // Act on receipt of a net message.
  - static NET_READ_HANDLER(processNetMsg)
  - void listen(bool restartListening) // Start listening for connections from antennas.
  - bool timedOut() // Return true if we timed out waiting for a response from an antenna
  - void startRecordingInitScript() // Mark subsequent commands as belonging to the initialization script.
  - void stopRecordingInitScript() // Finish recording initialization commands.

AntennaControl::constructor(Control parent)
  parent_ = parent;
  listener_ = 0;
  control_ = this;
  pending_ = 0;
  connectTcpIp();
    AntNum antnum;
    nAntenna_=antnum.getAntMax()
    listener_ = new TcpListener(TRANS_ANT_CONTROL_PORT, nAntenna_) // set up to listen for connection requests from the antenna computers.
    connectedHandlers_.reserve(nAntenna_);
    antennaInitState_.reserve(nAntenna_);
    antennaConnectState_.reserve(nAntenna_);
    sendPending_.reserve(nAntenna_);
    for each antenna
      connectHandlers_.push_back(new NetcommHandler())
      antennaconnectedState_.push_back(DISCONNECTED)
      antennaInitState_.push_back(UNINITIALIZED)
      sendPending_.push_back(false)

AntennaControl::serviceMsgQ()
  fdSet_.registerReadFd(msgqFd)
  listen(true) // start listening for connection requests from antennas.
  // wait for a message in a while loop.
    if( fdSet_.isSetInRead(msgFd) ) // message on our queue
      processTaskMsg(&stop)
    if( fdSet_.isSetInRead( listener_->getFd()) ) // connection request from antenna
      initializeConnection()
    // Process communication of a newly connected antenna:
    if( temporaryHandler_.getNetMsgHandler()->getReadFd() >=0 )
      if(fdSet_.isSetInRead(temporaryHandler_.getNetMsgHandler()->getReadFd())) // initialization msg
        temporaryHandler_.readNetMsg()
      if(fdSet_.isSetInWrite(temporaryHandler_.getNetMsgHandler()->getSendFd())) // send a greeting msg
        temporaryHandler_.sendNetMsg()
    // Process established connections
    for( antennas )
      NetCommHandler* handler = connectedHandlers_[iant]
      NetMsgHandler* msgHandler = handler->getNetMsgHandler()
      NetCmdHandler* cmdHandler = handler->getNetCmdHandler()
      if(fdSet_.isSetInWrite(cmdHandler->getSendFd())) // Check for partially send commands to established antennas
        handler->sendNetCmd()
      if(fdSet_.isSetInRead(msgHandler->getReadFd())) // Check for partially read messages
        handler->readNetMsg()
      if(fdSet_.isSetInWrite(msgHandler->getSendFd())) // Check for partially sent messages
        handler->sendNetMsg()

AntennaControl::processMsg
  switch(msg->type)
  case AntennaControlMsg::BEGIN_INIT
    beginInitScript()
  case AntennaControlMsg::END_INIT
    endInitScript()
  case AntennaControlMsg::FLAG_ANTENNA
    break;
  case AntennaControlMsg::init
    if( msg->body.init.start )
      startRecordingInitScript()
    else
      stopRecordingInitScript()
  case AntennacontrolMsg::NETCMD
    sendrtcNetCmd(msg)
  if(initInProgress_)
    sendNextInitMsg()

AntennaControl::beginInitScript()
  control_->initScriptIter_ = control_->initScript.begin()
  control_->initInProgress_ = true;
  control_->setInitState(INITIALIZING)
  control_->sendNextInitMsg()

AntennaControl::initializeConnection()
  int fd = -1
  fd = listener_->acceptConnection() // Allow the caller to connect
  temporaryHandler_.getNetMsgHandler()->attach(fd) // Attach this file descriptor to the temporary connection handler
  temporaryHandler_.getNetMsgHandler()->
    installReadHandler(processTemporaryNetMsg, 0) // Register a handler to be called when a network msg is received
  temporaryHandler_.getNetMsgHandler()->
    installErrorHandler(netErrorHandler, &temporaryHandler_) // Register a handler to be called if an error occurs
  fdSet_.registerReadFd(fd) // Register descriptor to be watched for input.
  listen(false) // Stop listening for further connections until this antenna has responded.

Communicator
Fields:
  - struct RcvdStr{
    string start_
    string stop_
    COMM_PARSER_FN(* parser_)
    void* arg_
    COMM_END_PARSER_FN(* endParser_)
    void* endArg_
    bool matchAny_
    std::ostringstream os
    RcvdStr()
    RcvdStr(...)
  }
  - TcpClient* client_
  - TimeVal timer_
  - list< string > sendStrings_
  - list< RcvdStr > rcvdStrings_
  - list< string >::iterator sendStringIter_
  - list< RcvdStr >::iterator rcvdStringIter_
  - std::ostringstream os_
Methods:
  - bool timedOut()
  - getFd() // Return the fd associated with this communicator
  - void run()
  - processClientMessage() // Read a line from the power strip and determine what to do
  - void registerTimeOut()
  - void terminateCommSequence(bool error) // Terminate a command sequence
  - void enableTimeOut( bool enable) // Set a timeout for waiting for a response from the strip.
  - void checkLine()
  - static COMM_PARSER_FN(sendNextString)
  - void sendNextString(void)
  - void advanceIterator(bool bufferReset) // Reset in preparation for searching for the next string
  - void checkIterators()

Control : Thread of Master gcp/mediator/Control.h, cc
Forwarded Classes: Master, MasterMsg, Control, AntennaControl, DcControl, DelayControl, DelayEngine, LobeRotator, NetCmdToMsg, GrabberControl, StripControl, WxControl.
Fields:
  - gcp::util::NetCommHandler netCommHandler_ // A network stream handler for handling communication with the control program
  - TransNetCmdForwarder* forwarder_
  - Master* parent_
  - AntennaControl* antennaControl_ // resources of threads spawned by this task.
  - DeControl* cdControl_
  - DelayControl* delayControl_
  - GrabberControl* grabberControl_
  - StripControl* stripControl_
  - WxControl* wxControl_
  - gcp::util::TcpClient client_
  - std::string host_
  - bool connected_

Methods:
  - CONTROL_TASK_FWD_FN(type), type = [forwardDelayControlMsg, forwardAntennaControlMsg, forwardControlMsg, forwardDcControlMsg, forwardGrabberControlMsg, forwardStripControlMsg, forwardWxControlMsg ]
  - forwardMasterMsg(MasterMsg* msg)
  - forwardNetCmd(gcp::util::NetCmd* netCmd)
  - gcp::util::RegMapDataFrameManager* getArrayShare(0
  - static THREAD_START(type), type = [startAntennacontrol, startDccontrol, startDelayControl, startGrabbercontrol, startStripControl, startWxcontrol ]
  - static THREAD_CLEAN(type)
  - static THREAD_PING(type)
  - bool isConnected() // True when connected to the RTC control port
  - bool connect() // connect to control socket
  - disconnect() // Disconnect from teh control socket
  - void connectControl(bool reEnable) // Attempt to connect to the host
  - void disconnectControl()
  - serviceMsgQ()
  - void sendHeartBeat() // Send a heartbeat request to all threads managed by this task.
  - void sendcontrolConnectedMsg(bool connected)
  - void sendAntennaInitMsg(bool start0 // A method to send the antenna control task an init message.
  - static LOG_HANDLER_FN(sendLogMsg)
  - static LOG_HANDLER_FN(sendErrMsg)
  - void processMsg(ControlMsg* taskMsg)
  - void respondToHeartBeat() // Override GenericTask::respondToHeartBeat()
  - void packNetMsg(ControlMsg* msg) // Pack a network message intended for the ACC
  - static NET_READ_HANDLER(readNetCmdHandler)
  - static NET_SEND_HANDLER(sendNetMsgHandler)
  - static NET_ERROR_HANDLER(networkErrorHandler)

Control::processMsg()
  switch (msg->type)
  case ControlMsg::CONNECT
    connectControl(bool reEnable = false)
      if( connect() )
        sendControlConnectedMsg(true)
      else if(renEnable) // Only send a message to reenable to econnect timer if it was previously disabled.
        sendControlConnectedMsg
  case ControlMsg::INIT
    sendAntennaInitMsg(msg->body.init.start)
  case ControlMsg::NETMSG
    packNetMsg(msg)
  case ControlMsg::ANTENNA_CONTROL_MSG
    forwardAntennaControlMsg(msg)
  case ControlMsg::GRABBER_CONTROL_MSG
    forwardGrabbercontrolMsg(msg)
  case ControlMsg::STRIP_CONTROL_MSG
    forwardStripControlMsg(msg)
  case ControlMsg::WX_CONTROL_MSG
    forwardWxControlMsg(msg)

GrabberControl : Thread of Master - Control gcp/mediator/specific/GrabberControl.h, cc
Fields:
  - Control* parent_
  - gcp::util::TcpListener* listener_ // the server socket on which to listen for connection requests from the antenna computers.
  - gcp::util::NetCommHandler netHandler_ // network buffer associated with the frame grabber connection
Methods:
  - processMsg(GrabberControlMsg* taskMsg)
  - static NET_READ_HANDLER(netMsgReadHandler) // A handler to be called when a frame has been completely sent.
  - static NET_SEND_HANDLER(netCmdSentHandler)
  - static NET_ERROR_HANDLER(netErrorHandler) // A handler to be called when an error occurs in communication
  - connectGrabber()
  - disconnectGrabber()
  - serviceMsgQ()
  - sendRtcNetCmd)GrabbercontrolMsg* msg)
  - readNetMsg()
  - void forwardNetMsg)NetMsg* msg)
  - processNetMsg()
  - void listen(bool restartListening) // Start listening for connections from antennas

GrabberControl::constructor(Control* parent)
  listener_ = new TcpListener(TRANS_GRABBER_CONTROL_PORT, 1)

GrabberControl::processMsg(GrabberControlMsg* msg)
  switch(msg->type)
  case GrabberControlMsg::NETCMD
    sendRtcNetCmd(msg)

GrabberControl::serviceMsgQ()
  listen(true)
  fdSet_.registerReadFd(msgqFd)
  wait for messages to arrive.
    if(fdSet_.isSetInRead(msgqFd)) // received a message
      processTaskMsg(&stop) // GenericTask function
    if(fdSet_.isSetInRead(listener_->getFd())) // received connection request
      connectGrabber()
    if(fdSet_.isSetInRead(netHandler_.getNetMsgHandler()->getReadFd())) // received partially read message from the frame grabber
      netHandler_.readNetMsg()
    if(fdSet_.isSetInWrite(netHandler_.getNetCmdHandler()->getSendFd())) // partially sent command to the frame grabber
      netHandler_.sendNetCmd()

StripControl : Thread of Master - Control gcp/mediator/specific/StripControl.h, cc
Fields:
  - enum State{ OFF, ON, UNKNOWN }
  - Control* parent_
  - unsigned pending_
  - TimeVal timer_
  - struct timeval* timeOut_
  - vector< StripCommunicator* > communicators_
Methods:
  - void incrementPending() // Increment the count of pending communications
  - void decrementPending()
    // Initiate communications with one or more power strips
  - void initiateTogglePowerCommSequence(AntNum::Id antennas, unsigned breaker, bool power)
  - initiateCheckPowerCommSequence(gcp::util::AntNum::Id antennas) // Initiate communciations with one or more power strips
  - serviceMsgQ()
  - processMsg(StripControlMsg* msg)
  - enableTimeOut(bool enable)
    // Write the on/off state of an outlet to the register database
  - void writeVals(gcp::util::AntNum::Id id, State circuit, State outlet1, State outlet2, State outlet3, State outlet4)

StripControl::constructor(Control* parent)
  communicators_.resize(AntNum:NANT)
  for( antennas iant )
    communicators_[iant] = new StripCommunicator(this, AntNum(iant))
  initiateCheckPowerCommSequence(AntNum::ANTALL)

StripControl::processMsg(msg)
  switch(msg->type)
  case StripControlMsg::POWER
    initiateTogglePowerCommSequence(msg->antennas, msg->body.power.breaker, msg->body.power.power)

StripControl::serviceMsgQ()
  wait for message
    if(fdSet_.isSetInRead(msgq_.fd()))
      processTaskMsg(&stop)
    // did one of the strip fds become readable?
    for( antennas iant )
      StripCommunicator* comm = communicators_[iant]
      if( comm->getFd() >= 0 ) // If the client is not connected, the fd will be < 0
        if(fdSet_.isSetInRead(comm->client_->getFd()))
          comm->processClientMessage()
        if(comm->timedOut())
          comm->registerTimeOut()

StripCommunicator
derrived class of Communicator
Fields:
  - static const std::string IP_PREFIX
  - StripControl* parent_
  - gcp::util::AntNum antNum_
Methods:
  - initiateTogglePowerCommSequence(unsigned breaker, bool power)
  - initiateCheckPowerCommSequence()
  - registerTimeOut()
  - terminateCommSequence(bool error)
  - void compileTogglePowerCommandStateMachine(unsigned breaker, bool power)
  - void compileCheckPowerCommandStateMachine()
  - static COMM_PARSER_FN(parseOnOff)
  - static COMM_END_PARSER_FN(endParseOnOff)

WxControl : Thread of Master - Control gcp/mediator/specific/WxControl.h, cc
Fields:
  - Control* parent_
  - unsigned pending_
  - gcp::util::TimeVal timer_
  - struct timeval* timeOut_
  - WxCommunicator* communicator_
  - gcp::util::MonitorPointManager* monitor_;
  - gcp::util::MonitorPoint* monAirTemp_;
  - gcp::util::MonitorPoint* monRelHum_;
  - gcp::util::MonitorPoint* monWindSpeed_;
  - gcp::util::MonitorPoint* monWindDir_;
  - gcp::util::MonitorPoint* monPressure_;
Methods:
  - incrementPending()
  - decrementPending()
  - writeVals(WxCommunicator::WxData& data)
  - void enableTimeOut(bool enable)
  - void initiateReadValuesCommSequence()
  - serviceMsgQ()
  - processMsg( WxControlMsg* msg)
  - distributeWeatherData(WxCommunicator::WxData& data)

WxControl::constructor()
  communicator_ = new WxCommunicator(this)
  monitor_ = new MonitorPointManager(parent_->getArrayShare())
  monAirTemp_ = monitor_->addMonitorPoint("weather", "airTemperature");
  monRelHum_ = monitor_->addMonitorPoint("weather", "relativeHumidity");
  monWindSpeed_ = monitor_->addMonitorPoint("weather", "windSpeed");
  monWindDir_ = monitor_->addMonitorPoint("weather", "windDirection");
  monPressure_ = monitor_->addMonitorPoint("weather", "pressure")
  initiateReadValuesCommSequence()

WxControl::processMsg()
  switch (msg->type)
  case WxControlMsg::READ
    initiateReadValuesCommSequence()

WxControl::serviceMsgQ()
  wait for message
    if(fdSet_.isSetInRead(msgq_.fd()))
      processTaskMsg(&stop)
    if(communicator_->getFd() >= 0) // if client is not connected, the fd will be < 0
      if(fdSet_.isSetInRead(communicator_->client_->getFd()))
        communicator_->processClientMessage()
    if(communicator_->timedOut())
      communicator_->registerTimeOut()

Master class of Mediator

Master gcp/mediator/specific/Master.h, cc
    /**............................................................
      * A class to encapsulate translation between the old-style DASI
      * array control code and the new SZA antenna code. DASI code
      * uses proprietary socket communications & network message
      * containers to relay command messages and data between the ACC
      * and the AC, while SZA code uses distributed CORBA objects and
      * event channels.
      *
      * Instantiating a object starts up five threads: the
      * main one, and four spawnws threads, represented by the
      * following objects:
      *
      * 1) Control: which listens to the szacontrol port
      * for network commands, and translates them into invocations
      * on the CORBA DO served by the antenna code
      *
      * 2) Scanner: which receives monitor events from
      * the antenna task, translates them into data frames, and
      * packages them for transmission to the szacontrol archiver
      * port.
      *
      * 3) Signal: which handles all signals for this task.
      * /
derrived class of GenericMasterTask< MasterMsg >
Fields:
  - static Master* master_
  - string host_
  - Control* control_
  - Scanner* scanner_
  -
Methods:
  - MASTER_TASK_FWD_FN(forwardMasterMsg) // Method by which tasks can forward messages to us.
  - gcp::util::ArrayRegMapDataFrameManager& getArrayShare()
  - static THREAD_START(startType), Type = [ Control, Scanner, Signal ]
  - static THREAD_CLEAN(cleanType), Type = [ Control, Scanner, Signal ]
  - static THREAD_PING(pingControl), ping Scanner
  - static SIGNALTASK_HANDLER_FN(sendSendHeartBeatMsg) // initiate a heartbeat-resonse cycle
  - static SIGNALTASK_HANDLER_FN(sendType), Type - [SendHeartBeatMsg, RestartMsg, ShutDownMst, StartDataFrameMsg, ScannerConnectMsg, ControlConnectMsg ]
  - void sendreadWeatherStationMsg()
  - MASTER_TASK_FWD_FN(forwardControlMsg)
  - MASTER_TASK_FWD_FN(forwardScannerMsg)
  - sendHeartBeat()
  - restart() // Restart subsystem threads.
  - installSignals()
  - installTimers()
  - processMsg(MasterMsg* taskMsg)

Scanner class of Mediator

Scanner gcp/mediator/Scanner.h, cc
derrived class of GenericTask< ScannerMsg >
Fields:
  - struct features_ {unsigned transient, persistent, seq }
  - Master* parent_
  - AntennaConsumer* antennaConsumer_
  - ArrayMap* arraymap_
  - string host_
  - gcp::util::TcpClient client_ // Object for managing connection to the control program
  - gcp::util::NetStr* arrayStr_ // The Tcp/IP network stream we will use to communicate with the array control program.
  - gcp::util::ArrayFrameBuffer fb_ // The output frame buffer
  - bool dispatchPending_
  - unsigned nAntenna_
  - vector< unsigned > nArchiveAntenna_ // Number of archived registers in a single Antenna map
  - vector< int > antStartSlots_ // A vector of locations corresponding to the beginning of each antenna register map in the array map
  - vector< int > antRecSlots_ // A vector of locations corresponding to the frame.received register of each register map in the array map.
  - unsigned antReceivedCurrent_
  - unsigned antReceivedLast_
Methods:
  - packAntennaFrame(gcp::util::AntennaDataFrameManager* frame) // Pack a fake data frame for sending to the control computer.
  - void initAntennaResources() // Initialize antenna resources
  - static THREAD_START(startAntennaConsumer)
  - static THREAD_CLEAN(cleanAntennaConsumer)
  - void setAntReceived(bool, ArrayDataFrameManater* frame=0) // Set the received status for all antenna register maps.
  - bool antennasChangedState()
  - void reportStateChange()
  - bool isConnected() // True when connected to the archiver port
  - bool connect(), disconnect()
  - void connectScanner(bool reenable) // Attempt to connect to the host
  - void disconnectScanner()
  - void processMsg(ScannerMsg* taskMsg) // Process a messag received on our message queue
  - gcp::util::ArrayDataFrameManager* startNewFrame(gcp::util::RegDate& date) // Start a new data frame
  - void checkDataFrames() // Check if there are data frames waiting to be sent
  - void packFrame(gcp::util::DataFrame* frame) //Install the frame buffer as the network buffer and pre-format th register frame output message.
  - void dispatchNextFrame()
  - void sendDispatchDataFrameMsg()
  - void sendFlagAntennaMsg(unsigned antenna, bool flag)
  - void sendScannerConnectedMsg(bool connected)
  - void sendControlConnectedMsg(bool connected)
  - void respondToHeartBeat()
  - void parseGreeting()
  - static NET_READ_HANDLER(readHandler)
  - static NET_SEND_HANDLER(sendHandler)
  - static NET_ERROR_HANDLER(networkError)
  - void serviceMsgQ()
  - void changeFeatures(unsigned seq, unsigned mode, unsigned mask)

Scanner::constructor(Master* master)
  parent_=master
  threads_.pushback(new Thread(&startAntennaConsumer, &cleanAntennaConsumer, 0, "AntennaConsumer")
  arraymap_ = new_ArrayMap()
  initAntennaResources()
  // Create a TCP/IP network input stream.
  arrayStr_ = new NetStr(-1, SCAN_MAX_CMD_SIZE, 0)
  //Install handlers
  arrayStr_->getReadStr()->installReadHandler(readHandler, this);
  arrayStr_->getSendStr()->installSendHandler(sendHandler, this);
  arrayStr_->getReadStr()->installErrorHandler(networkError, this);
  arrayStr_->getSendStr()->installErrorHandler(networkError, this);
  connectScanner(true) // Connect to the archiver port
  startThreads(this)

Scanner::initAntennaResources()
  ArrRegMapReg arreg
  AntNum antnum
  nAntenna_ = 1
  antStartSlots_.reserve(nAntenna_) //Reserve space for relevant vectors
  antRecSlots_.reserve(nAntenna_)
  nArchiveAntenna_.reserve(nAntenna_)
  antReceivedLast_ = 0 // Initialize the bitmask of received data to 0
  antReceivedCurrent_ = 0
  for( antennas iant ) // Initialize these vectors to something impossible
    antStartSlots_.push_back(-1)
    antRecSlots_.push_back(-1)
    nArchiveAntenna_.pushback(0)
  for( antennas iant )
    AntNum antenna(iant) // ceclare new AntNum object
    ArrRegMap* arregmap = fild_arrRegMap(arraymap_, antenna.getAntennaName()) // Get the register map for this antenna
    if(arregmap != 0) // ignore antenna register maps we can't find
      nArchiveAntenna_[iant] = arregmap->regmap->narchive_
      // Get the descriptor for the first register in this register map.
      if(find_ArrRegMapReg(arraymap_, antenna.getAntennaName(), "frame", "status", REG_PLAIN, 0, 1, &arreg)==1)
        throw errors
      antStartSlots_[iant] = arregmap->iByte_ // Record the starting point of this register
      if(find_ArrRegMapReg(arraymap_, antenna.getAntennaName(), "frame", "status", REG_PLAIN, 0, 1, &arreg)==1)

      antRecSlots_[iant] = arreg.reg.iByte_ // Record the starting point of this register
    //End(arregmap!=0)
  //End for(iant)

Scanner::connectScanner()
  if( client_.isConnected() )
    return
  if( connect() ) // Else attempt to connect
    sendScannerConnectedMsg(true)
  else if(reEnable)
    sendScannerconnectedMsg(false)

Scanner::serviceMsgQ()
  wait for messages in while loop
    if(fdSet_.isSetInRead(msgqFd))
      processTaskMsg(&stop)
    if( client_.isConnected() )
      if(fdSet_.isSetInRead(client_.getFd())) // Greeting message from archiver
        arrayStr_->read()
      if(fdSet_.isSetInWrite(client_.getFd())) // Send a pending data frame to the control program
        arrayStr_->send()

Scanner::processMsg(ScannerMsg* msg)
  switch(msg->type)
  case ScannerMsg::DISPATCH_DATAFRAME
    dispatchNextFrame()
  case ScannerMsg::FEATURE
    changeFeatures( msg->body.feature.seq, msg->body.feature.mode, msg->body.feature.mask)
  case ScannerMsg::CONNECT
    connectScanner(false)

Scanner::dispatchNextFrame()
  if(dispatchPending_ \or\ !client_.isConnected() )
    return
  DataFrameManager* frame = fb_.dispatchNextFrame() // Get the next frame to be dispatched
    //deals with slots, returns current frame to be dispatched
  packFrame(frame->frame() )
    //nss->setBuffer(), startPut(), incNput(), endPut()
  fdSet_.registerWriteFd( client_.gdtFd() )
  dispatchPending_ = true

Scanner::packAntennaFrame(AntennaDataFrameManager* antFrame)
  static gcp::util::RegDate utc
  antFrame->readReg("frame", "utc", utc.data() )
  ArrayDataFrameManater* frame = startNewFrame( utc )
  frame->writeAntennaRegMap(*antframe, false)
    //write the register map
  checkDataFrames()

Scanner:startNewFrame(gcp::util::RegDate& date)
  TimeVal timeVal
  static unsigned int counter = 0
  static ArrayDataFramemanager8 frame = 0
  ArrayRegmapDataFramemanager& share = parent_->getArrayShare()
  static unsigned newCounter = 0
  newCounter++
  // For SZA, frames were created on a timer, and filled in later, as
  // data arrived from the telescopes.
  //
  // For bicep, frames will be created only when data arrive from the
  // antenna. Thus the timestamp is irrelevant, and we will use the
  // record counter as the tag for a unique frame, since frames can
  // arrive with any timestamp whatsoever.
  frame =
    dynamic_cast(fb_.getFrame(counter, true))
  unsigned features = features_.transient \or\ features_.persistent
  share.writeReg("frame", "features", &features);
  share.writeReg("frame", "markSeq", &features_.seq);
  features_.transient = 0x0;
  share.writeReg("frame", "record", counter); // Update the record counter in shared memory
  share.writeReg("frame", "nsnap", (unsigned) 1);
  counter++
  share.writeReg("frame", "utc", date.data()) // Set the date
  if(frame != 0)
    frame->writeRegMap("array", share, false) // Copy the shared memory segment into the last frame
  return( ArrayDataFrameManager*) frame



Scanner::checkDataFrames()
  if(fb_.getNframesInQueue() > 3)
    senddispatchDataFrameMsg()

  // If there are multiple frames waiting in the queue, keep sending
  // until the buffer is drained. But don't send the next frame until
  // at least a full half-second period after its timestamp. If we
  // were creating frames for the current half-second, we would have
  // to wait until the count is at least 2, since the number of frames
  // in the queue is not decremented until the next call to
  // FrameBuffer::dispatchNextFrame(). But since we are always
  // creating frames for the next half-second, we must now wait until
  // the count is at least 3. This means that we have the frame we
  // just created, for the next half-second, a frame for the current
  // half-second, and a frame for the last half-second, which should
  // be the next one sent.

gcp::util::TcpListener
Fields:
  - int fd_ // The file descriptor associated with our server socket.
Methods:
  - int acceptConnection(bool blocking=false) // Accept a connection from our werver port
  - int getFd()

TcpListener::constructor(unsigned port, unsigned queueSize)
  LogStream errStr
  fd_ = -1
  // Attempt to allocate a TCP/IP port on which to listen for connection requests from the antenna computers
  fd_ = tcp_server_sock(port, queueSize)
  log errors if necessary (fd_ < 0)

NetCmdForwarder : util/util/NetCmdForwarder.h, .cc
Fields:
  [none]
Methods:
  - virtual void forwardNetCmd(gcp::util::NetCmd* netCmd) = 0;

ArrayNetCmdForwarder : util/bicep/ArrayNetCmdForwarder.h, .cc
Fields:
  - NetCmdForwarder* antennaForwarder_
  - NetCmdForwarder* controlForwarder_
  - NetCmdForwarder* dcForwarder_
  - NetCmdForwarder* delayForwarder_
  - NetCmdForwarder* grabberForwarder_
  - NetCmdForwarder* scannerForwarder_
  - NetCmdForwarder* stripForwarder_

Methods: (all private)
  - void ArrayNetCmdForwarder::forwardNetCmd(gcp::util::NetCmd* netCmd)
    Lots of cases for different opcode
  - void forwardAntennaNetCmd(gcp::util::NetCmd* netCmd);
  - void forwardControlNetCmd(gcp::util::NetCmd* netCmd)
  - void forwardDcNetCmd(gcp::util::NetCmd* netCmd)
  - void forwardDelayNetCmd(gcp::util::NetCmd* netCmd)
  - void forwardGrabberNetCmd(gcp::util::NetCmd* netCmd)
  - void forwardScannerNetCmd(gcp::util::NetCmd* netCmd)
  - void forwardStripNetCmd(gcp::util::NetCmd* netCmd)

TransNetCmdForwarder : mediator/specific/TransNetCmdForwarder.h, cc
Fields:
  - Control* parent_
  - bool receivedInitScript_
  -
Methods:
  - forwardNetCmd(gcp::util::NetCmd* netCmd) // forward a command received from the ACC
  - forwardAntennaNetCmd(gcp::uti::NetCmd* netCmd)
  - forwardControlNetCmd(gcp::util::NetCmd* netCmd)
  - forwardTrackerNetCmd(gcp::util::NetCmd* netCmd)
  - forwardRxNetCmd(gcp::util::NetCmd* netCmd)
  - forwardAntennaControlMsg(ControlMsg* msg)
  - forwardControlMsg(ControlMsg* msg)
  - forwardGrabberControlMsg(ControlMsg* msg)

TransNetCmdForwarder::constructor()
  antennaForwarder_ = new AntennaNetCmdForwarderNormal(parent)
  controlForwarder_ = new gcp::mediator::ControlNetCmdForwarder(parent)
  grabberForwarder_ = new gcp::mediator::GrabberNetCmdForwarder(parent)
  scannerForwarder_ = new gcp::mediator::ScannerNetCmdForwarder(parent)
  stripForwarder_ = new gcp::mediator::StripNetCmdForwarder(parent)

AntennaNetCmdForwarderNormal : mediator/specific/
derrived class of gcp::util::AntennaNetCmdForwarder
Fields:
  - Control* parent_
Methods:
  - forwardNetCmd(gcp::util::NetCmd* netCmd)

AntennaNetCmdForwarderNormal::constructor(Control* parent)
  parent_(parent) {} // call constructor of gcp::util::ANCFN

AntennaNetCmdForwarderNormal::forwardNetCmd(Control* parent)
  ControlMsg msg
  AntennaControlMsg* antennaMsg = msg.getAntennaControlMsg()
    genericMsgType_ = TASK_SPECIFIC
    type = ANTENNA_CONTROL_MSG
    return &body.antennaControlMsg
  antennaMsg-> packRtcNetCmdMsg(&netCmd->rtc_, netCmd->optcode_)
    initialize(RtcNetCmd* cmd, NetCmdId opcode)
      genericMsgType_ = TASK_SPECIFIC
      init_ = false
    antennas = (gcp::util::AntNum::Id) cmd->antennas
    type = NETCMD
    body.netCmd.cmd = * cmd
    body.netcmd.opcode = opcode
  antennaMsg->init_ = netCmd->init_
  parent_->forwardAntennaControlMsg(&msg)

AntennaNetCmdForwarder : gcp/util/specific/AntennaNetCmdForwarder
Methods:
  - forwardNetCmd(netCmd* netCmd)
  - forward[type]NetCmd(NetCmd* netCmd), type = [OpticalCamera, Thermo, Channelizer, RxSimulator, Gpib, noiseCal, Weather, Tracker, Rx, Scanner, Probe, Board, StripControl ]

ControlNetCmdForwarder : mediator/specific
derrived class of gcp/util/specific/CNCF
Fields:
  - Control* parent_
Methods:
  - forwardNetCmd(NetCmd* netCmd)

ControlNetCmdForwarder::forwardNetCmd(NetCmd* netCmd)
  ControlMsg controlMsg
  RtcNetCmd* rtc = &netcmd->rtc_
  NetCmdId opcode = netCmd->opcode_
  case( opcode = NET_INIT_CMD )
    controlMsg.packInitMsg( rtc->cmd.init.start )
      genericMstType_ = TASK_SPECIFIC
      type = INIT
      body.init.start = start
  forwardControlMsg(&controlMsg)
    parent-> forwardControlMsg(msg)
      sendTaskMsg() // calls GenericTask< Msg >::sendTaskMsg()

ControlNetCmdForwarder : gcp/util/specific/CNCF
Methods:
  - forwardNetCmd

GrabberNetCmdForwarder : gcp/mediator/specific/GNCF.h, cc
Fields:
  - Control* parent_
Methods: forwardNetCmd(NetCmd* netCmd)

GrabberNetCmdForwarder::forwardNetCmd(NetCmd* netCmd)
  ControlMsg msg
  GrabbercontrolMsg* grabberMsg = msg.getGrabberControlMsg()
  grabberMsg->packRtcNetCmdMsg(&netCmd->rtc_, netCmd->opcode_)
  parent_-> forwardGrabberControlMsg(&msg)
    grabberControl_->sendTaskMsg( msg->getGrabbercontrolMsg() )

ScannerNetCmdForwarder : gcp/mediator/specific/SNCF.h, cc
Fields:
  - Control* parent_
Methods:
  - forwardNetCmd(NetCmd* netCmd)

ScannerNetCmdForwarder::forwardNetCmd(NetCmd* netCmd)
  MasterMsg masterMsg
  ScannerMsg* scannerMsg = masterMsg.getScannerMsg()
  RtcNetCmd* rtc = &netCmd->rtc_
  NetCmdId opcode = netCmd->opcode_
  case( opcode = NET_FEATURE_CMD )
    scannerMsg-> packFeatureMsg( rtc->cmd.feature.seq, rtc->cmd.feature.mode, mask)
      genericMsgType_ = TASK_SPECIFIC
      type = FEATURE
      body.feature.seq = seq
      body.feature.mode = mode
      body.feature.mask = mask
  forwardScannerMsg(&masterMsg)
    parent_-> forwardMasterMsg(msg)
      parent_-> forwardMasterMsg(msg)
        sendTaskMsg(msg)

StripNetCmdForwarder : gcp/mediator/specific/SNCF.h, cc
Fields:
  - Control* parent_
Methods:
  - forwardNetCmd(NetCmd* netCmd)

StripNetCmdForwarder::forwardNetCmd(NetCmd* netCmd)
  ControlMsg controlMsg
  StripControlMsg* stripMsg = controlMsg.getStripControlMsg()
  RtcNetCmd* rtc = &netCmd->rtc_
  NetCmdId opcode = netCmd->opcode_
  stripMsg->antennas = static_cast( rtc->antennas )
  case( opcode = NET_POWER_CMD )
    stripMsg-> packPowerMsg(rtc->cmd.power.greaker, rtc->cmd.power.power)
      genericMsgType_ = TASK_SPECIFIC
      type = POWER
      body.power.breaker = breaker
      body.power = power
  forwardStripControlMsg(&controlMsg)
    parent_-> forwardStripControlMsg(msg)
      parent_-> forwardMasterMsg(msg)
        sendTaskMsg(msg)

gcp::util::NetCommHandler : gcp/util/common/NetCommHandler.h, cc
derrived class of gcp::util::NetHandler
Fields:
  - int readFd_
  - int sendFd_
  - AntNum antNum_
  - NetMsgHandler netMsgHandler_
  - NetCmdHandler netCmdHandler_
Methods:
  - attachReadStream() // attach the read network I/O streams to a socket.
  - attach() // attach all streams to an fd
  - packNetMsg(NetMsg* mst) // pack a network message into our send buffer
  - packNewRtcNetMsg(NetMsg* msg) // pack a network message into our send buffer
  - packNetCmd(NetCmd* cmd) // Pack a network command into oru send buffer
  - packRtcNetCmd(RtcNetCmd* cmd, NetCmdId opcode)
  - gcp::util::NetSendStr::NetSendId sendNetMsg() // send a message to our read buffer
  - gcp::util::NetReadStr::NetReadId readNetCmd() // read a command into our read buffer
  - gcp::util::NetSendStr::NetSendId sendNetCmd() // send a command to our send buffer
  - gcp::util::NetCmd* getLastReadNetCmd() // Return the last read command
  - gcp::util::NetCmd* getLastSentNetCmd() // Return last sent command
  - gcp::util::NetMsg* getLastReadNetMsg()
  - gcp::util::NetMsg* getLastSentNetMsg()
  - int getReadFd()
  - int getSendFd()
  - int getFd() // Return the single fd that both streams are attached to

NetCommHandler::constructor()
  call NetHandler constructor
  nrs_->setBuffer(...)
  nss_->setBuffer(...)
  NetHandler::installReadHandler(readHandler, this);
  NetHandler::installReadErrorHandler(errorHandler, this);
  NetHandler::installSendHandler(sendHandler, this);
  NetHandler::installSendErrorHandler(errorHandler, this);


gcp::util::NetCmdHandler
Fields:
  - gcp::util::NetCmd lastReadNetCmd_
  - gcp::util::NetCmd lastSentNetCmd_
  - void* usedReadArg_
  - void* usedSendArg_
  - void* usedErrorArg_
Methods:
  - packNetCmd(NetCmd* rtc) // pack a network command into our send buffer
  - gcp::util::NetCmd* getLastReadNetCmd()
  - gcp::util::NetCmd* getLastSentNetCmd()
  - void installReadHandler(NET_READ_HANDLER(handler), void arg)
  - void installSendHandler(NET_SEND_HANDLER(handler), void arg)
  - void installErrorHandler(NET_ERROR_HANDLER(handler), void arg)
  - readNetCmd()
  - static NET_READ_HANDLER(readHandler);
  - static NET_SEND_HANDLER(sendHandler);
  - static NET_ERROR_HANDLER(errorHandler)

gcp::util::NetCmd

gcp::util::ArrayDataFrameManager
derrived class of ArrayMapDataFramemanager
Methods:
  - void initialize(ArrayMap* arraymap, bool archivedOnly_ = false )
  - void writeAntennaRegMap(AntennaDataFrameManager& fm, bool lockFrame)
  - ArrRegmap* findAntennaRegMap(AntennaDataFrameManager& fm)

ArrayDataFrameManager::initialize(ArrayMap* arrayMap, bool archivedOnly)
  unsigned frameSize
  arraymap_ = alias_ArrayMap(arrayMap)
  frameSize = SCAN_BUFF_BYTE_SIZE(arrayMap_->nByte(archivedOnly))
  frame_ = new gcp::util::DataFrameNormal(frameSize)
  nBuffer_ = frameSize

gcp::util::ArrayMapDataFrameManager
derrived class of DataFrameManager
Fields:
  - ArrayMap* arrayMap_
  - bool archivedOnly_
Methods:
  - writeRegMap
  - readRegmap()
  - writeReg(...)
  - readReg(...)
  - getRegVal()
  - archivedOnly()
  - ArrayMap* arrayMap()
  - int getId()
  - byteOffsetInFrameOf()
  - void* getPtr()
  - packData()
  - unpackData()
  - checkType()
  - getReg(...)
  - findReg(...)
  - getArrReg(...)
  - regMapisPresent(regmap)
  - boardIsPresent(RegMapBoard)
  - boardIsFlagged(aregmap, brd)
  - blockIsPresent(Regmapblock)

tcpip.h : gcp/code/control/code/unix/libunix_src/common/tcpip.h
Methods:
  - int tcp_server_sock(int port, int qlen)
  - udp_server_sock(int port, int qlen)
  - tcp_connect(char* host, int port, int dowait)
  - udp_connect(char* host, int port, int dowait)
  - tcp_set_blocking(int sock, int doblock)

rtcnetcoms.h : gcp/control/code/unix/libunix_src/specific/rtcnetcoms.h
Location where Net Commands are defined.

Mediator Msg types

Types: AntennaControlMsg, ControlMsg, GrabberControlMsg, MasterMsg, OptCamMsg, ScannerMsg, StripControlMsg, WxControlMsg

AntennaControlMsg

AntennaControlMsg
derrived from GenericTaskMsg
enum MsgType { FLAG_ANTENNA, INIT, BEGIN_INIT, END_INIT, NETCMD, ANTENNA_MASTER_MSG, WEATHER }
union body {
  struct flagAntenna{ unsigned antenna, bool flag (true to flag) }
  struct init {bool start}
  struct netCmd{ gcp::control::NetCmdId opcode, gcp::control::RtcNetCmd cmd }
  gcp::antenna::control::AntennaMasterMsg antennaMasterMsg
  }
Fields:
  - MsgType type
  - union body
  - bool init_ // True if this is a command generated by an initialization script
  -
Methods:
  - gcp::antenna::control::AntennaMasterMsg* getMasterMsg()
  - void packBeginInitMsg()
  - void packEndInitMsg()
  - void packInitMsg()
  - void packFlagAntennaMsg()
  - void packRtcNetCmdMsg(RtcNetCmd* cmd, NetCmdId opcode)
  - void initialize()

AntennaControlMsg::getMasterMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = ANTENNA_MASTER_MSG
  return &body.antennaMasterMsg

AntennaControlMsg::packBeginInitMsg()
  initialize()
  type = BEGIN_INIT

AntennaControlMsg::packEndInitMsg()
  initialize()
  type = END_INIT

AntennaControlMsg::packInitMsg(bool start)
  initialize()
  type = INIT
  body.init.start = start

AntennaControlMsg::packFlagAntennaMsg(unsigned antenna, bool flag)
  initalize()
  type = FLAG_ANTENNA
  body.flagAntenna.antenna = antenna
  body.flagAntenna.flag = flag

AntennaControlMsg::packRtcNetCmdMsg(RtcNetCmd* cmd, NetCmdId opcode)
  initialize()
  antennas = (gcp::util::AntNum::Id)cmd->antennas
  type = NETCMD
  body.netCmd.cmd = * cmd
  body.netCmd.opcode = opcode

AntennaControlMsg::initialize()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  init_ = false

ControlMsg

ControlMsg
enum MsgType { CONNECT, INIT, NETMSG, ANTENNA_CONTROL_MSG, GRABBER_CONTROL_MSG, STRIP_CONTROL_MSG, WX_CONTROL_MSG }
union body {
  struct init { bool start }
  gcp::util::NetMsg networkMsg
  AntennaControlMsg antennaControlMsg // A message for the antenna control thread
  GrabberControlMsg grabberControlMsg // A message for the grabber control thread
  StripControlMsg stripControlMsg // A message for the strip control thread
  WxcontrolMsg wxControlMsg
  }
Fields:
  - MsgType type
  - union body
Methods:
  - AntennaControlMsg* getAntennaControlMsg()
  - grabberControlMsg* getGrabberControlMsg()
  - StripControlMsg* getStripControlMsg(0
  - WxcontrolMsg* getWxControlMsg()
  - void packConnectMsg() // Pack a message to connect something?
  - void packInitMsg(bool start) // Method to pack a message to send a data frame ?
  - gcp::util::NetMsg* getNetMsg()

ControlMsg::getAntnnaControlMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = ANTENNA_CONTROL_MSG
  return &body.antennaControlMsg

ControlMsg::getGrabberControlMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = GRABBER_CONTROL_MSG
  return &body.grabberControlMsg

ControlMsg::getStripControlMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = STRIP_CONTROL_MSG
  return &body.stripControlMsg

ControlMsg::getWxControlMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = WX_CONTROL_MSG
  return &body.wxControlMsg

ControlMsg::packConnectMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = CONNECT

ControlMsg::packInitMsg(bool start)
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = INIT
  body.init.start = start

ControlMsg::getNetMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = NETMSG
  return &body.networkMsg

GrabberControlMsg

GrabberControlMsg
enum MsgType { NETCMD }
union {
  struct netCmd { gcp::control::NetCmdId opcode, gcp::control::RtcNetCmd cmd }
Fields:
  - MsgType type
Methods:
  - void packRtcNetCmdMsg(gcp::control::RtcNetCmd* cmd, gcp::control::NetCmdId opcode)

GrabberControlMsg::packRtcNetCmdMsg(gcp::control::RtcNetCmd* cmd, gcp::control::NetCmdId opcode)
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = NETCMD
  body.netCmd.cmd * cmd

> body.netCmd.opcode opcode

MasterMsg

MasterMsg
enum MsgType { CONTROL_CONNECTED, DC_CONNECTED, DELAY_CONNECTED, LOBE_ROTATOR_CONNECTED, OPTCAM_CONNECTED, SCANNER_CONNECTED, SEND_HEARTBEAT, CONTROL_MSG, OPTCAM_MSG, SCANNER_MSG }
union body {
  struct controlConnected { bool connected }
  struct dcConnected { bool connected }
  struct lobeRotatorConnected { bool connected }
  struct scannerConnected { bool connected }
  struct opcamConnected { bool connected }
  ControlMsg controlMsg
  OptCamMsg optcamMsg
  ScannerMsg scannerMsg
  }
Fields:
  - MsgType type
  - union body
Methods:
  - OptCamMsg* getOptCamMsg()
  - ScannerMsg* getScannerMsg(0
  - ControlMsg* getcontrolMsg()
  - void packSendHeartBeatMsg()
  - void packControlConnectedMsg(bool connected)
  - void packDcConnectedMsg(bool connected)
  - void packDelayConnectedMsg(bool connected)
  - void packLobeRotatorConnectedMsg(bool connected)
  - void packScannerConnectedMsg(bool connected)
  - void packOptCamConnectedMsg(bool connected)

MasterMsg::getOptCamMsg
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = OPTCAM_MSG
  return &body.optcamMsg

MasterMsg::getScannerMsg
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = SCANNER_MSG
  return &body.scannerMsg

MasterMsg::getControlMsg
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = CONTROL_MSG
  return &body.controlMsg

MasterMsg::packSendHeartBeatMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = SEND_HEARTBEAT

MasterMsg::packControlConnectedMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = CONTROL_CONNECTED
  body.controlConnected.connected = connected

MasterMsg::packDcConnectedMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = CD_CONNECTED
  body.dcConnected.connected = connected

MasterMsg::packDelayConnectedMsg(bool connected)
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = DELAY_CONNECTED
  body.delayConnected.connected = connected

MasterMsg::packLobeRotatorConnectedMsg(bool connected)
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = LOBE_ROTATOR_CONNECTED
  body.lobeRotatorConnected.connected = connected
  body.lobeRotatorConnected.connected = connected

MasterMsg::packScannerConnectedMsg(bool connected)
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = SCANNER_CONNECTED
  body.scannerConnected.connected = connected

MasterMsg::packOptCamConnectedMsg(bool connected)
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = OPTCAM_CONNECTED
  body.optcamConnected.connected = connected

OptCamMsg

OptCamMsg
enum MsgType { CONNECT }
Fields:
  - MsgType type

ScannerMsg

ScannerMsg
derrived class of GenericTaskMsg
enum MsgType { START_DATAFRAME, DISPATCH_DATAFRAME, CONNECT, FEATURE }
union body {
  struct feature { unsigned seq, mode, mask }
  }

Field:
  - MsgType type
  - union body
Methods:
  - void packStartDataFrameMsg()
  - void packDispatchDataFrameMsg()
  - void packConnectMsg()
  - void packFeatureMsg(unsigned seq, mode, mask)

ScannerMsg::packStartDataFrameMsg()
  genericMsgType_ = TASK_SPECIFIC
  type = START_DATAFRAME

ScannerMsg::packDispatchDataFrameMsg()
  genericMsgType_ = TASK_SPECIFIC
  type = DISPATCH_DATAFRAME

ScannerMsg::packConnectMsg()
  genericMsgType_ = TASK_SPECIFIC
  type = CONNECT

ScannerMsg::packFeatureMsg(unsigned seq, mode, mask)
  genericMsgType_ = TASK_SPECIFIC
  type = FEATURE
  body.feature.seq = seq
  body.feature.mode = mode
  body.feature.mask = mask

StripControlMsg

StripControlMsg
enum MsgType { POWER, RESET }
union body {
  struct power { unsigned breaker, bool power }
Fields:
  - MsgType type
  - union body
  - gcp::util::AntNum::Id antennas
Methods:
  - void packPowerMsg(unsigned breaker, bool power)

StripControlMsg::packPowerMsg(unsigned breaker, bool power)
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = POWER
  body.power.breaker = breaker
  body.power.power = power

WxControlMsg

WxControlMsg
enum MsgType{ READ }
union body { }
Fields:
  - MsgType type
  - union body
Methods:
  - WxControlMsg::packReadMsg()

WxControlMsg::packReadMsg()
  genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
  type = READ

Mediator startup function: bin_Mediator.cc

bin_Mediator.cc
int Program::main(void) {
  sigset_t allSignals
  sigfillset(&allSignals) // C++ function of POSIX signals
  pthread_sigmask(SIG_BLOCK, &allSignals, NULL)
  AntNum antNum
  Master translator(Program::getParameter("host"); // Calls Master constructor.


Master Thread

Master::constructor(string host)
  master_ = this;
  control_ = 0;
  scanner_ = 0;
  // Initialize array of threads
  threads_.push_back(new Thread(&startControl, &cleanControl, &pingControl, "Control");
  Threads_.push_back("Scanner");
  Threads_.push_back("Signal");
  host_ = host
  // Start Threads
  startThreads(this) // Call THREAD_START(type) functions
  installSignals() // see SignalTask thread section
  installTimers() // see SignalTask thread section
  serviceMsgQ()


Mediator - Control Thread

Master::THREAD_START(Master::startControl)
  Master* trans = (Master*) arg
  Thread* thread = 0
  thread = trans-> getThread("Control") // GenericTask< Msg >::getThread(string name)
    returns poniter to thread that was initialized in push_back(new Thread(...))
  trans->control_ = new gcp::mediator::Control(trans)
    see below
  trans->control_->thread_ = thread; // Set our internal thread pointer pointing to the AntennaRx thread
  thread->broadcastReady()
  trans->control_->run() // call mediator/Control::run()
  catch errors.


Control::constructor(Master* parent) : mediator/specific/Control.cc
  control_ = this;
  forwarder_ = new TransNetCmdForwarder(this)
    antennaForwarder_ = new AntennaNetCmdForwarderNormal(parent);
    controlForwarder_ = new gcp::mediator::ControlNetCmdForwarder(parent);
    grabberForwarder_ = new gcp::mediator::GrabberNetCmdForwarder(parent);
    scannerForwarder_ = new gcp::mediator::ScannerNetCmdForwarder(parent);
    stripForwarder_ = new gcp::mediator::StripNetCmdForwarder(parent);
  threads_.push_back(new Thread(&startAntennaControl, &cleanAntennacControl, &pingAntennaControl, "AntennaControl"))
  threads_.push_back(new Thread("GrabberControl")
  threads_.push_back(new Thread("StripControl")))
  threads_.push_back(new Thread("WxControl))
  startThreads(this)

Mediator - Control - AntennaControl Thread

THREAD_START(Control::startAntennaControl)
  Control* parent = (Control* ) arg
  Thread* thread = 0;
  thread = parent->getThread("AntennaControl");
  parent->antennaControl_ =
    new gcp::mediator::AntennaControl::AntennaControl(parent) // see above for constructor
  thread->broadcastReady()
  parent->antennaControl_-> run()
    AntennaControl::serviceMsgQ()

Mediator - Control - GrabberControl Thread

THREAD_START(Control::startGrabberControl)
  Control* parent = (Control* ) arg
  Thread* thread = 0
  thread = parent->getThread("GrabberControl")
  parent->grabberControl_ =
    new gcp::mediator::GrabberControl(parent)
  parent->grabberControl_->thread_ = thread;
  thread->broadcastready()
  parent->grabberControl_-> run()
    GrabberControl::serviceMsgQ()

Mediator - Control - StripControl Thread

THREAD_START(Control::startStripControl)
  Control* parent = (Control* ) arg
  Thread* thread = 0
  thread = parent->getThread("StripControl")
  parent->stripControl_ =
    new gcp::mediator::StripControl(parent)
  parent->stripControl_->thread_ = thread
  thread->broadcastReady()
  parent->stripControl_-> run()
    StripControl::serviceMsgQ()

Mediator - Control - WxControl Thread

THREAD_START(Control::startWxControl)
  Control* parent = (Control* ) arg
  Thread* thread = 0
  thread = parent->getThread("WxControl")
  parent->wxControl_ =
    new gcp::mediator::WxControl(parent)
  parent->wxControl_->thread_ = thread;
  thread->broadcastready()
  parent->wxControl_-> run()
    WxControl::serviceMsgQ()


Mediator - Scanner Thread

Master::THREAD_START(Master::startScanner)
  Master* master = (Master*) arg
  Thread* thread = 0;
  thread = master->getThread("Scanner")
  master->scanner_ = new gcp::mediator::Scanner(master)
  master->scanner_->thread_ = thread;
  thread-> broadcastReady()
  master->scanner_-> run()
    Scanner::serviceMsgQ()

Scanner::constructor(Master* master)
  parent_=master
  threads_.pushback(new Thread(&startAntennaConsumer, &cleanAntennaConsumer, 0, "AntennaConsumer")
  arraymap_ = new_ArrayMap() // control/.../libunix_src/common/genericregs.c
  initAntennaResources() // set up registers, slots, handlers, etc.
  // Create a TCP/IP network input stream.
  arrayStr_ = new NetStr(-1, SCAN_MAX_CMD_SIZE, 0)
  //Install handlers
  arrayStr_->getReadStr()->installReadHandler(readHandler, this);
  arrayStr_->getSendStr()->installSendHandler(sendHandler, this);
  arrayStr_->getReadStr()->installErrorHandler(networkError, this);
  arrayStr_->getSendStr()->installErrorHandler(networkError, this);
  connectScanner(true) // Connect to the archiver port
  startThreads(this)

Mediator - Scanner - AntennaConsumer Thread

THREAD_START(Scanner::startAntennaConsumer)
  Scanner* parent = (Scanner*) arg
  Thread* thread = 0
  Master* master = parent->parent_
  parent->antennaConsumer_ =
    new gcp::mediator::AntennaConsumerNormal(parent)
      TcpListener
      vector< NetAntennaDataFrameHandler > connectedHandlers_
  parent->antennaConsumer_->thread_ = thread // Set our internal thread pointer
  thread-> broadcastReady()
  parent->antennaConsumer_-> run()
    AntennaConsumerNormal::serviceMsgQ()


Mediator - Signal Thread

Master::THREAD_START(Master::startSignal)
  Master* master = (Master*) arg
  Thread* thread = 0;
  thread = master->getThread("Signal")
  master->signal_ = new gcp::util::SignalTask()
  thread->broadcastReady()
  master->signal_-> run()
    SignalTask::serviceMsgQ()

SignalTask::constructor()
  signaltask_ = this
  id_ = pthread_self
  installSignal(sigIo_, &checkMsgQ)
    signalHandlers_.push_back(new SignalHandler(sigIo_, checkMsgQ) )
      handlers_.push_back( HandlerPair(handler, args) )
        handler_ = handler
        args_ = args

SignalTask::run()
  wait for next catchable signal, which is signifiec by sigNo
  find signalHandler in vector that has matching sigNo
    for each handler in vector handlers_
      if it is not null, call handler(sigNo, args) // in this case, serviceMsgQ()

Master::installSignals()
  sendInstallSignalMsg(SIGINT, &sendShutDownMsg) // GenericMasterTask(sigNo, handler)
    // SIGNALTASK_HANDLER_FN(Master::sendShutDownMsg) { master_->sendStopMsg() }
    Msg msg
    msg.packInstallSignalMsg(sigNo, handler) // GenericMasterTaskMsg
      genericMsgType_ = gcp::util::GenericMasterTaskMsg::INSTALL_SIGNAL
      genericMasterBody.installSignal.sigNo = sigNo
      genericMasterBody.installSignal.handler = handler
    sendTaskMsg(&msg)
      Master::serviceMsgQ() // GenericTask::serviceMsgQ
        processTaskMsg(&stop) // GenericMasterTask::processTaskMsg()
          case INSTALL_SIGNAL
          installSignal(&msg) // GenericMasterTask::installSignal(Msg* msg)
            // SignalTask::sendInstallSignalMsg(...) -> GenericTask::sendInstallSignalMsg()
            signal_-> sendInstallSignalMsg( msg->genericMasterBody.installSignal.sigNo, msg->genericMasterBody.installSignal.handler)
              SignalTaskMsg::msg.packInstallSignalMsg(sigNo, handler)
                genericMsgType_ = TASK_SPECIFIC
                type = SIG_INSTALL_SIGNAL
                body.installSignal.sigNo = sigNo
                body.installSignal.handler = handler
                body.installSignal.arg = arg
              sendTaskMsg(&msg) // SignalTask::serviceMsgQ()
                SignalTask::serviceMsgQ()
                  SignalTask::processTaskMsg()
                    case SIG_INSTALL_SIGNAL
                    SignalTask::installSignal(&msg)
                      signalHandlers_.pushback( new SignalHandler(sigNo, handler, args) )
                      sigaddset(&handlersignals_, sigNo)


Master::installTimers()
  sendInstallTimerMsg("heartbeat", HEARTBEAT_SIGNAL, HEARTBEAT_SEC, 0, &sendSendHeartBeatMsg)
    //calls GenericMasterTask::sendInstallTimerMsg()
    MasterMsg msg
    msg.packInstallTimerMsg("heartbeat", HEARTBEAT_SIGNAL, HEARTBEAT_SEC, 0, &sendSendHeartBeatMsg)
      //calls GenericMasterTaskMsg::packInstallTimerMsg()
      genericMsgType_ = INSTALL_TIMER
      fill genericMasterBody.installTimer.[stuff]
    sendTaskMsg(&msg)
      Master::serviceMsgQ() // GenericTask::serviceMsgQ()
        processTaskMsg(&stop) // GenericMasterTask::processTaskMsg()
          case INSTALL_TIMER
          installTimer(&msg) // GenericMasterTask::installTimer(Msg* msg)
            signal_->sendInstallTimerMsg( genericMasterBody.installTimer.[stuff])
              SignalTaskMsg msg
              msg.packInstallTimerMsg("heartbeat", HEARTBEAT_SIGNAL, HEARTBEAT_SEC, 0, HEARTBEAT_SEC, 0, &sendSendHeartBeatMsg)
                genericMsgType_ = TASK_SPECIFIC
                type = SIG_INSTALL_TIMER
                body.installTimer.[stuff] = [stuff]
              fwdTaskMsg(&msg)
                SignalTask::sendTaskMsg(msg) // SignalTask::serviceMsgQ()
                  SignalTask::serviceMsgQ()
                    SignalTask::processTaskMsg()
                      case SIG_INSTALL_TIMER
                      installTimer(&msg) // calls SignalTask::installTimer(name, sigNo...)
                        check that timers exist. If not, throw errors
                        for( ihand in signalHandlers_ )
                          if(signalHandler_[ihand]->sigNo_ == sigNo)
                            //Throw errors if a handler already exists for this signal
                        TimerInfo* timer = new TimerInfo(name, sigNo, initSec, initNsec, intervalSec, intervalNsec)
                        timers_.push_back(timer)
                        signalHandlers_.push_back(new signalHandler(sigNo, handler, timer))
                        sigaddset(&handledSignals_, sigNo)
  //End sendInstallTimerMsg

  sendEnableTimerMsg("heartbeat", true)
    //calls GenericMasterTask::sendEnableTimerMsg()
    MasterMsg msg
    msg.packEnableTimerMsg("heartbeat", true)
      //calls GenericMasterTaskMsg::packEnableTimerMsg()
      genericMsgType_ = ENABLE_TIMER
      genericMasterBody.enableTimer.name = "heartbeat"
      genericMasterbody.enableTimer.enale = true
    sendTaskMsg(&msg)
      Master::serviceMsgQ() // GenericTask::serviceMsgQ()
        processTaskMsg(&stop) // GenericMasterTask::processTaskMsg()
          case ENABLE_TIMERS
          enableTimer(&msg) // GenericMasterTask::enableTimer()
            signal->sendEnableTimerMsg(msg->genericMasterbody.enableTimer.name, msg->genericMasterBody.enableTimer.enable)
              SignalTaskMsg msg
              msg.packEnableTimerMsg(name, enable)
                genericMsgType_ = gcp::util::GenericTaskMsg::TASK_SPECIFIC
                type = SIG_ENABLE_TIMER
                body.enableTimer.name = "heartbeat"
                body.enableTimer.enable = true
              fwdTaskMsg(&msg)
                SignalTask::sendTaskMsg(msg)
                  SignalTask::serviceMsgQ()
                    SignalTask::processTaskMsg()
                      case SIG_ENABLE_TIMER
                      enableTimer(&msg)
                        startTimer("heartbeat")
                          for( itimer in timers_ )
                            timers_[itimer]->timer_-> start()
                              AbsTimer::start()
                                get current absolute time
                                setFutureTime(...)
                                targetSec_ = sec
                                targetNanoSec_ = nsec
                                isRunning_ = true

  //End sendEnableTimerMsg
  sendInstallTimerMsg("connect", CONNECT_SIGNAL, 0,0, CONNECT_SEC, 0, &sendControlConnectMsg)
  //End sendInstallTimerMsg("connect")
  sendEnableTimerMsg("connect", true)
  //End sendEnableTimerMsg("connect")

12/11

GenericTask.h

gcp::util::GenericTask
Fields:
  - Thread* thread_ // If this task was instantiated by another thread, keep a pointer there
  - vector< Thread* > threads_ // vector of Thread objects managed by this task.
  - PipeQ< Msg > msgq_ // A message queue, implimented as a pipe for communicating with this task.
  - gcp::util::FdSet fdSet_ // A set of file descriptors associated with this task.
  - vector< Command* > commands_ // A vector of commands used by this task
  - struct timeval* timeOut_
  - TimeVal commandtimeOut_
Methods:
  - sendRestartMsg()
  - sendStopMsg()
  - sendHeartBeatMsg()
  - virtual fwdTaskMsg(Mst* msg)
  - sendTaskMsg(Msg* msg)
  - startThreads(void* arg) // calls the run() method of all Threads, which calls pthread_create()
  - getMinStartOrder()
  - bool threadsNeedStarting()
  - void cancelThreads() // calcel threads managed by this task
  - cancelThread(unsigned order) // Cancel the next thread with the specific order
  - getMonCancelOrder()
  - bool threadsNeedCancelling() // Return true if there are still uncancelled threads
  - void pingThreads(void* arg)
  - void raise(name, int sigNo) // Raise a signal to a named thread
  - Thread* getThread(string name)
  - bool threadsAreRunning()
  - shutdownConnection(int fd) // Shutdown a connection; call shutdown() and close() on fd.
  - virtual void serviceMsgQ(void)
  - virtual void restart(void) // restart this thread
  - virtual void run(void)
  - virtual void processTaskMsg(bool* stop)
  - virtual void processMsg(Msg* msg) // Task specific messages
  - virtual void respondToHeartBeat()
Signals and Timers
  - virtual void installTimer(Msg* msg) // Respond to a message to install a timer
  - virtual void installSignal(Msg* msg) // Respond to a message to install a signal
  - virtual void enableTimer(Msg* msg) // Respond to a message to enable/disable a timer
  - virtual void addHandler(Msg* msg) // Respond to a message to add/remove a handler
  - void stepCommands()

GenericTask< Msg >::constructor()
  thread_ = 0
  timeOut_ = 0
  fdSet_.zeroReadFdSet()
  fdSet_.registerReadFd( msgq_.fd() )

GenericTask< Msg >::run(void)
  serviceMsgQ()

GenericTask< Msg >::serviceMsgQ(void)
  bool stop = false
  int nready // number of file descriptors ready for reading
  if( msgq_.fd() < 0 )
    ThrowError
  Wait for message in while loop select(...)
    processTaskMsg(&stop)

GenericTask< Msg >::processTaskMsg(bool* stop)
  Msg msg
  msgq_.readMsg(&msg)
  switch( msg.genericMsgType_ )
  case Msg::HEARTBEAT:
    respondToHeartBeat
  case Msg::RESTART
    restart()
  case Msg::STOP
    * stop = true
  default:
    processMsg(&msg)

GenericTask< Msg >::processMsg(Msg* msg) // defined by inheriters
  {}

GenericTask< Msg >::respondToHeartBeat()
  if( thread_ != 0 )
    thread_->setRunState(true)

GenericTask< Msg >::sendRestartMsg()
  Msg msg
  msg.genericMsgType_ = Msg::RESTART
  fwdTaskMsg(&msg)

GenericTaskMsg::sendStopMsg()
  Msg mst
  msg.genericMsgType_ = Msg::STOP
  fwdTaskMsg(&msg)

GenericTaskMsg::sendHeartBeatMsg()
  Msg msg
  msg.genericMsgType_ = Msg::HEARTBEAT
  fwdTaskMsg(&msg)

GenericTaskMsg::sendTaskMsg(Msg* msg)
  try{ msgq_.sendMsg(msg) }
  catch errors

GenericTask< Msg >::fwdTaskMsg(Msg* msg)
  try{ msgq_.sendMsg(msg) }
  catch errors

GenericTask< Msg >::startThreads(void* arg)
  while( threadsNeedStarting() )
    unsigned order = getMinStartOrder()
    startThread(arg, order)

GenericTask< Msg >::startThread(void* arg, unsigned order)
  for( ithread in threads_ )
    if( ithread->isRunning() && ithread->startOrder(0==order)
      threads_[ithread]->start(arg)
      //Check the error code from the start function

GenericTask< Msg >::pingthreads(void* arg)
  for( ithread in threads_ )
    if( ithread->isPingable() )
      ithread->setRunState(false)
      ithread->ping(arg)

GenericTask< Msg >::getThread(string name) returns Thread*
  for( ithread in threads_ )
    if( ithread->matchName(name)
      return threads_[ithread]

Signals and Timers

GenericTask< Msg >::installTimer(Msg* msg)
  {}

GenericTask< Msg >::installSignal(Msg* msg)
  {}

GenericTask< Msg >::enableTimer(Msg* msg)
  {}

GenericTask< Msg >::enableHandler(Msg* msg)
  {}

GenericTask< Msg >::shutdownConnection(int fd)
  if(fd >=0)
    fdSet_.clear(fd)
    : : shutdown(fd, 2)
    : : close(fd)

GenericMasterTask.h

gcp::util::GenericMasterTask
derrived from GenericTask
Fields:
  - SignalTask* signal_
Methods:
  - processTaskMsg(bool* stop)
  - sendInstallTimerMsg(std::string name, int sigNo, unsigned long intervalSec, unsigned long intervalNsec, SIGNALTASK_HANDLER_FN(* handler))
  - virtual void installTimers() // Install timers
  - sendInstallSignalMsg(int sigNo, SIGNALTASK_HANDLER_FN(* handler))
  - installSignal(Msg* msg) // Respond to a message to install a signal
  - virtual void installSignals()
  - void sendEnabletimerMsg( string name, bool enable )
  - void enabletimer(Msg* msg)
  - void sendAddHandlerMsg(string name, SIGNALTASK_HANDLER_FN(* handler), bool add)
  - void addHandler(Msg* msg)

GenericMasterTask::constructor()
  call GenericTask< Msg >::constructor()
  signal_ = 0

GenericMasterTask::processTaskMsg(bool* stop)
  Msg msg
  GenericTask< Msg >::msgq_.readMsg(&msg)
  switch( msg.genericMsgType_)
  case Msg::HEARTBEAT
    genericTask< Msg >::respondToHeartBeat()
  case Msg::RESTART
    GenericTask< Msg >::restart()
  case Msg::STOP
    * stop = true
  default:
    GenericMasterTaskMsg::GenericMasterMsgType type =
      (GenericMasterTaskMsg::GenericMasterMsgType)msg.genericMsgType_
    switch(type)
    case Msg::INSTALL_TIMER
      installTimer(&msg)
    case Msg::INSTALL_SIGNAL
      installSignal(&msg)
    case Msg::ADD_HANDLER
      addHandler(&msg)
    case Msg::ENABLE_TIMER
      enableTimer(&msg)
    default:
      processMsg(&msg)

GenericMasterTask< Msg >::sendInstallTimerMsg(std::string name, int sigNo, unsigned long initSec, unsigned long intervalSec, SIGNALTASK_HANDLER_FN(* handler)
  Msg msg
  msg. packInstallTimerMsg(name, sigNo, initSec, intervalSec, handler)
  sendTaskMsg(&msg)

GenericMasterTask< Msg >::installTimer(Msg* msg)
  if(signal_!=0)
    signal_->sendInstallTimerMsg(msg->internal stuff)

GenericMasterTask< Msg >::installTimers()
  {}

GenericMasterTask< Msg >::sendInstallSignalMsg(int sigNo, SIGNALTASK_HANDLER_FN(* handler))
  Msg msg
  msg.packInstallSignalMsg(sigNo, handler)
  sendTaskMsg(&msg)

GenericMasterTask< Msg >::installSignal(Msg* msg)
  if(signal_)
    signal_->sendInstallSignalMsg(msg->...sigNo, msg->...handler)

GenericMasterTask< Msg >::installSignals()
  {}

GenericMasterTask< Msg >::sendEnabletimerMsg(std::string name, bool enable)
  Msg msg
  msg.packEnableTimerMsg(name, enable)
  sendTaskMsg(&msg)

GenericMasterTask< Msg >::sendAddHandlerMsg(std::string name, SIGNALTASK_HANDLER_FN(* handler), bool add)
  Msg msg
  msg.packAddhandlerMsg(name, handler, add)
  sendTaskMsg(&msg)

GenericMasterTask< Msg >::enableTimer(Msg* msg)
  if(signal_ !=0)
    signal_->sendEnableTimerMsg(msg->...name, msg->...enable)

GenericMasterTask< Msg >::addHandler(Msg* msg)
  if(signal_ !=0)
    signal_->sendAddHandlerMsg(msg->...name, msg->...handler, msg->...add)

GenericTaskMsg.h

gcp::util::GenericTaskMsg
Fields:
  - enum GenericMsgType { HEEARTBEAT, STOP, RESTART, TASK_SPECIFIC, LAST }
  - GenericMsgType genericMsgType
Methods:
  - SIGNALTASK_HANDLER_FN(fn) void (fn)(int sigNo, void* args)

GenericMasterTaskMsg.h

gcp::util::GenericMasterTaskMsg
derrived from GenericTaskMsg
Fields:
  - enum GenericMasterMsgType { ADD_HANDLER, ENABLE_TIMER, INSTALL_TIMER, INSTALL_SIGNAL, TASK_SPECIFIC }
  - union genericMasterBody {
      struct installTimer {
        char name[SIGNAL_NAME_LEN+1];
        int sigNo;
        unsigned long initSec;
        unsigned long initNsec;
        unsigned long intervalSec;
        unsigned long intervalNsec;
        SIGNALTASK_HANDLER_FN(* handler);
      }
      struct installSignal {
        int sigNo;
        SIGNALTASK_HANDLER_FN(handler);
        void
args;
      }
      struct enableTimer {
        char name[SIGNAL_NAME_LEN+1];
        bool enable;
      }
      struct addHandler {
        char name[SIGNAL_NAME_LEN+1];
        SIGNALTASK_HANDLER_FN(handler);
        void
args;
        bool add;
      }
    }
Methods:
  - void packInstallTimerMsg(std::string name, int sigNo, unsigned long initSec, unsigned long initNsec, unsigned long intervalSec, unsigned long intervalNsec, SIGNALTASK_HANDLER_FN(* handler))
  - void packInstallSignalMsg(int sigNo, SIGNALTASK_HANDLER_FN(* handler))
  - void packEnableTimerMsg(string name, bool enable)
  - void packAddhandlerMsg(string name, SIGNALTASK_HANDLER_FN(* handler), bool add)

GenericMasterTaskMsg::packInstallTimerMsg(name, sigNo, initSec, initNsec, intervalSec, intervalNsec, handler)
  genericMsgType_ = (GenericTaskMsg::GenericMsgType) gcp::util::GenericMasterTaskMsg::INSTALL_TIMER
  strncpy( genericMasterBody.installTimer.name, name.c_str(), SIGNAL_NAME_LEN)
  genericMasterBody.installTimer.sigNo = sigNo;
  genericMasterBody.installTimer.initSec = initSec;
  genericMasterBody.installTimer.initNsec = initNsec;
  genericMasterBody.installTimer.intervalSec = intervalSec;
  genericMasterBody.installTimer.intervalNsec = intervalNsec;
  genericMasterBody.installTimer.handler = handler

GenericMasterTaskMsg::packInstallSignalMsg(int sigNo, SIGNALTASK_HANDLER_FN(* handler))
  genericMsgType_ = (GenericTaskMsg::GenericMsgType) gcp::util::GenericMasterTaskMsg::INSTALL_SIGNAL
  genericMasterBody.installSignal.sigNo = sigNo
  genericMasterBody.installSignal.handler = handler

GenericMasterTaskMsg::packEnableTimerMsg(string name, bool enable)
  genericMsgType_ = (GenericTaskMsg::GenericMsgType) gcp::util::GenericMasterTaskMsg::ENABLE_TIMER
  strncpy(genericMasterBody.enableTimer.name, name.c_str(), SIGNAL_NAME_LEN)
  genericMasterBody.enableTimer.enable = enable

GenericMasterTaskMsg::packAddHandlerMsg(string name SIGNALTASK_HANDLER_FN(* handler), bool add)
  genericMsgType_ = (GenericTaskMsg::GenericMsgType) gcp::util::GenericMasterTaskMsg::ADD_HANDLER
  strncpy(genericMasterBody.addHandler.name, name.c_str(), SIGNAL_NAME_LEN)
  genericMasterBody.addHandler.handler = handler
  genericMasterBody.addHandler.add = add

SignalTask

gcp::util::SignalTask
Classes:
  - TimerInfo
  - SignalHandler

Fields:
  - struct HandlerPair
  - sigset_t handledsignals_ // The set of signals handled by this task.
  - sigIo_ // A signal we will watch to indicate that an I/O event has arrived on our message queue
  - pthread_t id_ // The id of the thread which instantiated this object
  - static SignalTask* signaltask_ // A static pointer, for use in static functions.
  - vector< TimerInfo* > timers_ // A vector of timer information
  - Thread* spawnedThread_ // If this object is spawned in a separate thread, we will use a Thread container to mange it.
  - bool spawned_ // True if this object is spawned in a separate thread
  - vector< SignalHandler* > signalHandlers_ // A vector of SignalHandler objects, which stores functions to be called on a receipt of a signal.
Methods:
  - sendInstallTimerMsg()
  - sendAddHandlerMsg()
  - sendInsgallSignalMsg(int sigNo, SIGNALTASK_HANDLER_FN(* handler), void* arg=NULL)
  - sendEnableTimerMsg()
  - stopTimers()
  - getIoSig()
  - run()
  - serviceMsgQ()
  - THREAD_START(startUp) // A startup function for the spawned thread
  - installTimer(SignalTaskmst* msg) // Respond to a message to install a timer
  - installTimer(name, sigNo, initSec, initNsec, intervalSec, intervalNsec, SIGNALTASK_HANDLER_FN(* handler)
  - addHandler(name, SIGNALTASK_HANDLER_FN(* handler), void* args=NULL)
  - removeHandler(name, SIGNALTASK_HANDLER_FN(* handler) )
  - SignalHandler* gethandler(int sigNo)
  - timerInfo* getTimer()
  - installSignal(SignalTaskMsg* msg)
  - installSignal(int sigNo, SIGNALTASK_HANDLER_FN(* handler), void* arg=NULL)
  - void addHandler(int sigNo, SIGNALTASK_HANDLER_FN(* handler), void* args=NULL)
  - void removeHandler(int sigNo, SIGNALTASK_HANDLER_FN(* handler))
  - void enableTimer(SignalTaskMsg* msg)
  - void startTimer(std::string name)
  - void stopTimer(std::string name)
  - void startTimers()
  - void processTaskMsg(bool* stop)
  - static SIGNALTASK_HANDLER_FN(checkMsgQ)
  - void fwdTaskMsg(SignalTaskMsg* msg)

SignalTask::constructor
  id_ = pthread_self()
  sigIo_ = SIGNALTASK_IO_SIGNAL
  installSignal(sigIo_, &checkMsgQ)

SignalTask::installTimer(name, sigNo, initSec, initNsec, intervalSec, intervalNsec, SIGNALTASK_HANDLER_FN(* handler) )
  // First check if a timer already exists for this signal. If so, throw an Error.
  // now check if a handler already exists for this signal. If so, throw an Error.
  //Now add a new element to the vector of timers managed by this task.
  TimerInfo* timer = new TimerInfo(name, sigNo, initSec, initNsec, intervalSec, intervalNsec)
  timers_.pushback(timer)
  // Add a new element to the vector of handlers managed by this task
  signalHandlers_.push_back(timer)
  // Add this signal to the set of signals handled by this task
  sigaddset(&handledSignals_, sigNo)

SignalTask::addHandler(string name, SIGNALTASK_HANDLER_FN(* handler), void* args)
  for( timer in timers_ ) // find the timer by name if it exists
    timerInfo* tptr = * timer
    if(tptr->name_ == name)
      Signalhandler* sigHandler = gethandler(tptr->sigNo_) // Get the handler corresponding to this timer's signal
      unsigned nPrev = sigHandler->handlers_.size()
      sigHandler->addHandler( handler, args )
        handlers_.push_back( HandlerPair(handler, args) )
      if(nPref==0 && tptr->enabled_)
        tptr->timer_->start()

SignalTask::installSignal(int sigNo, SIGNALTASK_HANDLER_FN(* handler), void* args)
  signalHandlers_.pushback( new SignalHandler(sigNo, handler, args) )
  sigaddset(&handlerSignals_, sigNo)

SignalTask::run() // overview
  wait for next catchable signal, which is signifiec by sigNo
  find signalHandler in vector that has matching sigNo
    for each handler in vector handlers_
      if it is not null, call handler(sigNo, args)

SignalTask::run() // details
  int sigNo // A received signal.
  while(true) // Wait for the next catchable signal to be sent to the process.
    // Note that sigwait() atomically unblocks the specified signals
    // while it is waiting and reblocks them before returning, so
    // there is no danger of missing any signals that are delivered
    // between each call to sigwait().
    sigwait(&handledsignals_, &sigNo)
    for( isig in signalHandlers_.size() )
      if(sigNo == signalHandlers_[isig]->sigNo_)
        signalHandlers_[isig]-> reArm() // Rearm any periodic timer associated with this signal.
          AbsTimer::reArm()
            // This does nothing unless the timer is periodic.
            if(integral_ && periodic_ && reArm_)
              unsigned long sec = targetSec_ + intervalSec_
              unsigned long nsec = targetNanoSec_ + intervalNanoSec_
              fix(sec, nsec, sec, nsec) // Shift time intervals around so that nsec arg is always < NSEC_PER_SEC
              setFutureTime(sec, nsec, 0, 0)
              targetSec_ = sec
              targetNanoSec_ = nsec
        //End reArm()
        for(ihand in signalHandlers_ ) // Iterate through any handlers which have been installed
          if this handler is not NULL
            SIGNALTASK_HANDLER_FN(* handler) = signalHandlers_[isig]->handlers_[ihand].handler_
            void* args = signalHandlers_[isig]->handlers_[ihand].args_
            try{ handler(sigNo, args) }
        break // Found the handler for this signal
      //End if(sigNo==
    //End for(isig)
  //End while(true)

SIGNALTASK_HANDLER_FN(SignalTask::checkMsgQ)
  signaltask_->serviceMsgQ()

SignalTask::serviceMsgQ()
  int fd = msgq_.fd()
  TimeVal timeout(0,0,0) // This timeout causes select() to return immediately
  fd_set rfds = msgq_.rfds()
  //Loop, checking the message queue file descriptor for readibility
    //If no file descripters wre ready, throw an exception
    processTaskMsg(&stop)

SignalTask::processTaskMsg(bool* stop)
  SignalTaskMsg msg
  msgq_.readMsg(&msg)
  switch (msg.type)
  case SignalTaskMsg::ADD_SIGNAL_HANDLER
    if(msg.body.addSignalHandler.add)
      addHandler(msg.body.addSignalHandler.sigNo, msg.body.addSignalHandler.handler)
    else
      removeHandler(msg.body.addSignalHandler.sigNo, msg.body.addSignalHandler.handler)
  case SignalTaskMsg::ADD_TIMER_HANDLER
    if(msg.body.addTimerHandler.add)
      addHandler(msg.body.addTimerHandler.name, msg.body.addTimerHandler.handler)
    else
      removeHandler(msg.body.addTimerHandler.name, msg.body.addTimerHandler.handler)
  case SignalTaskMsg::SIG_INSTALL_TIMER
    installTimer(&msg)
  case SignalTaskMsg::SIG_INSTALL_SIGNAL
    installSignal(&msg)
  case SignalTaskMsg::SIG_ENABLE_TIMER
    enabletimer(&msg)

TimerInfo

gcp::util::TimerInfo gcp/util/common/SignalTask.h
Fields:
  - sigNo_ // the signal to handle
  - initSec_ // The initial delay, (sec) of this timer
  - initNsec_ // The initial delay, (nanosec) of this timer
  - intervalSec_ // The interval (sec) of this timer
  - intervalNsec_
  - string name_ // A name for this timer
  - bool enabled_
  - AbsTimer* timer_ // The timer
Methods:
  - reArm()

SignalHandler

gcp::util::SignalHandler gcp/util/common/SignalTask.h // A class to manage signal handlers for all signals
Fields:
  - int sigNo_ // the signal to handle
  - struct HandlerPair{
    HandlerPair( SIGNALtASK_HANDLER_FN(* handler), void* args) {
      handler_ = handler
      args_ = args
    }
    SIGNALTASK_HANDLER_FN(* handler)
    void* args_
    }
  - vector< HandlerPair > handlers_ // A vector of handlers to call when this signal is received
  - TimerInfo* timer_ // A TimerInfo object associated with this signal
Methods:
  - reArm() // Re-arm any periodic timer associated with this handler
  - addhandler( SIGNALTASK_HANDLER_FN(* handler), void* arg=NULL ) // Add a handler to the set attached to this signal
  - removeHandler( SIGNALTASK_HANDLER_FN(* handler) )

SignalHandler::constructor(int sigNo, SIGNALTASK_HANDLER_FN(* handler), void* args)
  handlers_.push_back( HandlerPair(handler, args) )

Thread of gcp/util/common/

gcp::util::Thread : gcp/util/common/Thread.h, cc
Fields:
  - unsigned startOrder_
  - unsigned cancelOrder_
  - pthread_attr_t attr_
  - void* startupArg_
  - bool running_
  - pthread_mutex_t runningGuard_
  - pthread_t id_
  - pthread_mutex_t guard
  - pthread_cond_t cond // Variable which we will use to signal other threads
  - CondVar ready_ // Indicate that the thread has allocated its resources adn is ready for communication.
  - CondVar done_ // Indicate that the thread has deallocated its resources and is ready to exit
  - string name_
Methods:
  - THREAD_START
  - THREAD_STOP
  - TRHEAD_CLEAN
  - THREAD_PING
  - INSTALL_MUTEX_CLEANUP
  - UNINSTALL_MUTEX_CLEANUP
  - start(void* arg)
  - cancel()
  - ping()
  - broadcastReady()
  - broadcastDone()
  - setRunState(bool state)
  - matchName(string compname)
  - string strName()
  - isRunning()
  - isPingable()
  - raise(int signNo) // Raise a signal to this thread

AbsTimer of gcp/util/common/

Sub classes:
TimerId
  - timer_t* timer_
  - int sigNo_ // Signal associated with this timer

TimerId_eq : public std::unary_function< TimerId, bool >
  - timer_t* timer_
  - bool operator()

Timersig_eq : public std:unary_function< TimerId, bool >
  - int sigNo_
  - bool operator()
Fields:
  - std::list< TimerId > timerList_ // A static list of timers. Added to by addTimer()
  - bool reArm_
  - bool isRunning_
  - bool integral_
  - bool periodic_
  - int sigNo_
  - timer_t timer_ // the id of this timer
  - struct sigevent evp_ // container for managing the action to take on expiry of this timer
  - long targetSec_ // Number of seconds in the target time
  - long targetNanoSec_
  - long initSec_ // number of seconds before the initial expiry of the timer
  - long initNanoSec_
  - long intervalSec_
  - long intervalNanoSec_

Methods:
  - long getResolution() // Returns the resolution of the clock in nanosec
  - void setInitialDelay(long sec, long, nsec) // Set initial deal when timer is to start from the moment its start() method is called
  - void setIntervalDelay(long sec, long nsec) // Set interval delay for timer
  - void reArm() // Re-arm a periodic timer which we want to fire relative to absolute second boundaries
  - void start(bool rearm = false) // start the timer.
  - void start(long sec, long nsec) // Set a timer to go off at the specified absolute time
  - void stop()
  - bool isRunning()
  - void setIntegral(bool integral) // Set whether this clock should run on integral second boundaries relative to current time
  - void checkTimer()
  - void fix(inSec, inNsec, long& outSed, long& outNsec) // Shift time intervals around so that nsec arg is always < NSEC_PER_SEC
  - addTimer(timer_t* timer, int signo)
  - void remTimer(timer_t* timer)
  - timerAlreadyExists(int sigNo)
  - void setFutureTime(long initSec, initNanoSec, intervalSec, intervalNanoSec) // Set up a timer to go off at a future time.

NetHandler of gcp/util/common

NetHandler
Fields:
  - int fd_
  - NetReadStr* nrs_
  - NetSendStr* nss_
  - unsigned readBufSize_
  - unsigned sendBufSize_
Methods:
  - attachReadStream(int fd) // Attach the network I/O stream to a socket.
  - attachSendStream(int fd) // Attach the network I/O stream to a socket.
  - attach(int fd) // Attach all streams to the same socket
  - virtual int getReadFd() // Overwritable method for returning the read fd
  - virtual int getSendFd()
  - virtual int getFd() // Method for returning a single fd.
  - void sendreadBuffer(void* buffer, unsigned int size) // Set the network buffer pointing to an external buffer, or pass buffer=NULL to dynamically allocate it.
  - setSendBuffer(void* buffer, unsitned int size)
  - NetSendId send() // Send a message packed into our network buffer to a socket described by a previously attached fd.
  - NetSendId send(int fd) // Send a message packed into our network buffer to the specified socket.
  - NetReadId read() // Read a message into our network buffer from a socket described by a previously attached fd.
  - NetReadId read(int fd)
  - NetReadStr* getReadStr() // Return a pointer to our read stream
  - NetSendStr* getSendStr() // Return a pointer to our send stream
  - virtual void installReadHandler((NET_READ_HANDLER(* handler), void* arg)
  - virtual void installReadErrorHandler(NET_ERROR_HANDLER(* handler))
  - virtual void installSendHandler(NET_SEND_HANDLER(* handler), void* arg)
  - virtual void installSendErrorHandler(NET_ERROR_HANDLER(* handler))
  - virtual void installErrorHandler(NET_ERROR_HANDLER(* handler), void* arg)
  - unsigned readBufSize()
  - unsigned sendBufSize()
  - void initizlize()

NetHandler::constructor(int fc)
  initizlize()
  attach(fd)

NetHandler::initizlize()
  fd_ = -1
  nrs_=0
  nss_=0
  nrs_ = new NetReadStr(-1, 0)
  nss_ = new NetSendStr(-1, 0)

NetHandler::attach(int fd)
  fd_ = fd
  nrs_->attach(fd)
  nss_->attach(fd)

NetMsgHandler of gcp/util/common

NetMsgHandler
derrived class of NetHandler
Fields:
  - ArrayMap* arraymap_
  - gcp::util::NetMsg lastReadNetMsg_
  - gcp::util::NetMsg lastSentNetMsg_
  - void* userReadArg_
  - void* userSendArg_
  - void* userErrorArg_
Methods:
  - NetSendId sendNetMsg(gcp::util::NetMsg* msg)
  - NetSendId sendNetMsg(int fd, gcp::util::NetMsg* msg)
  - void packNetMsg(gcp::util::NetMsg* msg) // Pack a network message into the network buffer.
  - bool packNetRtcNetMsg(NetMsg* msg) // Pack a new-syle network message into our send buffer.
  - void packGreetingMsg(unsigned int antenna)
  - void packAntennaIdMsg(unsigned int antenna)
  - readNetMsg() // Read a net message out of the network buffer
  - void installReadHandler(NET_READ_HANDLER(* handler), void* arg)
  - installSendHandler(NET_SEND_HANDLER(* handler), void* arg)
  - installErrorHandler(NET_ERROR_HANDLER(* handler), void* arg)
  - static NET_READ_HANDLER(readHandler)
  - NET_READ_HANDLER(* userReadHandler_)
  - static NET_SEND_HANDLER(sendHandler)
  - NET_SEND_HANDLER(* userSendHandler_)
  - static NET_ERROR_HANDLER(errorHandler)
  - NET_ERROR_HANDLER(* userErrorHandler_)

NetMsgHandler::constructor()
  call NetHandler constructor()
  arraymap_=0
  Set the user handlers to NULL
  gcp::control::RtcNetMsg netMsg
  unsigned bufferSize = NET_PREFIX_LEN + netMsg.size()
  setReadBuffer(NULL, bufferSize)
  setSendBuffer(NULL, bufferSize)
  // Install our handlers as the default handlers
  NetHandler::installReadHandler(readHandler, this)
  NetHandler::installReadErrorHandler(errorHandler, this)
  NetHandler::installSendHandler(sendHandler, this)
  NetHandler::installSendErrorHandler(errorHandler, this)

NetMsgHandler::sendNetMsg(int fd, NetMsg* msg)
  LogStream ls
  if(nss_->state() != NetSendStr::NET_SEND_DONE)
    ls.appendMessage(true, "Last message wasn't completely sent")
    throw Error(ls)
  packNetMsg(msg)
  return NetHandler::send(fd)

NetMsgHandler::packNetMsg(NetMsg* msg)
  lastSentNetMsg_ = * msg
  nss_->startPut(msg->type)
  nss_->putInt(1, &msg->body.antenna)
  nss_->putObj(&rtc_msg_table, msg->type, (void* )&msg->body.msg)
  nss_->endPut()

NetMsgHandler::packGreetingMsg(unsigned int antenna)
  AntNum antNum(antenna);
  std::string regMapName = antNum.getAntennaName()
  RegMap* regmap = arraymap_->findRegMap(regMapName)
  if(regmap == 0)
    throw errors
  NetMsg netMsg
  netMsg.packGreetingMsg(antenna, REGMAP_PREVISION, regmap->nreg_, regmap->nByte_)
  packNetMsg(&netMsg)

NetMsgHandler::readNetMsg()
  nrs_->startGet((int* )&lastReadNetMsg_.type
  nrs_->getInt(1, &lastReadNetMsg_.body.antenna)
  nrs_->getObj(&rtc_msg_table, lastReadNetMsg_.type, &lastReadNetMsg_.body.msg)
  nrs_->endGet()

AntNum of gcp/util/common

AntNum
enum Id { ANTNONE=0, ANTO=1, ANT1=2, ANT2=4, ANT3=8, ANT4=16, ANT5=32, ANT6=64, ANT7=128, ANTMAX=ANT7, ANTALL = }
Fields:
  - static const unsigned int NANT = 8
  - static const unsigned int NBASE = (NANT*(NANT-1))/2
  - Id id_
Methods:
  - bool isValidSingleAnt()
  - static bool isValidSingleAnt(Id antId)
  - string getObjectName()
  - string getEventChannelName()
  - string getAntennaName()
  - string getString() // Return a string representation of this antenna set
  - string getLoggerPrefix()
  - unsigned int getDelayEngineIntId()
  - unsigned int getIntId()
  - Id getId()
  - unsigned short getDcAntennaIndex()
  - unsigned short getDcNodeIndex()
  - unsigned int getAntMax()
  - void set(AntNum::Id id)
  - bool isSet(unsigned id), (AntNum::Id id), (AntNum& antNum), (AntNum* antNum)
  - bool setId(AntNum::Id), (unsigned int id), (const AntNum& antNum)
  - void setIdFromHost()
  - static AntNum::Id intToId(unsigned int iant) // Convert from integer index to enumerator
  - static unsigned idToInt(AntNum::Id id)
  - string printAntennaSet()
  - string printAntennaSet(AntNum::Id id)
  - operator [ +, <, <, >, >, ==, ++,


RegMap definitions

RegMapDataFrameManager: gcp/util/RegMapDataFrameManager

Derrived class of DataFrameManager
Fields:
  - ArrayMap* arrayMap_
  - RegMap* regMap_
Methods:
  - writeBoard(...)
  - writeReg(...)
  - writeRegNoLock(...)
  - readReg(...)
  - readRegNoLock(...)
  - unsigned int getId()
  - void setMjd(...)
  - void setReceived()
  - RegMapBlock* findReg(char( boardName, char* blockName)
  - int byteOffsetInFrameOf(...)
  - void packData(...)
  - unpackData(...)
  - checkType(...)
  - RegMapBlock* getReg(board, block)

12/12

Connection from Antenna to Monitor

Antenna Layer: AntennaMonitor

In the AntennaMonitor initialization process, it calls
AntennaMonitor::connect()
  client_.connectToServer( parent->host, TRANS_ANT_SCANNER_PORT, true)
    TRANS_ANT_SCANNER_PORT is defined in util/common/Ports.h
    fd_ = tcp_connect( (char* ) host_.c_str(), port_, true)
  netMsgHandler_.attach( client_.getFd() )
  other netMsgHandler_ stuff
  fdStet_.registerReadFd( client_.getFd() ) // register the socket to be watched for input
  sendAntennaIdMsg()
    netMsgHandler_.packAntennaIdMsg( parent_->getAnt()->getIntId() )
      NetMsg netMsg
      netMsg.packAntennaIdMsg( intId )
        type = ID
        body.antenna = id
      packNetMsg(&netMsg)
        nss_->startPut(...) etc.
        nss->endPut()
    fdSet_.registerWriteFd( netMsgHandler_.getSendFd() )

Mediator Layer: AntennaConsumerNormal

On the Mediator side, we are sitting in the serviceMsgQ loop, waiting for a connection request message to arrive.
AntennaConsumerNormal::serviceMsgQ()
  listen(true)
  fdSet_.isSetInRead( listener->getFd() == 1)
  initializeConnection()
    fd = listener_-> acceptConnection()
      TcpListener::acceptConnection()
        int addr_len
        int fd
        LogStream errStr
        addr_len = (int) sizeof(client_addr)
        fd = accept(fd_, (struct sockaddr * ) &client_addr, (socklen_t* )&addr_len)
        //deal with errors
        tcp_set_blocking( fd, blocking )
        return fd
    //Attach this file descriptor to the temporary connection handler
    temporaryHandler_.getNetMsgHandler()-> attach(fd) // NetCommHandler::getNetMsgHandler() returns NetMsgHandler (derrived from NetHandler)
      NetHandler::attach()
        fd_ = fd
        nrs_->attach(fd)
        nss_->attach(fd)
          attach_NetSendStr(netStream_, fd)
            // Method of netbuf.h
    //Register a handler to be called when a network msg is received.
    //On receipt we will send a greeting message with the register map revision and byte count.
    temporaryHandler_.getNetMsgHandler()-> installErrorHandler(netMsgErrorHandler, 0)
      nrs->installErrorHandler(handler, arg)
      nss_->installErrorHandler(handler, arg)
    fdSet_.registerReadFd(fd)
    listen(false) // Stop listening for further connections until this antenna has responded

Antenna Layer: AntennaMonitor

On Antenna Side, connect() is followed by sendScannerConnectedMsg(true):
AntennaMonitor::sendScannerConnectedMsg(true)
  AntennaMasterMsg msg
  msg.pckScannerConnectedMsg(connected)
    genericMsgType_ = TASK_SPECIFIC
    type = SCANNER_CONNECTED
  parent_-> forwardMasterMsg(&mst)
    master_-> sendTaskMsg(msg) // GenericTask, send msg to MsgQ
      GenericTask::serviceMsgQ()
        GenericMasterTask::processTaskMsg()
          case default:
          AntennaMaster::processMsg(msg)
            case SCANNER_CONNECTED
            if(msg->body.scannerConnected.connected)
              GenericMasterTask::sendAddHandlerMsg("connect", &sendConnectScannerMsg, false)
                AntennaMasterMsg msg
                msg.packAddHandlerMsg("connect", &sendConnectScannerMsg, false)
                  genericMsgType_ = ADD_HANDLER
                  genericMasterBody.addHandler.name = "connect"
                  genericMasterBody.addHandler.handler = &sendConnectScannerMsg
                  genericMasterBody.addHandler.add = false
                sendTaskMsg(&msg)
                  GenericTask::serviceMsgQ()
                    GenericMasterTask::processTaskMsg()
                      case ADD_HANDLER
                        addHandler(&msg)
                          signal-> sendAddHandlerMsg( name, handler, add)
                            SignalTaskMsg msg
                            msg.packAddHandlerMsg(name, handler, add)
                              genericMsgType_ = TASK_SPECIFIC
                              type = ADD_TIMER_HANDLER
                              body.addTimerHandler.name = name
                              body.addTimerHandler.handler = handler
                              body.addTimerHandler.add = add
                            fwdTaskMsg(&msg)
                              SignalTask::serviceMsgQ()
                                SignalTask::processTaskMsg()
                                  msg.body.addTimerHandler.add=false
                                  removeHandler("connect",&sendConnectScannerMsg)
                                    loop over handlers_ to find hand=&sendConnectScannerMsg
                                    handlers_.erase(hand)

Mediator Layer: AntennaConsumerNormal

Somehow, receiving the sendAntennaIdMsg() call from the Antenna layer calls the following function:
AntennaConsumerNormal::NET_READ_HANDLER(AntennaConsumerNormal::netMsgReadHandler)
  NetMsg* netMsg = consumer_->termporaryHandler_.getLastReadNetMsg()
  switch(netMsg->type)
  case NetMsg::ID
    consumer_->finalizeConnection()
      NetMsg* netMsg = temporaryHandler_.getLastReadNetMsg()
      unsigned int antennaId = netMsg->body.antenna
      AntNum antNum(antennaId);
      int fd = temporaryHandler_.getFd()
      if(antNum.isValidSingleAnt() )
        temporaryHandler_.getNetMsgHandler()-> installSendHandler(netMsgSentHandler, 0)
        userSendHandler_ = handler [netMsgSendHandler]

> userSendArg_ arg [0] > **sendGreetingMsg()** > NetMsg* netMsg temporaryHandler_.getLastReadNetMsg()

        unsigned int antennaId = netMsg->body.antenna
        temporaryHandler_.getNetMsgHandler()-> packGreetingMsg(antennaId)
          NetMsgHandler::packGreetingMsg(unsigned int antenna)
            AntNum antNum(antenna)
            string regMapNae = antNum.getAntennaName()
            RegMap* regmap = arraymap_->findRegMap(regMapName)
            if (regmap==0) log errors
            NetMsg netMsg
            netMsg.packGreetingMsg(antenna, REGMAP_PREVISION, regmap->nreg_,retmap->nByte_)
              type = GREETING
              body.antenna = id [antenna]

> body.msg.greeting.revision revision [REGMAP_PREVISION] > body.msg.greeting.nReg nReg

              body.msg.greeting.nByte = nByte
            packNetMsg(&netMsg)
              lastSentNetMsg_ = msg
              nss_->startPut(), ..., endPut()
        
*fdSet_.registerWriteFd(temporaryHandler_.getFd() )**
          AntennaConsumerNormal::serviceMsgQ()
            fdSet_.isSetInWrite( temporaryHandler_.getNetMsgHandler()->getSendFd()) == 1
            temporaryHandler_.sendNetMsg()
              NetCommHandler::sendNetMsg()
                return netMsgHandler_.send()
                  NetHandler::send()
                    return nss_->send()
                      This calls the sendHandler_

AntennaConsumerNormal::NET_SEND_HANDLER(AntennaConsumerNormal::netMsgSentHandler)
See below.

Antenna Layer : AntennaMonitor

AntennaMonitor::serviceMsgQ()
  FdSet_.isSetInRead(netMsgHandler_.getReadFd())==1
  netMsgHandler_.read()
    NetHandler::read()
      return nrs_->read()

This now calls:
AntennaMonitor::NET_READ_HANDLER(AntennaMonitor::netMsgReadHandler)
  AntennaMonitor* scanner = arg
  NetMsgHandler* handler = &scanner->netMsgHandler_
  NetMsg* msg = handler->getLastReadNetMsg()
  switch(msg->type)
  case NetMsg::GREETING
    scanner->parseGreetingMsg(msg)
      Throw an error if:
        msg->body.msg.greeting.revision != REGMAP_REVISION or
        msg->body.msg.greeting.nReg != parent_->getShare()->getNreg() or
        msg->body.msg.greeting.nByte != parent_->getShare()->getNbyte()
      netDataFrameHandler_.attachSendStream(netMsgHandler_.getReadFd())
        nss_->attach(fd)
      netDataFrameHandler_.installSendHandler(netDataFrameSentHandler, this)
      netDataFrameHandler_.installSendErrorHandler(netErrorHandler, this)
      fdSet_.clearFromReadFdSet(netMsgHandler_.getReadFd())
      netMsgHandler_.attachReadStream(-1)
      connectionPending_ = false



Mediator Layer : AntennaConsumerNormal

From the nss_->send() of the greeting messate, the following gets called:
AntennaConsumerNormal::NET_SEND_HANDLER(AntennaConsumerNormal::netMsgSentHandler)
  COUT("Calling netMsgSentHandler")
  NetMsg* netMsg = consumer_->temporaryHandler_.getNetMsgHandler()->getLastSentNetMsg()
  AntNum antNum(netMsg->body.antenna)
  // Get the handler we will use for communicating with this antenna
  NetAntennaDataFrameHandler* handler = consumer_->connectedHandlers_[antNum.getIntId()];
  consumer_-> terminateConnection(handler)
    terminateConnection(handler->getNetMsgHandler())
      shutdownConnection(handler->getReadFd())
        fdSet_.clear(fd)
        : : shutdown(fd, 2)
        : : close(fd)
      shutdownConnection(str->getSendFd())
      str->attach(-1)
    terminateConnection(handler->getNetCmdHandler())
      blah
  handler-> attachReadStream(consumer_->temporaryHandler_.getFd())
  // Install a handler to be called when a data frame has been completely read
  handler-> installReadHandler(netAntennaDataFrameReadHandler, handler)
  handler-> installReadErrorHandler(netAntennaDataFrameErrorHandler, handler)
  handler->setAnt(antNum.getId())
  consumer_-> fdSet_.clearFromWriteFdSet(consumer_->temporaryHandler_.getSendFd())
  consumer_->temporaryHandler_.attachSendStream(-1)
  consumer_->listen(true)
  ReportMessage("Scanner connection established to Antenna" << handler->getA\
nt())


Read DataFrame from Antenna in Monitor

Receive message on message queue
AntennaConsumerNormal::serviceMsgQ()
  fdSet_.isSetInRead(msgqFd) == 1
    processTaskMsg(&stop)
??

Write New MceConsumer class

new files:
gcp/mediator/specific/MceConsumer.h
gcp/mediator/specific/MceConsumer.cc

Other Classes I need to define:
NetMceDataFrameHandler

Other Stuff:
TRANS_MCE_SCANNER_PORT
Scanner::packMceFrame()

For Next Time:
  - Check out brand new version of gcp
  - put in new MceConsumer code
  - Edit other files to make sense
  - For now, make Scanner::packMceFrame just write out to a file or something simple.
  - Get it to compile.
  - Write toy MceDaemon, which establishes a connection to the mediator. This will be modeled after the Antenna Connection.

Off to Caltech!!

12/15

At Caltech!!

This morning we set up the gcp computer. It runs fine. However, we don't know the login name and password. Also, we don't know where the PCI card for the Pmac is. So after a delicious lunch from the truck, I am coding for a while.

Modify mediator layer to accomidate MceConsumer.

New Classes:
1) MceConsumer
  - defined in gcp/mediator/specific/MecConsumer.h
2) NetMceDataFrameHandler
  - defined in gcp/util/common/NetMceDataFrameHandler

gcp/mediator/util/MceConsumer

MceConsumer
derrived from GenericTask< ScannerMsg >
Fields:
  - Scanner* parent_
  - static MceConsumer* consumer_
  - gcp::util::TcpListener* listener_
  - gcp::util::NetCommHandler temporaryHandler_
  - NetMceDataFrameHandler* mceDataFrameHandler_
  - gcp::util::TimeVal startTime_
  - gcp::util::timeVal timer_
  - struct timeval* timeOut_
Methods:
  - void connectTcpIp()
  - void serviceMsgQ()
  - void listen(bool listenVar)
  - void initializeConnection()
  - void terminateconnection(gcp::util::NetHandler* str)
  - void terminateConnection(gcp::util::NetCommHandler* str)
  - void finalizeConnection()
  - void sendGreetingMsg()
  - bool timeOut()
  - static NET_READ_HANDLER(netMsgReadHandler)
  - static NET_SEND_HANDLER(netMsgSentHandler)
  - static NET_ERROR_HANDLER(netMsgErrorHandler)
  - static NET_READ_HANDLER(netMceDataFrameReadHandler)
  - static NET_ERROR_HANDLER(netMceDataFrameErrorHandler)

gcp/util/common/NetMceDataFrameHandler

NetMceDataFrameHandler
Fields:
  - MceDataFrameManager frame_;
Methods:
  - MceDataFrameManager* getFrame()

gcp/util/common/MceDataFrameManager

MceDataFrameManager
derrived from RegMapDataFrameManager
Fields:
  - MceDataFrame* mceFrame_
Methods:
  - initialize(bool archiveOnly=false)
  - operator=(RegMapDataFrameManager& fm);
  - operator=(AntennaDataFrameManager& fm);

gcp/util/common/MceDataFrame

MceDataFrame
derrived from DataFrameNormal
Fields:
  -
Methods:
  - operator=(DataFrameNormal& frame);
  - operator=(MceDataFrame& frame);

/gcp/mediator/specific/Scanner

Scanner
New Fields:
  - MceConsumer* mceConsumer_
New Methods:
  - packMceFrame(gcp::util::MceDataFrameManager* frame)
Modified Methods:

Other Changes:
L36
namespace util {
  class MceDataFrameManager
}

L48
    class MceConsumer;

Other changes

util/common/Ports.h
  

TRANS_MCE_SCANNER_PORT 451+PORT_OFFSET

Deal with makefiles

gcp/mediator/specific/Makefile.rules
Add MceConsumer.o: MceConsumer.cc \

In Scanner.o: Scanner.cc
  add MceConsumer.h \

gcp/util/common/Makefiles.rules
Add MceDataFrame.o: MceDataFrame.cc \
Add MceDataFrameManager.o : MceDataFrameManager.cc \
Add NetMceDataFrameHandler.o: NetMceDataFrameHandler.cc \

add MceDataFrameManager.h, MceDataFrame.h
In
  ArcFileConverter.cc
  ArrayDataFrameManager.cc
  ArrayFrameBuffer.cc
  bin_Monitor.cc
  Monitor.cc
  PagerMonitor.cc
  RegCal.cc
  RegDescription.cc
  RegisterSet.cc

Other Classes I need to define:
AntennaFrameBuffer - MceFrameBuffer?

Other Stuff:
ArcFileConverter - modify
ArrayDataFrameManager - modify
ArrayFrameBuffer - modify
util/common/NetMsgHandler
util/common/NetMsg.h new packMceGreetingMsg(), rename old to packAntGreetingMsg()

Compile #1

kstory@spudws2:gcp> make |& less > 12.15.compile

It compiles now, with no major problems, just the normal bugs.

For Tomorrow:
  - get my bicep0 account working again.
  - New cvs branch

12/16

Next:
  - Run it to make sure it still works. -> Done
  -
  - Write a dummy MASDaemon
  - What data formats are being transferred where?
  - Figure out how to make MAS write to a pipe file into MASD

  - Write Mediator layer out to file.
  - Register map stuff in Mediator layer.

Run gcp: It runs no problem.

Email from Steve Benton on PCI connection from Sync Box

Your three cards and a BLASTbus-PCI-snyc cable were shipped today. Hopefully it arrives tomorrow. Right now, you get the first installment of my info dump on how to use them.

The first thing to do (possibly before the cards arrives) is to check out the driver. It comes in two parts: bbcpci controls the PCI communication, and bbcsync deals with timing and frame-sync interrupts. You will have to customize the latter for your purposes. Be warned: you may have trouble compiling on new kernels, but for bbcpci at least I know how to fix it.

My cvs repository is:
:ext:parker.astro.utoronto.ca:/var/cvs
There's an account with same name and password as http://cmb.phys.cwru.edu/spider. (Ask me if you don't know the password.) Under clearinghouse/references/bbus/ that spider site also contains a few documents I wrote a while ago about using the system as a whole. If you're just integrating the PCI card for now, it won't be a lot of use.
Tell me if parker isn't responding, it has unresolved routing issues and sometimes needs poking before it will accept external connections.

Here's a rough guide of what to do next:

1. With the card inserted and at least the power jack on its cable connected, run test_bbcpci. Press enter after it shows you some initial info. If you see non-zero numbers in the second column of this infinite dump, then it's communicating successfully through its loopback. Feel free to send me the output for a double check or if you don't think it's working.

2. Then with the two snyc DV spare jacks connected the third column should be a frame number from the snyc box.

3. Now you're ready to get frame syncs in your program. You could use the ioctl call that test_bbcpci does, but the preferred method is through mcplib's BB_getIndex() method. mcplib is also in my cvs repository, and mostly serves for accessing BLASTbus data.

And that should do it for now.

Initial commit to Subversion on spudwsw

kstory@spudws2:~/work> svn import gcp/ file:///home/kstory/work/svn/gcp

Well, it appears to have worked...

Edit Scanner more.

see Projects -> gcp for BICEP2

Note of interest:
In gcp/mediator/specific/Scanner::initMceResources:
  // We assume here that each antenna has a frame.status register as
  // the first register in its register map. If this changes, as
  // undoubtedly it will, this should be changed accordingly.

arraymap::find_ArrRegMap(ArrayMap* arraymap, string regmap_name)
Defined in gcp/control/code/unix/libunix_src/common/arraymap.c
  Symbol* sym // The symbol container of the board
  sym = find_HashSymbol(arraymap->hash, (char*)regmap_name.c_str())
  if(!sym)
    return NULL
  ArrRegMap* regmap = (ArrRegMap*) sym->data;
  return regmap

For tomorrow:
  - start with Scanner::initMceResources

12/17

Talking with Walt

1) What is the register map format?
2) How does data get from the MAS into the MASD?
  - Pipe file
  - The
  - fopen, fread,
http://developers.sun.com/solaris/articles/named_pipes.html
3) What do we do about the run files?
Pipe run file on a separate pipe into the MASD, where it is read and its values are stored in variables. These vales can then be put into all of the data frames as they are written.
4) How does the sync box fit in?
It is connected to the MCE crate. The sequence number is in the header of each fast-rate data frame coming from the MCE. Thus when a new fast-rate frame is read from the pipe, it can be put into the appropriate slow-rate register based on its header information.
5) Are the sync box numbers serial, i.e. sequential? Walt emailed Steve Benton.
6) How often does the Antenna information need to be sampled?


12/18

View current directories:

kstory@spudws2:~/work> svn list file:///home/kstory/work/svn/gcp/
.gdbinit
11.25
12.15.compile
12.5
20081125_224154.dat
20081125_224557.dat
20081125_224649.dat
CVS/
Doxyfile
Makefile
Makefile_generic
TAGS
antenna/
...

Now check in a new copy:

kstory@spudws2:~/work> svn add gcp file:///home/kstory/work/svn/gcp
svn: '.' is not a working copy
svn: Can't open file '.svn/entries': No such file or directory

Well that failed. Hmm. I think that I needed to re-check out the svn version before it was linked to the svn repository?

Check in current (broken) gcp into subversion

kstory@spudws2:~/work> svn import gcp/ file:///home/kstory/work/svn/gcp12.08 ... kstory@spudws2:~/work> svn list file:///home/kstory/work/svn/gcp12.08 ...

Check the code back out:

kstory@spudws2:~/work> svn checkout file:///home/kstory/work/svn/gcp12.08 gcp/
...

Check the status:

kstory@spudws2:gcp> svn status -v
... shows every file in the entire system.

Understand Register Maps

gcp/control/code/unix/libunix_src/common/arraymap.h

struct ArrRegMap : gcp/control/code/unix/libunix_src/common/arraymap.h
  - char name[]
  - std::string* comment
  - unsitned number // The index of this register map in the parent array map
  - int slot // The start index of this register map in the archive array
  - int iSlot_ // The start index of this register map in the slot array
  - int iArcSlot_ // The start index of this register mpa in the archive slot array
  - int iBypte_ // The sequential byte index of this register map in the array map
  - int iArcByte_ // The sequential byte index of this register map in the archived array map,
                  // or -1 if this register map contains no archived registers in the archive byte array.
  - RegMap* retmap
Methods:
  - int byteOffsetInArcArrayMap()
  - etc

// A structure that is used to encapsulate a single register block from an array map.
struct ArrRegMapReg
  - int regmap
  - RegMapReg reg

// Collect information about all register maps.
struct ArrayMap
  - unsigned ref_count
  - HashMemory* hash_mem
  - std::vector< ArrRegMap* > regmaps // All register maps in this array
  - int nregmap // The number of register maps
  - HashTable* hasl // Symbol table of register maps
  - unsigned nreg // The total number of registers
  - unsigned narchive // The total number of archived registers
  - unsigned nByte_ // The total number of bytes
  - unsigned nArcByte_ // The total number of archived bytes
Methods:
  - byteOffsetInArcArrayMapOf()
  - etc
  - RegMapBlock* findArrayMapBlock(string regmap_name, string board_name) // find the named block
  - RegMapBoard* findArrayMapBoard(regmap_name, board_name, doThrow=false)
  - RegMap* findRegMap(regmap_name, doThrow=false) // find the named register map
  - ArrRegMap* findArrRegMap(RegMap* regmapPtr) // Return the arregmap associated with a register.

int find_ArrRegMapReg(ArrayMap* arraymap, string regmap_name, string board_name, string block_name, RegAspect facet, unsigned index, unsigned n, ArrRegMapReg* arreg)
  ArrRegMap* arregmap=NULL
  RegMap* regmap = NULL
  RegMapBlock* blk=NULL // The register map block that contains the register
  unsigned size // The number of slots per register element
  arregmap = find_ArrRegMap(arraymap, regmap_name)
    blah
  regmap = arregmap->regmap
  // Attempt to locate the specified register by name
  blk = find_RegMapBlock(retmap, board_name, block_name_
    blah
  // Get the number of slots per register element
  switch(facet)
  case REG_PLAIN
    size = 1
    break
  // Check the requested dimensions.
  if( size*(index+n) > blk->nreg_) errors.
  // Fill the return container.
  if( init_ArrRegMapReg( arraymap, arregmap->number, blk->brd_->number,
          blk->number_, index, n ? n : blk->nreg_/size - index,
          facet, arreg) )
    return 1
  return 0

gcp/control/code/unix/libunix_src/common/regmap.h

typedef enum RegAddrMode
  ex: ADDR_A16D08_O, ADDR_A32D16_L

enum RegFlags

// Describe an array of registers
struct RegMapBlock
Fields:
  - RegMapBoard* brd_ // the parent register board
  - unsigned number_ // The index of the block on its parent board
  - char name_[] // The name of the block of registers
  - string* comment_
  - unsigned flags_ // A bit-set of RegFlags enumerators
  - RegAddrMode addr_mode_
  - unsigned location_ // The address of the first register in the VxWorks address-space
  - unsigned ireg_
  - unsigned nreg_ // The total number of elements in the block
  - int slot_ // The start index of the block in the archive array
  - gcp::util::CordAxes* axes_ // An axis specifier for this register
  - int iSlot_ // The sequential slot index of the first register in parent slot array
  - int iArcSlot_ // The sequential slot index of hte first register in the parent archived slot array
  - unsigned iByte_
  - int iArcByte_
  - unsigned nBytePerEl_
  -
Methods:
  - nByte()
  - etc

// Collect registers that reside on a given board.
struct RegMapBoard
  - RegMap* regmap // The parent register map
  - unsigned number // The index of the board in the register map
  - char name[]
  - string* comment_
  - vector< RegMapBlock* > blocks // The registers of the board
  - int nblock
  - HashTable* hash
  - unsigned nreg // The total number of registers on the board
  - unsigned narchive // The number of archived registers on the board
  - unsigned nByte_
  - unsigned nArcByte_
  - unsigned iSlot_
  - int iArcSlot_
  - unsigned iByte_
  - int iArcByte_
Methods:
  - byteOffsetInRegMap()
  - slotOffsetInRegMap()
  - nByte() // Return the number of bytes in this board
  - RegMapBlock* findRegMapBlock(string blockName)
  - vector< RegMapBlock* > matchRegMapBlock(string regExpStr)

// Clooect information about all boards
struct RegMap
Fields:
  - unsigned ref_count_
  - HashMemory* hash_mem_
  - vector< RegMapBoard* > boards_ // All addressable boards
  - int nboard_ // The number of boards
  - HaslTable* hash_ // Symbol table of boards
  - unsigned nreg_ // The total number of registers
  - unsigned narchive_ // The total number of archived registers
  - unsigned nByte_ // The size of all registers in this register map
  - unsigned nArcByte_
  -
Methods:
  - byteOffsetInArcRegMapOf()
  - etc
  - RegMapBlock* findRegMapBlock(board_name, block_name, doThrow=false)
  - RegMapBoard* find_RegMapBoard(RegMap* regmap, board_name)
  - RegMapBlock* find_RegMapBoard_Block(RegMapBoard* board, block_name)
  - RegMapBlock* find_RegMapBlock(RegMap* regmap, board_name, block_name)

gcp/control/code/unix/libunix_src/regtemplate.h

typedef enum RegBase { REG_BASE0, REG_BASE1, REG_BASE2, REG_BASE3, NBASE }

// The VME registers of a given board are specified via an array of the
// following type. This is a template for creation of a RegBlock object.
typedef struct RegBlockTemp
  - char name_[]
  - unsigned flags_ // A bit-set of RegFlags enumerators
  - RegAddrMode addr_mode_ // The addressing mode of the register
  - RegBase base_ // Use the base-address in board->bases[base]
  - unsigned address_ // The address of the block in the address space given by addr_mode_
  - gcp::util::CordAxes* axes_ // An axis specifier for this register
  - string* commeng_
  - (unsigned nreg) // (axex_.nreg_)The number of registers in the block
  - (unsigned nel) // (axes_.nel_)number of elements per register

RegBlockTemp::constructor(string comment, string name, unsigned flags, unsigned address=0, unsigned nel0=1, unsigned nel1=0, unsigned nel2=0)

RegBlockTemp::nEl()
  return axes_->nEl();


// Each board of registers is descried by an element of the following type.
typedef struct RegBoardTemp
  - char name[]
  - RegBlockTemp* blocks // The register of the board
  - int nblock // The number of register blocks in blocks[]
  - unsigned bases[NBASE] An array of up to NBASE base addresses


// Collect the register map template information into a single object
typedef struct RegTemplate
  - RegBoardTemp* boards // The array of register-board maps
  - unsigned nboard // The number of elements in boards[]

gcp/util/common/CoordAxes.h, cc

Fields:
  - std::vector< unsigned int> nEl_
Methods:
  - void setAxis(unsigned nAxis, unsigned nEl);
  - unsigned int nAxis();
  - unsigned int nEl(int axis=-1);
  - Coord coordOf(unsigned element);
  - std::vecotr< Range< unsigned> > getRanges(CoordRange range)
  - std::vecotr< Range< unsigned> > getRanges(coordRange* range=0)
  - bool rangeIsValid(CoordRange* range)
  - unsigned nEl(CoordRange* range)




Antenna0 register

In specificregs.c
/**.......................................................................
  * Collect all bicep templates into an array and give them names.
  /
static RegTemp bicep_regtemplates[] = {
  {"array", &bicep_array_template, "General array boards"},
  {"antenna0", &bicep_antenna_template, "Boards of the antenna"},
};

/
*.......................................................................
  * Create a template for a single antenna
  /
static RegTemplate bicep_antenna_template = {
  bicep_antenna_boards, ARRAY_DIM(bicep_antenna_boards)
};

/
*.......................................................................
  * Collect the bicep per-antenna boards into an array and give them names
  */
static RegBoardTemp bicep_antenna_boards[] = {
  {"fridge", bicepFridge, ARRAY_DIM(bicepFridge), {0x0},
    "BICEP He3 Fridge"},
  {"bolo", bicepBolo, ARRAY_DIM(bicepBolo), {0x0},
    "BICEP bolometer data"},
  {"rotator", bicepRotator, ARRAY_DIM(bicepRotator), {0x0},
    "BICEP rotator waveforms"},
  {"time", bicepTime, ARRAY_DIM(bicepTime), {0x0},
    "Slow and fast time axes"},
  {"level", bicepLevel, ARRAY_DIM(bicepLevel), {0x0},
    "LHe4 level sensors"},
  {"datasystem", bicepDataSystem, ARRAY_DIM(bicepDataSystem), {0x0},
    "Datasystem status info (such as voltages and temperature)"},
  {"dewar", bicepDewar, ARRAY_DIM(bicepDewar), {0x0},
    "Dewar temperature housekeeping"},
  {"pmac", bicepPmac, ARRAY_DIM(bicepPmac), {0x0, 0x\
0},
    "PMAC motion controller"},
  {"tracker", bicepTracker, ARRAY_DIM(bicepTracker), {0x0}, \

    "Tracking information"},
  {"auxiliary", bicepAuxiliary, ARRAY_DIM(bicepAuxiliary), {0x0}, \

    "Auxiliary Beam-mapping Inputs"},
  {"cal", bicepCalibrator, ARRAY_DIM(bicepCalibrator), {0x0},
    "Swing-arm calibrator"},
  {"irsrc", bicepIrSrc, ARRAY_DIM(bicepIrSrc), {0x0},
    "IR source"},
  {"weather", bicepWeather, ARRAY_DIM(bicepWeather), {0x0},
    "Weather information (from QUAD weather station)"},
  {"tipper", bicepTipper, ARRAY_DIM(bicepTipper), {0x0},
    "Tipper information (from Simon Radford's submillimeter tipper)"},
};

static RegBlockTemp bicepBolo[] = {

  RegBlockTemp("Cosine component of the bolometer data",
                "cosine", REG_FLOAT|REG_PREAVG|REG_FAST|REG_EXC, 0,
                BOLO_DATA_NBOX*NCHAN, NSAMPLESPERFRAME),
  RegBlockTemp("Sine component of the bolometer data",
                "sine", REG_FLOAT|REG_PREAVG|REG_FAST|REG_EXC, 0,
                BOLO_DATA_NBOX*NCHAN, NSAMPLESPERFRAME),
  RegBlockTemp("In AC mode: magnitude of the cosine and sine components "
                "of the bolometer data
"
                "In DC mode: cosine component only",
                "mag", REG_FLOAT|REG_FAST|REG_PREAVG, 0,
                BOLO_DATA_NBOX*NCHAN, NSAMPLESPERFRAME),
  RegBlockTemp("Phase, in radians, vector-averaged over the frame",
                "phase", REG_FLOAT|REG_PREAVG, 0,
                BOLO_DATA_NBOX*NCHAN),
  RegBlockTemp("Bias Voltage",
                "voltage", REG_FAST|REG_FLOAT, 0, 3, NSAMPLESPERFRAME),
  RegBlockTemp("Bias Frequency",
                "frequency", REG_FAST|REG_FLOAT, 0, 1, NSAMPLESPERFRAME),
  RegBlockTemp("Bias Mode (AC=0, DC=1)",
                "mode", REG_FAST|REG_UINT, 0, 1, NSAMPLESPERFRAME),
  RegBlockTemp("Bitmask of received flags for all boxes",
                "received", REG_FAST|REG_UINT, 0, 1, NSAMPLESPERFRAME),
};

Compile:

kstory@spudws2:gcp> make |& less > 12.18.compile

It compiles... too easily. I'm worried. Run time errors, oh boy.

Try to run.

Run:

Mediator output:

19-DEC-2008 00:21:06.280: In void gcp::util::LogFile::open(): Opened logfile: /home/kstory/work/gcp/runlogs/bicepTestMediator4 on Thu Dec 18 18:21:06 2008
19-DEC-2008 00:21:06.370: TCP/IP port 5464 at address "localhost " is currently unreachable
Connection refused
Accepted connection from: 127.0.0.1
Calling netMsgSentHandler
19-DEC-2008 00:21:06.399: Scanner connection established to Antenna0
19-DEC-2008 00:21:07.000: TCP/IP port 5460 at address "localhost " is currently unreachable
Connection refused
19-DEC-2008 00:21:07.000: TCP/IP port 5464 at address "localhost " is currently unreachable
Connection refused
Accepted connection from: 127.0.0.1
19-DEC-2008 00:21:07.001: Control connection established to Antenna0

Exactly what we expect. It connected to Antenna0.
It does not connect to 5460 or 5464, which are ??

This is the same output as before my modifications.

Check into subversion:

kstory@spudws2:gcp> pwd
/home/kstory/work/gcp
kstory@spudws2:gcp> svn commit -m "Add Mce functions to Mediator::Scanner."
Sending        TAGS
Sending        bin/bicepRegDoc
Sending        bin/logfile
Sending        control/code/unix/libquad_src/regtemplate.h
Sending        control/code/unix/libunix_src/bicep/specificregs.c
Sending        control/code/unix/libunix_src/common/arraymap.h
Sending        help/registers.html
Sending        mediator/bicep/AntennaConsumerNormal.h
Sending        mediator/bicep/MceConsumer.h
Sending        mediator/bicep/Scanner.cc
Sending        mediator/bicep/Scanner.h
Transmitting file data ...........
Committed revision 17.
kstory@spudws2:gcp>

Note:
I still need to write all command structure in the Mediator layer. However, I want to write a MASD that can connect to the Mediator first.

Start MASD code

Pick up tomorrow at L330 in AntennaMaster.h

12/19

I spent all day in the high bay working on making the sync box, mce, and mas talk to each other. They all more-or-less work now.

Notes

1) Sync box generates a signal (fast frame rate). This signal is sent to two places: the Mce crate, and the Gcp computer (Dedicated PCI card). This connection is over fiber optics cable.
This signal has a sequence number associated with it.
2) The Mce crate receives the signal and reads the squids. It then sends the bites across a fiber optical connection to the MAS control computer.
3) The MAS takes the bites and packs them into a datafile. The data is made up of ?32? bit words.
4) The MAS writes the datafile to a local file, which we set to be a pipe into the MASD.
5a) The first time the mce starts running, it sends a runfile to the MASD over a dedicated runfile pipe. This runfile is then parsed into a struct of some kind that can be read into the data frames and registers.

5b) The MASD reads the datafile from the pipe. For a given run, the data frame has a fixed length, and a fixed type.
  - Parse the header information and write it to a "header" array. 43 words.
  - The sync box sequence number is word #10.
  - Read the data information and write it to a "data" array.
  - These arrays should be NPIXELS x NSAMPLES_PER_SLOW_FRAME
  - store these arrays in an object called "FastMceFrame"
6) After 100 datafiles have been read, call "packMceFrame" method which packs all 100 FastMceFrames into a SlowMceFrame. This will include information from the data_arr, header_arr, and the runfile.
7) Send the SlowMceFrame off to the Gcp Mediator.

Meanwhile...
The Gcp AntennaLayer receives pulses from the syncbox. Every 100th signal, sample the necessary information (i.e. mount, weather, etc.). Pack this into a frame. Lable frame with the 100th sequence number from the sync box. Send it off to the gcp Mediator.

Mediator:
Receives Slow Rate Frames (SF) from the Antenna Layer and the MASD. It maintains a queue of ~10 SFs and when a frame from either location arrives it puts it into the appropriate frame in the queue. When the frame reaches the front of the queue, it is sent off to the archiver on a fixed time schedule.

Datafile format:
  - array of 32 bit words. For any given run, has a constant length.
  - mce flat_file format
  - header: 43 words. #10 = sync box number.
  - For each pixel, three fields:
    feedback
    number of flux jumps
    error signal
  - The data depends on the data mode.
  - Array should be NPIXELS x NSAMPLES_PER_SLOW_FRAME

Runfile format:
  - generated once per total run.
  - holds data mode information. - Write enumerator for data mode in MASD.
  - Walt already has code that parses this into a struct.
Read / write from a pipe:
write - cat to pipe.
read - fread into POSIX data types.
read the pipe, something like fread to memory, set struct pointers to that memory.
makefifo
has buffering.
Simulate:
Write a toy program that writes datafiles to a pipe, which is piped into the MASD. This should have a changing sequence number somehow. Maybe just have someone at Caltech send me several minutes worth of data files?
cat data to the pipe.

Simulate the sync box on the Antenna Layer side the same way: "simSync" flag that calls a function to generate HK frames based on an internal clock.

Questions:
  - What drives archiving of frames? Arrival of frames from the Antenna Layer? Or some other external timer? Arrival of pulses from the sync box?
  - Timing of fast rate: The mce computer specifies the sample rate, but the sync box also does by generating signals. Do these have to match? Does one set precidence over the other if they do not match?
  - simulate: is there a MAS simulate mode?
  - Sync Box PCI card: how will this be treated in the gcp AntennaLayer code? Like the Pmac?
  - Multiple Mce crates?

People:
Bryce at UBC.
Matt Hasselfield at UBC.

Caltech:
Angiola
Justus
Walt


Notes from Walt

Here's a record of what I've been doing on bicep1, for reference.  My goal was
to clone the setup on bicep4 to get things working quickly.  If I've made any
errors, Matt and Mandana can correct me.  I also installed some basic
standard packages like build-essentials, cvs server, without explicitly
noting this.

- Walt

-----

* To get the PCI fiber card working:

Burned firmware with Viktor's help, using the image file left on the
programmer PC by Spider.

Installed PCI card.

Copied bigphys-patched kernel from bicep4: downloaded .deb packages

bicep4:/usr/src/linux-headers-2.6.24.3-bigphys_2.6.24.3-bigphys-10.00.Custom_amd64.deb,
bicep4:/usr/src/linux-image-2.6.24.3-bigphys_2.6.24.3-bigphys-10.00.Custom_amd64.deb

and installed with dpkg -i.  This updated the initrd, grub menu.lst, etc.  I
had to also edit /boot/grub/menu.lst to add the kernel parameter
       bigphysarea=16384
to the end of the kernel line.

Copied mce_dsp kernel module from
bicep4:/lib/modules/2.6.24.3-bigphys/kernel/drivers/misc/mce_dsp.ko

to same location on bicep1.  I also had to edit
/lib/modules/2.6.24.3-bigphys/modules.dep
by adding the line
       /lib/modules/2.6.24.3-bigphys/kernel/drivers/misc/mce_dsp.ko:

Reboot with new kernel, and I can now load the module using "modprobe
mce_dsp".

-----

* To install MAS:

Copied the MCE directories from
bicep4:/usr/mce
to the same location on bicep1.

Edited /etc/rc.local by adding the lines:
       modprobe mce_dsp
       /usr/mce/bin/mas_mknodes
       sudo -u bicep /usr/mce/bin/maslog_server

Created the "mce" group
Created /data/cryo/current_data with proper permissions
Created /data/cryo/array_id with contents "default".

Edited /usr/mce/mce_script/test_suite/mce_check by removing references to
readout cards 3 & 4.

Copied config files from
bicep4:/etc/mce
to same location on bicep1.

Edited my .bashrc by adding the lines
       #MAS
       export MAS_ROOT=/usr/mce/mce_script/
       source $MAS_ROOT/template/mas_env.bash
       export IDL_PATH="<IDL_DEFAULT>:$MAS_IDL/mas"

Reboot

Updated firmware on RC1 and RC2 to version 0x04000009, with help from Bryce.

-----

* To install libconfig:

Copied the build directory from
bicep4:/home/mhasse/install/libconfig-1.3
to my home directory on bicep1.

Ran "su make install" from build directory.

Moved results from /usr/local/lib to /usr/lib and
from /usr/local/lib/pkgconfig to /usr/lib/pkgconfig, so that libraries would
be found without changing library paths.

-----

* To talk to sync box:

Install RS-232 cable between bicep1 and sync box
Install "gtkterminal" on bicep1
Set baud rate, etc. according to sync box user's guide from UBC web page

-----

The following are steps in attempting to compile the symmetricom driver.  I
eventually concluded that it's unlikely to compile against a current kernel;
too many internal changes since the kernel version it was written against.

* To install Symmetricon driver:

Copied BCPCIV606.tgz from CD to bicep1:/home/reuben/symmetricon/
Made sym link from /usr/src/linux to /usr/src/linux-headers-2.6.24.3-bigphys
so that configuration script will find libraries

tar xvfz BC*
chmod u+w *

Config script is slightly broken:
edited /home/reuben/symmetricon/drvr/configure
by changing "linux/version.h" on line 606 to "linux/utsrelease.h"
changing "#!/bin/sh" to "#!/bin/bash" on line 1 so that line 651 will work
removing -mpreferred-stack-boundary=2 on line 737 (related to 64 bit OS?)

Change "linux/config.h" to "linux/autoconf.h" in drvr/configure and
drvr/linux_common.h

Need some files that are in the source but not the headers...

Copy linux source tree from
bicep4:/usr/src/linux-source-2.6.24-bigphys to same location on bicep1
copy /usr/src/linux-source-2.6.24-bigphys/arch/x86/Makefile_64
to /usr/src/linux-headers-2.6.24.3-bigphys/arch/x86/

have a broken sym link for asm...
cd /usr/src/linux/include
sudo ln -s /usr/src/linux-source-2.6.24-bigphys/include/asm asm

in drvr/configure, replace line
       -DKBUILD_MODNAME=$MODULE_NAME -O"
with
       -DKBUILD_MODNAME=\"\\\"$MODULE_NAME\\\"\" -O"

edit drvr/linux_wrappers.h

Questions:
  1) How do I use a debugger (ex. gdb)? How do I use the DBPRINT stuff?
  2) What is Walsh?
  3) What is COBRA and are we using it?
Fluxbox:
  - startup script
  - font sizes
  - calendar
  - one-click minimize everything
  - nvidia
  - dual monitor
  - mount usb flashdrive
C++:
  - what is the operator ( |= ) ?