1 /*
2 */
3
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <sys/time.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <stdio.h>
10 #include <unistd.h>
11 #include <stdarg.h>
12 #include <string.h>
13 #include <gphoto2/gphoto2.h>
14
15 #include "samples.h"
16
17 static void
errordumper(GPLogLevel level,const char * domain,const char * str,void * data)18 errordumper(GPLogLevel level, const char *domain, const char *str, void *data) {
19 fprintf(stderr, "%s\n", str);
20 }
21
22 static struct queue_entry {
23 CameraFilePath path;
24 int offset;
25 } *queue = NULL;
26 static int nrofqueue=0;
27 static int nrdownloads=0;
28
29 static const char *buffer;
30
31 static int
wait_event_and_download(Camera * camera,int waittime,GPContext * context)32 wait_event_and_download (Camera *camera, int waittime, GPContext *context) {
33 CameraEventType evtype;
34 CameraFilePath *path;
35 void *data;
36 int retval;
37 struct timeval start, curtime;
38
39 gettimeofday (&start, NULL);
40 data = NULL;
41 if (nrofqueue)
42 waittime = 10; /* just drain the event queue */
43
44 while (1) {
45 int timediff;
46
47 gettimeofday (&curtime, NULL);
48
49 timediff = ((curtime.tv_sec - start.tv_sec)*1000)+((curtime.tv_usec - start.tv_usec)/1000);
50 if (timediff >= waittime)
51 break;
52
53 retval = gp_camera_wait_for_event(camera, waittime - timediff, &evtype, &data, context);
54 if (retval != GP_OK) {
55 fprintf (stderr, "return from waitevent in trigger sample with %d\n", retval);
56 return retval;
57 }
58 path = data;
59 switch (evtype) {
60 case GP_EVENT_CAPTURE_COMPLETE:
61 fprintf (stderr, "wait for event CAPTURE_COMPLETE\n");
62 break;
63 case GP_EVENT_UNKNOWN:
64 case GP_EVENT_TIMEOUT:
65 break;
66 case GP_EVENT_FOLDER_ADDED:
67 fprintf (stderr, "wait for event FOLDER_ADDED\n");
68 free(data);
69 break;
70 case GP_EVENT_FILE_CHANGED:
71 fprintf (stderr, "wait for event FILE_CHANGED\n");
72 free(data);
73 break;
74 case GP_EVENT_FILE_ADDED:
75 fprintf (stderr, "File %s / %s added to queue.\n", path->folder, path->name);
76 if (nrofqueue) {
77 struct queue_entry *q;
78 q = realloc(queue, sizeof(struct queue_entry)*(nrofqueue+1));
79 if (!q) return GP_ERROR_NO_MEMORY;
80 queue = q;
81 } else {
82 queue = malloc (sizeof(struct queue_entry));
83 if (!queue) return GP_ERROR_NO_MEMORY;
84 }
85 memcpy (&queue[nrofqueue].path, path, sizeof(CameraFilePath));
86 queue[nrofqueue].offset = 0;
87 nrofqueue++;
88 free(data);
89 break;
90 }
91 }
92 if (nrofqueue) {
93 unsigned long size;
94 int fd;
95 struct stat stbuf;
96 CameraFile *file;
97
98 retval = gp_file_new(&file);
99
100 fprintf(stderr,"camera getfile of %s / %s\n",
101 queue[0].path.folder,
102 queue[0].path.name
103 );
104 retval = gp_camera_file_get(camera, queue[0].path.folder, queue[0].path.name,
105 GP_FILE_TYPE_NORMAL, file, context);
106 if (retval != GP_OK) {
107 fprintf (stderr,"gp_camera_file_get failed: %d\n", retval);
108 gp_file_free (file);
109 return retval;
110 }
111
112 /* buffer is returned as pointer, not as a copy */
113 retval = gp_file_get_data_and_size (file, &buffer, &size);
114
115 if (retval != GP_OK) {
116 fprintf (stderr,"gp_file_get_data_and_size failed: %d\n", retval);
117 gp_file_free (file);
118 return retval;
119 }
120 if (-1 == stat(queue[0].path.name, &stbuf))
121 fd = creat(queue[0].path.name, 0644);
122 else
123 fd = open(queue[0].path.name, O_RDWR | O_BINARY, 0644);
124 if (fd == -1) {
125 perror(queue[0].path.name);
126 return GP_ERROR;
127 }
128 if (-1 == lseek(fd, 0, SEEK_SET))
129 perror("lseek");
130 if (-1 == write (fd, buffer, size))
131 perror("write");
132 close (fd);
133
134 gp_file_free (file); /* Note: this invalidates buffer. */
135
136 fprintf(stderr,"ending download %d, deleting file.\n", nrdownloads);
137 retval = gp_camera_file_delete(camera, queue[0].path.folder, queue[0].path.name, context);
138 memmove(&queue[0],&queue[1],sizeof(queue[0])*(nrofqueue-1));
139 nrofqueue--;
140 }
141 return GP_OK;
142 }
143
144 int
main(int argc,char ** argv)145 main(int argc, char **argv) {
146 Camera *camera;
147 int retval, nrcapture = 0;
148 struct timeval tval;
149 GPContext *context = sample_create_context();
150
151 gp_log_add_func(GP_LOG_ERROR, errordumper, NULL);
152 /*gp_log_add_func(GP_LOG_DATA, errordumper, NULL); */
153 gp_camera_new(&camera);
154
155 retval = gp_camera_init(camera, context);
156 if (retval != GP_OK) {
157 printf("gp_camera_init: %d\n", retval);
158 exit (1);
159 }
160 while (1) {
161 if ((time(NULL) & 1) == 1) {
162 fprintf(stderr,"triggering capture %d\n", ++nrcapture);
163 retval = gp_camera_trigger_capture (camera, context);
164 if ((retval != GP_OK) && (retval != GP_ERROR) && (retval != GP_ERROR_CAMERA_BUSY)) {
165 fprintf(stderr,"triggering capture had error %d\n", retval);
166 break;
167 }
168 fprintf (stderr, "done triggering\n");
169 }
170 /*fprintf(stderr,"waiting for events\n");*/
171 retval = wait_event_and_download(camera, 100, context);
172 if (retval != GP_OK)
173 break;
174 /*fprintf(stderr,"end waiting for events\n");*/
175 gettimeofday (&tval, NULL);
176 fprintf(stderr,"loop is at %d.%06d\n", (int)tval.tv_sec,(int)tval.tv_usec);
177 }
178 gp_camera_exit(camera, context);
179 return 0;
180 }
181