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
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
- unsigned int nSlot_
- Mutex guard_
- std::map
- 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
- std::list
- 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
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
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
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]
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]
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
TRANS_MCE_SCANNER_PORT 451+PORT_OFFSETDeal 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 ( |= ) ?