]> sigrok.org Git - libsigrok.git/blame - bindings/cxx/classes.cpp
log: Remove sr_log_logdomain_{get,set} from the API
[libsigrok.git] / bindings / cxx / classes.cpp
CommitLineData
c23c8659
ML
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2013-2014 Martin Ling <martin-sigrok@earth.li>
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
b5f07319 20#include <libsigrokcxx/libsigrokcxx.hpp>
c23c8659 21
f36ca889 22#include <sstream>
35114c33 23#include <cmath>
f36ca889 24
c23c8659
ML
25namespace sigrok
26{
27
c23c8659
ML
28/** Helper function to translate C errors to C++ exceptions. */
29static void check(int result)
30{
31 if (result != SR_OK)
32 throw Error(result);
33}
34
35/** Helper function to obtain valid strings from possibly null input. */
36static const char *valid_string(const char *input)
37{
38 if (input != NULL)
39 return input;
40 else
41 return "";
42}
43
58aa1f83
ML
44/** Helper function to convert between map<string, VariantBase> and GHashTable */
45static GHashTable *map_to_hash_variant(map<string, Glib::VariantBase> input)
46{
47 auto output = g_hash_table_new_full(
b31581f8 48 g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
58aa1f83
ML
49 for (auto entry : input)
50 g_hash_table_insert(output,
51 g_strdup(entry.first.c_str()),
52 entry.second.gobj_copy());
53 return output;
54}
55
c23c8659
ML
56Error::Error(int result) : result(result)
57{
58}
59
60const char *Error::what() const throw()
61{
62 return sr_strerror(result);
63}
64
65Error::~Error() throw()
66{
67}
68
69shared_ptr<Context> Context::create()
70{
71 return shared_ptr<Context>(new Context(), Context::Deleter());
72}
73
74Context::Context() :
3b161085
ML
75 UserOwned(_structure),
76 _session(NULL)
c23c8659 77{
3b161085 78 check(sr_init(&_structure));
90e89c2a 79
032da34b 80 struct sr_dev_driver **driver_list = sr_driver_list(_structure);
c23c8659
ML
81 if (driver_list)
82 for (int i = 0; driver_list[i]; i++)
3b161085 83 _drivers[driver_list[i]->name] =
c23c8659 84 new Driver(driver_list[i]);
ca3291e3 85 const struct sr_input_module **input_list = sr_input_list();
c23c8659
ML
86 if (input_list)
87 for (int i = 0; input_list[i]; i++)
3b161085 88 _input_formats[sr_input_id_get(input_list[i])] =
c23c8659 89 new InputFormat(input_list[i]);
58aa1f83 90 const struct sr_output_module **output_list = sr_output_list();
c23c8659
ML
91 if (output_list)
92 for (int i = 0; output_list[i]; i++)
3b161085 93 _output_formats[sr_output_id_get(output_list[i])] =
c23c8659
ML
94 new OutputFormat(output_list[i]);
95}
96
3b161085 97string Context::package_version()
c23c8659
ML
98{
99 return sr_package_version_string_get();
100}
101
3b161085 102string Context::lib_version()
c23c8659
ML
103{
104 return sr_lib_version_string_get();
105}
106
3b161085 107map<string, shared_ptr<Driver>> Context::drivers()
c23c8659
ML
108{
109 map<string, shared_ptr<Driver>> result;
3b161085 110 for (auto entry: _drivers)
c23c8659
ML
111 {
112 auto name = entry.first;
113 auto driver = entry.second;
bf52cc8c 114 result[name] = driver->get_shared_pointer(this);
c23c8659
ML
115 }
116 return result;
117}
118
3b161085 119map<string, shared_ptr<InputFormat>> Context::input_formats()
c23c8659
ML
120{
121 map<string, shared_ptr<InputFormat>> result;
3b161085 122 for (auto entry: _input_formats)
c23c8659
ML
123 {
124 auto name = entry.first;
125 auto input_format = entry.second;
bf52cc8c 126 result[name] = input_format->get_shared_pointer(this);
c23c8659
ML
127 }
128 return result;
129}
130
3b161085 131map<string, shared_ptr<OutputFormat>> Context::output_formats()
c23c8659
ML
132{
133 map<string, shared_ptr<OutputFormat>> result;
3b161085 134 for (auto entry: _output_formats)
c23c8659
ML
135 {
136 auto name = entry.first;
137 auto output_format = entry.second;
bf52cc8c 138 result[name] = output_format->get_shared_pointer(this);
c23c8659
ML
139 }
140 return result;
141}
142
143Context::~Context()
144{
3b161085 145 for (auto entry : _drivers)
c23c8659 146 delete entry.second;
3b161085 147 for (auto entry : _input_formats)
c23c8659 148 delete entry.second;
3b161085 149 for (auto entry : _output_formats)
c23c8659 150 delete entry.second;
3b161085 151 check(sr_exit(_structure));
c23c8659
ML
152}
153
3b161085 154const LogLevel *Context::log_level()
c23c8659
ML
155{
156 return LogLevel::get(sr_log_loglevel_get());
157}
158
159void Context::set_log_level(const LogLevel *level)
160{
3b161085 161 check(sr_log_loglevel_set(level->id()));
c23c8659
ML
162}
163
c23c8659
ML
164static int call_log_callback(void *cb_data, int loglevel, const char *format, va_list args)
165{
166 va_list args_copy;
167 va_copy(args_copy, args);
168 int length = vsnprintf(NULL, 0, format, args_copy);
169 va_end(args_copy);
170 char *buf = (char *) g_malloc(length + 1);
171 vsprintf(buf, format, args);
172 string message(buf, length);
173 g_free(buf);
174
175 LogCallbackFunction callback = *((LogCallbackFunction *) cb_data);
176
177 try
178 {
179 callback(LogLevel::get(loglevel), message);
180 }
181 catch (Error e)
182 {
183 return e.result;
184 }
185
186 return SR_OK;
187}
188
189void Context::set_log_callback(LogCallbackFunction callback)
190{
3b161085
ML
191 _log_callback = callback;
192 check(sr_log_callback_set(call_log_callback, &_log_callback));
c23c8659
ML
193}
194
195void Context::set_log_callback_default()
196{
197 check(sr_log_callback_set_default());
3b161085 198 _log_callback = nullptr;
c23c8659
ML
199}
200
201shared_ptr<Session> Context::create_session()
202{
203 return shared_ptr<Session>(
204 new Session(shared_from_this()), Session::Deleter());
205}
206
9fa5b426
ML
207shared_ptr<UserDevice> Context::create_user_device(
208 string vendor, string model, string version)
209{
210 return shared_ptr<UserDevice>(
211 new UserDevice(vendor, model, version), UserDevice::Deleter());
212}
213
304be4a7
ML
214shared_ptr<Packet> Context::create_header_packet(Glib::TimeVal start_time)
215{
216 auto header = g_new(struct sr_datafeed_header, 1);
217 header->feed_version = 1;
218 header->starttime.tv_sec = start_time.tv_sec;
219 header->starttime.tv_usec = start_time.tv_usec;
220 auto packet = g_new(struct sr_datafeed_packet, 1);
221 packet->type = SR_DF_HEADER;
222 packet->payload = header;
223 return shared_ptr<Packet>(new Packet(nullptr, packet), Packet::Deleter());
224}
225
226shared_ptr<Packet> Context::create_meta_packet(
227 map<const ConfigKey *, Glib::VariantBase> config)
228{
229 auto meta = g_new0(struct sr_datafeed_meta, 1);
230 for (auto input : config)
231 {
232 auto key = input.first;
233 auto value = input.second;
234 auto output = g_new(struct sr_config, 1);
235 output->key = key->id();
236 output->data = value.gobj();
237 g_variant_ref(output->data);
238 meta->config = g_slist_append(meta->config, output);
239 }
240 auto packet = g_new(struct sr_datafeed_packet, 1);
241 packet->type = SR_DF_META;
242 packet->payload = meta;
243 return shared_ptr<Packet>(new Packet(nullptr, packet), Packet::Deleter());
244}
245
246shared_ptr<Packet> Context::create_logic_packet(
247 void *data_pointer, size_t data_length, unsigned int unit_size)
248{
249 auto logic = g_new(struct sr_datafeed_logic, 1);
250 logic->length = data_length;
251 logic->unitsize = unit_size;
252 logic->data = data_pointer;
253 auto packet = g_new(struct sr_datafeed_packet, 1);
254 packet->type = SR_DF_LOGIC;
255 packet->payload = logic;
256 return shared_ptr<Packet>(new Packet(nullptr, packet), Packet::Deleter());
257}
258
259shared_ptr<Packet> Context::create_analog_packet(
260 vector<shared_ptr<Channel> > channels,
261 float *data_pointer, unsigned int num_samples, const Quantity *mq,
262 const Unit *unit, vector<const QuantityFlag *> mqflags)
263{
264 auto analog = g_new0(struct sr_datafeed_analog, 1);
265 for (auto channel : channels)
266 analog->channels = g_slist_append(analog->channels, channel->_structure);
267 analog->num_samples = num_samples;
268 analog->mq = mq->id();
269 analog->unit = unit->id();
270 analog->mqflags = QuantityFlag::mask_from_flags(mqflags);
271 analog->data = data_pointer;
272 auto packet = g_new(struct sr_datafeed_packet, 1);
273 packet->type = SR_DF_ANALOG;
274 packet->payload = analog;
275 return shared_ptr<Packet>(new Packet(nullptr, packet), Packet::Deleter());
276}
277
c23c8659
ML
278shared_ptr<Session> Context::load_session(string filename)
279{
280 return shared_ptr<Session>(
281 new Session(shared_from_this(), filename), Session::Deleter());
282}
283
284shared_ptr<Trigger> Context::create_trigger(string name)
285{
286 return shared_ptr<Trigger>(
287 new Trigger(shared_from_this(), name), Trigger::Deleter());
288}
289
ca3291e3
ML
290shared_ptr<Input> Context::open_file(string filename)
291{
f88c7373
BV
292 const struct sr_input *input;
293
d4cf45e5 294 check(sr_input_scan_file(filename.c_str(), &input));
ca3291e3
ML
295 return shared_ptr<Input>(
296 new Input(shared_from_this(), input), Input::Deleter());
297}
298
299shared_ptr<Input> Context::open_stream(string header)
300{
f88c7373
BV
301 const struct sr_input *input;
302
ca3291e3 303 auto gstr = g_string_new(header.c_str());
f88c7373
BV
304 auto ret = sr_input_scan_buffer(gstr, &input);
305 g_string_free(gstr, true);
306 check(ret);
ca3291e3
ML
307 return shared_ptr<Input>(
308 new Input(shared_from_this(), input), Input::Deleter());
309}
310
24287ea9
AJ
311map<string, string> Context::serials(shared_ptr<Driver> driver)
312{
313 GSList *serial_list = sr_serial_list(driver ? driver->_structure : NULL);
314 map<string, string> serials;
315
316 for (GSList *serial = serial_list; serial; serial = serial->next) {
317 struct sr_serial_port *port = (sr_serial_port *) serial->data;
318 serials[string(port->name)] = string(port->description);
319 }
320
321 g_slist_free_full(serial_list, (GDestroyNotify)sr_serial_free);
322 return serials;
323}
324
c23c8659 325Driver::Driver(struct sr_dev_driver *structure) :
541c855e 326 ParentOwned(structure),
59b74d28 327 Configurable(structure, NULL, NULL),
3b161085 328 _initialized(false)
c23c8659
ML
329{
330}
331
332Driver::~Driver()
333{
c23c8659
ML
334}
335
3b161085 336string Driver::name()
c23c8659 337{
3b161085 338 return valid_string(_structure->name);
c23c8659
ML
339}
340
3b161085 341string Driver::long_name()
c23c8659 342{
3b161085 343 return valid_string(_structure->longname);
c23c8659
ML
344}
345
346vector<shared_ptr<HardwareDevice>> Driver::scan(
347 map<const ConfigKey *, Glib::VariantBase> options)
348{
349 /* Initialise the driver if not yet done. */
3b161085 350 if (!_initialized)
c23c8659 351 {
3b161085
ML
352 check(sr_driver_init(_parent->_structure, _structure));
353 _initialized = true;
c23c8659
ML
354 }
355
c23c8659
ML
356 /* Translate scan options to GSList of struct sr_config pointers. */
357 GSList *option_list = NULL;
358 for (auto entry : options)
359 {
360 auto key = entry.first;
361 auto value = entry.second;
362 auto config = g_new(struct sr_config, 1);
3b161085 363 config->key = key->id();
c23c8659
ML
364 config->data = value.gobj();
365 option_list = g_slist_append(option_list, config);
366 }
367
368 /* Run scan. */
3b161085 369 GSList *device_list = sr_driver_scan(_structure, option_list);
c23c8659
ML
370
371 /* Free option list. */
372 g_slist_free_full(option_list, g_free);
373
a4e47454 374
c23c8659 375 /* Create device objects. */
a4e47454 376 vector<shared_ptr<HardwareDevice>> result;
c23c8659
ML
377 for (GSList *device = device_list; device; device = device->next)
378 {
379 auto sdi = (struct sr_dev_inst *) device->data;
a4e47454
ML
380 result.push_back(shared_ptr<HardwareDevice>(
381 new HardwareDevice(shared_from_this(), sdi),
382 HardwareDevice::Deleter()));
c23c8659
ML
383 }
384
385 /* Free GSList returned from scan. */
386 g_slist_free(device_list);
387
c23c8659
ML
388 return result;
389}
390
391Configurable::Configurable(
392 struct sr_dev_driver *driver,
393 struct sr_dev_inst *sdi,
394 struct sr_channel_group *cg) :
395 config_driver(driver),
396 config_sdi(sdi),
397 config_channel_group(cg)
398{
399}
400
401Configurable::~Configurable()
402{
403}
404
405Glib::VariantBase Configurable::config_get(const ConfigKey *key)
406{
407 GVariant *data;
408 check(sr_config_get(
409 config_driver, config_sdi, config_channel_group,
3b161085 410 key->id(), &data));
c23c8659
ML
411 return Glib::VariantBase(data);
412}
413
414void Configurable::config_set(const ConfigKey *key, Glib::VariantBase value)
415{
416 check(sr_config_set(
417 config_sdi, config_channel_group,
3b161085 418 key->id(), value.gobj()));
c23c8659
ML
419}
420
e194c011 421Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key)
c23c8659
ML
422{
423 GVariant *data;
424 check(sr_config_list(
425 config_driver, config_sdi, config_channel_group,
3b161085 426 key->id(), &data));
e194c011 427 return Glib::VariantContainerBase(data);
c23c8659
ML
428}
429
4c7c4194 430map<const ConfigKey *, set<Capability>> Configurable::config_keys(const ConfigKey *key)
d54190a3
ML
431{
432 GVariant *gvar_opts;
433 gsize num_opts;
03a4c07a 434 const uint32_t *opts;
4c7c4194 435 map<const ConfigKey *, set<Capability>> result;
d54190a3
ML
436
437 check(sr_config_list(
438 config_driver, config_sdi, config_channel_group,
3b161085 439 key->id(), &gvar_opts));
d54190a3 440
03a4c07a
AJ
441 opts = (const uint32_t *) g_variant_get_fixed_array(
442 gvar_opts, &num_opts, sizeof(uint32_t));
d54190a3
ML
443
444 for (gsize i = 0; i < num_opts; i++)
4c7c4194
ML
445 {
446 auto key = ConfigKey::get(opts[i] & SR_CONF_MASK);
447 set<Capability> capabilities;
448 if (opts[i] & SR_CONF_GET)
449 capabilities.insert(GET);
450 if (opts[i] & SR_CONF_SET)
451 capabilities.insert(SET);
452 if (opts[i] & SR_CONF_LIST)
453 capabilities.insert(LIST);
454 result[key] = capabilities;
455 }
d54190a3
ML
456
457 g_variant_unref(gvar_opts);
458
459 return result;
460}
461
d9eed47d
ML
462bool Configurable::config_check(const ConfigKey *key,
463 const ConfigKey *index_key)
464{
465 GVariant *gvar_opts;
466 gsize num_opts;
03a4c07a 467 const uint32_t *opts;
d9eed47d
ML
468
469 if (sr_config_list(config_driver, config_sdi, config_channel_group,
3b161085 470 index_key->id(), &gvar_opts) != SR_OK)
d9eed47d
ML
471 return false;
472
03a4c07a
AJ
473 opts = (const uint32_t *) g_variant_get_fixed_array(
474 gvar_opts, &num_opts, sizeof(uint32_t));
d9eed47d
ML
475
476 for (gsize i = 0; i < num_opts; i++)
477 {
9d229ecb 478 if ((opts[i] & SR_CONF_MASK) == (uint32_t) key->id())
d9eed47d
ML
479 {
480 g_variant_unref(gvar_opts);
481 return true;
482 }
483 }
484
485 g_variant_unref(gvar_opts);
486
487 return false;
488}
489
c23c8659 490Device::Device(struct sr_dev_inst *structure) :
80fe5247 491 Configurable(sr_dev_inst_driver_get(structure), structure, NULL),
3b161085 492 _structure(structure)
c23c8659 493{
80fe5247 494 for (GSList *entry = sr_dev_inst_channels_get(structure); entry; entry = entry->next)
c23c8659
ML
495 {
496 auto channel = (struct sr_channel *) entry->data;
3b161085 497 _channels[channel] = new Channel(channel);
c23c8659 498 }
6be7a7f2 499
80fe5247 500 for (GSList *entry = sr_dev_inst_channel_groups_get(structure); entry; entry = entry->next)
6be7a7f2
ML
501 {
502 auto group = (struct sr_channel_group *) entry->data;
3b161085 503 _channel_groups[group->name] = new ChannelGroup(this, group);
6be7a7f2 504 }
c23c8659
ML
505}
506
507Device::~Device()
508{
3b161085 509 for (auto entry : _channels)
4178d971 510 delete entry.second;
3b161085 511 for (auto entry : _channel_groups)
6be7a7f2 512 delete entry.second;
c23c8659
ML
513}
514
3b161085 515string Device::vendor()
c23c8659 516{
80fe5247 517 return valid_string(sr_dev_inst_vendor_get(_structure));
c23c8659
ML
518}
519
3b161085 520string Device::model()
c23c8659 521{
80fe5247 522 return valid_string(sr_dev_inst_model_get(_structure));
c23c8659
ML
523}
524
3b161085 525string Device::version()
c23c8659 526{
80fe5247 527 return valid_string(sr_dev_inst_version_get(_structure));
c23c8659
ML
528}
529
d1075e5a
ML
530string Device::serial_number()
531{
80fe5247 532 return valid_string(sr_dev_inst_sernum_get(_structure));
d1075e5a
ML
533}
534
535string Device::connection_id()
536{
80fe5247 537 return valid_string(sr_dev_inst_connid_get(_structure));
d1075e5a
ML
538}
539
3b161085 540vector<shared_ptr<Channel>> Device::channels()
c23c8659
ML
541{
542 vector<shared_ptr<Channel>> result;
80fe5247 543 for (auto channel = sr_dev_inst_channels_get(_structure); channel; channel = channel->next)
be43d5d5 544 result.push_back(
3b161085 545 _channels[(struct sr_channel *) channel->data]->get_shared_pointer(
be43d5d5 546 get_shared_from_this()));
c23c8659
ML
547 return result;
548}
549
4178d971
ML
550shared_ptr<Channel> Device::get_channel(struct sr_channel *ptr)
551{
3b161085 552 return _channels[ptr]->get_shared_pointer(get_shared_from_this());
4178d971
ML
553}
554
6be7a7f2 555map<string, shared_ptr<ChannelGroup>>
3b161085 556Device::channel_groups()
6be7a7f2
ML
557{
558 map<string, shared_ptr<ChannelGroup>> result;
3b161085 559 for (auto entry: _channel_groups)
6be7a7f2
ML
560 {
561 auto name = entry.first;
562 auto channel_group = entry.second;
bf52cc8c 563 result[name] = channel_group->get_shared_pointer(get_shared_from_this());
6be7a7f2
ML
564 }
565 return result;
566}
567
c23c8659
ML
568void Device::open()
569{
3b161085 570 check(sr_dev_open(_structure));
c23c8659
ML
571}
572
573void Device::close()
574{
3b161085 575 check(sr_dev_close(_structure));
c23c8659
ML
576}
577
a4e47454
ML
578HardwareDevice::HardwareDevice(shared_ptr<Driver> driver,
579 struct sr_dev_inst *structure) :
580 UserOwned(structure),
c23c8659 581 Device(structure),
3b161085 582 _driver(driver)
c23c8659 583{
c23c8659
ML
584}
585
586HardwareDevice::~HardwareDevice()
587{
c23c8659
ML
588}
589
d01d2314
ML
590shared_ptr<Device> HardwareDevice::get_shared_from_this()
591{
bf52cc8c 592 return static_pointer_cast<Device>(shared_from_this());
d01d2314
ML
593}
594
3b161085 595shared_ptr<Driver> HardwareDevice::driver()
c23c8659 596{
a4e47454 597 return _driver;
c23c8659
ML
598}
599
9fa5b426
ML
600UserDevice::UserDevice(string vendor, string model, string version) :
601 UserOwned(sr_dev_inst_user_new(
602 vendor.c_str(), model.c_str(), version.c_str())),
603 Device(UserOwned::_structure)
604{
605}
606
607UserDevice::~UserDevice()
608{
609}
610
611shared_ptr<Device> UserDevice::get_shared_from_this()
612{
613 return static_pointer_cast<Device>(shared_from_this());
614}
615
616shared_ptr<Channel> UserDevice::add_channel(unsigned int index,
617 const ChannelType *type, string name)
618{
619 check(sr_dev_inst_channel_add(Device::_structure,
620 index, type->id(), name.c_str()));
621 struct sr_channel *structure = (struct sr_channel *)
622 g_slist_last(sr_dev_inst_channels_get(Device::_structure))->data;
623 Channel *channel = new Channel(structure);
624 _channels[structure] = channel;
625 return get_channel(structure);
626}
627
c23c8659 628Channel::Channel(struct sr_channel *structure) :
541c855e 629 ParentOwned(structure),
3b161085 630 _type(ChannelType::get(_structure->type))
c23c8659
ML
631{
632}
633
634Channel::~Channel()
635{
636}
637
3b161085 638string Channel::name()
c23c8659 639{
3b161085 640 return valid_string(_structure->name);
c23c8659
ML
641}
642
643void Channel::set_name(string name)
644{
6f1346fb 645 check(sr_dev_channel_name_set(_structure, name.c_str()));
c23c8659
ML
646}
647
3b161085 648const ChannelType *Channel::type()
c23c8659 649{
3b161085 650 return ChannelType::get(_structure->type);
c23c8659
ML
651}
652
3b161085 653bool Channel::enabled()
c23c8659 654{
3b161085 655 return _structure->enabled;
c23c8659
ML
656}
657
658void Channel::set_enabled(bool value)
659{
6f1346fb 660 check(sr_dev_channel_enable(_structure, value));
c23c8659
ML
661}
662
3b161085 663unsigned int Channel::index()
06bd935e 664{
3b161085 665 return _structure->index;
06bd935e
ML
666}
667
6be7a7f2 668ChannelGroup::ChannelGroup(Device *device,
c23c8659 669 struct sr_channel_group *structure) :
541c855e 670 ParentOwned(structure),
80fe5247 671 Configurable(sr_dev_inst_driver_get(device->_structure), device->_structure, structure)
c23c8659
ML
672{
673 for (GSList *entry = structure->channels; entry; entry = entry->next)
3b161085 674 _channels.push_back(device->_channels[(struct sr_channel *)entry->data]);
c23c8659
ML
675}
676
677ChannelGroup::~ChannelGroup()
678{
679}
680
3b161085 681string ChannelGroup::name()
c23c8659 682{
3b161085 683 return valid_string(_structure->name);
c23c8659
ML
684}
685
3b161085 686vector<shared_ptr<Channel>> ChannelGroup::channels()
c23c8659
ML
687{
688 vector<shared_ptr<Channel>> result;
3b161085
ML
689 for (auto channel : _channels)
690 result.push_back(channel->get_shared_pointer(_parent));
c23c8659
ML
691 return result;
692}
693
694Trigger::Trigger(shared_ptr<Context> context, string name) :
90e89c2a 695 UserOwned(sr_trigger_new(name.c_str())),
3b161085 696 _context(context)
c23c8659 697{
3b161085
ML
698 for (auto stage = _structure->stages; stage; stage = stage->next)
699 _stages.push_back(
700 new TriggerStage((struct sr_trigger_stage *) stage->data));
c23c8659
ML
701}
702
703Trigger::~Trigger()
704{
3b161085 705 for (auto stage: _stages)
c23c8659
ML
706 delete stage;
707
3b161085 708 sr_trigger_free(_structure);
c23c8659
ML
709}
710
3b161085 711string Trigger::name()
c23c8659 712{
3b161085 713 return _structure->name;
c23c8659
ML
714}
715
3b161085 716vector<shared_ptr<TriggerStage>> Trigger::stages()
c23c8659
ML
717{
718 vector<shared_ptr<TriggerStage>> result;
3b161085 719 for (auto stage : _stages)
bf52cc8c 720 result.push_back(stage->get_shared_pointer(this));
c23c8659
ML
721 return result;
722}
723
724shared_ptr<TriggerStage> Trigger::add_stage()
725{
3b161085
ML
726 auto stage = new TriggerStage(sr_trigger_stage_add(_structure));
727 _stages.push_back(stage);
bf52cc8c 728 return stage->get_shared_pointer(this);
c23c8659
ML
729}
730
731TriggerStage::TriggerStage(struct sr_trigger_stage *structure) :
541c855e 732 ParentOwned(structure)
c23c8659
ML
733{
734}
735
736TriggerStage::~TriggerStage()
737{
3b161085 738 for (auto match : _matches)
c23c8659
ML
739 delete match;
740}
741
3b161085 742int TriggerStage::number()
c23c8659 743{
3b161085 744 return _structure->stage;
c23c8659
ML
745}
746
3b161085 747vector<shared_ptr<TriggerMatch>> TriggerStage::matches()
c23c8659
ML
748{
749 vector<shared_ptr<TriggerMatch>> result;
3b161085 750 for (auto match : _matches)
bf52cc8c 751 result.push_back(match->get_shared_pointer(this));
c23c8659
ML
752 return result;
753}
754
3b161085
ML
755void TriggerStage::add_match(shared_ptr<Channel> channel,
756 const TriggerMatchType *type, float value)
c23c8659 757{
3b161085
ML
758 check(sr_trigger_match_add(_structure,
759 channel->_structure, type->id(), value));
760 _matches.push_back(new TriggerMatch(
761 (struct sr_trigger_match *) g_slist_last(
762 _structure->matches)->data, channel));
c23c8659
ML
763}
764
3b161085
ML
765void TriggerStage::add_match(shared_ptr<Channel> channel,
766 const TriggerMatchType *type)
c23c8659
ML
767{
768 add_match(channel, type, NAN);
769}
770
3b161085
ML
771TriggerMatch::TriggerMatch(struct sr_trigger_match *structure,
772 shared_ptr<Channel> channel) :
773 ParentOwned(structure),
774 _channel(channel)
c23c8659
ML
775{
776}
777
778TriggerMatch::~TriggerMatch()
779{
780}
781
3b161085 782shared_ptr<Channel> TriggerMatch::channel()
c23c8659 783{
3b161085 784 return _channel;
c23c8659
ML
785}
786
3b161085 787const TriggerMatchType *TriggerMatch::type()
c23c8659 788{
3b161085 789 return TriggerMatchType::get(_structure->match);
c23c8659
ML
790}
791
3b161085 792float TriggerMatch::value()
c23c8659 793{
3b161085 794 return _structure->value;
c23c8659
ML
795}
796
797DatafeedCallbackData::DatafeedCallbackData(Session *session,
798 DatafeedCallbackFunction callback) :
3b161085
ML
799 _callback(callback),
800 _session(session)
c23c8659
ML
801{
802}
803
804void DatafeedCallbackData::run(const struct sr_dev_inst *sdi,
805 const struct sr_datafeed_packet *pkt)
806{
ca4e307a 807 auto device = _session->get_device(sdi);
2928f47d 808 auto packet = shared_ptr<Packet>(new Packet(device, pkt), Packet::Deleter());
3b161085 809 _callback(device, packet);
c23c8659
ML
810}
811
812SourceCallbackData::SourceCallbackData(shared_ptr<EventSource> source) :
3b161085 813 _source(source)
c23c8659
ML
814{
815}
816
817bool SourceCallbackData::run(int revents)
818{
3b161085 819 return _source->_callback((Glib::IOCondition) revents);
c23c8659
ML
820}
821
822shared_ptr<EventSource> EventSource::create(int fd, Glib::IOCondition events,
823 int timeout, SourceCallbackFunction callback)
824{
825 auto result = new EventSource(timeout, callback);
3b161085
ML
826 result->_type = EventSource::SOURCE_FD;
827 result->_fd = fd;
828 result->_events = events;
c23c8659
ML
829 return shared_ptr<EventSource>(result, EventSource::Deleter());
830}
831
832shared_ptr<EventSource> EventSource::create(Glib::PollFD pollfd, int timeout,
833 SourceCallbackFunction callback)
834{
835 auto result = new EventSource(timeout, callback);
3b161085
ML
836 result->_type = EventSource::SOURCE_POLLFD;
837 result->_pollfd = pollfd;
c23c8659
ML
838 return shared_ptr<EventSource>(result, EventSource::Deleter());
839}
840
841shared_ptr<EventSource> EventSource::create(Glib::RefPtr<Glib::IOChannel> channel,
842 Glib::IOCondition events, int timeout, SourceCallbackFunction callback)
843{
844 auto result = new EventSource(timeout, callback);
3b161085
ML
845 result->_type = EventSource::SOURCE_IOCHANNEL;
846 result->_channel = channel;
847 result->_events = events;
c23c8659
ML
848 return shared_ptr<EventSource>(result, EventSource::Deleter());
849}
850
851EventSource::EventSource(int timeout, SourceCallbackFunction callback) :
3b161085
ML
852 _timeout(timeout),
853 _callback(callback)
c23c8659
ML
854{
855}
856
857EventSource::~EventSource()
858{
859}
860
cac58676
ML
861SessionDevice::SessionDevice(struct sr_dev_inst *structure) :
862 ParentOwned(structure),
863 Device(structure)
864{
865}
866
867SessionDevice::~SessionDevice()
868{
869}
870
871shared_ptr<Device> SessionDevice::get_shared_from_this()
872{
873 return static_pointer_cast<Device>(shared_from_this());
874}
875
c23c8659 876Session::Session(shared_ptr<Context> context) :
3b161085
ML
877 UserOwned(_structure),
878 _context(context),
879 _saving(false)
c23c8659 880{
60f6b001 881 check(sr_session_new(context->_structure, &_structure));
3b161085 882 _context->_session = this;
c23c8659
ML
883}
884
885Session::Session(shared_ptr<Context> context, string filename) :
3b161085
ML
886 UserOwned(_structure),
887 _context(context),
98d39b91 888 _filename(filename),
3b161085 889 _saving(false)
c23c8659 890{
c879dca3 891 check(sr_session_load(context->_structure, filename.c_str(), &_structure));
cac58676 892 GSList *dev_list;
3b161085 893 check(sr_session_dev_list(_structure, &dev_list));
cac58676
ML
894 for (GSList *dev = dev_list; dev; dev = dev->next)
895 {
896 auto sdi = (struct sr_dev_inst *) dev->data;
ca4e307a 897 _owned_devices[sdi] = new SessionDevice(sdi);
cac58676 898 }
3b161085 899 _context->_session = this;
c23c8659
ML
900}
901
902Session::~Session()
903{
3b161085 904 check(sr_session_destroy(_structure));
c23c8659 905
3b161085 906 for (auto callback : _datafeed_callbacks)
c23c8659
ML
907 delete callback;
908
3b161085 909 for (auto entry : _source_callbacks)
c23c8659 910 delete entry.second;
ca4e307a
ML
911
912 for (auto entry : _owned_devices)
913 delete entry.second;
914}
915
916shared_ptr<Device> Session::get_device(const struct sr_dev_inst *sdi)
917{
918 if (_owned_devices.count(sdi))
919 return static_pointer_cast<Device>(
920 _owned_devices[sdi]->get_shared_pointer(this));
921 else if (_other_devices.count(sdi))
922 return _other_devices[sdi];
923 else
924 throw Error(SR_ERR_BUG);
c23c8659
ML
925}
926
927void Session::add_device(shared_ptr<Device> device)
928{
3b161085 929 check(sr_session_dev_add(_structure, device->_structure));
ca4e307a 930 _other_devices[device->_structure] = device;
c23c8659
ML
931}
932
3b161085 933vector<shared_ptr<Device>> Session::devices()
c23c8659
ML
934{
935 GSList *dev_list;
3b161085 936 check(sr_session_dev_list(_structure, &dev_list));
c23c8659
ML
937 vector<shared_ptr<Device>> result;
938 for (GSList *dev = dev_list; dev; dev = dev->next)
939 {
940 auto sdi = (struct sr_dev_inst *) dev->data;
ca4e307a 941 result.push_back(get_device(sdi));
c23c8659
ML
942 }
943 return result;
944}
945
946void Session::remove_devices()
947{
ca4e307a 948 _other_devices.clear();
3b161085 949 check(sr_session_dev_remove_all(_structure));
c23c8659
ML
950}
951
952void Session::start()
953{
3b161085 954 check(sr_session_start(_structure));
c23c8659
ML
955}
956
957void Session::run()
958{
3b161085 959 check(sr_session_run(_structure));
c23c8659
ML
960}
961
962void Session::stop()
963{
3b161085 964 check(sr_session_stop(_structure));
c23c8659
ML
965}
966
967void Session::begin_save(string filename)
968{
3b161085
ML
969 _saving = true;
970 _save_initialized = false;
971 _save_filename = filename;
972 _save_samplerate = 0;
c23c8659
ML
973}
974
1d67cfb4 975void Session::append(shared_ptr<Packet> packet)
c23c8659 976{
3b161085 977 if (!_saving)
c23c8659
ML
978 throw Error(SR_ERR);
979
3b161085 980 switch (packet->_structure->type)
c23c8659
ML
981 {
982 case SR_DF_META:
983 {
984 auto meta = (const struct sr_datafeed_meta *)
3b161085 985 packet->_structure->payload;
c23c8659
ML
986
987 for (auto l = meta->config; l; l = l->next)
988 {
989 auto config = (struct sr_config *) l->data;
990 if (config->key == SR_CONF_SAMPLERATE)
3b161085 991 _save_samplerate = g_variant_get_uint64(config->data);
c23c8659
ML
992 }
993
994 break;
995 }
996 case SR_DF_LOGIC:
997 {
3b161085 998 if (_save_samplerate == 0)
c23c8659
ML
999 {
1000 GVariant *samplerate;
1001
80fe5247 1002 check(sr_config_get(sr_dev_inst_driver_get(packet->_device->_structure),
3b161085 1003 packet->_device->_structure, NULL, SR_CONF_SAMPLERATE,
1d67cfb4 1004 &samplerate));
c23c8659 1005
3b161085 1006 _save_samplerate = g_variant_get_uint64(samplerate);
c23c8659
ML
1007
1008 g_variant_unref(samplerate);
1009 }
1010
3b161085 1011 if (!_save_initialized)
c23c8659
ML
1012 {
1013 vector<shared_ptr<Channel>> save_channels;
1014
3b161085
ML
1015 for (auto channel : packet->_device->channels())
1016 if (channel->_structure->enabled &&
1017 channel->_structure->type == SR_CHANNEL_LOGIC)
c23c8659
ML
1018 save_channels.push_back(channel);
1019
1020 auto channels = g_new(char *, save_channels.size());
1021
1022 int i = 0;
1023 for (auto channel : save_channels)
3b161085 1024 channels[i++] = channel->_structure->name;
c23c8659
ML
1025 channels[i] = NULL;
1026
3b161085
ML
1027 int ret = sr_session_save_init(_structure, _save_filename.c_str(),
1028 _save_samplerate, channels);
c23c8659
ML
1029
1030 g_free(channels);
1031
1032 if (ret != SR_OK)
1033 throw Error(ret);
1034
3b161085 1035 _save_initialized = true;
c23c8659
ML
1036 }
1037
1038 auto logic = (const struct sr_datafeed_logic *)
3b161085 1039 packet->_structure->payload;
c23c8659 1040
3b161085 1041 check(sr_session_append(_structure, _save_filename.c_str(),
c23c8659
ML
1042 (uint8_t *) logic->data, logic->unitsize,
1043 logic->length / logic->unitsize));
1044 }
1045 }
1046}
1047
1d67cfb4
ML
1048void Session::append(void *data, size_t length, unsigned int unit_size)
1049{
3b161085 1050 check(sr_session_append(_structure, _save_filename.c_str(),
1d67cfb4
ML
1051 (uint8_t *) data, unit_size, length));
1052}
1053
c23c8659
ML
1054static void datafeed_callback(const struct sr_dev_inst *sdi,
1055 const struct sr_datafeed_packet *pkt, void *cb_data)
1056{
1057 auto callback = static_cast<DatafeedCallbackData *>(cb_data);
1058 callback->run(sdi, pkt);
1059}
1060
1061void Session::add_datafeed_callback(DatafeedCallbackFunction callback)
1062{
1063 auto cb_data = new DatafeedCallbackData(this, callback);
3b161085
ML
1064 check(sr_session_datafeed_callback_add(_structure,
1065 datafeed_callback, cb_data));
1066 _datafeed_callbacks.push_back(cb_data);
c23c8659
ML
1067}
1068
1069void Session::remove_datafeed_callbacks(void)
1070{
3b161085
ML
1071 check(sr_session_datafeed_callback_remove_all(_structure));
1072 for (auto callback : _datafeed_callbacks)
c23c8659 1073 delete callback;
3b161085 1074 _datafeed_callbacks.clear();
c23c8659
ML
1075}
1076
1077static int source_callback(int fd, int revents, void *cb_data)
1078{
1079 (void) fd;
1080 auto callback = (SourceCallbackData *) cb_data;
1081 return callback->run(revents);
1082}
1083
1084void Session::add_source(shared_ptr<EventSource> source)
1085{
3b161085 1086 if (_source_callbacks.count(source) == 1)
c23c8659
ML
1087 throw Error(SR_ERR_ARG);
1088
1089 auto cb_data = new SourceCallbackData(source);
1090
3b161085 1091 switch (source->_type)
c23c8659
ML
1092 {
1093 case EventSource::SOURCE_FD:
3b161085
ML
1094 check(sr_session_source_add(_structure, source->_fd, source->_events,
1095 source->_timeout, source_callback, cb_data));
c23c8659
ML
1096 break;
1097 case EventSource::SOURCE_POLLFD:
3b161085
ML
1098 check(sr_session_source_add_pollfd(_structure,
1099 source->_pollfd.gobj(), source->_timeout, source_callback,
c23c8659
ML
1100 cb_data));
1101 break;
1102 case EventSource::SOURCE_IOCHANNEL:
3b161085
ML
1103 check(sr_session_source_add_channel(_structure,
1104 source->_channel->gobj(), source->_events, source->_timeout,
c23c8659
ML
1105 source_callback, cb_data));
1106 break;
1107 }
1108
3b161085 1109 _source_callbacks[source] = cb_data;
c23c8659
ML
1110}
1111
1112void Session::remove_source(shared_ptr<EventSource> source)
1113{
3b161085 1114 if (_source_callbacks.count(source) == 0)
c23c8659
ML
1115 throw Error(SR_ERR_ARG);
1116
3b161085 1117 switch (source->_type)
c23c8659
ML
1118 {
1119 case EventSource::SOURCE_FD:
3b161085 1120 check(sr_session_source_remove(_structure, source->_fd));
c23c8659
ML
1121 break;
1122 case EventSource::SOURCE_POLLFD:
3b161085
ML
1123 check(sr_session_source_remove_pollfd(_structure,
1124 source->_pollfd.gobj()));
c23c8659
ML
1125 break;
1126 case EventSource::SOURCE_IOCHANNEL:
3b161085
ML
1127 check(sr_session_source_remove_channel(_structure,
1128 source->_channel->gobj()));
c23c8659
ML
1129 break;
1130 }
1131
3b161085 1132 delete _source_callbacks[source];
c23c8659 1133
3b161085 1134 _source_callbacks.erase(source);
c23c8659
ML
1135}
1136
3b161085 1137shared_ptr<Trigger> Session::trigger()
6fa0eb86 1138{
3b161085 1139 return _trigger;
6fa0eb86
ML
1140}
1141
1142void Session::set_trigger(shared_ptr<Trigger> trigger)
1143{
e835e808
UH
1144 if (!trigger)
1145 // Set NULL trigger, i.e. remove any trigger from the session.
1146 check(sr_session_trigger_set(_structure, NULL));
1147 else
1148 check(sr_session_trigger_set(_structure, trigger->_structure));
3b161085 1149 _trigger = trigger;
6fa0eb86
ML
1150}
1151
1411f7d8
ML
1152string Session::filename()
1153{
1154 return _filename;
1155}
1156
624d1610
UH
1157shared_ptr<Context> Session::context()
1158{
1159 return _context;
1160}
1161
2928f47d
ML
1162Packet::Packet(shared_ptr<Device> device,
1163 const struct sr_datafeed_packet *structure) :
90e89c2a 1164 UserOwned(structure),
3b161085 1165 _device(device)
c23c8659
ML
1166{
1167 switch (structure->type)
1168 {
2928f47d 1169 case SR_DF_HEADER:
3b161085 1170 _payload = new Header(
2928f47d
ML
1171 static_cast<const struct sr_datafeed_header *>(
1172 structure->payload));
1173 break;
1174 case SR_DF_META:
3b161085 1175 _payload = new Meta(
2928f47d
ML
1176 static_cast<const struct sr_datafeed_meta *>(
1177 structure->payload));
1178 break;
c23c8659 1179 case SR_DF_LOGIC:
3b161085 1180 _payload = new Logic(
c23c8659
ML
1181 static_cast<const struct sr_datafeed_logic *>(
1182 structure->payload));
1183 break;
1184 case SR_DF_ANALOG:
3b161085 1185 _payload = new Analog(
c23c8659
ML
1186 static_cast<const struct sr_datafeed_analog *>(
1187 structure->payload));
1188 break;
4cd883a7 1189 default:
3b161085 1190 _payload = nullptr;
4cd883a7 1191 break;
c23c8659
ML
1192 }
1193}
1194
1195Packet::~Packet()
1196{
3b161085
ML
1197 if (_payload)
1198 delete _payload;
c23c8659
ML
1199}
1200
3b161085 1201const PacketType *Packet::type()
90ba83f2 1202{
3b161085 1203 return PacketType::get(_structure->type);
90ba83f2
ML
1204}
1205
3b161085 1206shared_ptr<PacketPayload> Packet::payload()
c23c8659 1207{
3b161085
ML
1208 if (_payload)
1209 return _payload->get_shared_pointer(this);
4cd883a7
ML
1210 else
1211 throw Error(SR_ERR_NA);
c23c8659
ML
1212}
1213
1214PacketPayload::PacketPayload()
1215{
1216}
1217
1218PacketPayload::~PacketPayload()
1219{
1220}
1221
2928f47d 1222Header::Header(const struct sr_datafeed_header *structure) :
541c855e 1223 ParentOwned(structure),
4cd883a7 1224 PacketPayload()
2928f47d
ML
1225{
1226}
1227
1228Header::~Header()
1229{
1230}
1231
3b161085 1232shared_ptr<PacketPayload> Header::get_shared_pointer(Packet *_parent)
4cd883a7 1233{
4f7bcf0e 1234 return static_pointer_cast<PacketPayload>(
3b161085 1235 ParentOwned::get_shared_pointer(_parent));
4cd883a7
ML
1236}
1237
3b161085 1238int Header::feed_version()
2928f47d 1239{
3b161085 1240 return _structure->feed_version;
2928f47d
ML
1241}
1242
3b161085 1243Glib::TimeVal Header::start_time()
2928f47d
ML
1244{
1245 return Glib::TimeVal(
3b161085
ML
1246 _structure->starttime.tv_sec,
1247 _structure->starttime.tv_usec);
2928f47d
ML
1248}
1249
1250Meta::Meta(const struct sr_datafeed_meta *structure) :
541c855e 1251 ParentOwned(structure),
4cd883a7 1252 PacketPayload()
2928f47d
ML
1253{
1254}
1255
1256Meta::~Meta()
1257{
1258}
1259
3b161085 1260shared_ptr<PacketPayload> Meta::get_shared_pointer(Packet *_parent)
4cd883a7 1261{
4f7bcf0e 1262 return static_pointer_cast<PacketPayload>(
3b161085 1263 ParentOwned::get_shared_pointer(_parent));
4cd883a7
ML
1264}
1265
3b161085 1266map<const ConfigKey *, Glib::VariantBase> Meta::config()
2928f47d
ML
1267{
1268 map<const ConfigKey *, Glib::VariantBase> result;
3b161085 1269 for (auto l = _structure->config; l; l = l->next)
2928f47d
ML
1270 {
1271 auto config = (struct sr_config *) l->data;
1272 result[ConfigKey::get(config->key)] = Glib::VariantBase(config->data);
1273 }
1274 return result;
1275}
1276
1277Logic::Logic(const struct sr_datafeed_logic *structure) :
541c855e 1278 ParentOwned(structure),
4cd883a7 1279 PacketPayload()
2928f47d
ML
1280{
1281}
c23c8659
ML
1282
1283Logic::~Logic()
1284{
1285}
1286
3b161085 1287shared_ptr<PacketPayload> Logic::get_shared_pointer(Packet *_parent)
4cd883a7 1288{
4f7bcf0e 1289 return static_pointer_cast<PacketPayload>(
3b161085 1290 ParentOwned::get_shared_pointer(_parent));
4cd883a7
ML
1291}
1292
3b161085 1293void *Logic::data_pointer()
c23c8659 1294{
3b161085 1295 return _structure->data;
c23c8659
ML
1296}
1297
3b161085 1298size_t Logic::data_length()
c23c8659 1299{
3b161085 1300 return _structure->length;
c23c8659
ML
1301}
1302
3b161085 1303unsigned int Logic::unit_size()
2928f47d 1304{
3b161085 1305 return _structure->unitsize;
2928f47d
ML
1306}
1307
c23c8659 1308Analog::Analog(const struct sr_datafeed_analog *structure) :
541c855e 1309 ParentOwned(structure),
4cd883a7 1310 PacketPayload()
c23c8659
ML
1311{
1312}
1313
1314Analog::~Analog()
1315{
1316}
1317
3b161085 1318shared_ptr<PacketPayload> Analog::get_shared_pointer(Packet *_parent)
4cd883a7 1319{
4f7bcf0e 1320 return static_pointer_cast<PacketPayload>(
3b161085 1321 ParentOwned::get_shared_pointer(_parent));
4cd883a7
ML
1322}
1323
3b161085 1324float *Analog::data_pointer()
c23c8659 1325{
3b161085 1326 return _structure->data;
c23c8659
ML
1327}
1328
3b161085 1329unsigned int Analog::num_samples()
c23c8659 1330{
3b161085 1331 return _structure->num_samples;
c23c8659
ML
1332}
1333
3b161085 1334vector<shared_ptr<Channel>> Analog::channels()
c23c8659 1335{
2928f47d 1336 vector<shared_ptr<Channel>> result;
3b161085
ML
1337 for (auto l = _structure->channels; l; l = l->next)
1338 result.push_back(_parent->_device->get_channel(
2928f47d
ML
1339 (struct sr_channel *)l->data));
1340 return result;
c23c8659
ML
1341}
1342
3b161085 1343const Quantity *Analog::mq()
c23c8659 1344{
3b161085 1345 return Quantity::get(_structure->mq);
c23c8659
ML
1346}
1347
3b161085 1348const Unit *Analog::unit()
c23c8659 1349{
3b161085 1350 return Unit::get(_structure->unit);
c23c8659
ML
1351}
1352
3b161085 1353vector<const QuantityFlag *> Analog::mq_flags()
c23c8659 1354{
3b161085 1355 return QuantityFlag::flags_from_mask(_structure->mqflags);
c23c8659
ML
1356}
1357
ca3291e3 1358InputFormat::InputFormat(const struct sr_input_module *structure) :
541c855e 1359 ParentOwned(structure)
c23c8659
ML
1360{
1361}
1362
1363InputFormat::~InputFormat()
1364{
1365}
1366
3b161085 1367string InputFormat::name()
c23c8659 1368{
3b161085 1369 return valid_string(sr_input_id_get(_structure));
c23c8659
ML
1370}
1371
3b161085 1372string InputFormat::description()
c23c8659 1373{
3b161085 1374 return valid_string(sr_input_description_get(_structure));
ca3291e3
ML
1375}
1376
c7bc82ff
JH
1377vector<string> InputFormat::extensions()
1378{
1379 vector<string> exts;
1380 for (const char *const *e = sr_input_extensions_get(_structure);
1381 e && *e; e++)
1382 exts.push_back(*e);
1383 return exts;
1384}
1385
3b161085 1386map<string, shared_ptr<Option>> InputFormat::options()
43942280 1387{
3b161085 1388 const struct sr_option **options = sr_input_options_get(_structure);
43942280 1389 map<string, shared_ptr<Option>> result;
48d92e2c
ML
1390 if (options)
1391 {
1392 auto option_array = shared_ptr<const struct sr_option *>(
1393 options, sr_input_options_free);
1394 for (int i = 0; options[i]; i++)
1395 result[options[i]->id] = shared_ptr<Option>(
1396 new Option(options[i], option_array), Option::Deleter());
1397 }
43942280
ML
1398 return result;
1399}
1400
ca3291e3
ML
1401shared_ptr<Input> InputFormat::create_input(
1402 map<string, Glib::VariantBase> options)
1403{
3b161085 1404 auto input = sr_input_new(_structure, map_to_hash_variant(options));
ca3291e3
ML
1405 if (!input)
1406 throw Error(SR_ERR_ARG);
1407 return shared_ptr<Input>(
3b161085 1408 new Input(_parent->shared_from_this(), input), Input::Deleter());
c23c8659
ML
1409}
1410
ca3291e3 1411Input::Input(shared_ptr<Context> context, const struct sr_input *structure) :
90e89c2a 1412 UserOwned(structure),
3b161085
ML
1413 _context(context),
1414 _device(nullptr)
c23c8659 1415{
c23c8659
ML
1416}
1417
3b161085 1418shared_ptr<InputDevice> Input::device()
c23c8659 1419{
3b161085 1420 if (!_device)
ca3291e3 1421 {
3b161085 1422 auto sdi = sr_input_dev_inst_get(_structure);
ca3291e3
ML
1423 if (!sdi)
1424 throw Error(SR_ERR_NA);
3b161085 1425 _device = new InputDevice(shared_from_this(), sdi);
ca3291e3 1426 }
c23c8659 1427
3b161085 1428 return _device->get_shared_pointer(shared_from_this());
ca3291e3 1429}
c23c8659 1430
2b51d48b 1431void Input::send(void *data, size_t length)
ca3291e3 1432{
2b51d48b 1433 auto gstr = g_string_new_len((gchar *)data, length);
3b161085 1434 auto ret = sr_input_send(_structure, gstr);
ca3291e3
ML
1435 g_string_free(gstr, false);
1436 check(ret);
c23c8659
ML
1437}
1438
9c51e8ec
ML
1439void Input::end()
1440{
1441 check(sr_input_end(_structure));
1442}
1443
ca3291e3 1444Input::~Input()
c23c8659 1445{
3b161085
ML
1446 if (_device)
1447 delete _device;
9c51e8ec 1448 sr_input_free(_structure);
c23c8659
ML
1449}
1450
6e5240f4
ML
1451InputDevice::InputDevice(shared_ptr<Input> input,
1452 struct sr_dev_inst *structure) :
541c855e 1453 ParentOwned(structure),
6e5240f4 1454 Device(structure),
3b161085 1455 _input(input)
c23c8659 1456{
c23c8659
ML
1457}
1458
ca3291e3 1459InputDevice::~InputDevice()
c23c8659 1460{
c23c8659
ML
1461}
1462
d01d2314
ML
1463shared_ptr<Device> InputDevice::get_shared_from_this()
1464{
bf52cc8c 1465 return static_pointer_cast<Device>(shared_from_this());
d01d2314
ML
1466}
1467
58aa1f83 1468Option::Option(const struct sr_option *structure,
70d3b20b 1469 shared_ptr<const struct sr_option *> structure_array) :
90e89c2a 1470 UserOwned(structure),
3b161085 1471 _structure_array(structure_array)
58aa1f83
ML
1472{
1473}
1474
1475Option::~Option()
1476{
1477}
1478
3b161085 1479string Option::id()
58aa1f83 1480{
3b161085 1481 return valid_string(_structure->id);
58aa1f83
ML
1482}
1483
3b161085 1484string Option::name()
58aa1f83 1485{
3b161085 1486 return valid_string(_structure->name);
58aa1f83
ML
1487}
1488
3b161085 1489string Option::description()
58aa1f83 1490{
3b161085 1491 return valid_string(_structure->desc);
58aa1f83
ML
1492}
1493
3b161085 1494Glib::VariantBase Option::default_value()
58aa1f83 1495{
3b161085 1496 return Glib::VariantBase(_structure->def, true);
58aa1f83
ML
1497}
1498
3b161085 1499vector<Glib::VariantBase> Option::values()
58aa1f83
ML
1500{
1501 vector<Glib::VariantBase> result;
3b161085 1502 for (auto l = _structure->values; l; l = l->next)
58aa1f83
ML
1503 result.push_back(Glib::VariantBase((GVariant *) l->data, true));
1504 return result;
1505}
1506
1507OutputFormat::OutputFormat(const struct sr_output_module *structure) :
541c855e 1508 ParentOwned(structure)
c23c8659
ML
1509{
1510}
1511
1512OutputFormat::~OutputFormat()
1513{
1514}
1515
3b161085 1516string OutputFormat::name()
c23c8659 1517{
3b161085 1518 return valid_string(sr_output_id_get(_structure));
c23c8659
ML
1519}
1520
3b161085 1521string OutputFormat::description()
c23c8659 1522{
3b161085 1523 return valid_string(sr_output_description_get(_structure));
58aa1f83
ML
1524}
1525
8a174d23
JH
1526vector<string> OutputFormat::extensions()
1527{
1528 vector<string> exts;
1529 for (const char *const *e = sr_output_extensions_get(_structure);
1530 e && *e; e++)
1531 exts.push_back(*e);
1532 return exts;
1533}
1534
3b161085 1535map<string, shared_ptr<Option>> OutputFormat::options()
58aa1f83 1536{
3b161085 1537 const struct sr_option **options = sr_output_options_get(_structure);
58aa1f83 1538 map<string, shared_ptr<Option>> result;
48d92e2c
ML
1539 if (options)
1540 {
1541 auto option_array = shared_ptr<const struct sr_option *>(
1542 options, sr_output_options_free);
1543 for (int i = 0; options[i]; i++)
1544 result[options[i]->id] = shared_ptr<Option>(
1545 new Option(options[i], option_array), Option::Deleter());
1546 }
58aa1f83 1547 return result;
c23c8659
ML
1548}
1549
1550shared_ptr<Output> OutputFormat::create_output(
58aa1f83 1551 shared_ptr<Device> device, map<string, Glib::VariantBase> options)
c23c8659
ML
1552{
1553 return shared_ptr<Output>(
bf52cc8c 1554 new Output(shared_from_this(), device, options),
c23c8659
ML
1555 Output::Deleter());
1556}
1557
81b3ce37
SA
1558shared_ptr<Output> OutputFormat::create_output(string filename,
1559 shared_ptr<Device> device, map<string, Glib::VariantBase> options)
1560{
1561 return shared_ptr<Output>(
1562 new Output(filename, shared_from_this(), device, options),
1563 Output::Deleter());
1564}
1565
3cd4b381
SA
1566bool OutputFormat::test_flag(const OutputFlag *flag)
1567{
1568 return sr_output_test_flag(_structure, flag->id());
1569}
1570
c23c8659 1571Output::Output(shared_ptr<OutputFormat> format,
58aa1f83 1572 shared_ptr<Device> device, map<string, Glib::VariantBase> options) :
3b161085 1573 UserOwned(sr_output_new(format->_structure,
81b3ce37
SA
1574 map_to_hash_variant(options), device->_structure, NULL)),
1575 _format(format),
1576 _device(device),
1577 _options(options)
1578{
1579}
1580
1581Output::Output(string filename, shared_ptr<OutputFormat> format,
1582 shared_ptr<Device> device, map<string, Glib::VariantBase> options) :
1583 UserOwned(sr_output_new(format->_structure,
1584 map_to_hash_variant(options), device->_structure, filename.c_str())),
3b161085
ML
1585 _format(format),
1586 _device(device),
1587 _options(options)
c23c8659
ML
1588{
1589}
1590
1591Output::~Output()
1592{
3b161085 1593 check(sr_output_free(_structure));
c23c8659
ML
1594}
1595
1596string Output::receive(shared_ptr<Packet> packet)
1597{
1598 GString *out;
3b161085 1599 check(sr_output_send(_structure, packet->_structure, &out));
c23c8659
ML
1600 if (out)
1601 {
1602 auto result = string(out->str, out->str + out->len);
1603 g_string_free(out, true);
1604 return result;
1605 }
1606 else
1607 {
1608 return string();
1609 }
1610}
1611
b5f07319 1612#include <enums.cpp>
c23c8659
ML
1613
1614}