aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/util/gnunet-qr.c221
1 files changed, 161 insertions, 60 deletions
diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c
index 1106d5cb2..fa95d6c05 100644
--- a/src/util/gnunet-qr.c
+++ b/src/util/gnunet-qr.c
@@ -17,7 +17,12 @@
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19*/
20 20/**
21 * @file util/gnunet-qr.c
22 * @author Hartmut Goebel (original implementation)
23 * @author Martin Schanzenbach (integrate gnunet-uri)
24 * @author Christian Grothoff (error handling)
25 */
21#include <stdio.h> 26#include <stdio.h>
22#include <zbar.h> 27#include <zbar.h>
23#include <stdbool.h> 28#include <stdbool.h>
@@ -26,18 +31,35 @@
26 31
27#define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) 32#define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__)
28 33
29// Command line options 34/**
35 * Video device to capture from. Sane default for GNU/Linux systems.
36 */
30static char* device = "/dev/video0"; 37static char* device = "/dev/video0";
38
39/**
40 * --verbose option
41 */
31static int verbose = false; 42static int verbose = false;
43
44/**
45 * --silent option
46 */
32static int silent = false; 47static int silent = false;
33 48
34// Handler exit code 49/**
50 * Handler exit code
51 */
35static long unsigned int exit_code = 1; 52static long unsigned int exit_code = 1;
36 53
37// Helper process we started. 54/**
55 * Helper process we started.
56 */
38static struct GNUNET_OS_Process *p; 57static struct GNUNET_OS_Process *p;
39 58
40// Pipe used to communicate shutdown via signal. 59
60/**
61 * Pipe used to communicate child death via signal.
62 */
41static struct GNUNET_DISK_PipeHandle *sigpipe; 63static struct GNUNET_DISK_PipeHandle *sigpipe;
42 64
43 65
@@ -69,8 +91,10 @@ maint_child_death (void *cls)
69 * @param cfg configuration 91 * @param cfg configuration
70 */ 92 */
71static void 93static void
72gnunet_uri (void *cls, const char *uri, const char *cfgfile, 94gnunet_uri (void *cls,
73 const struct GNUNET_CONFIGURATION_Handle *cfg) 95 const char *uri,
96 const char *cfgfile,
97 const struct GNUNET_CONFIGURATION_Handle *cfg)
74{ 98{
75 const char *orig_uri; 99 const char *orig_uri;
76 const char *slash; 100 const char *slash;
@@ -88,7 +112,8 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile,
88 uri += strlen ("gnunet://"); 112 uri += strlen ("gnunet://");
89 if (NULL == (slash = strchr (uri, '/'))) 113 if (NULL == (slash = strchr (uri, '/')))
90 { 114 {
91 fprintf (stderr, _("Invalid URI: fails to specify subsystem\n")); 115 fprintf (stderr,
116 _("Invalid URI: fails to specify subsystem\n"));
92 return; 117 return;
93 } 118 }
94 subsystem = GNUNET_strndup (uri, slash - uri); 119 subsystem = GNUNET_strndup (uri, slash - uri);
@@ -98,7 +123,9 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile,
98 subsystem, 123 subsystem,
99 &program)) 124 &program))
100 { 125 {
101 fprintf (stderr, _("No handler known for subsystem `%s'\n"), subsystem); 126 fprintf (stderr,
127 _("No handler known for subsystem `%s'\n"),
128 subsystem);
102 GNUNET_free (subsystem); 129 GNUNET_free (subsystem);
103 return; 130 return;
104 } 131 }
@@ -120,6 +147,111 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile,
120 147
121 148
122/** 149/**
150 * Obtain QR code 'symbol' from @a proc.
151 *
152 * @param proc zbar processor to use
153 * @return NULL on error
154 */
155static const zbar_symbol_t *
156get_symbol (zbar_processor_t *proc)
157{
158 const zbar_symbol_set_t* symbols;
159 int rc;
160 int n;
161
162 if (0 !=
163 zbar_processor_parse_config (proc, "enable"))
164 {
165 GNUNET_break (0);
166 return NULL;
167 }
168
169 /* initialize the Processor */
170 if (0 !=
171 (rc = zbar_processor_init(proc, device, 1)))
172 {
173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
174 "Failed to open device `%s': %d\n",
175 device,
176 rc);
177 return NULL;
178 }
179
180 /* enable the preview window */
181 if ( (0 != (rc = zbar_processor_set_visible (proc, 1))) ||
182 (0 != (rc = zbar_processor_set_active(proc, 1))) )
183 {
184 GNUNET_break (0);
185 return NULL;
186 }
187
188 /* read at least one barcode (or until window closed) */
189 LOG ("Capturing\n");
190 n = zbar_process_one (proc, -1);
191
192 /* hide the preview window */
193 (void) zbar_processor_set_active (proc, 0);
194 (void) zbar_processor_set_visible (proc, 0);
195 if (-1 == n)
196 return NULL; /* likely user closed the window */
197 LOG ("Got %i images\n",
198 n);
199 /* extract results */
200 symbols = zbar_processor_get_results (proc);
201 if (NULL == symbols)
202 {
203 GNUNET_break (0);
204 return NULL;
205 }
206 return zbar_symbol_set_first_symbol (symbols);
207}
208
209
210/**
211 * Run zbar QR code parser.
212 *
213 * @return NULL on error, otherwise the URI that we found
214 */
215static char *
216run_zbar ()
217{
218 zbar_processor_t *proc;
219 const char *data;
220 char *ret;
221 const zbar_symbol_t* symbol;
222
223 /* configure the Processor */
224 proc = zbar_processor_create (1);
225 if (NULL == proc)
226 {
227 GNUNET_break (0);
228 return NULL;
229 }
230
231 symbol = get_symbol (proc);
232 if (NULL == symbol)
233 {
234 zbar_processor_destroy (proc);
235 return NULL;
236 }
237 data = zbar_symbol_get_data (symbol);
238 if (NULL == data)
239 {
240 GNUNET_break (0);
241 zbar_processor_destroy (proc);
242 return NULL;
243 }
244 LOG ("Found %s \"%s\"\n",
245 zbar_get_symbol_name (zbar_symbol_get_type(symbol)),
246 data);
247 ret = GNUNET_strdup (data);
248 /* clean up */
249 zbar_processor_destroy(proc);
250 return ret;
251}
252
253
254/**
123 * Main function that will be run by the scheduler. 255 * Main function that will be run by the scheduler.
124 * 256 *
125 * @param cls closure 257 * @param cls closure
@@ -133,65 +265,33 @@ run (void *cls,
133 const char *cfgfile, 265 const char *cfgfile,
134 const struct GNUNET_CONFIGURATION_Handle *cfg) 266 const struct GNUNET_CONFIGURATION_Handle *cfg)
135{ 267{
136 /* create a Processor */ 268 char *data;
137 LOG("Initializing\n");
138 zbar_processor_t *proc = zbar_processor_create(1);
139
140 // FIXME: Wrap all this into a function which returns an error on
141 // failure. And here ensure the processor is destroyed at the end.
142
143 /* configure the Processor */
144 zbar_processor_parse_config(proc, "enable");
145
146 /* initialize the Processor */
147 LOG("Opening video device %s\n", device);
148 // FIXME: error handling
149 zbar_processor_init(proc, device, 1);
150
151 /* enable the preview window */
152 zbar_processor_set_visible(proc, 1);
153 zbar_processor_set_active(proc, 1);
154
155 /* keep scanning until user provides key/mouse input */
156 //zbar_processor_user_wait(proc, -1);
157 269
158 // read at least one barcode (or until window closed) 270 data = run_zbar ();
159 LOG("Capturing\n"); 271 if (NULL == data)
160 int n; 272 return;
161 n = zbar_process_one(proc, -1); 273 gnunet_uri (cls,
162 LOG("Got %i images\n", n); 274 data,
163 // FIXME: Error handling (n = -1) 275 cfgfile,
164 276 cfg);
165 // hide the preview window 277 if (exit_code != 0)
166 zbar_processor_set_active(proc, 0); 278 {
167 zbar_processor_set_visible(proc, 0); 279 printf ("Failed to add URI %s\n",
168 280 data);
169 // extract results
170 const zbar_symbol_set_t* symbols = zbar_processor_get_results(proc);
171 const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(symbols);
172
173 if (symbol != NULL) {
174 const char* data = zbar_symbol_get_data(symbol);
175 LOG("Found %s \"%s\"\n",
176 zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data);
177
178 gnunet_uri(cls, data, cfgfile, cfg);
179 if (exit_code != 0) {
180 printf("Failed to add URI %s\n", data);
181 } else {
182 printf("Added URI %s\n", data);
183 }
184 } 281 }
185 282 else
186 /* clean up */ 283 {
187 zbar_processor_destroy(proc); 284 printf ("Added URI %s\n",
285 data);
286 }
287 GNUNET_free (data);
188}; 288};
189 289
190 290
191int 291int
192main (int argc, char *const *argv) 292main (int argc, char *const *argv)
193{ 293{
194 static int ret; 294 int ret;
195 struct GNUNET_GETOPT_CommandLineOption options[] = { 295 struct GNUNET_GETOPT_CommandLineOption options[] = {
196 GNUNET_GETOPT_option_string ('d', "device", "DEVICE", 296 GNUNET_GETOPT_option_string ('d', "device", "DEVICE",
197 gettext_noop ("use video-device DEVICE (default: /dev/video0"), 297 gettext_noop ("use video-device DEVICE (default: /dev/video0"),
@@ -204,6 +304,7 @@ main (int argc, char *const *argv)
204 &silent), 304 &silent),
205 GNUNET_GETOPT_OPTION_END 305 GNUNET_GETOPT_OPTION_END
206 }; 306 };
307
207 ret = GNUNET_PROGRAM_run (argc, 308 ret = GNUNET_PROGRAM_run (argc,
208 argv, 309 argv,
209 "gnunet-qr", 310 "gnunet-qr",