uvc-gadget: Constify request data pointers
[uvc-gadget.git] / uvc-gadget.c
1 /*
2  * UVC gadget test application
3  *
4  * Copyright (C) 2010 Ideas on board SPRL <laurent.pinchart@ideasonboard.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  */
19
20 #include <sys/ioctl.h>
21 #include <sys/mman.h>
22 #include <sys/select.h>
23 #include <sys/stat.h>
24 #include <sys/time.h>
25 #include <sys/types.h>
26
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 #include <linux/usb/ch9.h>
37 #include <linux/usb/g_uvc.h>
38 #include <linux/usb/video.h>
39 #include <linux/videodev2.h>
40
41 #include "events.h"
42 #include "tools.h"
43 #include "v4l2.h"
44
45 #define UVC_INTF_CONTROL        0
46 #define UVC_INTF_STREAMING      1
47
48 struct uvc_device
49 {
50         struct v4l2_device *vdev;
51
52         struct uvc_streaming_control probe;
53         struct uvc_streaming_control commit;
54
55         int control;
56
57         unsigned int fcc;
58         unsigned int width;
59         unsigned int height;
60
61         unsigned int bulk;
62         uint8_t color;
63         unsigned int imgsize;
64         void *imgdata;
65
66         struct events events;
67 };
68
69 static struct uvc_device *
70 uvc_open(const char *devname)
71 {
72         struct uvc_device *dev;
73
74         dev = malloc(sizeof *dev);
75         if (dev == NULL)
76                 return NULL;
77
78         memset(dev, 0, sizeof *dev);
79
80         dev->vdev = v4l2_open(devname);
81         if (dev->vdev == NULL) {
82                 free(dev);
83                 return NULL;
84         }
85
86         events_init(&dev->events);
87
88         return dev;
89 }
90
91 static void
92 uvc_close(struct uvc_device *dev)
93 {
94         v4l2_close(dev->vdev);
95         dev->vdev = NULL;
96
97         free(dev->imgdata);
98         free(dev);
99 }
100
101 /* ---------------------------------------------------------------------------
102  * Video streaming
103  */
104
105 static void
106 uvc_video_fill_buffer(struct uvc_device *dev, struct v4l2_video_buffer *buf)
107 {
108         unsigned int bpl;
109         unsigned int i;
110
111         switch (dev->fcc) {
112         case V4L2_PIX_FMT_YUYV:
113                 /* Fill the buffer with video data. */
114                 bpl = dev->width * 2;
115                 for (i = 0; i < dev->height; ++i)
116                         memset(buf->mem + i*bpl, dev->color++, bpl);
117
118                 buf->bytesused = bpl * dev->height;
119                 break;
120
121         case V4L2_PIX_FMT_MJPEG:
122                 memcpy(buf->mem, dev->imgdata, dev->imgsize);
123                 buf->bytesused = dev->imgsize;
124                 break;
125         }
126 }
127
128 static void
129 uvc_video_process(void *d)
130 {
131         struct uvc_device *dev = d;
132         struct v4l2_video_buffer buf;
133         int ret;
134
135         ret = v4l2_dequeue_buffer(dev->vdev, &buf);
136         if (ret < 0)
137                 return;
138
139         uvc_video_fill_buffer(dev, &buf);
140
141         v4l2_queue_buffer(dev->vdev, &buf);
142 }
143
144 static int
145 uvc_video_stream(struct uvc_device *dev, int enable)
146 {
147         unsigned int i;
148         int ret;
149
150         if (!enable) {
151                 printf("Stopping video stream.\n");
152                 events_unwatch_fd(&dev->events, dev->vdev->fd, EVENT_WRITE);
153                 v4l2_stream_off(dev->vdev);
154                 v4l2_free_buffers(dev->vdev);
155                 return 0;
156         }
157
158         printf("Starting video stream.\n");
159
160         ret = v4l2_alloc_buffers(dev->vdev, V4L2_MEMORY_MMAP, 4);
161         if (ret < 0) {
162                 printf("Failed to allocate buffers.\n");
163                 return ret;
164         }
165
166         ret = v4l2_mmap_buffers(dev->vdev);
167         if (ret < 0) {
168                 printf("Failed to mmap buffers.\n");
169                 goto error;
170         }
171
172         for (i = 0; i < dev->vdev->nbufs; ++i) {
173                 struct v4l2_video_buffer *buf = &dev->vdev->buffers[i];
174
175                 uvc_video_fill_buffer(dev, buf);
176
177                 ret = v4l2_queue_buffer(dev->vdev, buf);
178                 if (ret < 0)
179                         goto error;
180         }
181
182         v4l2_stream_on(dev->vdev);
183         events_watch_fd(&dev->events, dev->vdev->fd, EVENT_WRITE,
184                         uvc_video_process, dev);
185
186         return 0;
187
188 error:
189         v4l2_free_buffers(dev->vdev);
190         return ret;
191 }
192
193 static int
194 uvc_video_set_format(struct uvc_device *dev)
195 {
196         struct v4l2_pix_format fmt;
197
198         printf("Setting format to 0x%08x %ux%u\n",
199                 dev->fcc, dev->width, dev->height);
200
201         memset(&fmt, 0, sizeof fmt);
202         fmt.width = dev->width;
203         fmt.height = dev->height;
204         fmt.pixelformat = dev->fcc;
205         fmt.field = V4L2_FIELD_NONE;
206         if (dev->fcc == V4L2_PIX_FMT_MJPEG)
207                 fmt.sizeimage = dev->imgsize * 1.5;
208
209         return v4l2_set_format(dev->vdev, &fmt);
210 }
211
212 static int
213 uvc_video_init(struct uvc_device *dev __attribute__((__unused__)))
214 {
215         return 0;
216 }
217
218 /* ---------------------------------------------------------------------------
219  * Request processing
220  */
221
222 struct uvc_frame_info
223 {
224         unsigned int width;
225         unsigned int height;
226         unsigned int intervals[8];
227 };
228
229 struct uvc_format_info
230 {
231         unsigned int fcc;
232         const struct uvc_frame_info *frames;
233 };
234
235 static const struct uvc_frame_info uvc_frames_yuyv[] = {
236         {  640, 360, { 666666, 10000000, 50000000, 0 }, },
237         { 1280, 720, { 50000000, 0 }, },
238         { 0, 0, { 0, }, },
239 };
240
241 static const struct uvc_frame_info uvc_frames_mjpeg[] = {
242         {  640, 360, { 666666, 10000000, 50000000, 0 }, },
243         { 1280, 720, { 50000000, 0 }, },
244         { 0, 0, { 0, }, },
245 };
246
247 static const struct uvc_format_info uvc_formats[] = {
248         { V4L2_PIX_FMT_YUYV, uvc_frames_yuyv },
249         { V4L2_PIX_FMT_MJPEG, uvc_frames_mjpeg },
250 };
251
252 static void
253 uvc_fill_streaming_control(struct uvc_device *dev,
254                            struct uvc_streaming_control *ctrl,
255                            int iformat, int iframe, unsigned int ival)
256 {
257         const struct uvc_format_info *format;
258         const struct uvc_frame_info *frame;
259         const unsigned int *interval;
260         unsigned int nframes;
261
262         /*
263          * Restrict the iformat, iframe and ival to valid values. Negative
264          * values for iformat or iframe will result in the maximum valid value
265          * being selected.
266          */
267         iformat = clamp((unsigned int)iformat, 1U,
268                         (unsigned int)ARRAY_SIZE(uvc_formats));
269         format = &uvc_formats[iformat-1];
270
271         nframes = 0;
272         while (format->frames[nframes].width != 0)
273                 ++nframes;
274
275         iframe = clamp((unsigned int)iframe, 1U, nframes);
276         frame = &format->frames[iframe-1];
277
278         interval = frame->intervals;
279         while (interval[0] < ival && interval[1])
280                 ++interval;
281
282         memset(ctrl, 0, sizeof *ctrl);
283
284         ctrl->bmHint = 1;
285         ctrl->bFormatIndex = iformat;
286         ctrl->bFrameIndex = iframe ;
287         ctrl->dwFrameInterval = *interval;
288
289         switch (format->fcc) {
290         case V4L2_PIX_FMT_YUYV:
291                 ctrl->dwMaxVideoFrameSize = frame->width * frame->height * 2;
292                 break;
293         case V4L2_PIX_FMT_MJPEG:
294                 ctrl->dwMaxVideoFrameSize = dev->imgsize;
295                 break;
296         }
297
298         ctrl->dwMaxPayloadTransferSize = 512;   /* TODO this should be filled by the driver. */
299         ctrl->bmFramingInfo = 3;
300         ctrl->bPreferedVersion = 1;
301         ctrl->bMaxVersion = 1;
302 }
303
304 static void
305 uvc_events_process_standard(struct uvc_device *dev,
306                             const struct usb_ctrlrequest *ctrl,
307                             struct uvc_request_data *resp)
308 {
309         printf("standard request\n");
310         (void)dev;
311         (void)ctrl;
312         (void)resp;
313 }
314
315 static void
316 uvc_events_process_control(struct uvc_device *dev, uint8_t req, uint8_t cs,
317                            struct uvc_request_data *resp)
318 {
319         printf("control request (req %02x cs %02x)\n", req, cs);
320         (void)dev;
321         (void)resp;
322 }
323
324 static void
325 uvc_events_process_streaming(struct uvc_device *dev, uint8_t req, uint8_t cs,
326                              struct uvc_request_data *resp)
327 {
328         struct uvc_streaming_control *ctrl;
329
330         printf("streaming request (req %02x cs %02x)\n", req, cs);
331
332         if (cs != UVC_VS_PROBE_CONTROL && cs != UVC_VS_COMMIT_CONTROL)
333                 return;
334
335         ctrl = (struct uvc_streaming_control *)&resp->data;
336         resp->length = sizeof *ctrl;
337
338         switch (req) {
339         case UVC_SET_CUR:
340                 dev->control = cs;
341                 resp->length = 34;
342                 break;
343
344         case UVC_GET_CUR:
345                 if (cs == UVC_VS_PROBE_CONTROL)
346                         memcpy(ctrl, &dev->probe, sizeof *ctrl);
347                 else
348                         memcpy(ctrl, &dev->commit, sizeof *ctrl);
349                 break;
350
351         case UVC_GET_MIN:
352         case UVC_GET_MAX:
353         case UVC_GET_DEF:
354                 uvc_fill_streaming_control(dev, ctrl, req == UVC_GET_MAX ? -1 : 1,
355                                            req == UVC_GET_MAX ? -1 : 1, 0);
356                 break;
357
358         case UVC_GET_RES:
359                 memset(ctrl, 0, sizeof *ctrl);
360                 break;
361
362         case UVC_GET_LEN:
363                 resp->data[0] = 0x00;
364                 resp->data[1] = 0x22;
365                 resp->length = 2;
366                 break;
367
368         case UVC_GET_INFO:
369                 resp->data[0] = 0x03;
370                 resp->length = 1;
371                 break;
372         }
373 }
374
375 static void
376 uvc_events_process_class(struct uvc_device *dev,
377                          const struct usb_ctrlrequest *ctrl,
378                          struct uvc_request_data *resp)
379 {
380         if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE)
381                 return;
382
383         switch (ctrl->wIndex & 0xff) {
384         case UVC_INTF_CONTROL:
385                 uvc_events_process_control(dev, ctrl->bRequest, ctrl->wValue >> 8, resp);
386                 break;
387
388         case UVC_INTF_STREAMING:
389                 uvc_events_process_streaming(dev, ctrl->bRequest, ctrl->wValue >> 8, resp);
390                 break;
391
392         default:
393                 break;
394         }
395 }
396
397 static void
398 uvc_events_process_setup(struct uvc_device *dev,
399                          const struct usb_ctrlrequest *ctrl,
400                          struct uvc_request_data *resp)
401 {
402         dev->control = 0;
403
404         printf("bRequestType %02x bRequest %02x wValue %04x wIndex %04x "
405                 "wLength %04x\n", ctrl->bRequestType, ctrl->bRequest,
406                 ctrl->wValue, ctrl->wIndex, ctrl->wLength);
407
408         switch (ctrl->bRequestType & USB_TYPE_MASK) {
409         case USB_TYPE_STANDARD:
410                 uvc_events_process_standard(dev, ctrl, resp);
411                 break;
412
413         case USB_TYPE_CLASS:
414                 uvc_events_process_class(dev, ctrl, resp);
415                 break;
416
417         default:
418                 break;
419         }
420 }
421
422 static void
423 uvc_events_process_data(struct uvc_device *dev,
424                         const struct uvc_request_data *data)
425 {
426         const struct uvc_streaming_control *ctrl =
427                 (const struct uvc_streaming_control *)&data->data;
428         struct uvc_streaming_control *target;
429
430         switch (dev->control) {
431         case UVC_VS_PROBE_CONTROL:
432                 printf("setting probe control, length = %d\n", data->length);
433                 target = &dev->probe;
434                 break;
435
436         case UVC_VS_COMMIT_CONTROL:
437                 printf("setting commit control, length = %d\n", data->length);
438                 target = &dev->commit;
439                 break;
440
441         default:
442                 printf("setting unknown control, length = %d\n", data->length);
443                 return;
444         }
445
446         uvc_fill_streaming_control(dev, target, ctrl->bFormatIndex,
447                                    ctrl->bFrameIndex, ctrl->dwFrameInterval);
448
449         if (dev->control == UVC_VS_COMMIT_CONTROL) {
450                 const struct uvc_format_info *format;
451                 const struct uvc_frame_info *frame;
452
453                 format = &uvc_formats[target->bFormatIndex-1];
454                 frame = &format->frames[target->bFrameIndex-1];
455
456                 dev->fcc = format->fcc;
457                 dev->width = frame->width;
458                 dev->height = frame->height;
459
460                 uvc_video_set_format(dev);
461                 if (dev->bulk)
462                         uvc_video_stream(dev, 1);
463         }
464 }
465
466 static void
467 uvc_events_process(void *d)
468 {
469         struct uvc_device *dev = d;
470         struct v4l2_event v4l2_event;
471         const struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
472         struct uvc_request_data resp;
473         int ret;
474
475         ret = ioctl(dev->vdev->fd, VIDIOC_DQEVENT, &v4l2_event);
476         if (ret < 0) {
477                 printf("VIDIOC_DQEVENT failed: %s (%d)\n", strerror(errno),
478                         errno);
479                 return;
480         }
481
482         memset(&resp, 0, sizeof resp);
483         resp.length = -EL2HLT;
484
485         switch (v4l2_event.type) {
486         case UVC_EVENT_CONNECT:
487         case UVC_EVENT_DISCONNECT:
488                 return;
489
490         case UVC_EVENT_SETUP:
491                 uvc_events_process_setup(dev, &uvc_event->req, &resp);
492                 break;
493
494         case UVC_EVENT_DATA:
495                 uvc_events_process_data(dev, &uvc_event->data);
496                 return;
497
498         case UVC_EVENT_STREAMON:
499                 uvc_video_stream(dev, 1);
500                 return;
501
502         case UVC_EVENT_STREAMOFF:
503                 uvc_video_stream(dev, 0);
504                 return;
505         }
506
507         ioctl(dev->vdev->fd, UVCIOC_SEND_RESPONSE, &resp);
508         if (ret < 0) {
509                 printf("UVCIOC_S_EVENT failed: %s (%d)\n", strerror(errno),
510                         errno);
511                 return;
512         }
513 }
514
515 static void
516 uvc_events_init(struct uvc_device *dev)
517 {
518         struct v4l2_event_subscription sub;
519
520         /* Default to the minimum values. */
521         uvc_fill_streaming_control(dev, &dev->probe, 1, 1, 0);
522         uvc_fill_streaming_control(dev, &dev->commit, 1, 1, 0);
523
524         if (dev->bulk) {
525                 /* FIXME Crude hack, must be negotiated with the driver. */
526                 dev->probe.dwMaxPayloadTransferSize = 16 * 1024;
527                 dev->commit.dwMaxPayloadTransferSize = 16 * 1024;
528         }
529
530
531         memset(&sub, 0, sizeof sub);
532         sub.type = UVC_EVENT_SETUP;
533         ioctl(dev->vdev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
534         sub.type = UVC_EVENT_DATA;
535         ioctl(dev->vdev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
536         sub.type = UVC_EVENT_STREAMON;
537         ioctl(dev->vdev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
538         sub.type = UVC_EVENT_STREAMOFF;
539         ioctl(dev->vdev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
540 }
541
542 /* ---------------------------------------------------------------------------
543  * main
544  */
545
546 static void image_load(struct uvc_device *dev, const char *img)
547 {
548         int fd = -1;
549
550         if (img == NULL)
551                 return;
552
553         fd = open(img, O_RDONLY);
554         if (fd == -1) {
555                 printf("Unable to open MJPEG image '%s'\n", img);
556                 return;
557         }
558
559         dev->imgsize = lseek(fd, 0, SEEK_END);
560         lseek(fd, 0, SEEK_SET);
561         dev->imgdata = malloc(dev->imgsize);
562         if (dev->imgdata == NULL) {
563                 printf("Unable to allocate memory for MJPEG image\n");
564                 dev->imgsize = 0;
565                 return;
566         }
567
568         read(fd, dev->imgdata, dev->imgsize);
569         close(fd);
570 }
571
572 static void usage(const char *argv0)
573 {
574         fprintf(stderr, "Usage: %s [options]\n", argv0);
575         fprintf(stderr, "Available options are\n");
576         fprintf(stderr, " -b            Use bulk mode\n");
577         fprintf(stderr, " -d device     Video device\n");
578         fprintf(stderr, " -h            Print this help screen and exit\n");
579         fprintf(stderr, " -i image      MJPEG image\n");
580 }
581
582 /* Necessary for and only used by signal handler. */
583 static struct uvc_device *uvc_device;
584
585 static void sigint_handler(int signal __attribute__((__unused__)))
586 {
587         /* Stop the main loop when the user presses CTRL-C */
588         events_stop(&uvc_device->events);
589 }
590
591 int main(int argc, char *argv[])
592 {
593         char *device = "/dev/video0";
594         struct uvc_device *dev;
595         int bulk_mode = 0;
596         char *mjpeg_image = NULL;
597         int opt;
598
599         while ((opt = getopt(argc, argv, "bd:hi:")) != -1) {
600                 switch (opt) {
601                 case 'b':
602                         bulk_mode = 1;
603                         break;
604
605                 case 'd':
606                         device = optarg;
607                         break;
608
609                 case 'h':
610                         usage(argv[0]);
611                         return 0;
612
613                 case 'i':
614                         mjpeg_image = optarg;
615                         break;
616
617                 default:
618                         fprintf(stderr, "Invalid option '-%c'\n", opt);
619                         usage(argv[0]);
620                         return 1;
621                 }
622         }
623
624         dev = uvc_open(device);
625         if (dev == NULL)
626                 return 1;
627
628         image_load(dev, mjpeg_image);
629
630         dev->bulk = bulk_mode;
631
632         uvc_events_init(dev);
633         uvc_video_init(dev);
634
635         /*
636          * Register a signal handler for SIGINT, received when the user presses
637          * CTRL-C. This will allow the main loop to be interrupted, and resources
638          * to be freed cleanly.
639          */
640         uvc_device = dev;
641         signal(SIGINT, sigint_handler);
642
643         events_watch_fd(&dev->events, dev->vdev->fd, EVENT_EXCEPTION,
644                         uvc_events_process, dev);
645
646         /* Main capture loop */
647         events_loop(&dev->events);
648
649         events_cleanup(&dev->events);
650         uvc_close(dev);
651         return 0;
652 }