50 #define STD_REPLY_TIMEOUT SEC_TO_USEC(0.2) // Should be tens of ms at least or flash writes will fail. 51 #define STOP_REPLY_TIMEOUT SEC_TO_USEC(0.001) 96 static const char *badprefix =
"Bad URL prefix, expected name://, serial:// or any://.";
97 static const char *multiaddress =
"Multiple @-prefixed camera addresses found.";
98 static const char *multiinterface =
"Multiple #-prefixed host interfaces found.";
99 static const char *discoverfailed =
"Discover failed. The specified address or interface may be bad.";
100 static const char *badserial =
"serial:// may only be followed by an integer.";
101 static const char *badany =
"Unexpected characters after any://.";
102 static const char *badip =
"@ must be followed by a valid IP address.";
103 static const char *nomatch =
"No cameras matched the URL.";
104 static const char *multimatch =
"More than one camera matched the URL.";
105 static const char *illegalcase =
"Illegal case, this is a bug.";
106 static const char *nomem =
"malloc failed";
107 const char *name =
"name://";
int namelen = strlen(name);
108 const char *serial =
"serial://";
int seriallen = strlen(serial);
109 const char *any =
"any://";
int anylen = strlen(any);
112 char *address = NULL;
113 char *
interface = NULL;
114 char *copy = malloc(strlen(url) + 1);
118 unsigned int serialnum = -1;
125 *errmsg = illegalcase;
135 if (!strncmp(copy, name, namelen))
137 idstart = copy + namelen;
140 else if (!strncmp(copy, serial, seriallen))
142 idstart = copy + seriallen;
145 else if (!strncmp(copy, any, anylen))
147 idstart = copy + anylen;
158 for (curpos = idstart; *curpos; curpos++)
165 *errmsg = multiaddress;
168 address = curpos + 1;
170 else if (*curpos ==
'#')
175 *errmsg = multiinterface;
178 interface = curpos + 1;
186 if (mode == 3 && *idstart)
196 serialnum = strtol(idstart, &endpos, 10);
197 if (*idstart == 0 || *endpos != 0)
211 *errmsg = discoverfailed;
219 if ((mode == 1 && strcmp(idstart, curEntry->
cam_name) == 0) ||
220 (mode == 2 && serialnum == curEntry->
serial) ||
227 *errmsg = multimatch;
230 memcpy(camera, curEntry,
sizeof(
IpCamList));
234 if (inet_aton(address, &ip))
236 uint8_t *ipbytes = (uint8_t *) &ip.s_addr;
237 snprintf(camera->
ip_str,
sizeof(camera->
ip_str),
"%i.%i.%i.%i", ipbytes[0], ipbytes[1], ipbytes[2], ipbytes[3]);
238 camera->
ip = ip.s_addr;
263 *errmsg = illegalcase;
290 if( recvfrom( s, &sPkt,
sizeof(
PacketStatus), 0, NULL, NULL ) == -1 ) {
291 perror(
"wge100StatusWait unable to receive from socket");
308 static void xormem(uint8_t *dst, uint8_t *src,
size_t w)
320 strncpy(dPkt.
hdr.
hrt,
"DISCOVER",
sizeof(dPkt.
hdr.
hrt));
334 struct in_addr newIP;
337 inet_aton(ipAddress, &newIP);
342 struct in_addr localip;
343 struct in_addr netmask;
346 dPkt.
ip_addr = localip.s_addr ^ netmask.s_addr ^ ~0;
350 perror(
"Unable to send broadcast\n");
378 const char **ifNames = NULL;
379 struct ifaddrs *ifaces = NULL;
380 struct ifaddrs *curif;
386 if (!ifName || !ifName[0])
389 if (getifaddrs(&ifaces))
391 perror(
"getifaddrs failed");
396 for (curif = ifaces; curif; curif = curif->ifa_next)
401 ifNames = calloc(numif,
sizeof(
char *));
404 perror(
"allocating interfaces memory");
412 for (numif = 0, curif = ifaces; curif; curif = curif->ifa_next)
415 if (curif->ifa_addr && curif->ifa_addr->sa_family == AF_INET)
416 ifNames[numif++] = curif->ifa_name;
420 s = calloc(numif,
sizeof(
int));
423 perror(
"allocating socket memory");
427 for (nums = 0; nums < numif; nums++)
435 for (i = nums; i < numif; i++)
437 ifNames[i] = ifNames[i+1];
446 if( curs != -1 && wait_us != 0 ) {
449 struct sockaddr_in fromaddr;
450 fromaddr.sin_family = AF_INET;
451 socklen_t fromlen =
sizeof(fromaddr);
454 packet_len = recvfrom( s[curs], &aPkt,
sizeof(
PacketAnnounce), 0, (
struct sockaddr *) &fromaddr, &fromlen);
455 if(packet_len == -1 ) {
456 perror(
"wge100Discover unable to receive from socket");
474 perror(
"Malloc failed");
483 uint8_t *ipbytes = (uint8_t *) &aPkt.
camera_ip;
484 snprintf(tmpListItem->
ip_str,
sizeof(tmpListItem->
ip_str),
"%i.%i.%i.%i", ipbytes[0], ipbytes[1], ipbytes[2], ipbytes[3]);
486 memcpy(&tmpListItem->
mac, aPkt.
mac,
sizeof(aPkt.
mac));
489 strncpy(tmpListItem->
ifName, ifNames[curs],
sizeof(tmpListItem->
ifName));
490 tmpListItem->
ifName[
sizeof(tmpListItem->
ifName) - 1] = 0;
492 char pcb_rev = 0x0A + (0x0000000F & ntohl(aPkt.
hw_version));
493 int hdl_rev = 0x00000FFF & (ntohl(aPkt.
hw_version)>>4);
500 wge100_debug(
"MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", aPkt.
mac[0], aPkt.
mac[1], aPkt.
mac[2], aPkt.
mac[3], aPkt.
mac[4], aPkt.
mac[5]);
501 wge100_debug(
"Product #%07u : Unit #%04u\n", ntohl(aPkt.
product_id), ntohl(aPkt.
ser_no));
502 wge100_debug(
"%s\n", tmpListItem->
hwinfo);
506 }
while(wait_us > 0);
507 retval = newCamCount;
512 for (i = 0; i < nums; i++)
539 strncpy(cPkt.
hdr.
hrt,
"CONFIGURE",
sizeof(cPkt.
hdr.
hrt));
551 perror(
"wge100Configure socket creation failed");
556 if (!ipAddress || !*ipAddress)
558 wge100_debug(
"No ipAddress, using %x\n", camInfo->
ip);
562 wge100_debug(
"Unable to send packet\n");
569 struct in_addr newIP;
570 inet_aton(ipAddress, &newIP);
572 wge100_debug(
"Using ipAddress %s -> %x iface %s\n", ipAddress, cPkt.
ip_addr, camInfo->
ifName);
574 wge100_debug(
"Sending broadcast discover packet.\n");
576 wge100_debug(
"Unable to send broadcast\n");
584 wge100_debug(
"Connecting to %x.\n", camIP);
586 wge100_debug(
"Unable to connect\n");
596 if( recvfrom( s, &aPkt,
sizeof(
PacketAnnounce), 0, NULL, NULL ) == -1 ) {
597 perror(
"wge100Discover unable to receive from socket");
614 }
while(wait_us > 0);
620 wge100_debug(
"Timed out.\n");
644 strncpy(vPkt.
hdr.
hrt,
"Start Video",
sizeof(vPkt.
hdr.
hrt));
648 inet_aton(ipAddress, (
struct in_addr*)&vPkt.
receiver.
addr);
683 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
706 strncpy(vPkt.
hdr.
hrt,
"Stop Video",
sizeof(vPkt.
hdr.
hrt));
734 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
756 strncpy(gPkt.
hdr.
hrt,
"ReconfigureFPGA",
sizeof(gPkt.
hdr.
hrt));
838 strncpy(gPkt.
hdr.
hrt,
"Time Req",
sizeof(gPkt.
hdr.
hrt));
863 if( recvfrom( s, &tPkt,
sizeof(
PacketTimer), 0, NULL, NULL ) == -1 ) {
864 perror(
"GetTime unable to receive from socket");
869 *time_us = (uint64_t)ntohl(tPkt.
ticks_hi) << 32;
883 }
while(wait_us > 0);
885 wge100_debug(
"Timed out waiting for time value\n");
913 for (; *retries > 0; (*retries)--)
920 wge100_debug(
"Flash read failed.");
951 rPkt.
address = htonl(address<<9);
953 strncpy(rPkt.
hdr.
hrt,
"Flash read",
sizeof(rPkt.
hdr.
hrt));
980 perror(
"GetTime unable to receive from socket");
990 }
while(wait_us > 0);
992 wge100_debug(
"Timed out waiting for flash value\n");
1020 if (retries == NULL)
1026 for (; *retries > 0; (*retries)--)
1032 wge100_debug(
"Failed write, retries left: %i.", *retries);
1088 rPkt.
address = htonl(address<<9);
1089 strncpy(rPkt.
hdr.
hrt,
"Flash write",
sizeof(rPkt.
hdr.
hrt));
1113 uint32_t type, code;
1120 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
1144 strncpy(tPkt.
hdr.
hrt,
"Int. Trigger",
sizeof(tPkt.
hdr.
hrt));
1146 strncpy(tPkt.
hdr.
hrt,
"Ext. Trigger",
sizeof(tPkt.
hdr.
hrt));
1169 uint32_t type, code;
1176 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
1201 strncpy(sPkt.
hdr.
hrt,
"System Config",
sizeof(sPkt.
hdr.
hrt));
1202 memcpy(&sPkt.
mac, mac, 6);
1203 sPkt.
serial = htonl(serial);
1225 uint32_t type, code;
1232 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
1253 uint16_t readbackdata;
1257 if (retries == NULL)
1260 for (; *retries > 0; (*retries)--)
1270 if (readbackdata == data)
1298 strncpy(sPkt.
hdr.
hrt,
"Write I2C",
sizeof(sPkt.
hdr.
hrt));
1300 sPkt.
data = htons(data);
1322 uint32_t type, code;
1329 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
1354 if (retries == NULL)
1356 for (; *retries > 0; (*retries)--)
1385 strncpy(rPkt.
hdr.
hrt,
"Read I2C",
sizeof(rPkt.
hdr.
hrt));
1410 if( recvfrom( s, &sPkt,
sizeof(
PacketSensorData), 0, NULL, NULL ) == -1 ) {
1411 perror(
"SensorRead unable to receive from socket");
1416 *data = ntohs(sPkt.
data);
1420 }
while(wait_us > 0);
1422 wge100_debug(
"Timed out waiting for sensor value\n");
1445 strncpy(sPkt.
hdr.
hrt,
"Select I2C",
sizeof(sPkt.
hdr.
hrt));
1469 uint32_t type, code;
1476 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
1498 mPkt.
mode = htonl(mode);
1500 strncpy(mPkt.
hdr.
hrt,
"Set Mode",
sizeof(mPkt.
hdr.
hrt));
1522 uint32_t type, code;
1529 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
1558 strncpy(rPkt.
hdr.
hrt,
"Set Res",
sizeof(rPkt.
hdr.
hrt));
1580 uint32_t type, code;
1587 wge100_debug(
"Error: wge100StatusWait returned status %d, code %d\n", type, code);
1592 #define MAX_HORIZ_RESOLUTION 752 1593 #define LINE_NUMBER_MASK 0x3FF 1609 size_t bufsize = 16*1024*1024;
1613 int return_value = 0;
1615 if( setsockopt(s, SOL_SOCKET,SO_RCVBUF, &bufsize,
sizeof(bufsize)) == -1) {
1616 perror(
"Can't set rcvbuf option");
1621 socklen_t bufsizesize =
sizeof(bufsize);
1622 if( getsockopt(s, SOL_SOCKET,SO_RCVBUF, &bufsize, &bufsizesize) == 0) {
1623 wge100_debug(
"Receive buffer size is: %i (%i)\n", bufsize, bufsizesize);
1627 perror(
"Can't read receive buffer size");
1632 frame_buf = malloc(
sizeof(uint8_t)*width*height);
1633 if(frame_buf == NULL) {
1634 perror(
"Can't malloc frame buffer");
1642 perror(
"Can't malloc line packet buffer");
1648 bool firstPacket =
true;
1654 bool frameStartTimeSet;
1669 struct sockaddr_in fromaddr;
1677 uint8_t xorline[
width];
1681 frameComplete =
false;
1682 frameStartTimeSet =
false;
1688 memset(frame_buf, 0, width*height);
1693 if( (eof==NULL) && (firstPacket==
false) ) {
1704 struct timeval readtimeout;
1706 socklen_t fromaddrlen =
sizeof(
struct sockaddr_in);
1707 fromaddr.sin_family = AF_INET;
1712 readtimeout.tv_sec = 1;
1713 readtimeout.tv_usec = 0;
1718 if( select(s+1, &
set, NULL, NULL, &readtimeout) == -1 ) {
1719 perror(
"wge100VidReceive select failed");
1725 if(! FD_ISSET(s, &
set) && errno != EINTR) {
1726 wge100_debug(
"Select timed out. Calling handler.");
1727 handlerReturn = frameHandler(NULL, userData);
1731 }
while (! FD_ISSET(s, &
set));
1737 if( recvfrom( s, vPkt,
sizeof(
HeaderVideoLine)+width, 0, (
struct sockaddr *) &fromaddr, &fromaddrlen ) == -1 ) {
1738 perror(
"wge100VidReceive unable to receive from socket");
1753 wge100_debug(
"Mismatched line/frame numbers: %02X / %02X\n", temp, (vPkt->
header.
frame_number & 0x003F));
1764 if(firstPacket ==
true) {
1765 firstPacket =
false;
1770 if (!frameStartTimeSet)
1772 gettimeofday(&frameInfo.
startTime, NULL);
1773 frameStartTimeSet =
true;
1786 wge100_debug(
"Video aborted\n");
1790 wge100_debug(
"Frame #%u missing EOF, got %i lines\n", frameInfo.
frame_number, lineCount);
1791 frameComplete =
true;
1795 memcpy(xorline, vPkt->
data, width);
1799 frameComplete =
true;
1812 eof->
i2c[i] = ntohs(eof->
i2c[i]);
1815 if(lineCount != height) {
1816 if ((1 == (height - lineCount)) && has_xor) {
1822 memcpy(repair, xorline, width);
1824 for (y = 0; y <
height; y++) {
1826 xormem(repair, &frame_buf[y * width], width);
1842 if(lineCount > height)
1844 wge100_debug(
"Too many lines received for frame!\n")
1856 wge100_debug(
"Frame #%i missed %i line(s) starting at %i src port %i\n", vPkt->
header.
frame_number,
1857 missedLines, lineCount + frameInfo.
missingLines, ntohs(fromaddr.sin_port));
1863 }
while(frameComplete ==
false);
1865 if( frameComplete ==
true ) {
1869 handlerReturn = frameHandler(&frameInfo, userData);
1874 uint8_t dummy = 0xff;
1875 if( sendto( s, &dummy,
sizeof(dummy), 0, (
struct sockaddr *) &fromaddr,
sizeof(fromaddr) ) == -1 ) {
1883 }
while( handlerReturn == 0 );
1886 return return_value;
1890 struct in_addr host_addr;
1893 if( frameHandler == NULL ) {
1894 wge100_debug(
"Invalid frame handler, aborting.\n");
1898 wge100_debug(
"wge100VidReceive ready to receive on %s (%s:%u)\n", ifName, inet_ntoa(host_addr), port);
1909 struct sockaddr localMac;
1910 struct in_addr localIp;
1911 struct sockaddr localPort;
1912 socklen_t localPortLen;
1918 fprintf(stderr,
"Unable to get local IP address for interface %s", camera->
ifName);
1923 fprintf(stderr,
"Unable to get local MAC address for interface %s", camera->
ifName);
1927 if( frameHandler == NULL ) {
1928 wge100_debug(
"Invalid frame handler, aborting.\n");
1937 localPortLen =
sizeof(localPort);
1938 if (getsockname(s, &localPort, &localPortLen) == -1)
1940 fprintf(stderr,
"Unable to get local port for socket.");
1945 port = ntohs(((
struct sockaddr_in *)&localPort)->sin_port);
1948 wge100_debug(
"wge100VidReceiveAuto ready to receive on %s (%s:%u)\n", camera->
ifName, inet_ntoa(localIp), port);
1950 if (
wge100StartVid( camera, (uint8_t *)&(localMac.sa_data[0]), inet_ntoa(localIp), port) != 0 )
1952 wge100_debug(
"Could not start camera streaming.");
int wge100IpGetLocalAddr(const char *ifName, struct in_addr *addr)
int wge100CamListAdd(IpCamList *ipCamList, IpCamList *newItem)
int wge100SocketCreate(const struct in_addr *addr, uint16_t port)
int wge100VidReceiveSocket(int s, size_t height, size_t width, FrameHandler frameHandler, void *userData)
int wge100WaitForPacket(int *s, int nums, uint32_t type, size_t pktLen, uint32_t *wait_us)
char hwinfo[WGE100_CAMINFO_LEN]
uint32_t type
The packet type (see list of packet types, above)
#define STOP_REPLY_TIMEOUT
int wge100SendUDP(int s, const IPAddress *ip, const void *data, size_t dataSize)
int wge100StatusWait(int s, uint32_t wait_us, uint32_t *type, uint32_t *code)
int wge100ConfigureBoard(const IpCamList *camInfo, uint32_t serial, MACAddress *mac)
int wge100Reset(IpCamList *camInfo)
#define PKT_ERROR_SYSERR
An internal system error occurred.
int wge100Configure(IpCamList *camInfo, const char *ipAddress, unsigned wait_us)
HeaderVideoLine header
Standard video line header.
uint8_t index
The index of the register in the EOF packet (range 0..3)
uint8_t data[FLASH_PAGE_SIZE]
32-bit address as specified in the PacketFlashPayload definition
#define TRIG_STATE_INTERNAL
static void xormem(uint8_t *dst, uint8_t *src, size_t w)
uint16_t line_number
Frame/line number as reported by Imager peripheral.
int wge100ImagerSetRes(const IpCamList *camInfo, uint16_t horizontal, uint16_t vertical)
int wge100Discover(const char *ifName, IpCamList *ipCamList, const char *ipAddress, unsigned wait_us)
IPAddress camera_ip
The default power-up IP address for the camera.
#define IMAGER_LINENO_SHORT
Flags a frame as Short (used only by the library)
NetHost reply_to
All packet replies should be directed to this host.
uint32_t status_code
Response code (Error type, etc)
int wge100CmdSocketCreate(const char *ifName, NetHost *localHost)
char hrt[16]
A human-readable text field describing the packet contents.
IPAddress ip_addr
IP Address device should use when responding.
#define PKT_ERROR_TIMEOUT
No valid response was received during the allotted interval.
int wge100IpGetLocalNetmask(const char *ifName, struct in_addr *bcast)
#define WGE100LIB_VERSION
#define IMAGER_MAGICLINE_MASK
Line numbers that match this mask are reserved to indicate special packet types.
int wge100VidReceiveAuto(IpCamList *camera, size_t height, size_t width, FrameHandler frameHandler, void *userData)
#define PKT_STATUST_ERROR
Command could not be completed. See status_code for details.
uint32_t ser_no
Indicates the specific serial number of this unit from the flash.
#define PKT_STATUST_OK
Command completed successfully.
#define list_for_each_entry(pos, head, member)
void wge100CamListDelAll(IpCamList *ipCamList)
uint32_t ticks_lo
32 LSBs of system time base
#define IMAGER_LINENO_OVF
Flags this video packet as being an Overflow packet.
int wge100SensorSelect(const IpCamList *camInfo, uint8_t index, uint32_t reg)
int wge100VidReceive(const char *ifName, uint16_t port, size_t height, size_t width, FrameHandler frameHandler, void *userData)
int wge100CamListInit(IpCamList *ipCamList)
uint32_t frame_number
Frame number as reported by Imager peripheral.
uint16_t vert_resolution
Number of video line packets per frame (not including EOF packet)
int wge100ReliableSensorWrite(const IpCamList *camInfo, uint8_t reg, uint16_t data, int *retries)
uint32_t trig_state
Trigger state configuration.
uint16_t vertical
Number of video lines per frame.
NetHost receiver
Receiver Designation.
int wge100StopVid(const IpCamList *camInfo)
#define WGE100_CAMINFO_LEN
uint16_t horiz_resolution
Number of 8-bit pixels per video line.
int wge100EthGetLocalMac(const char *ifName, struct sockaddr *macAddr)
#define IMAGER_LINENO_XOR
(Not an error) provides an XOR line for the frame (used only by the library)
uint32_t ticks_per_sec
Number of time base ticks that occur per second.
#define IMAGER_LINENO_ABORT
Flags this video packet as being an Abort packet.
uint32_t product_id
Camera Identification Section.
uint32_t mode
The mode number to select (range 0..9)
int wge100ImagerModeSelect(const IpCamList *camInfo, uint32_t mode)
char camera_name[40]
The name assigned to this particular camera. Null terminated string.
#define PKTT_RECONFIG_FPGA
int wge100SensorRead(const IpCamList *camInfo, uint8_t reg, uint16_t *data)
int wge100ReconfigureFPGA(IpCamList *camInfo)
uint32_t magic_no
The Willow Garage Magic number (always WG_MAGIC_NO)
int wge100ReliableSensorRead(const IpCamList *camInfo, uint8_t reg, uint16_t *data, int *retries)
char cam_name[CAMERA_NAME_LEN]
int wge100TriggerControl(const IpCamList *camInfo, uint32_t triggerType)
#define IMAGER_LINENO_ERR
Flags this video packet as being a General Error packet.
PacketGeneric hdr
Generic Command Packet Headers.
#define CONFIG_PRODUCT_ID
int wge100ReliableFlashRead(const IpCamList *camInfo, uint32_t address, uint8_t *pageDataOut, int *retries)
int wge100FlashRead(const IpCamList *camInfo, uint32_t address, uint8_t *pageDataOut)
int wge100SocketConnect(int s, const IPAddress *ip)
uint32_t address
Dataflash page address.
#define STD_REPLY_TIMEOUT
Amount of time in microseconds that the host should wait for packet replies.
#define IMAGER_LINENO_EOF
Flags this video packet as being an normal End Of Frame packet.
static int wge100DiscoverSend(const char *ifName, const char *ipAddress)
int wge100GetTimer(const IpCamList *camInfo, uint64_t *time_us)
uint32_t i2c_valid
Flags that indicate which 'i2c' values were updated during the previous frame.
int wge100FlashWrite(const IpCamList *camInfo, uint32_t address, const uint8_t *pageDataIn)
MACAddress mac
Camera Identification Section.
int(* FrameHandler)(wge100FrameInfo *frame_info, void *userData)
A FrameHandler function returns zero to continue to receive data, non-zero otherwise.
int wge100SendUDPBcast(int s, const char *ifName, const void *data, size_t dataSize)
uint16_t i2c[I2C_REGS_PER_FRAME]
Storage for I2C values read during the frame.
int wge100StartVid(const IpCamList *camInfo, const uint8_t mac[6], const char *ipAddress, uint16_t port)
int wge100ReliableFlashWrite(const IpCamList *camInfo, uint32_t address, const uint8_t *pageDataIn, int *retries)
int wge100SensorWrite(const IpCamList *camInfo, uint8_t reg, uint16_t data)
uint32_t ticks_hi
32 MSBs of system time base
uint32_t status_type
Type of status report (OK, Error, etc)
uint16_t horizontal
Number of 8-bit video pixels per image row.
#define I2C_REGS_PER_FRAME
Number of I2C register to read during each video frame interval.
int wge100FindByUrl(const char *url, IpCamList *camera, unsigned wait_us, const char **errmsg)