22 #define ERROR_REPORT(er) if(global_error_report) (*global_error_report)(er,__FILE__,__LINE__);
26 #define LOG_INFO(li) if(global_log_info) (*global_log_info)(li);
33 frameserver::frameserver(
int argc,
char **argv)
throw (AOException) : VisAOApp_standalone(argc, argv)
38 frameserver::frameserver(std::string name,
const std::string &conffile)
throw (AOException) : VisAOApp_standalone(name, conffile)
43 int frameserver::Create()
47 std::string visao_root = getenv(
"VISAO_ROOT");
52 pathtmp = (std::string)(ConfigDictionary())[
"pingFifoPath"];
54 catch(Config_File_Exception)
58 pingFifoPath = visao_root +
"/" + pathtmp +
"/";
59 _logger->log(Logger::LOG_LEV_INFO,
"Set pingFifoPath: %s", pingFifoPath.c_str());
64 remoteIP = (std::string)(ConfigDictionary())[
"remoteIP"];
66 catch(Config_File_Exception)
68 remoteIP =
"127.0.0.1";
70 _logger->log(Logger::LOG_LEV_INFO,
"Set remoteIP: %s", remoteIP.c_str());
74 localPort =(ConfigDictionary())[
"localPort"];
76 catch(Config_File_Exception)
80 _logger->log(Logger::LOG_LEV_INFO,
"Set localPort: %i", localPort);
84 remotePort = (ConfigDictionary())[
"remotePort"];
86 catch(Config_File_Exception)
90 _logger->log(Logger::LOG_LEV_INFO,
"Set remotePort: %i", remotePort);
100 set_fifo_list_channel(&
fl, FRAME_READY_FIFO_CH,
RWBUFF_SZ, (
char *)std::string(pingFifoPath +
"frameserver47_ping_in").c_str(), (
char *)std::string(pingFifoPath +
"frameserver47_ping_out").c_str(), 0, (
void *)
this);
103 attached_to_shmem =
false;
113 _logger->log(Logger::LOG_LEV_ERROR,
"Could not create status board.");
118 strncpy(bsb->appname, MyFullName().c_str(), 25);
119 bsb->max_update_interval = 1;
125 _MAX_TDP_PACKET_SIZE = Constants::MAX_TDP_PACKET_SIZE;
126 _MAX_ETH_PACKET_SIZE = Constants::MAX_ETH_PACKET_SIZE;
131 int frameserver::setPingFifoPath(std::string &pfp)
137 int frameserver::setRemoteIp(std::string &ip)
143 int frameserver::setLocalPort(
int lp)
149 int frameserver::setRemotePort(
int rp)
161 int frameserver::set_shmem_key(
int sk)
167 int frameserver::connect_shmem()
172 ERROR_REPORT(
"Error attaching to shared memory.");
173 attached_to_shmem =
false;
177 attached_to_shmem =
true;
214 signal(SIGIO, SIG_IGN);
215 signal(RTSIGIO, SIG_IGN);
220 ERROR_REPORT(
"Error installing main thread catcher.");
227 ERROR_REPORT(
"Error starting signal catching thread.");
236 ERROR_REPORT(
"Error blicking SIGIO.");
243 fcntl(
fl.
fifo_ch[FRAME_READY_FIFO_CH].fd_in, F_SETOWN, getpid());
245 int rv = fcntl(
fl.
fifo_ch[FRAME_READY_FIFO_CH].fd_in, F_SETSIG, RTSIGPING);
249 logss <<
"Error changing signal: " << strerror(errno);
250 ERROR_REPORT(
logss.str().c_str());
254 struct sigaction act;
257 act.sa_sigaction = &frame_ready_handler;
258 act.sa_flags = SA_SIGINFO;
264 if(sigaction(RTSIGPING, &act, 0) < 0)
267 logss <<
"Error setting signal handler for RTSIGPING. Errno says: " << strerror(errno) <<
".";
272 conn =
new UdpConnection(localPort, remoteIP, remotePort, 0);
274 LOG_INFO(
"starting up . . .");
287 frameSizeDw = (frameSizePixels * bitPerPix) / (Constants::DWORD_SIZE*8) + 8;
289 int frameSizeBytes =
frameSizeDw * Constants::DWORD_SIZE;
293 if(frameSizeBytes % _MAX_TDP_PACKET_SIZE)
304 static int last_image_abs = -1, last_image = -1, last_save_sequence = -1;
308 static int frames = 0;
313 if(attached_to_shmem ==
false)
315 if(connect_shmem() != 0)
return -1;
319 if(
sis->get_last_image_abs() < last_image_abs || last_save_sequence !=
sis->
header->save_sequence)
321 last_image_abs =
sis->get_last_image_abs();
323 last_save_sequence =
sis->
header->save_sequence;
326 if(
sis->get_last_image_abs() < last_image_abs) LOG_INFO(
"Detected framegrabber restart, resetting");
329 if(last_image_abs < 0)
332 last_save_sequence =
sis->
header->save_sequence;
333 last_image_abs =
sis->get_last_image_abs()-1;
336 DiagnosticUdpHeader* header = (DiagnosticUdpHeader*) &((TDPHeader*)sendBuff)->header;
339 while(last_image_abs < sis->get_last_image_abs() && !
TimeToDie)
341 last_image_abs =
sis->get_last_image_abs();
344 int tosend, maxpcksz, pcktsz, bytesent;
351 maxpcksz = Constants::MAX_ETH_PACKET_SIZE;
355 header->tot_len = tosend;
357 header->packetId = 0;
358 header->frameId =
sim.frameNo;
361 std::cout <<
"frameSizeDw = " <<
frameSizeDw <<
"\n";
363 std::cout <<
"bytes tosend = " << tosend <<
"\n";
364 std::cout <<
"frameId = " << header->frameId << std::endl;
373 if(tosend - bytesent + Constants::TDP_PACKET_HEADER_SIZE > maxpcksz) pcktsz = maxpcksz;
374 else pcktsz = tosend - bytesent+Constants::TDP_PACKET_HEADER_SIZE;
378 for(
int j= 0; j < 16; j++)
380 sendBuff[Constants::TDP_PACKET_HEADER_SIZE+j] = 0;
382 for(
int j = 16; j < pcktsz - Constants::TDP_PACKET_HEADER_SIZE; j++)
384 sendBuff[Constants::TDP_PACKET_HEADER_SIZE + j] = ((BYTE *)
sim.imdata)[bytesent + j-16];
387 else if(i == packetsPerFrame -1)
390 for(j = 0; j < pcktsz - Constants::TDP_PACKET_HEADER_SIZE - 16; j++)
392 sendBuff[Constants::TDP_PACKET_HEADER_SIZE + j] = ((BYTE *)
sim.imdata)[bytesent + j-16];
394 for(; j < pcktsz - Constants::TDP_PACKET_HEADER_SIZE; j++)
396 sendBuff[Constants::TDP_PACKET_HEADER_SIZE+j] = 0;
401 for(
int j = 0; j < pcktsz - Constants::TDP_PACKET_HEADER_SIZE; j++)
403 sendBuff[Constants::TDP_PACKET_HEADER_SIZE + j] = ((BYTE *)
sim.imdata)[bytesent + j-16];
407 int old_packet = header->packetId;
409 while(header->packetId == old_packet && !
TimeToDie)
413 conn->send(sendBuff, pcktsz);
424 bytesent += pcktsz-Constants::TDP_PACKET_HEADER_SIZE;
426 catch (UdpFatalException u)
431 std::cout << u.what() <<
"\n";
432 std::cout << frames <<
" " << bytesent <<
"\n";
433 ERROR_REPORT(
"Exception thrown sending data via udp");
442 std::cout <<
"bytes sent = " << bytesent <<
"\n";
443 std::cout <<
"packets sent = " << i <<
"\n" << std::endl;
459 std::cout <<
"last_image " << last_image <<
"\n";
460 std::cout <<
"last_image_abs " << last_image_abs <<
"\n";
463 ERROR_REPORT(
"Error getting image in send_frame().");
466 behind =
sis->get_last_image_abs() - last_image_abs;
475 _logger->log(Logger::LOG_LEV_ERROR,
"Behind %i frames, skipping %i frames. Total skipped: %i",
behind, skipped,
total_skipped);
477 last_image_abs += skipped;
478 last_image += skipped;
488 void frame_ready_handler(
int signum __attribute__((unused)), siginfo_t *siginf,
void *ucont __attribute__((unused)))
493 if(siginf->si_code == POLL_IN)
506 int frame_ready(fifo_channel *fc)
510 fw = (frameserver *)fc->auxdata;
virtual int Run()
The application main loop, to be re-implemented in derived classes.
fifo_list * global_fifo_list
The global fifo_list, for signal handling.
virtual int start_signal_catcher(bool inherit_sched=true)
Starts the signal catching loop.
Declarations for a class for serving frames over UDP.
int packetsPerFrame
No of UDP messages per frame.
int read_fifo_channel(fifo_channel *fc)
Read data from the input fifo channel.
int send_frame()
Send the frame, packet by packet, as if we're a BCU 47.
std::ostringstream logss
Conveninence string stream for building log messages.
void * statusboard_shmemptr
The pointer to the shared memory block for the statusboard.
virtual void error_report(int LogLevel, std::string emsg)
Report an error. Also calls log_msg.
sharedim_stack_header * header
Convenient pointer to the stack header, has same value as shmemptr.
virtual int setup_baseApp(bool usethreads=false)
Install fifo channels.
sharedim_stackS * sis
Manages a VisAO shared memory image stack.
fifo_channel * fifo_ch
An array of fifo_channels.
int setup_fifo_list(int nfifos)
Allocate the fifo_list.
a class for serving frames over UDP.
key_t statusboard_shmemkey
The key used to lookup the shared memory.
virtual int block_sigio()
Sets the signal mask to block SIGIO and RTSIGIO.
int TimeToDie
Global set by SIGTERM.
int attach_shm(key_t mkey)
Attachess the shared memory. A Reader process should start here.
int frameSizeDw
Size of the frame in DWORD.
fifo_list fl
The list of named-pipe fifos used for inter-process comms.
int behind
The number of frames currently behind.
#define STATUS_frameserver47
Shared memory key for the ccd47 frameserver status board.
sharedim< IMDATA_TYPE > get_image(int imno)
Gets an image, as a sharedim structure, with the imdata pointer properly set for the calling process...
int total_skipped
The total number of frames skipped.
int create_statusboard(size_t sz)
Creates and attaches to the statusboard shared memory.
virtual int install_sig_mainthread_catcher()
Install the SIG_MAINTHREAD signal catcher.
int calc_packetsPerFrame(int frameSizeBytes, int bitsPerPix)
Calculate frameSizeDW and packetsPerFrame.
sharedimS sim
The sharedim structure retreived from the stack.
The namespace of VisAO software.
int get_last_image()
Returns the value of last_image currently in the header.
#define RWBUFF_SZ
The size of the i/o buffer.
int set_fifo_list_channel(fifo_list *fl, int nch, int buffsz, const char *fin, const char *fout, int(*inp_hand)(fifo_channel *), void *adata)
Set the details of one channel in the list.
int get_max_n_images()
Returns the value of max_n_images currently in the header.