2 * This file is part of buxton.
4 * Copyright (C) 2013 Intel Corporation
6 * buxton is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
13 * \file lbuxton.c Buxton library implementation
25 #include <sys/socket.h>
27 #include <sys/types.h>
34 #include "buxtonclient.h"
35 #include "buxtonkey.h"
36 #include "buxtonresponse.h"
37 #include "buxtonstring.h"
38 #include "configurator.h"
44 static Hashmap *key_hash = NULL;
46 int buxton_set_conf_file(char *path)
55 if (st.st_mode & S_IFDIR) {
60 buxton_add_cmd_line(CONFIG_CONF_FILE, path);
65 int buxton_open(BuxtonClient *client)
67 _BuxtonClient **c = (_BuxtonClient **)client;
68 _BuxtonClient *cl = NULL;
70 struct sockaddr_un remote;
73 if ((bx_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
77 remote.sun_family = AF_UNIX;
78 sock_name_len = strlen(buxton_socket()) + 1;
79 if (sock_name_len >= sizeof(remote.sun_path)) {
80 buxton_log("Provided socket name: %s is too long, maximum allowed length is %d bytes\n",
81 buxton_socket(), sizeof(remote.sun_path));
85 strncpy(remote.sun_path, buxton_socket(), sock_name_len);
86 r = connect(bx_socket, (struct sockaddr *)&remote, sizeof(remote));
92 if (fcntl(bx_socket, F_SETFL, O_NONBLOCK)) {
97 if (!setup_callbacks()) {
102 cl = malloc0(sizeof(_BuxtonClient));
114 void buxton_close(BuxtonClient client)
117 BuxtonKey key = NULL;
120 /* Free all remaining allocated keys */
121 HASHMAP_FOREACH_KEY(key, key, key_hash, i) {
122 hashmap_remove_value(key_hash, key, key);
123 buxton_key_free(key);
126 hashmap_free(key_hash);
132 c = (_BuxtonClient *)client;
141 int buxton_get_value(BuxtonClient client,
143 BuxtonCallback callback,
149 _BuxtonKey *k = (_BuxtonKey *)key;
151 if (!k || !(k->group.value) || !(k->name.value) ||
152 k->type <= BUXTON_TYPE_MIN || k->type >= BUXTON_TYPE_MAX) {
156 r = buxton_wire_get_value((_BuxtonClient *)client, k, callback, data);
162 ret = buxton_wire_get_response(client);
173 int buxton_register_notification(BuxtonClient client,
175 BuxtonCallback callback,
181 _BuxtonKey *k = (_BuxtonKey *)key;
183 if (!k || !k->group.value || !k->name.value ||
184 k->type <= BUXTON_TYPE_MIN || k->type >= BUXTON_TYPE_MAX) {
188 r = buxton_wire_register_notification((_BuxtonClient *)client, k,
195 ret = buxton_wire_get_response(client);
206 int buxton_unregister_notification(BuxtonClient client,
208 BuxtonCallback callback,
214 _BuxtonKey *k = (_BuxtonKey *)key;
216 if (!k || !k->group.value || !k->name.value ||
217 k->type <= BUXTON_TYPE_MIN || k->type >= BUXTON_TYPE_MAX) {
221 r = buxton_wire_unregister_notification((_BuxtonClient *)client, k,
228 ret = buxton_wire_get_response(client);
239 int buxton_set_value(BuxtonClient client,
242 BuxtonCallback callback,
248 _BuxtonKey *k = (_BuxtonKey *)key;
250 if (!k || !k->group.value || !k->name.value || !k->layer.value ||
251 k->type <= BUXTON_TYPE_MIN || k->type >= BUXTON_TYPE_MAX || !value) {
255 r = buxton_wire_set_value((_BuxtonClient *)client, k, value, callback,
262 ret = buxton_wire_get_response(client);
273 int buxton_set_label(BuxtonClient client,
276 BuxtonCallback callback,
283 _BuxtonKey *k = (_BuxtonKey *)key;
285 if (!k || !k->group.value || !k->layer.value || !value) {
290 v = buxton_string_pack(value);
292 r = buxton_wire_set_label((_BuxtonClient *)client, k, &v, callback,
299 ret = buxton_wire_get_response(client);
310 int buxton_create_group(BuxtonClient client,
312 BuxtonCallback callback,
318 _BuxtonKey *k = (_BuxtonKey *)key;
320 /* We require the key name to be NULL, since it is not used for groups */
321 if (!k || !k->group.value || k->name.value || !k->layer.value) {
326 r = buxton_wire_create_group((_BuxtonClient *)client, k, callback, data);
332 ret = buxton_wire_get_response(client);
343 int buxton_remove_group(BuxtonClient client,
345 BuxtonCallback callback,
351 _BuxtonKey *k = (_BuxtonKey *)key;
353 /* We require the key name to be NULL, since it is not used for groups */
354 if (!k || !k->group.value || k->name.value || !k->layer.value) {
359 r = buxton_wire_remove_group((_BuxtonClient *)client, k, callback, data);
365 ret = buxton_wire_get_response(client);
376 int buxton_client_list_keys(BuxtonClient client,
378 BuxtonCallback callback,
390 l = buxton_string_pack(layer_name);
392 r = buxton_wire_list_keys((_BuxtonClient *)client, &l, callback, data);
398 ret = buxton_wire_get_response(client);
409 int buxton_unset_value(BuxtonClient client,
411 BuxtonCallback callback,
417 _BuxtonKey *k = (_BuxtonKey *)key;
419 if (!k || !k->group.value || !k->name.value || !k->layer.value ||
420 k->type <= BUXTON_TYPE_MIN || k->type >= BUXTON_TYPE_MAX) {
424 r = buxton_wire_unset_value((_BuxtonClient *)client, k, callback, data);
430 ret = buxton_wire_get_response(client);
441 BuxtonKey buxton_key_create(char *group, char *name, char *layer,
444 _BuxtonKey *key = NULL;
453 if (type <= BUXTON_TYPE_MIN || type >= BUXTON_TYPE_MAX) {
458 /* Create on hashmap on first call to key_create */
459 key_hash = hashmap_new(trivial_hash_func, trivial_compare_func);
484 key = malloc0(sizeof(_BuxtonKey));
489 key->group.value = g;
490 key->group.length = (uint32_t)strlen(g) + 1;
493 key->name.length = (uint32_t)strlen(n) + 1;
495 key->name.value = NULL;
496 key->name.length = 0;
499 key->layer.value = l;
500 key->layer.length = (uint32_t)strlen(l) + 1;
502 key->layer.value = NULL;
503 key->layer.length = 0;
507 /* Add new keys to internal hash for cleanup on close */
508 hashmap_put(key_hash, key, key);
510 return (BuxtonKey)key;
519 char *buxton_key_get_group(BuxtonKey key)
521 _BuxtonKey *k = (_BuxtonKey *)key;
530 char *buxton_key_get_name(BuxtonKey key)
532 _BuxtonKey *k = (_BuxtonKey *)key;
541 char *buxton_key_get_layer(BuxtonKey key)
543 _BuxtonKey *k = (_BuxtonKey *)key;
552 BuxtonDataType buxton_key_get_type(BuxtonKey key)
554 _BuxtonKey *k = (_BuxtonKey *)key;
563 void buxton_key_free(BuxtonKey key)
565 _BuxtonKey *k = (_BuxtonKey *)key;
571 hashmap_remove_value(key_hash, key, key);
573 free(k->group.value);
575 free(k->layer.value);
579 ssize_t buxton_client_handle_response(BuxtonClient client)
581 return buxton_wire_handle_response((_BuxtonClient *)client);
584 BuxtonControlMessage buxton_response_type(BuxtonResponse response)
586 _BuxtonResponse *r = (_BuxtonResponse *)response;
595 int32_t buxton_response_status(BuxtonResponse response)
598 _BuxtonResponse *r = (_BuxtonResponse *)response;
604 if (buxton_response_type(response) == BUXTON_CONTROL_CHANGED) {
608 d = buxton_array_get(r->data, 0);
611 return d->store.d_int32;
617 BuxtonKey buxton_response_key(BuxtonResponse response)
619 _BuxtonKey *key = NULL;
620 _BuxtonResponse *r = (_BuxtonResponse *)response;
626 if (buxton_response_type(response) == BUXTON_CONTROL_LIST) {
630 key = malloc0(sizeof(_BuxtonKey));
635 if (!buxton_key_copy(r->key, key)) {
640 return (BuxtonKey)key;
643 void *buxton_response_value(BuxtonResponse response)
646 BuxtonData *d = NULL;
647 _BuxtonResponse *r = (_BuxtonResponse *)response;
648 BuxtonControlMessage type;
654 type = buxton_response_type(response);
655 if (type == BUXTON_CONTROL_GET) {
656 d = buxton_array_get(r->data, 1);
657 } else if (type == BUXTON_CONTROL_CHANGED) {
659 d = buxton_array_get(r->data, 0);
671 return strdup(d->store.d_string.value);
673 p = malloc0(sizeof(int32_t));
677 *(int32_t *)p = (int32_t)d->store.d_int32;
680 p = malloc0(sizeof(uint32_t));
684 *(uint32_t *)p = (uint32_t)d->store.d_uint32;
687 p = malloc0(sizeof(int64_t));
691 *(int64_t *)p = (int64_t)d->store.d_int64;
694 p = malloc0(sizeof(uint64_t));
698 *(uint64_t *)p = (uint64_t)d->store.d_uint64;
701 p = malloc0(sizeof(float));
705 *(float *)p = (float)d->store.d_float;
708 p = malloc0(sizeof(double));
712 *(double *)p = (double)d->store.d_double;
715 p = malloc0(sizeof(bool));
719 *(bool *)p = (bool)d->store.d_boolean;
730 * Editor modelines - http://www.wireshark.org/tools/modelines.html
735 * indent-tabs-mode: t
738 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
739 * :indentSize=8:tabSize=8:noTabs=false: