# Core
#
SRCS = src/version.c \
+ src/uuid.c \
src/main.c \
src/tvhlog.c \
src/idnode.c \
#include "idnode.h"
#include "notify.h"
#include "settings.h"
+#include "uuid.h"
typedef struct idclass_link
{
RB_ENTRY(idclass_link) link;
} idclass_link_t;
-static int randfd = 0;
static RB_HEAD(,idnode) idnodes;
static RB_HEAD(,idclass_link) idclasses;
static pthread_cond_t idnode_cond;
* Utilities
* *************************************************************************/
-/**
- *
- */
-static int
-hexnibble(char c)
-{
- switch(c) {
- case '0' ... '9': return c - '0';
- case 'a' ... 'f': return c - 'a' + 10;
- case 'A' ... 'F': return c - 'A' + 10;
- default:
- return -1;
- }
-}
-
-
-/**
- *
- */
-static int
-hex2bin(uint8_t *buf, size_t buflen, const char *str)
-{
- int hi, lo;
-
- while(*str) {
- if(buflen == 0)
- return -1;
- if((hi = hexnibble(*str++)) == -1)
- return -1;
- if((lo = hexnibble(*str++)) == -1)
- return -1;
-
- *buf++ = hi << 4 | lo;
- buflen--;
- }
- return 0;
-}
-
-/**
- *
- */
-static void
-bin2hex(char *dst, size_t dstlen, const uint8_t *src, size_t srclen)
-{
- while(dstlen > 2 && srclen > 0) {
- *dst++ = "0123456789abcdef"[*src >> 4];
- *dst++ = "0123456789abcdef"[*src & 0xf];
- src++;
- srclen--;
- dstlen -= 2;
- }
- *dst = 0;
-}
-
/**
*
*/
void
idnode_init(void)
{
- randfd = open("/dev/urandom", O_RDONLY);
- if(randfd == -1)
- exit(1);
-
idnode_queue = NULL;
pthread_mutex_init(&idnode_mutex, NULL);
pthread_cond_init(&idnode_cond, NULL);
{
idnode_t *c;
lock_assert(&global_lock);
- if(uuid == NULL) {
- if(read(randfd, in->in_uuid, sizeof(in->in_uuid)) != sizeof(in->in_uuid)) {
- perror("read(random for uuid)");
- exit(1);
- }
- } else {
- if(hex2bin(in->in_uuid, sizeof(in->in_uuid), uuid))
- return -1;
- }
+ uuid_t u;
+ if (uuid_init_bin(&u, uuid))
+ return -1;
+ memcpy(in->in_uuid, u.bin, sizeof(in->in_uuid));
in->in_class = class;
*
*/
const char *
-idnode_uuid_as_str0(const idnode_t *in, char *b)
-{
- bin2hex(b, UUID_STR_LEN, in->in_uuid, sizeof(in->in_uuid));
- return b;
-}
-const char *
idnode_uuid_as_str(const idnode_t *in)
{
- static char ret[16][UUID_STR_LEN];
- static int p = 0;
- char *b = ret[p];
+ static uuid_t ret[16];
+ static uint8_t p = 0;
+ bin2hex(ret[p].hex, sizeof(ret[p].hex), in->in_uuid, sizeof(in->in_uuid));
+ const char *s = ret[p].hex;
p = (p + 1) % 16;
- return idnode_uuid_as_str0(in, b);
-}
-const char *
-idnode_uuid_as_str1 ( const uint8_t *bin, size_t len, char *b )
-{
- bin2hex(b, UUID_STR_LEN, bin, len);
- return b;
+ return s;
}
/**
#include "tvheadend.h"
#include "prop.h"
+#include "uuid.h"
#include <regex.h>
-#define UUID_STR_LEN 33 // inc NUL char
-#define UUID_BIN_LEN 16
-
struct htsmsg;
typedef struct idnode idnode_t;
* Node definition
*/
struct idnode {
- uint8_t in_uuid[UUID_BIN_LEN]; ///< Unique ID
- RB_ENTRY(idnode) in_link; ///< Global hash
- const idclass_t *in_class; ///< Class definition
+ uint8_t in_uuid[UUID_BIN_SIZE]; ///< Unique ID
+ RB_ENTRY(idnode) in_link; ///< Global hash
+ const idclass_t *in_class; ///< Class definition
};
/*
void idnode_unlink(idnode_t *in);
uint32_t idnode_get_short_uuid (const idnode_t *in);
-const char *idnode_uuid_as_str1 (const uint8_t *bin, size_t len, char *b);
-const char *idnode_uuid_as_str0 (const idnode_t *in, char *b);
const char *idnode_uuid_as_str (const idnode_t *in);
idnode_set_t *idnode_get_childs (idnode_t *in);
const char *idnode_get_title (idnode_t *in);
{
extern int linuxdvb_adapter_mask;
int a, i, j, r, fd;
- char fe_path[512], dmx_path[512], dvr_path[512], uuid[UUID_STR_LEN];
+ char fe_path[512], dmx_path[512], dvr_path[512];
+ uuid_t uuid;
linuxdvb_adapter_t *la = NULL;
struct dvb_frontend_info dfi;
SHA_CTX sha1;
SHA1_Update(&sha1, (void*)path, strlen(path));
SHA1_Update(&sha1, (void*)dfi.name, strlen(dfi.name));
SHA1_Final(uuidbin, &sha1);
- idnode_uuid_as_str1(uuidbin, sizeof(uuidbin), uuid);
+ bin2hex(uuid.hex, sizeof(uuid.hex), uuidbin, sizeof(uuidbin));
/* Load config */
conf = hts_settings_load("input/linuxdvb/adapters/%s", uuid);
save = 1;
/* Create */
- if (!(la = linuxdvb_adapter_create(uuid, conf, path, a, &dfi))) {
+ if (!(la = linuxdvb_adapter_create(uuid.hex, conf, path, a, &dfi))) {
tvhlog(LOG_ERR, "linuxdvb", "failed to create %s", path);
htsmsg_destroy(conf);
return; // Note: save to return here as global_lock is held
tvhlog_options &= ~TVHLOG_OPT_DECORATE;
/* Initialise configuration */
+ uuid_init();
idnode_init();
hts_settings_init(opt_config);
--- /dev/null
+/*
+ * TV headend - UUID generation routines
+ *
+ * Copyright (C) 2014 Adam Sutton
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tvheadend.h"
+#include "uuid.h"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define RANDOM_PATH "/dev/urandom"
+
+static int fd = -1;
+
+/* **************************************************************************
+ * Utilities
+ * *************************************************************************/
+
+/**
+ *
+ */
+static int
+hexnibble(char c)
+{
+ switch(c) {
+ case '0' ... '9': return c - '0';
+ case 'a' ... 'f': return c - 'a' + 10;
+ case 'A' ... 'F': return c - 'A' + 10;
+ default:
+ return -1;
+ }
+}
+
+
+/**
+ *
+ */
+int
+hex2bin(uint8_t *buf, size_t buflen, const char *str)
+{
+ int hi, lo;
+
+ while(*str) {
+ if(buflen == 0)
+ return -1;
+ if((hi = hexnibble(*str++)) == -1)
+ return -1;
+ if((lo = hexnibble(*str++)) == -1)
+ return -1;
+
+ *buf++ = hi << 4 | lo;
+ buflen--;
+ }
+ return 0;
+}
+
+/**
+ *
+ */
+void
+bin2hex(char *dst, size_t dstlen, const uint8_t *src, size_t srclen)
+{
+ while(dstlen > 2 && srclen > 0) {
+ *dst++ = "0123456789abcdef"[*src >> 4];
+ *dst++ = "0123456789abcdef"[*src & 0xf];
+ src++;
+ srclen--;
+ dstlen -= 2;
+ }
+ *dst = 0;
+}
+
+/* **************************************************************************
+ * UUID Handling
+ * *************************************************************************/
+
+void
+uuid_init ( void )
+{
+ fd = open(RANDOM_PATH, O_RDONLY);
+ if (fd == -1) {
+ tvherror("uuid", "failed to open %s", RANDOM_PATH);
+ exit(1);
+ }
+}
+
+/* Initialise binary */
+int
+uuid_init_bin ( uuid_t *u, const char *str )
+{
+ memset(u, 0, sizeof(uuid_t));
+ if (str) {
+ return hex2bin(u->bin, sizeof(u->bin), str);
+ } else if (read(fd, u->bin, sizeof(u->bin)) != sizeof(u->bin)) {
+ tvherror("uuid", "failed to read from %s", RANDOM_PATH);
+ exit(1);
+ }
+ return 0;
+}
+
+/* Initialise hex string */
+int
+uuid_init_hex ( uuid_t *u, const char *str )
+{
+ uuid_t tmp;
+ if (uuid_init_bin(&tmp, str))
+ return 1;
+ return uuid_bin2hex(&tmp, u);
+}
+
+/* Convert bin to hex string */
+int
+uuid_bin2hex ( const uuid_t *a, uuid_t *b )
+{
+ uuid_t tmp;
+ memset(&tmp, 0, sizeof(tmp));
+ bin2hex(tmp.hex, sizeof(tmp.hex), a->bin, sizeof(a->bin));
+ memcpy(b, &tmp, sizeof(tmp));
+ return 0;
+}
+
+/* Convert hex string to bin (in place) */
+int
+uuid_hex2bin ( const uuid_t *a, uuid_t *b )
+{
+ uuid_t tmp;
+ memset(&tmp, 0, sizeof(tmp));
+ if (hex2bin(tmp.bin, sizeof(tmp.bin), a->hex))
+ return 1;
+ memcpy(b, &tmp, sizeof(tmp));
+ return 0;
+}
--- /dev/null
+/*
+ * TV headend - UUID generation routines
+ *
+ * Copyright (C) 2014 Adam Sutton
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TVH_UUID_H__
+#define __TVH_UUID_H__
+
+#include <stdint.h>
+
+#define UUID_BIN_SIZE (16)
+#define UUID_HEX_SIZE (33) // inc NUL
+
+/* Structure to hold UUID */
+typedef struct uuid {
+ union {
+ uint8_t bin[UUID_BIN_SIZE];
+ char hex[UUID_HEX_SIZE];
+ };
+} uuid_t;
+
+/* Initialise subsystem */
+void uuid_init ( void );
+
+/* Initialise binary */
+int uuid_init_bin ( uuid_t *u, const char *str );
+
+/* Initialise hex string */
+int uuid_init_hex ( uuid_t *u, const char *str );
+
+/**
+ * Convert bin to hex string
+ *
+ * Note: conversion is done such that a and b can be the same
+ */
+int uuid_bin2hex ( const uuid_t *a, uuid_t *b );
+
+/**
+ * Convert hex string to bin (in place)
+ *
+ * Note: conversion is done such that a and b can be the same
+ */
+int uuid_hex2bin ( const uuid_t *a, uuid_t *b );
+
+/**
+ * Hex string to binary
+ */
+int hex2bin ( uint8_t *buf, size_t buflen, const char *hex );
+
+/**
+ * Binary to hex string
+ */
+void bin2hex ( char *dst, size_t dstlen, const uint8_t *src, size_t srclen );
+
+#endif /* __TVH_UUID_H__ */