2 * This file is part of the sigrok project.
4 * Copyright (C) 2010 Bert Vermeulen <bert@biot.com>
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.
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.
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/>.
27 /* there can only be one session at a time */
28 struct session *session;
31 struct session *session_load(const char *filename)
33 struct session *session;
45 struct session *session_new(void)
48 session = calloc(1, sizeof(struct session));
54 void session_destroy(void)
57 g_slist_free(session->devices);
59 /* TODO: loop over protocols and free them */
66 void session_device_clear(void)
69 g_slist_free(session->devices);
70 session->devices = NULL;
75 int session_device_add(struct device *device)
79 ret = device->plugin->open(device->plugin_index);
81 session->devices = g_slist_append(session->devices, device);
87 void session_pa_clear(void)
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;
97 void session_pa_add(struct analyzer *an)
100 session->analyzers = g_slist_append(session->analyzers, an);
105 void session_datafeed_callback_clear(void)
108 g_slist_free(session->datafeed_callbacks);
109 session->datafeed_callbacks = NULL;
114 void session_datafeed_callback_add(datafeed_callback callback)
117 session->datafeed_callbacks = g_slist_append(session->datafeed_callbacks, callback);
122 int session_start(void)
124 struct device *device;
128 g_message("starting acquisition");
129 for(l = session->devices; l; l = l->next)
132 if( (ret = device->plugin->start_acquisition(device->plugin_index, device)) != SIGROK_OK)
140 void session_stop(void)
142 struct device *device;
145 g_message("stopping acquisition");
146 for(l = session->devices; l; l = l->next)
149 device->plugin->stop_acquisition(device->plugin_index, device);
155 void session_bus(struct device *device, struct datafeed_packet *packet)
158 datafeed_callback cb;
160 /* TODO: send packet through PA pipe, and send the output of that to
161 * the callbacks as well
164 for(l = session->datafeed_callbacks; l; l = l->next)
173 void make_metadata(char *filename)
176 struct device *device;
181 f = fopen(filename, "wb");
187 for(l = session->devices; l; l = l->next) {
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) {
197 fprintf(f, "probe %d", probe->index);
199 fprintf(f, " name \"%s\"", probe->name);
201 fprintf(f, " trigger \"%s\"", probe->trigger);
208 /* TODO: protocol analyzers */
215 int session_save(char *filename)
218 struct device *device;
219 struct datastore *ds;
221 struct zip_source *src;
222 int bufcnt, devcnt, tmpfile, ret, error;
223 char version[1], rawname[16], metafile[32], *buf;
225 /* quietly delete it first, libzip wants replace ops otherwise */
228 if( !(zipfile = zip_open(filename, ZIP_CREATE, &error)) )
233 if( !(src = zip_source_buffer(zipfile, version, 1, 0)) )
235 if(zip_add(zipfile, "version", src) == -1) {
236 g_message("error saving version into zipfile: %s", zip_strerror(zipfile));
241 strcpy(metafile, "sigrok-meta-XXXXXX");
242 if( (tmpfile = g_mkstemp(metafile)) == -1)
245 make_metadata(metafile);
246 if( !(src = zip_source_file(zipfile, metafile, 0, -1)) )
248 if(zip_add(zipfile, "metadata", src) == -1)
254 for(l = session->devices; l; l = l->next) {
256 ds = device->datastore;
258 buf = malloc(ds->num_units * ds->ds_unitsize + DATASTORE_CHUNKSIZE);
260 for(d = ds->chunklist; d; d = d->next) {
261 memcpy(buf + bufcnt, d->data, DATASTORE_CHUNKSIZE);
262 bufcnt += DATASTORE_CHUNKSIZE;
264 if( !(src = zip_source_buffer(zipfile, buf, ds->num_units * ds->ds_unitsize, TRUE)) )
266 snprintf(rawname, 15, "raw-%d", devcnt);
267 if(zip_add(zipfile, rawname, src) == -1)
273 if( (ret = zip_close(zipfile)) == -1) {
274 g_message("error saving zipfile: %s", zip_strerror(zipfile));