Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161026644
D57914.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D57914.diff
View Options
diff --git a/sys/dev/firewire/fwcam.h b/sys/dev/firewire/fwcam.h
--- a/sys/dev/firewire/fwcam.h
+++ b/sys/dev/firewire/fwcam.h
@@ -200,6 +200,70 @@
#define FWCAM_STATE_STREAMING 2
#define FWCAM_STATE_DETACHING 3
+/* IIDC format/mode/rate/feature/state name tables for userland and driver */
+#define FWCAM_FMT_NMAX 8
+#define FWCAM_RATE_NMAX 8
+
+static const char * const fwcam_fmt_names[FWCAM_FMT_NMAX] = {
+ "VGA (Format_0)",
+ "Super VGA 1 (Format_1)",
+ "Super VGA 2 (Format_2)",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Still Image (Format_6)",
+ "Partial Image (Format_7)",
+};
+
+static const char * const fwcam_rate_names[FWCAM_RATE_NMAX] = {
+ "1.875 fps", "3.75 fps", "7.5 fps", "15 fps",
+ "30 fps", "60 fps", "120 fps", "240 fps",
+};
+
+static const char * const fwcam_feat_names[FWCAM_FEAT_MAX] = {
+ [FWCAM_FEAT_BRIGHTNESS] = "brightness",
+ [FWCAM_FEAT_AUTO_EXPOSURE] = "auto_exposure",
+ [FWCAM_FEAT_SHARPNESS] = "sharpness",
+ [FWCAM_FEAT_WHITE_BALANCE] = "white_balance",
+ [FWCAM_FEAT_HUE] = "hue",
+ [FWCAM_FEAT_SATURATION] = "saturation",
+ [FWCAM_FEAT_GAMMA] = "gamma",
+ [FWCAM_FEAT_SHUTTER] = "shutter",
+ [FWCAM_FEAT_GAIN] = "gain",
+ [FWCAM_FEAT_IRIS] = "iris",
+ [FWCAM_FEAT_FOCUS] = "focus",
+ [FWCAM_FEAT_TEMPERATURE] = "temperature",
+ [FWCAM_FEAT_TRIGGER] = "trigger",
+ [FWCAM_FEAT_ZOOM] = "zoom",
+ [FWCAM_FEAT_PAN] = "pan",
+ [FWCAM_FEAT_TILT] = "tilt",
+};
+
+static const char * const fwcam_state_names[] = {
+ [FWCAM_STATE_IDLE] = "idle",
+ [FWCAM_STATE_PROBED] = "probed",
+ [FWCAM_STATE_STREAMING] = "streaming",
+ [FWCAM_STATE_DETACHING] = "detaching",
+};
+
+/* Format_0 (VGA non-compressed) mode geometry */
+struct fwcam_fmt0_mode {
+ int w, h;
+ const char *pixfmt;
+};
+
+#define FWCAM_FMT0_NMODES 7
+
+static const struct fwcam_fmt0_mode fwcam_fmt0_modes[FWCAM_FMT0_NMODES] = {
+ { 160, 120, "YUV444" }, /* mode 0 */
+ { 320, 240, "YUV422" }, /* mode 1 */
+ { 640, 480, "YUV411" }, /* mode 2 */
+ { 640, 480, "YUV422" }, /* mode 3 */
+ { 640, 480, "RGB8" }, /* mode 4 */
+ { 640, 480, "Mono8" }, /* mode 5 */
+ { 640, 480, "Mono16" }, /* mode 6 */
+};
+
/*
* Internal constants
*/
diff --git a/sys/dev/firewire/fwcam.c b/sys/dev/firewire/fwcam.c
--- a/sys/dev/firewire/fwcam.c
+++ b/sys/dev/firewire/fwcam.c
@@ -149,27 +149,6 @@
return (err);
}
-#if 0
-static const char *
-fwcam_format_name(int format)
-{
- static const char *names[] = {
- "VGA (Format_0)",
- "Super VGA 1 (Format_1)",
- "Super VGA 2 (Format_2)",
- "Reserved",
- "Reserved",
- "Reserved",
- "Still Image (Format_6)",
- "Partial Image (Format_7)",
- };
-
- if (format >= 0 && format <= 7)
- return (names[format]);
- return ("Unknown");
-}
-#endif
-
static int
fwcam_read_capabilities(struct fwcam_softc *sc)
{
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -27,6 +27,7 @@
extattrctl \
fifolog \
fstyp \
+ fwcamctl \
fwcontrol \
fwget \
getfmac \
diff --git a/usr.sbin/fwcamctl/Makefile b/usr.sbin/fwcamctl/Makefile
new file mode 100644
--- /dev/null
+++ b/usr.sbin/fwcamctl/Makefile
@@ -0,0 +1,9 @@
+PROG= fwcamctl
+SRCS= fwcamctl.c
+MAN= fwcamctl.8
+WARNS?= 3
+
+SDIR= ${SRCTOP}/sys
+CFLAGS+= -I${SDIR}
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/fwcamctl/fwcamctl.8 b/usr.sbin/fwcamctl/fwcamctl.8
new file mode 100644
--- /dev/null
+++ b/usr.sbin/fwcamctl/fwcamctl.8
@@ -0,0 +1,156 @@
+.\" Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd May 27, 2026
+.Dt FWCAMCTL 8
+.Os
+.Sh NAME
+.Nm fwcamctl
+.Nd control utility for IIDC FireWire cameras
+.Sh SYNOPSIS
+.Nm
+.Op Fl f Ar device
+.Cm info
+.Nm
+.Op Fl f Ar device
+.Cm snap
+.Op Fl o Ar output.ppm
+.Op Fl s Ar skip
+.Nm
+.Op Fl f Ar device
+.Cm mode
+.Ar format mode rate
+.Nm
+.Op Fl f Ar device
+.Cm feat get
+.Ar id
+.Nm
+.Op Fl f Ar device
+.Cm feat set
+.Ar id value Op Ar value2
+.Sh DESCRIPTION
+The
+.Nm
+utility controls IIDC 1394-based digital cameras via the
+.Xr fwcam 4
+driver.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl f Ar device
+Specify the camera device.
+Defaults to
+.Pa /dev/fwcam0 .
+.El
+.Pp
+The subcommands are:
+.Bl -tag -width indent
+.It Cm info
+Display camera state, current format/mode/framerate, supported formats,
+basic function capabilities, and present features.
+.It Cm snap Op Fl o Ar output.ppm Op Fl s Ar skip
+Capture a single video frame and write it as a PPM image.
+.Pp
+.Bl -tag -width indent -compact
+.It Fl o Ar output.ppm
+Output file path.
+Use
+.Sq -
+for stdout.
+Defaults to
+.Pa snap.ppm .
+.It Fl s Ar skip
+Number of frames to skip before capturing, to allow auto-exposure
+and auto-white-balance to settle.
+Defaults to 5.
+.El
+.Pp
+Supported pixel formats: YUV444, YUV422, YUV411, RGB8, Mono8.
+The frame is converted to RGB24 and written as a binary PPM (P6).
+.It Cm mode Ar format mode rate
+Set the camera video format, mode, and frame rate.
+All arguments are integer indices per the IIDC specification.
+Only Format_0 (VGA) is currently supported by the
+.Xr fwcam 4
+frame assembly path.
+.Pp
+Format_0 modes:
+.Bl -column "Mode" "Resolution" "Pixel format" -compact
+.It Em Mode Ta Em Resolution Ta Em Pixel format
+.It 0 Ta 160x120 Ta YUV444
+.It 1 Ta 320x240 Ta YUV422
+.It 2 Ta 640x480 Ta YUV411
+.It 3 Ta 640x480 Ta YUV422
+.It 4 Ta 640x480 Ta RGB8
+.It 5 Ta 640x480 Ta Mono8
+.El
+.Pp
+Frame rates: 0=1.875 1=3.75 2=7.5 3=15 4=30 5=60 fps.
+.It Cm feat get Ar id
+Query the camera feature with the given numeric ID and display its
+inquiry (presence, on/off, auto, manual, range) and current value.
+.It Cm feat set Ar id value Op Ar value2
+Set the camera feature with the given numeric ID to
+.Ar value .
+For the
+.Sq white_balance
+feature (id 3),
+.Ar value
+is the U/B component and
+.Ar value2
+is the V/R component.
+.El
+.Pp
+Feature IDs:
+.Bl -column "ID" "Name" -compact
+.It Em ID Ta Em Name
+.It 0 Ta brightness
+.It 1 Ta auto_exposure
+.It 2 Ta sharpness
+.It 3 Ta white_balance
+.It 4 Ta hue
+.It 5 Ta saturation
+.It 6 Ta gamma
+.It 7 Ta shutter
+.It 8 Ta gain
+.It 9 Ta iris
+.It 10 Ta focus
+.It 11 Ta temperature
+.It 12 Ta trigger
+.It 13 Ta zoom
+.It 14 Ta pan
+.It 15 Ta tilt
+.El
+.Sh EXAMPLES
+Show camera information:
+.Bd -literal -offset indent
+fwcamctl info
+.Ed
+.Pp
+Capture a photo to
+.Pa photo.ppm ,
+skipping 10 frames for AE to settle:
+.Bd -literal -offset indent
+fwcamctl snap -o photo.ppm -s 10
+.Ed
+.Pp
+Switch to 320x240 YUV422 at 30 fps:
+.Bd -literal -offset indent
+fwcamctl mode 0 1 4
+.Ed
+.Pp
+Read the current gain value:
+.Bd -literal -offset indent
+fwcamctl feat get 8
+.Ed
+.Pp
+Set brightness to 200:
+.Bd -literal -offset indent
+fwcamctl feat set 0 200
+.Ed
+.Sh SEE ALSO
+.Xr fwcam 4 ,
+.Xr fwcontrol 8
+.Sh AUTHORS
+.An Abdelkader Boudih Aq Mt freebsd@seuros.com
diff --git a/usr.sbin/fwcamctl/fwcamctl.c b/usr.sbin/fwcamctl/fwcamctl.c
new file mode 100644
--- /dev/null
+++ b/usr.sbin/fwcamctl/fwcamctl.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * fwcamctl - control utility for fwcam(4) IIDC FireWire cameras
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <dev/firewire/fwcam.h>
+
+static const char *default_dev = "/dev/fwcam0";
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "usage: fwcamctl [-f device] info\n"
+ " fwcamctl [-f device] snap [-o output.ppm] [-s skip]\n"
+ " fwcamctl [-f device] mode <format> <mode> <rate>\n"
+ " fwcamctl [-f device] feat get <id>\n"
+ " fwcamctl [-f device] feat set <id> <value> [value2]\n"
+ "\n"
+ " Feature IDs: 0=brightness 1=auto_exposure 2=sharpness\n"
+ " 3=white_balance 4=hue 5=saturation 6=gamma\n"
+ " 7=shutter 8=gain 9=iris 10=focus 11=temperature\n"
+ " 12=trigger 13=zoom 14=pan 15=tilt\n");
+ exit(1);
+}
+
+static inline int
+clamp_u8(int v)
+{
+ if (v < 0) return (0);
+ if (v > 255) return (255);
+ return (v);
+}
+
+/*
+ * IIDC YUV 4:2:2 → RGB24
+ * IIDC spec layout: U0 Y0 V0 Y1 (UYVY, 2 pixels per 4 bytes)
+ */
+static void
+yuv422_to_rgb(const uint8_t *src, uint8_t *dst, int w, int h)
+{
+ int i, n = w * h / 2;
+
+ for (i = 0; i < n; i++) {
+ int cb = src[0] - 128;
+ int y0 = src[1];
+ int cr = src[2] - 128;
+ int y1 = src[3];
+ src += 4;
+
+ /* pixel 0 */
+ dst[0] = clamp_u8(y0 + (int)(1.402f * cr));
+ dst[1] = clamp_u8(y0 - (int)(0.34414f * cb) - (int)(0.71414f * cr));
+ dst[2] = clamp_u8(y0 + (int)(1.772f * cb));
+ /* pixel 1 */
+ dst[3] = clamp_u8(y1 + (int)(1.402f * cr));
+ dst[4] = clamp_u8(y1 - (int)(0.34414f * cb) - (int)(0.71414f * cr));
+ dst[5] = clamp_u8(y1 + (int)(1.772f * cb));
+ dst += 6;
+ }
+}
+
+/*
+ * IIDC YUV 4:1:1 → RGB24
+ * Layout: U0 Y0 Y1 V0 Y2 Y3 (4 pixels per 6 bytes)
+ */
+static void
+yuv411_to_rgb(const uint8_t *src, uint8_t *dst, int w, int h)
+{
+ int i, j, n = w * h / 4;
+
+ for (i = 0; i < n; i++) {
+ int cb = src[0] - 128;
+ int y[4];
+ y[0] = src[1];
+ y[1] = src[2];
+ int cr = src[3] - 128;
+ y[2] = src[4];
+ y[3] = src[5];
+ src += 6;
+
+ for (j = 0; j < 4; j++) {
+ *dst++ = clamp_u8(y[j] + (int)(1.402f * cr));
+ *dst++ = clamp_u8(y[j] - (int)(0.34414f * cb) - (int)(0.71414f * cr));
+ *dst++ = clamp_u8(y[j] + (int)(1.772f * cb));
+ }
+ }
+}
+
+/*
+ * IIDC YUV 4:4:4 → RGB24
+ * Layout: U Y V (3 bytes/pixel)
+ */
+static void
+yuv444_to_rgb(const uint8_t *src, uint8_t *dst, int w, int h)
+{
+ int i, n = w * h;
+
+ for (i = 0; i < n; i++) {
+ int cb = src[0] - 128;
+ int y = src[1];
+ int cr = src[2] - 128;
+ src += 3;
+
+ *dst++ = clamp_u8(y + (int)(1.402f * cr));
+ *dst++ = clamp_u8(y - (int)(0.34414f * cb) - (int)(0.71414f * cr));
+ *dst++ = clamp_u8(y + (int)(1.772f * cb));
+ }
+}
+
+static int
+write_ppm(const char *path, const uint8_t *rgb, int w, int h)
+{
+ FILE *f;
+
+ if (strcmp(path, "-") == 0) {
+ f = stdout;
+ } else {
+ f = fopen(path, "wb");
+ if (f == NULL) {
+ warn("fopen %s", path);
+ return (-1);
+ }
+ }
+
+ fprintf(f, "P6\n%d %d\n255\n", w, h);
+ if (fwrite(rgb, 1, (size_t)(w * h * 3), f) != (size_t)(w * h * 3)) {
+ warn("fwrite");
+ if (f != stdout)
+ fclose(f);
+ return (-1);
+ }
+
+ if (f != stdout)
+ fclose(f);
+ return (0);
+}
+
+static int
+do_snap(int fd, const char *outpath, int skip)
+{
+ struct fwcam_info info;
+ uint8_t *frame_buf, *rgb_buf;
+ uint32_t rgb_size;
+ ssize_t n;
+ int w, h, i;
+ const char *pixfmt;
+
+ if (ioctl(fd, FWCAM_GINFO, &info) < 0)
+ err(1, "FWCAM_GINFO");
+
+ if (info.frame_size == 0)
+ errx(1, "frame_size is 0 — camera not yet probed?");
+
+ if (info.cur_format != IIDC_FMT_VGA ||
+ info.cur_mode >= nitems(fwcam_fmt0_modes))
+ errx(1, "unsupported format %d mode %d for snap "
+ "(only Format_0 VGA supported)",
+ info.cur_format, info.cur_mode);
+
+ w = fwcam_fmt0_modes[info.cur_mode].w;
+ h = fwcam_fmt0_modes[info.cur_mode].h;
+ pixfmt = fwcam_fmt0_modes[info.cur_mode].pixfmt;
+
+ if (strcmp(pixfmt, "Mono16") == 0)
+ errx(1, "Mono16 not supported for PPM output");
+
+ rgb_size = (uint32_t)(w * h * 3);
+ frame_buf = malloc(info.frame_size);
+ rgb_buf = malloc(rgb_size);
+ if (frame_buf == NULL || rgb_buf == NULL)
+ err(1, "malloc");
+
+ /* Read frames; skip the first N to let AE/AWB settle */
+ for (i = 0; i <= skip; i++) {
+ n = read(fd, frame_buf, info.frame_size);
+ if (n < 0)
+ err(1, "read");
+ if ((uint32_t)n < info.frame_size)
+ errx(1, "short read: got %zd of %u bytes",
+ n, info.frame_size);
+ if (i < skip)
+ fprintf(stderr, "skipping frame %d/%d...\n", i + 1, skip);
+ }
+
+ /* Convert to RGB24 */
+ if (strcmp(pixfmt, "YUV422") == 0) {
+ yuv422_to_rgb(frame_buf, rgb_buf, w, h);
+ } else if (strcmp(pixfmt, "YUV411") == 0) {
+ yuv411_to_rgb(frame_buf, rgb_buf, w, h);
+ } else if (strcmp(pixfmt, "YUV444") == 0) {
+ yuv444_to_rgb(frame_buf, rgb_buf, w, h);
+ } else if (strcmp(pixfmt, "RGB8") == 0) {
+ memcpy(rgb_buf, frame_buf, rgb_size);
+ } else if (strcmp(pixfmt, "Mono8") == 0) {
+ for (i = 0; i < w * h; i++) {
+ rgb_buf[i * 3 + 0] = frame_buf[i];
+ rgb_buf[i * 3 + 1] = frame_buf[i];
+ rgb_buf[i * 3 + 2] = frame_buf[i];
+ }
+ } else {
+ errx(1, "no converter for pixel format %s", pixfmt);
+ }
+
+ if (write_ppm(outpath, rgb_buf, w, h) < 0) {
+ free(frame_buf);
+ free(rgb_buf);
+ return (1);
+ }
+
+ fprintf(stderr, "saved %s (%dx%d %s, %u bytes raw)\n",
+ outpath, w, h, pixfmt, info.frame_size);
+
+ free(frame_buf);
+ free(rgb_buf);
+ return (0);
+}
+
+static void
+do_info(int fd)
+{
+ struct fwcam_info info;
+ int i;
+
+ if (ioctl(fd, FWCAM_GINFO, &info) < 0)
+ err(1, "FWCAM_GINFO");
+
+ printf("state: %s\n",
+ info.state < nitems(fwcam_state_names) ?
+ fwcam_state_names[info.state] : "unknown");
+ printf("cur format: %d (%s)\n", info.cur_format,
+ info.cur_format < nitems(fwcam_fmt_names) ?
+ fwcam_fmt_names[info.cur_format] : "?");
+
+ if (info.cur_format == IIDC_FMT_VGA &&
+ info.cur_mode < nitems(fwcam_fmt0_modes)) {
+ printf("cur mode: %d (%dx%d %s)\n", info.cur_mode,
+ fwcam_fmt0_modes[info.cur_mode].w,
+ fwcam_fmt0_modes[info.cur_mode].h,
+ fwcam_fmt0_modes[info.cur_mode].pixfmt);
+ } else {
+ printf("cur mode: %d\n", info.cur_mode);
+ }
+
+ printf("cur rate: %d (%s)\n", info.cur_framerate,
+ info.cur_framerate < nitems(fwcam_rate_names) ?
+ fwcam_rate_names[info.cur_framerate] : "?");
+ printf("iso_channel: %u\n", info.iso_channel);
+ printf("frame_size: %u bytes\n", info.frame_size);
+ printf("dropped: %u frames\n", info.frame_dropped);
+
+ printf("formats: 0x%08x (", info.formats);
+ for (i = 0; i < 8; i++) {
+ if (info.formats & (1 << (31 - i)))
+ printf("F%d ", i);
+ }
+ printf(")\n");
+
+ printf("basic_func: 0x%08x", info.basic_func);
+ if (info.basic_func & IIDC_CAM_POWER_CTRL) printf(" [power_ctrl]");
+ if (info.basic_func & IIDC_ONE_SHOT_INQ) printf(" [one_shot]");
+ if (info.basic_func & IIDC_MULTI_SHOT_INQ) printf(" [multi_shot]");
+ printf("\n");
+
+ printf("features: hi=0x%08x lo=0x%08x\n",
+ info.features_hi, info.features_lo);
+ if (info.features_hi) {
+ printf(" ");
+ if (info.features_hi & IIDC_HAS_BRIGHTNESS) printf("brightness ");
+ if (info.features_hi & IIDC_HAS_AUTO_EXPOSURE) printf("auto_exp ");
+ if (info.features_hi & IIDC_HAS_SHARPNESS) printf("sharpness ");
+ if (info.features_hi & IIDC_HAS_WHITE_BALANCE) printf("white_bal ");
+ if (info.features_hi & IIDC_HAS_HUE) printf("hue ");
+ if (info.features_hi & IIDC_HAS_SATURATION) printf("saturation ");
+ if (info.features_hi & IIDC_HAS_GAMMA) printf("gamma ");
+ if (info.features_hi & IIDC_HAS_SHUTTER) printf("shutter ");
+ if (info.features_hi & IIDC_HAS_GAIN) printf("gain ");
+ if (info.features_hi & IIDC_HAS_IRIS) printf("iris ");
+ if (info.features_hi & IIDC_HAS_FOCUS) printf("focus ");
+ if (info.features_hi & IIDC_HAS_TEMPERATURE) printf("temperature ");
+ if (info.features_hi & IIDC_HAS_TRIGGER) printf("trigger ");
+ printf("\n");
+ }
+}
+
+static void
+do_mode(int fd, int argc, char **argv)
+{
+ struct fwcam_mode mode;
+
+ if (argc < 3)
+ usage();
+
+ mode.format = (uint8_t)atoi(argv[0]);
+ mode.mode = (uint8_t)atoi(argv[1]);
+ mode.framerate = (uint8_t)atoi(argv[2]);
+ mode.frame_size = 0;
+ mode._pad = 0;
+
+ if (ioctl(fd, FWCAM_SMODE, &mode) < 0)
+ err(1, "FWCAM_SMODE");
+
+ printf("mode set: format=%d mode=%d framerate=%d frame_size=%u\n",
+ mode.format, mode.mode, mode.framerate, mode.frame_size);
+}
+
+static void
+do_feat_get(int fd, int feat_id)
+{
+ struct fwcam_feature feat;
+
+ if (feat_id < 0 || feat_id >= FWCAM_FEAT_MAX)
+ errx(1, "invalid feature id %d (0-%d)", feat_id, FWCAM_FEAT_MAX - 1);
+
+ memset(&feat, 0, sizeof(feat));
+ feat.id = (uint32_t)feat_id;
+
+ if (ioctl(fd, FWCAM_GFEAT, &feat) < 0)
+ err(1, "FWCAM_GFEAT");
+
+ printf("feature %d (%s):\n", feat_id,
+ fwcam_feat_names[feat_id] != NULL ? fwcam_feat_names[feat_id] : "?");
+ printf(" present: %s\n",
+ (feat.flags & FWCAM_FEATF_PRESENT) ? "yes" : "no");
+ printf(" flags: 0x%x", feat.flags);
+ if (feat.flags & FWCAM_FEATF_ONOFF) printf(" [on/off]");
+ if (feat.flags & FWCAM_FEATF_AUTO) printf(" [auto]");
+ if (feat.flags & FWCAM_FEATF_MANUAL) printf(" [manual]");
+ printf("\n");
+ printf(" range: %u - %u\n", feat.min, feat.max);
+
+ if (feat_id == FWCAM_FEAT_WHITE_BALANCE)
+ printf(" value: U/B=%u V/R=%u\n", feat.value, feat.value2);
+ else
+ printf(" value: %u\n", feat.value);
+}
+
+static void
+do_feat_set(int fd, int feat_id, uint32_t value, uint32_t value2)
+{
+ struct fwcam_feature feat;
+
+ if (feat_id < 0 || feat_id >= FWCAM_FEAT_MAX)
+ errx(1, "invalid feature id %d (0-%d)", feat_id, FWCAM_FEAT_MAX - 1);
+
+ memset(&feat, 0, sizeof(feat));
+ feat.id = (uint32_t)feat_id;
+ feat.value = value;
+ feat.value2 = value2;
+
+ if (ioctl(fd, FWCAM_SFEAT, &feat) < 0)
+ err(1, "FWCAM_SFEAT");
+
+ printf("feature %d (%s) set to %u\n", feat_id,
+ fwcam_feat_names[feat_id] != NULL ? fwcam_feat_names[feat_id] : "?", value);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *devpath = default_dev;
+ int fd, ch;
+
+ while ((ch = getopt(argc, argv, "f:")) != -1) {
+ switch (ch) {
+ case 'f':
+ devpath = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1)
+ usage();
+
+ fd = open(devpath, O_RDWR);
+ if (fd < 0)
+ err(1, "open %s", devpath);
+
+ if (strcmp(argv[0], "info") == 0) {
+ do_info(fd);
+
+ } else if (strcmp(argv[0], "snap") == 0) {
+ const char *out = "snap.ppm";
+ int skip = 5;
+
+ /* re-parse the snap subcommand's own flags */
+ optreset = 1;
+ optind = 1;
+ while ((ch = getopt(argc, argv, "o:s:")) != -1) {
+ switch (ch) {
+ case 'o':
+ out = optarg;
+ break;
+ case 's':
+ skip = atoi(optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+ do_snap(fd, out, skip);
+
+ } else if (strcmp(argv[0], "mode") == 0) {
+ do_mode(fd, argc - 1, argv + 1);
+
+ } else if (strcmp(argv[0], "feat") == 0) {
+ if (argc < 3)
+ usage();
+
+ int feat_id = atoi(argv[2]);
+
+ if (strcmp(argv[1], "get") == 0) {
+ do_feat_get(fd, feat_id);
+ } else if (strcmp(argv[1], "set") == 0) {
+ if (argc < 4)
+ usage();
+ uint32_t val = (uint32_t)atoi(argv[3]);
+ uint32_t val2 = (argc > 4) ? (uint32_t)atoi(argv[4]) : 0;
+ do_feat_set(fd, feat_id, val, val2);
+ } else {
+ usage();
+ }
+
+ } else {
+ warnx("unknown command: %s", argv[0]);
+ usage();
+ }
+
+ close(fd);
+ return (0);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jun 30, 11:07 PM (8 h, 31 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34497629
Default Alt Text
D57914.diff (18 KB)
Attached To
Mode
D57914: fwcamctl: add control utility for fwcam(4) IIDC FireWire cameras
Attached
Detach File
Event Timeline
Log In to Comment