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