]> sigrok.org Git - libsigrok.git/blob - session.c
Fix all warnings and re-enable -Wextra.
[libsigrok.git] / session.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010 Bert Vermeulen <bert@biot.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 3 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
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <zip.h>
25 #include "sigrok.h"
26
27 /* there can only be one session at a time */
28 struct session *session;
29
30
31 struct session *session_load(const char *filename)
32 {
33         struct session *session;
34
35         /* TODO: implement */
36         session = NULL;
37
38         /* QUICK HACK */
39         filename = filename;
40
41         return session;
42 }
43
44
45 struct session *session_new(void)
46 {
47
48         session = calloc(1, sizeof(struct session));
49
50         return session;
51 }
52
53
54 void session_destroy(void)
55 {
56
57         g_slist_free(session->devices);
58
59         /* TODO: loop over protocols and free them */
60
61         g_free(session);
62
63 }
64
65
66 void session_device_clear(void)
67 {
68
69         g_slist_free(session->devices);
70         session->devices = NULL;
71
72 }
73
74
75 int session_device_add(struct device *device)
76 {
77         int ret;
78
79         ret = device->plugin->open(device->plugin_index);
80         if(ret == SIGROK_OK)
81                 session->devices = g_slist_append(session->devices, device);
82
83         return ret;
84 }
85
86
87 void session_pa_clear(void)
88 {
89
90         /* the protocols are pointers to the global set of PA plugins, so don't free them */
91         g_slist_free(session->analyzers);
92         session->analyzers = NULL;
93
94 }
95
96
97 void session_pa_add(struct analyzer *an)
98 {
99
100         session->analyzers = g_slist_append(session->analyzers, an);
101
102 }
103
104
105 void session_datafeed_callback_clear(void)
106 {
107
108         g_slist_free(session->datafeed_callbacks);
109         session->datafeed_callbacks = NULL;
110
111 }
112
113
114 void session_datafeed_callback_add(datafeed_callback callback)
115 {
116
117         session->datafeed_callbacks = g_slist_append(session->datafeed_callbacks, callback);
118
119 }
120
121
122 int session_start(void)
123 {
124         struct device *device;
125         GSList *l;
126         int ret;
127
128         g_message("starting acquisition");
129         for(l = session->devices; l; l = l->next)
130         {
131                 device = l->data;
132                 if( (ret = device->plugin->start_acquisition(device->plugin_index, device)) != SIGROK_OK)
133                         break;
134         }
135
136         return ret;
137 }
138
139
140 void session_stop(void)
141 {
142         struct device *device;
143         GSList *l;
144
145         g_message("stopping acquisition");
146         for(l = session->devices; l; l = l->next)
147         {
148                 device = l->data;
149                 device->plugin->stop_acquisition(device->plugin_index, device);
150         }
151
152 }
153
154
155 void session_bus(struct device *device, struct datafeed_packet *packet)
156 {
157         GSList *l;
158         datafeed_callback cb;
159
160         /* TODO: send packet through PA pipe, and send the output of that to
161          * the callbacks as well
162          */
163
164         for(l = session->datafeed_callbacks; l; l = l->next)
165         {
166                 cb = l->data;
167                 cb(device, packet);
168         }
169
170 }
171
172
173 void make_metadata(char *filename)
174 {
175         GSList *l, *p;
176         struct device *device;
177         struct probe *probe;
178         FILE *f;
179         int devcnt;
180
181         f = fopen(filename, "wb");
182
183         /* general */
184
185         /* devices */
186         devcnt = 1;
187         for(l = session->devices; l; l = l->next) {
188                 device = l->data;
189                 fprintf(f, "[device]\n");
190                 fprintf(f, "driver = %s\n", device->plugin->name);
191                 if(device->datastore)
192                         fprintf(f, "capturefile = raw-%d\n", devcnt);
193                 for(p = device->probes; p; p = p->next) {
194                         probe = p->data;
195                         if(probe->enabled)
196                         {
197                                 fprintf(f, "probe %d", probe->index);
198                                 if(probe->name)
199                                         fprintf(f, " name \"%s\"", probe->name);
200                                 if(probe->trigger)
201                                         fprintf(f, " trigger \"%s\"", probe->trigger);
202                                 fprintf(f, "\n");
203                         }
204                 }
205                 devcnt++;
206         }
207
208         /* TODO: protocol analyzers */
209
210         fclose(f);
211
212 }
213
214
215 int session_save(char *filename)
216 {
217         GSList *l, *d;
218         struct device *device;
219         struct datastore *ds;
220         struct zip *zipfile;
221         struct zip_source *src;
222         int bufcnt, devcnt, tmpfile, ret, error;
223         char version[1], rawname[16], metafile[32], *buf;
224
225         /* quietly delete it first, libzip wants replace ops otherwise */
226         unlink(filename);
227
228         if( !(zipfile = zip_open(filename, ZIP_CREATE, &error)) )
229                 return SIGROK_ERR;
230
231         /* version */
232         version[0] = '1';
233         if( !(src = zip_source_buffer(zipfile, version, 1, 0)) )
234                 return SIGROK_ERR;
235         if(zip_add(zipfile, "version", src) == -1) {
236                 g_message("error saving version into zipfile: %s", zip_strerror(zipfile));
237                 return SIGROK_ERR;
238         }
239
240         /* metadata */
241         strcpy(metafile, "sigrok-meta-XXXXXX");
242         if( (tmpfile = g_mkstemp(metafile)) == -1)
243                 return SIGROK_ERR;
244         close(tmpfile);
245         make_metadata(metafile);
246         if( !(src = zip_source_file(zipfile, metafile, 0, -1)) )
247                 return SIGROK_ERR;
248         if(zip_add(zipfile, "metadata", src) == -1)
249                 return SIGROK_ERR;
250         unlink(metafile);
251
252         /* raw */
253         devcnt = 1;
254         for(l = session->devices; l; l = l->next) {
255                 device = l->data;
256                 ds = device->datastore;
257                 if(ds) {
258                         buf = malloc(ds->num_units * ds->ds_unitsize + DATASTORE_CHUNKSIZE);
259                         bufcnt = 0;
260                         for(d = ds->chunklist; d; d = d->next) {
261                                 memcpy(buf + bufcnt, d->data, DATASTORE_CHUNKSIZE);
262                                 bufcnt += DATASTORE_CHUNKSIZE;
263                         }
264                         if( !(src = zip_source_buffer(zipfile, buf, ds->num_units * ds->ds_unitsize, TRUE)) )
265                                 return SIGROK_ERR;
266                         snprintf(rawname, 15, "raw-%d", devcnt);
267                         if(zip_add(zipfile, rawname, src) == -1)
268                                 return SIGROK_ERR;
269                 }
270                 devcnt++;
271         }
272
273         if( (ret = zip_close(zipfile)) == -1) {
274                 g_message("error saving zipfile: %s", zip_strerror(zipfile));
275                 return SIGROK_ERR;
276         }
277
278         return SIGROK_OK;
279 }