]> sigrok.org Git - libsigrok.git/blob - hardware/demo/demo.c
demo: Split supported device options by probe group.
[libsigrok.git] / hardware / demo / demo.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
5  * Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
6  * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21  */
22
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #ifdef _WIN32
27 #include <io.h>
28 #include <fcntl.h>
29 #define pipe(fds) _pipe(fds, 4096, _O_BINARY)
30 #endif
31 #include "libsigrok.h"
32 #include "libsigrok-internal.h"
33
34 #define LOG_PREFIX "demo"
35
36 #define DEFAULT_NUM_LOGIC_PROBES     8
37 #define DEFAULT_NUM_ANALOG_PROBES    4
38
39 /* The size in bytes of chunks to send through the session bus. */
40 #define LOGIC_BUFSIZE        4096
41 /* Size of the analog pattern space per channel. */
42 #define ANALOG_BUFSIZE       4096
43
44 /* Patterns we can generate */
45 enum {
46         /* Logic */
47         /**
48          * Spells "sigrok" across 8 probes using '0's (with '1's as
49          * "background") when displayed using the 'bits' output format.
50          * The pattern is repeasted every 8 probes, shifted to the right
51          * in time by one bit.
52          */
53         PATTERN_SIGROK,
54
55         /** Pseudo-random values on all probes. */
56         PATTERN_RANDOM,
57
58         /**
59          * Incrementing number across 8 probes. The pattern is repeasted
60          * every 8 probes, shifted to the right in time by one bit.
61          */
62         PATTERN_INC,
63
64         /** All probes have a low logic state. */
65         PATTERN_ALL_LOW,
66
67         /** All probes have a high logic state. */
68         PATTERN_ALL_HIGH,
69
70         /* Analog */
71         /**
72          * Square wave.
73          */
74         PATTERN_SQUARE,
75 };
76
77 static const char *logic_pattern_str[] = {
78         "sigrok",
79         "random",
80         "incremental",
81         "all-low",
82         "all-high",
83 };
84
85 static const char *analog_pattern_str[] = {
86         "square",
87 };
88
89 struct analog_gen {
90         int pattern;
91         float pattern_data[ANALOG_BUFSIZE];
92         unsigned int num_samples;
93         struct sr_datafeed_analog packet;
94 };
95
96 /* Private, per-device-instance driver context. */
97 struct dev_context {
98         int pipe_fds[2];
99         GIOChannel *channel;
100         uint64_t cur_samplerate;
101         uint64_t limit_samples;
102         uint64_t limit_msec;
103         uint64_t samples_counter;
104         int64_t starttime;
105         uint64_t step;
106         /* Logic */
107         int32_t num_logic_probes;
108         unsigned int logic_unitsize;
109         uint8_t logic_pattern;
110         unsigned char logic_data[LOGIC_BUFSIZE];
111         /* Analog */
112         int32_t num_analog_probes;
113         GSList *analog_probe_groups;
114 };
115
116 static const int32_t scanopts[] = {
117         SR_CONF_NUM_LOGIC_PROBES,
118         SR_CONF_NUM_ANALOG_PROBES,
119 };
120
121 static const int devopts[] = {
122         SR_CONF_LOGIC_ANALYZER,
123         SR_CONF_DEMO_DEV,
124         SR_CONF_SAMPLERATE,
125         SR_CONF_LIMIT_SAMPLES,
126         SR_CONF_LIMIT_MSEC,
127 };
128
129 static const int devopts_pg[] = {
130         SR_CONF_PATTERN_MODE,
131 };
132
133 static const uint64_t samplerates[] = {
134         SR_HZ(1),
135         SR_GHZ(1),
136         SR_HZ(1),
137 };
138
139 static uint8_t pattern_sigrok[] = {
140         0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
141         0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
142         0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
143         0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
144         0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
145         0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
146         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147         0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 };
149
150 SR_PRIV struct sr_dev_driver demo_driver_info;
151 static struct sr_dev_driver *di = &demo_driver_info;
152
153 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
154
155
156 static int dev_clear(void)
157 {
158         return std_dev_clear(di, NULL);
159 }
160
161 static int init(struct sr_context *sr_ctx)
162 {
163         return std_init(sr_ctx, di, LOG_PREFIX);
164 }
165
166 static void set_analog_pattern(const struct sr_probe_group *probe_group, int pattern)
167 {
168         struct analog_gen *ag;
169         float value;
170         unsigned int num_samples, i;
171         int last_end;
172
173         ag = probe_group->priv;
174         ag->pattern = pattern;
175
176         switch (pattern) {
177         case PATTERN_SQUARE:
178                 num_samples = ANALOG_BUFSIZE / sizeof(float);
179                 value = 5.0;
180                 last_end = 0;
181                 for (i = 0; i < num_samples; i++) {
182                         if (i % 5 == 0)
183                                 value = -value;
184                         if (i % 10 == 0)
185                                 last_end = i - 1;
186                         ag->pattern_data[i] = value;
187                 }
188                 ag->num_samples = last_end;
189                 break;
190         }
191 }
192
193 static GSList *scan(GSList *options)
194 {
195         struct drv_context *drvc;
196         struct dev_context *devc;
197         struct sr_dev_inst *sdi;
198         struct sr_probe *probe;
199         struct sr_probe_group *pg;
200         struct sr_config *src;
201         struct analog_gen *ag;
202         GSList *devices, *l;
203         int num_logic_probes, num_analog_probes, i;
204         char probe_name[16];
205
206         drvc = di->priv;
207
208         num_logic_probes = DEFAULT_NUM_LOGIC_PROBES;
209         num_analog_probes = DEFAULT_NUM_ANALOG_PROBES;
210         for (l = options; l; l = l->next) {
211                 src = l->data;
212                 switch (src->key) {
213                 case SR_CONF_NUM_LOGIC_PROBES:
214                         num_logic_probes = g_variant_get_int32(src->data);
215                         break;
216                 case SR_CONF_NUM_ANALOG_PROBES:
217                         num_analog_probes = g_variant_get_int32(src->data);
218                         break;
219                 }
220         }
221
222         devices = NULL;
223         sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
224         if (!sdi) {
225                 sr_err("Device instance creation failed.");
226                 return NULL;
227         }
228         sdi->driver = di;
229
230         if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
231                 sr_err("Device context malloc failed.");
232                 return NULL;
233         }
234         devc->cur_samplerate = SR_KHZ(200);
235         devc->limit_samples = 0;
236         devc->limit_msec = 0;
237         devc->step = 0;
238         devc->num_logic_probes = num_logic_probes;
239         devc->logic_unitsize = (devc->num_logic_probes + 7) / 8;
240         devc->logic_pattern = PATTERN_SIGROK;
241         devc->num_analog_probes = num_analog_probes;
242         devc->analog_probe_groups = NULL;
243
244         /* Logic probes, all in one probe group. */
245         if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
246                 return NULL;
247         pg->name = g_strdup("Logic");
248         pg->probes = NULL;
249         pg->priv = NULL;
250         for (i = 0; i < num_logic_probes; i++) {
251                 sprintf(probe_name, "D%d", i);
252                 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
253                         return NULL;
254                 sdi->probes = g_slist_append(sdi->probes, probe);
255                 pg->probes = g_slist_append(pg->probes, probe);
256         }
257         sdi->probe_groups = g_slist_append(NULL, pg);
258
259         /* Analog probes, probe groups and pattern generators. */
260         for (i = 0; i < num_analog_probes; i++) {
261                 sprintf(probe_name, "A%d", i);
262                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, probe_name)))
263                         return NULL;
264                 sdi->probes = g_slist_append(sdi->probes, probe);
265
266                 /* Every analog probe gets its own probe group. */
267                 if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
268                         return NULL;
269                 pg->name = g_strdup(probe_name);
270                 pg->probes = g_slist_append(NULL, probe);
271
272                 /* Every probe group gets a generator struct. */
273                 if (!(ag = g_try_malloc(sizeof(struct analog_gen))))
274                         return NULL;
275                 ag->packet.probes = pg->probes;
276                 ag->packet.mq = 0;
277                 ag->packet.mqflags = 0;
278                 ag->packet.unit = SR_UNIT_VOLT;
279                 ag->packet.data = ag->pattern_data;
280                 pg->priv = ag;
281                 set_analog_pattern(pg, PATTERN_SQUARE);
282
283                 sdi->probe_groups = g_slist_append(sdi->probe_groups, pg);
284                 devc->analog_probe_groups = g_slist_append(devc->analog_probe_groups, pg);
285         }
286
287         sdi->priv = devc;
288         devices = g_slist_append(devices, sdi);
289         drvc->instances = g_slist_append(drvc->instances, sdi);
290
291         return devices;
292 }
293
294 static GSList *dev_list(void)
295 {
296         return ((struct drv_context *)(di->priv))->instances;
297 }
298
299 static int dev_open(struct sr_dev_inst *sdi)
300 {
301         sdi->status = SR_ST_ACTIVE;
302
303         return SR_OK;
304 }
305
306 static int dev_close(struct sr_dev_inst *sdi)
307 {
308         sdi->status = SR_ST_INACTIVE;
309
310         return SR_OK;
311 }
312
313 static int cleanup(void)
314 {
315         return dev_clear();
316 }
317
318 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
319                 const struct sr_probe_group *probe_group)
320 {
321         struct dev_context *devc;
322
323         (void)probe_group;
324
325         devc = sdi->priv;
326         switch (id) {
327         case SR_CONF_SAMPLERATE:
328                 *data = g_variant_new_uint64(devc->cur_samplerate);
329                 break;
330         case SR_CONF_LIMIT_SAMPLES:
331                 *data = g_variant_new_uint64(devc->limit_samples);
332                 break;
333         case SR_CONF_LIMIT_MSEC:
334                 *data = g_variant_new_uint64(devc->limit_msec);
335                 break;
336         case SR_CONF_PATTERN_MODE:
337                 *data = g_variant_new_string(logic_pattern_str[devc->logic_pattern]);
338                 break;
339         case SR_CONF_NUM_LOGIC_PROBES:
340                 *data = g_variant_new_int32(devc->num_logic_probes);
341                 break;
342         case SR_CONF_NUM_ANALOG_PROBES:
343                 *data = g_variant_new_int32(devc->num_analog_probes);
344                 break;
345         default:
346                 return SR_ERR_NA;
347         }
348
349         return SR_OK;
350 }
351
352 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
353                 const struct sr_probe_group *probe_group)
354 {
355         struct dev_context *devc;
356         struct sr_probe_group *pg;
357         GSList *l;
358         int logic_pattern, analog_pattern, ret;
359         unsigned int i;
360         const char *stropt;
361
362         devc = sdi->priv;
363
364         if (sdi->status != SR_ST_ACTIVE)
365                 return SR_ERR_DEV_CLOSED;
366
367         ret = SR_ERR;
368         if (id == SR_CONF_SAMPLERATE) {
369                 devc->cur_samplerate = g_variant_get_uint64(data);
370                 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
371                 ret = SR_OK;
372         } else if (id == SR_CONF_LIMIT_SAMPLES) {
373                 devc->limit_msec = 0;
374                 devc->limit_samples = g_variant_get_uint64(data);
375                 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
376                 ret = SR_OK;
377         } else if (id == SR_CONF_LIMIT_MSEC) {
378                 /* TODO: convert to limit_samples */
379                 devc->limit_msec = g_variant_get_uint64(data);
380                 devc->limit_samples = 0;
381                 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
382                 ret = SR_OK;
383         } else if (id == SR_CONF_PATTERN_MODE) {
384                 stropt = g_variant_get_string(data, NULL);
385                 logic_pattern = analog_pattern = -1;
386                 /* Is it a logic pattern? */
387                 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
388                         if (!strcmp(stropt, logic_pattern_str[i])) {
389                                 logic_pattern = i;
390                                 break;
391                         }
392                 }
393                 if (logic_pattern == -1) {
394                         /* Is it an analog pattern? */
395                         for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
396                                 if (!strcmp(stropt, analog_pattern_str[i])) {
397                                         analog_pattern = i;
398                                         break;
399                                 }
400                         }
401                 }
402                 if (logic_pattern > -1) {
403                         devc->logic_pattern = logic_pattern;
404                         /* Might as well do this now. */
405                         if (logic_pattern == PATTERN_ALL_LOW)
406                                 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
407                         else if (logic_pattern == PATTERN_ALL_HIGH)
408                                 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
409                         ret = SR_OK;
410                         sr_dbg("Setting logic pattern to %s", logic_pattern_str[logic_pattern]);
411                 } else if (analog_pattern > -1) {
412                         sr_dbg("Setting analog pattern to %s", analog_pattern_str[analog_pattern]);
413                         if (probe_group)
414                                 set_analog_pattern(probe_group, analog_pattern);
415                         else {
416                                 /* No probe group specified, apply pattern to all of them. */
417                                 for (l = sdi->probe_groups; l; l = l->next) {
418                                         pg = l->data;
419                                         set_analog_pattern(pg, analog_pattern);
420                                 }
421                                 ret = SR_OK;
422                         }
423                 } else {
424                         ret = SR_ERR;
425                 }
426         } else {
427                 ret = SR_ERR_NA;
428         }
429
430         return ret;
431 }
432
433 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
434                 const struct sr_probe_group *probe_group)
435 {
436         struct sr_probe *probe;
437         GVariant *gvar;
438         GVariantBuilder gvb;
439
440         (void)sdi;
441
442         if (key == SR_CONF_SCAN_OPTIONS) {
443                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
444                                 scanopts, ARRAY_SIZE(scanopts), sizeof(int32_t));
445                 return SR_OK;
446         }
447
448         if (!sdi)
449                 return SR_ERR_ARG;
450
451         if (!probe_group) {
452                 switch (key) {
453                 case SR_CONF_DEVICE_OPTIONS:
454                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
455                                         devopts, ARRAY_SIZE(devopts), sizeof(int32_t));
456                         break;
457                 case SR_CONF_SAMPLERATE:
458                         g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
459                         gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
460                                         ARRAY_SIZE(samplerates), sizeof(uint64_t));
461                         g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
462                         *data = g_variant_builder_end(&gvb);
463                         break;
464                 default:
465                         return SR_ERR_NA;
466                 }
467         } else {
468                 probe = probe_group->probes->data;
469                 switch (key) {
470                 case SR_CONF_DEVICE_OPTIONS:
471                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
472                                         devopts_pg, ARRAY_SIZE(devopts_pg), sizeof(int32_t));
473                         break;
474                 case SR_CONF_PATTERN_MODE:
475                         if (probe->type == SR_PROBE_LOGIC)
476                                 *data = g_variant_new_strv(logic_pattern_str,
477                                                 ARRAY_SIZE(logic_pattern_str));
478                         else
479                                 *data = g_variant_new_strv(analog_pattern_str,
480                                                 ARRAY_SIZE(analog_pattern_str));
481                         break;
482                 default:
483                         return SR_ERR_NA;
484                 }
485         }
486
487         return SR_OK;
488 }
489
490 static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
491 {
492         struct dev_context *devc;
493         uint64_t i, j;
494         uint8_t pat;
495
496         devc = sdi->priv;
497
498         switch (devc->logic_pattern) {
499         case PATTERN_SIGROK:
500                 memset(devc->logic_data, 0x00, size);
501                 for (i = 0; i < size; i += devc->logic_unitsize) {
502                         for (j = 0; j < devc->logic_unitsize; j++) {
503                                 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
504                                 devc->logic_data[i + j] = ~pat;
505                         }
506                         devc->step++;
507                 }
508                 break;
509         case PATTERN_RANDOM:
510                 for (i = 0; i < size; i++)
511                         devc->logic_data[i] = (uint8_t)(rand() & 0xff);
512                 break;
513         case PATTERN_INC:
514                 for (i = 0; i < size; i++) {
515                         for (j = 0; j < devc->logic_unitsize; j++) {
516                                 devc->logic_data[i + j] = devc->step;
517                         }
518                         devc->step++;
519                 }
520                 break;
521         case PATTERN_ALL_LOW:
522         case PATTERN_ALL_HIGH:
523                 /* These were set when the pattern mode was selected. */
524                 break;
525         default:
526                 sr_err("Unknown pattern: %d.", devc->logic_pattern);
527                 break;
528         }
529 }
530
531 /* Callback handling data */
532 static int prepare_data(int fd, int revents, void *cb_data)
533 {
534         struct sr_dev_inst *sdi;
535         struct dev_context *devc;
536         struct sr_datafeed_packet packet;
537         struct sr_datafeed_logic logic;
538         struct sr_probe_group *pg;
539         struct analog_gen *ag;
540         GSList *l;
541         uint64_t samples_to_send, expected_samplenum, analog_samples, sending_now;
542         int64_t time, elapsed;
543
544         (void)fd;
545         (void)revents;
546
547         sdi = cb_data;
548         devc = sdi->priv;
549
550         /* How many "virtual" samples should we have collected by now? */
551         time = g_get_monotonic_time();
552         elapsed = time - devc->starttime;
553         expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
554         /* Of those, how many do we still have to send? */
555         samples_to_send = expected_samplenum - devc->samples_counter;
556
557         if (devc->limit_samples) {
558                 samples_to_send = MIN(samples_to_send,
559                                 devc->limit_samples - devc->samples_counter);
560         }
561
562         while (samples_to_send > 0) {
563                 sending_now = 0;
564
565                 /* Logic */
566                 if (devc->num_logic_probes > 0) {
567                         sending_now = MIN(samples_to_send,
568                                         LOGIC_BUFSIZE / devc->logic_unitsize);
569                         logic_generator(sdi, sending_now * devc->logic_unitsize);
570                         packet.type = SR_DF_LOGIC;
571                         packet.payload = &logic;
572                         logic.length = sending_now * devc->logic_unitsize;
573                         logic.unitsize = devc->logic_unitsize;
574                         logic.data = devc->logic_data;
575                         sr_session_send(sdi, &packet);
576                 }
577
578                 /* Analog, one probe at a time */
579                 if (devc->num_analog_probes > 0) {
580                         sending_now = 0;
581                         for (l = devc->analog_probe_groups; l; l = l->next) {
582                                 pg = l->data;
583                                 ag = pg->priv;
584                                 packet.type = SR_DF_ANALOG;
585                                 packet.payload = &ag->packet;
586                                 analog_samples = MIN(samples_to_send, ag->num_samples);
587                                 /* Whichever probe group gets there first. */
588                                 sending_now = MAX(sending_now, analog_samples);
589                                 ag->packet.num_samples = analog_samples;
590                                 sr_session_send(sdi, &packet);
591                         }
592                 }
593
594                 samples_to_send -= sending_now;
595                 devc->samples_counter += sending_now;
596         }
597
598         if (devc->limit_samples &&
599                 devc->samples_counter >= devc->limit_samples) {
600                 sr_info("Requested number of samples reached.");
601                 dev_acquisition_stop(sdi, cb_data);
602                 return TRUE;
603         }
604
605         return TRUE;
606 }
607
608 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
609 {
610         struct dev_context *devc;
611
612         if (sdi->status != SR_ST_ACTIVE)
613                 return SR_ERR_DEV_CLOSED;
614
615         /* TODO: don't start without a sample limit set */
616         devc = sdi->priv;
617         devc->samples_counter = 0;
618
619         /*
620          * Setting two channels connected by a pipe is a remnant from when the
621          * demo driver generated data in a thread, and collected and sent the
622          * data in the main program loop.
623          * They are kept here because it provides a convenient way of setting
624          * up a timeout-based polling mechanism.
625          */
626         if (pipe(devc->pipe_fds)) {
627                 sr_err("%s: pipe() failed", __func__);
628                 return SR_ERR;
629         }
630
631         devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
632
633         g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
634
635         /* Set channel encoding to binary (default is UTF-8). */
636         g_io_channel_set_encoding(devc->channel, NULL, NULL);
637
638         /* Make channels to unbuffered. */
639         g_io_channel_set_buffered(devc->channel, FALSE);
640
641         sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
642                         40, prepare_data, (void *)sdi);
643
644         /* Send header packet to the session bus. */
645         std_session_send_df_header(cb_data, LOG_PREFIX);
646
647         /* We use this timestamp to decide how many more samples to send. */
648         devc->starttime = g_get_monotonic_time();
649
650         return SR_OK;
651 }
652
653 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
654 {
655         struct dev_context *devc;
656         struct sr_datafeed_packet packet;
657
658         (void)cb_data;
659
660         devc = sdi->priv;
661         sr_dbg("Stopping aquisition.");
662
663         sr_session_source_remove_channel(devc->channel);
664         g_io_channel_shutdown(devc->channel, FALSE, NULL);
665         g_io_channel_unref(devc->channel);
666         devc->channel = NULL;
667
668         /* Send last packet. */
669         packet.type = SR_DF_END;
670         sr_session_send(sdi, &packet);
671
672         return SR_OK;
673 }
674
675 SR_PRIV struct sr_dev_driver demo_driver_info = {
676         .name = "demo",
677         .longname = "Demo driver and pattern generator",
678         .api_version = 1,
679         .init = init,
680         .cleanup = cleanup,
681         .scan = scan,
682         .dev_list = dev_list,
683         .dev_clear = dev_clear,
684         .config_get = config_get,
685         .config_set = config_set,
686         .config_list = config_list,
687         .dev_open = dev_open,
688         .dev_close = dev_close,
689         .dev_acquisition_start = dev_acquisition_start,
690         .dev_acquisition_stop = dev_acquisition_stop,
691         .priv = NULL,
692 };