22 static struct sockaddr_nl sa_local;
24 static struct sockaddr_nl sa_kernel;
32 init_framegrabber39();
35 framegrabber39::framegrabber39(std::string name,
const std::string &conffile)
throw (AOException) :
framegrabber<unsigned char>(name, conffile)
37 init_framegrabber39();
48 return a.value < b.value;
51 void framegrabber39::init_framegrabber39()
53 sa_local.nl_family = AF_NETLINK;
54 sa_local.nl_groups = 1;
56 sa_kernel.nl_family = AF_NETLINK;
58 sa_kernel.nl_groups = 1;
66 std::vector<lutentry> le(6400);
67 for(
int i=0;i<6400;i++)
70 le[i].value = displayLUT[i];
73 std::sort(le.begin(), le.end(), complutentries);
76 for(
int i=0;i<6400;i++) bcuLUT[i] = le[i].order;
84 _logger->log(Logger::LOG_LEV_ERROR,
"Could not create status board.");
89 strncpy(bsb->appname, MyFullName().c_str(), 25);
100 ebt_ulog_packet_msg_t * framegrabber39::ulog_get_packet()
102 static struct nlmsghdr *nlh = NULL;
103 static int len, remain_len;
104 static int pkts_per_msg = 0;
106 ebt_ulog_packet_msg_t *msg;
108 socklen_t addrlen =
sizeof(sa_kernel);
113 if (pkts_per_msg && DEBUG_QUEUE)
116 logss <<
"PACKETS IN LAST MSG: " << pkts_per_msg;
122 len = recvfrom(sfd, buf, BUFLEN, 0, (
struct sockaddr *)&sa_kernel, &addrlen);
126 if (addrlen !=
sizeof(sa_kernel))
129 logss <<
"addrlen" << addrlen <<
" != " <<
sizeof(sa_kernel);
137 logss <<
"recvmsg: " << strerror(errno);
142 nlh = (
struct nlmsghdr *)buf;
143 if (nlh->nlmsg_flags & MSG_TRUNC || len > BUFLEN)
146 logss <<
"packet truncated";
152 if (!NLMSG_OK(nlh, BUFLEN))
155 logss <<
"Netlink message parse error: " << strerror(errno);
162 msg = (ebt_ulog_packet_msg_t *) NLMSG_DATA(nlh);
164 remain_len = (len - ((
char *)nlh - buf));
165 if (nlh->nlmsg_flags & NLM_F_MULTI && nlh->nlmsg_type != NLMSG_DONE)
166 nlh = NLMSG_NEXT(nlh, remain_len);
179 sa_local.nl_pid = getpid();
181 sa_local.nl_groups = sa_kernel.nl_groups = 1 << (30 - 1);
183 sfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_NFLOG);
188 logss <<
"socket: " << strerror(errno);
194 if (bind(sfd, (
struct sockaddr *)(&sa_local),
sizeof(sa_local)) == -1)
197 logss <<
"bind: " << strerror(errno);
203 if(setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
sizeof(rcvbufsize)) < 0)
206 logss <<
"setsockopt: " << strerror(errno);
214 logss <<
"framegrabber39 running.";
222 DiagnosticUdpHeader * bcuhead;
224 int curr_frameId = -1;
225 int last_packetId=-1;
228 int curr_pixel_offset = 4*2;
232 _frameSizeBytes = frameSizeDw * _FRAME_HEADER_SIZE_DW;
233 _packetsPerFrame = _frameSizeBytes / Constants::MAX_TDP_PACKET_SIZE;
234 if(_frameSizeBytes % Constants::MAX_TDP_PACKET_SIZE)
242 if (!(msg = ulog_get_packet()))
248 if (msg->version != EBT_ULOG_VERSION)
250 printf(
"WRONG VERSION: %d INSTEAD OF %d\n",
251 msg->version, EBT_ULOG_VERSION);
259 if (msg->data_len < curr_len)
265 ehdr = (
struct ethhdr *)msg->data;
266 etype = getethertypebynumber(ntohs(ehdr->h_proto));
268 if (ehdr->h_proto == htons(ETH_P_IP))
269 iph = (
struct iphdr *)(((
char *)ehdr) + curr_len);
273 curr_len +=
sizeof(
struct iphdr);
274 if (msg->data_len < curr_len || msg->data_len < (curr_len += iph->ihl * 4 -
sizeof(
struct iphdr)))
280 bcuhead = (DiagnosticUdpHeader *)((
char *) iph + iph->ihl*4 + 10);
282 bcudata = (
char *) ((
char *)bcuhead + 12);
284 if(bcuhead->frameId == curr_frameId && bcuhead->packetId == last_packetId + 1)
287 last_packetId = bcuhead->packetId;
289 if(last_packetId == 0)
294 gettimeofday(&
tv, 0);
295 sim->frame_time =
tv;
298 cursor = ((uint8 *) bcudata + curr_pixel_offset);
306 while(((
char *) cursor - (
char *)ehdr) < msg->data_len)
308 sim->imdata[curr_pixel] = *((
unsigned char*) cursor);
315 if(last_packetId == _packetsPerFrame-1)
320 curr_pixel_offset = 0;
322 sim->frameNo = *( (uint32*)
sim->imdata);
331 curr_frameId = bcuhead->frameId + 1;
345 logss << pktcnt <<
" frames.";
360 logss <<
"framegrabber39 stopped.";
369 static int last_pktcnt = 0;
370 static double last_t0 =
t0;
385 fsb->fps = ((double)(pktcnt-last_pktcnt))/(t1-last_t0)/_packetsPerFrame;
386 last_pktcnt = pktcnt;
virtual int update_statusboard()
Update the status board.
double t0
Starting time of framegrabber loop.
void log_msg(int LogLevel, std::string lmsg)
Report an error. Also calls log_msg. Overloaded from VisAOApp_base.
int enable_next_image()
Increments last_image.
double get_curr_time(void)
Gets the current CLOCK_REALTIME time, returns it in seconds to double precision.
sharedim_stack< unsigned char > sis
The shared memory ring buffer for image storage.
#define STATUS_framegrabber39
Shared memory key for the BCU39 framegrabber status board.
std::ostringstream logss
Conveninence string stream for building log messages.
void * statusboard_shmemptr
The pointer to the shared memory block for the statusboard.
virtual int stop_framegrabber()
Override this: framegrabber clean up.
virtual int update_statusboard()
Update the status board.
sharedim< unsigned char > * sim
Pointer to a shared memory image.
sharedim< IMDATA_TYPE > * set_next_image(int nx, int ny)
Sets the next image, and returns a pointer to it, but does not increment last_image.
int writerPingEnabled
Send pings on frame ready when true.
key_t statusboard_shmemkey
The key used to lookup the shared memory.
int TimeToDie
Global set by SIGTERM.
int serverPingEnabled
Send pings on frame ready when true.
double pause_time
Time to pause during application main loop.
int STOP_FRAMEGRABBER
If true, framegrabber stops at top of next loop.
int create_statusboard(size_t sz)
Creates and attaches to the statusboard shared memory.
int set_euid_called()
Changes the user id of the process to euid_called.
int send_ping()
Sends a ping to the waiting process (usuallly a framewriter).
virtual int start_framegrabber()
Override this: it is where your framegrabber should do all its work. Check for !STOP_FRAMEGRABBER and...
The namespace of VisAO software.
Declarations for a class to capture frames from the BCU39, using the ebtables ulog.
timeval tv
Convenience variable for filling in the frame time in the image header.
int set_euid_real()
Changes the user id fo the process to the real user id.
int RUNNING
Status of framegrabber.