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
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

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)

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 [ +, <, <, >, >, ==, ++,


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

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/libquad_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
  - unsigned nreg // The number of registers in the block
  - unsigned nel // number of elements per register

// 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[]

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 ( |= ) ?