random ai stuff
This commit is contained in:
14
telldus-core/3rdparty/openbsd-getopt/CMakeLists.txt
vendored
Normal file
14
telldus-core/3rdparty/openbsd-getopt/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
SET( SRCS
|
||||
getopt_long.c
|
||||
)
|
||||
|
||||
SET( HDRS
|
||||
getopt.h
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
|
||||
ADD_LIBRARY(openbsd-getopt STATIC
|
||||
${SRCS}
|
||||
${HDRS}
|
||||
)
|
||||
9
telldus-core/3rdparty/openbsd-getopt/err.h
vendored
Normal file
9
telldus-core/3rdparty/openbsd-getopt/err.h
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
__inline void warnx(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
78
telldus-core/3rdparty/openbsd-getopt/getopt.h
vendored
Normal file
78
telldus-core/3rdparty/openbsd-getopt/getopt.h
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */
|
||||
/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Dieter Baron and Thomas Klausner.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _GETOPT_H_
|
||||
#define _GETOPT_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
|
||||
*/
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
struct option {
|
||||
/* name of long option */
|
||||
const char *name;
|
||||
/*
|
||||
* one of no_argument, required_argument, and optional_argument:
|
||||
* whether option takes an argument
|
||||
*/
|
||||
int has_arg;
|
||||
/* if not NULL, set *flag to val when option found */
|
||||
int *flag;
|
||||
/* if flag not NULL, value to set *flag to; else return value */
|
||||
int val;
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
int getopt_long(int, char * const *, const char *,
|
||||
const struct option *, int *);
|
||||
int getopt_long_only(int, char * const *, const char *,
|
||||
const struct option *, int *);
|
||||
#ifndef _GETOPT_DEFINED_
|
||||
#define _GETOPT_DEFINED_
|
||||
int getopt(int, char * const *, const char *);
|
||||
int getsubopt(char **, char * const *, char **);
|
||||
|
||||
extern char *optarg; /* getopt(3) external variables */
|
||||
extern int opterr;
|
||||
extern int optind;
|
||||
extern int optopt;
|
||||
extern int optreset;
|
||||
extern char *suboptarg; /* getsubopt(3) external variable */
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_GETOPT_H_ */
|
||||
511
telldus-core/3rdparty/openbsd-getopt/getopt_long.c
vendored
Normal file
511
telldus-core/3rdparty/openbsd-getopt/getopt_long.c
vendored
Normal file
@@ -0,0 +1,511 @@
|
||||
/* $OpenBSD: getopt_long.c,v 1.25 2011/03/05 22:10:11 guenther Exp $ */
|
||||
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Sponsored in part by the Defense Advanced Research Projects
|
||||
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Dieter Baron and Thomas Klausner.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int opterr = 1; /* if error message should be printed */
|
||||
int optind = 1; /* index into parent argv vector */
|
||||
int optopt = '?'; /* character checked for validity */
|
||||
int optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
#define PRINT_ERROR ((opterr) && (*options != ':'))
|
||||
|
||||
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
|
||||
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
|
||||
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
|
||||
|
||||
/* return values */
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
|
||||
#define INORDER (int)1
|
||||
|
||||
#define EMSG ""
|
||||
|
||||
static int getopt_internal(int, char * const *, const char *,
|
||||
const struct option *, int *, int);
|
||||
static int parse_long_options(char * const *, const char *,
|
||||
const struct option *, int *, int);
|
||||
static int gcd(int, int);
|
||||
static void permute_args(int, int, int, char * const *);
|
||||
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
|
||||
/* XXX: set optreset to 1 rather than these two */
|
||||
static int nonopt_start = -1; /* first non option argument (for permute) */
|
||||
static int nonopt_end = -1; /* first option after non options (for permute) */
|
||||
|
||||
/* Error messages */
|
||||
static const char recargchar[] = "option requires an argument -- %c";
|
||||
static const char recargstring[] = "option requires an argument -- %s";
|
||||
static const char ambig[] = "ambiguous option -- %.*s";
|
||||
static const char noarg[] = "option doesn't take an argument -- %.*s";
|
||||
static const char illoptchar[] = "unknown option -- %c";
|
||||
static const char illoptstring[] = "unknown option -- %s";
|
||||
|
||||
/*
|
||||
* Compute the greatest common divisor of a and b.
|
||||
*/
|
||||
static int
|
||||
gcd(int a, int b)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = a % b;
|
||||
while (c != 0) {
|
||||
a = b;
|
||||
b = c;
|
||||
c = a % b;
|
||||
}
|
||||
|
||||
return (b);
|
||||
}
|
||||
|
||||
/*
|
||||
* Exchange the block from nonopt_start to nonopt_end with the block
|
||||
* from nonopt_end to opt_end (keeping the same order of arguments
|
||||
* in each block).
|
||||
*/
|
||||
static void
|
||||
permute_args(int panonopt_start, int panonopt_end, int opt_end,
|
||||
char * const *nargv)
|
||||
{
|
||||
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
|
||||
char *swap;
|
||||
|
||||
/*
|
||||
* compute lengths of blocks and number and size of cycles
|
||||
*/
|
||||
nnonopts = panonopt_end - panonopt_start;
|
||||
nopts = opt_end - panonopt_end;
|
||||
ncycle = gcd(nnonopts, nopts);
|
||||
cyclelen = (opt_end - panonopt_start) / ncycle;
|
||||
|
||||
for (i = 0; i < ncycle; i++) {
|
||||
cstart = panonopt_end+i;
|
||||
pos = cstart;
|
||||
for (j = 0; j < cyclelen; j++) {
|
||||
if (pos >= panonopt_end)
|
||||
pos -= nnonopts;
|
||||
else
|
||||
pos += nopts;
|
||||
swap = nargv[pos];
|
||||
/* LINTED const cast */
|
||||
((char **) nargv)[pos] = nargv[cstart];
|
||||
/* LINTED const cast */
|
||||
((char **)nargv)[cstart] = swap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse_long_options --
|
||||
* Parse long options in argc/argv argument vector.
|
||||
* Returns -1 if short_too is set and the option does not match long_options.
|
||||
*/
|
||||
static int
|
||||
parse_long_options(char * const *nargv, const char *options,
|
||||
const struct option *long_options, int *idx, int short_too)
|
||||
{
|
||||
char *current_argv, *has_equal;
|
||||
size_t current_argv_len;
|
||||
int i, match;
|
||||
|
||||
current_argv = place;
|
||||
match = -1;
|
||||
|
||||
optind++;
|
||||
|
||||
if ((has_equal = strchr(current_argv, '=')) != NULL) {
|
||||
/* argument found (--option=arg) */
|
||||
current_argv_len = has_equal - current_argv;
|
||||
has_equal++;
|
||||
} else
|
||||
current_argv_len = strlen(current_argv);
|
||||
|
||||
for (i = 0; long_options[i].name; i++) {
|
||||
/* find matching long option */
|
||||
if (strncmp(current_argv, long_options[i].name,
|
||||
current_argv_len))
|
||||
continue;
|
||||
|
||||
if (strlen(long_options[i].name) == current_argv_len) {
|
||||
/* exact match */
|
||||
match = i;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* If this is a known short option, don't allow
|
||||
* a partial match of a single character.
|
||||
*/
|
||||
if (short_too && current_argv_len == 1)
|
||||
continue;
|
||||
|
||||
if (match == -1) /* partial match */
|
||||
match = i;
|
||||
else {
|
||||
/* ambiguous abbreviation */
|
||||
if (PRINT_ERROR)
|
||||
warnx(ambig, (int)current_argv_len,
|
||||
current_argv);
|
||||
optopt = 0;
|
||||
return (BADCH);
|
||||
}
|
||||
}
|
||||
if (match != -1) { /* option found */
|
||||
if (long_options[match].has_arg == no_argument
|
||||
&& has_equal) {
|
||||
if (PRINT_ERROR)
|
||||
warnx(noarg, (int)current_argv_len,
|
||||
current_argv);
|
||||
/*
|
||||
* XXX: GNU sets optopt to val regardless of flag
|
||||
*/
|
||||
if (long_options[match].flag == NULL)
|
||||
optopt = long_options[match].val;
|
||||
else
|
||||
optopt = 0;
|
||||
return (BADARG);
|
||||
}
|
||||
if (long_options[match].has_arg == required_argument ||
|
||||
long_options[match].has_arg == optional_argument) {
|
||||
if (has_equal)
|
||||
optarg = has_equal;
|
||||
else if (long_options[match].has_arg ==
|
||||
required_argument) {
|
||||
/*
|
||||
* optional argument doesn't use next nargv
|
||||
*/
|
||||
optarg = nargv[optind++];
|
||||
}
|
||||
}
|
||||
if ((long_options[match].has_arg == required_argument)
|
||||
&& (optarg == NULL)) {
|
||||
/*
|
||||
* Missing argument; leading ':' indicates no error
|
||||
* should be generated.
|
||||
*/
|
||||
if (PRINT_ERROR)
|
||||
warnx(recargstring,
|
||||
current_argv);
|
||||
/*
|
||||
* XXX: GNU sets optopt to val regardless of flag
|
||||
*/
|
||||
if (long_options[match].flag == NULL)
|
||||
optopt = long_options[match].val;
|
||||
else
|
||||
optopt = 0;
|
||||
--optind;
|
||||
return (BADARG);
|
||||
}
|
||||
} else { /* unknown option */
|
||||
if (short_too) {
|
||||
--optind;
|
||||
return (-1);
|
||||
}
|
||||
if (PRINT_ERROR)
|
||||
warnx(illoptstring, current_argv);
|
||||
optopt = 0;
|
||||
return (BADCH);
|
||||
}
|
||||
if (idx)
|
||||
*idx = match;
|
||||
if (long_options[match].flag) {
|
||||
*long_options[match].flag = long_options[match].val;
|
||||
return (0);
|
||||
} else
|
||||
return (long_options[match].val);
|
||||
}
|
||||
|
||||
/*
|
||||
* getopt_internal --
|
||||
* Parse argc/argv argument vector. Called by user level routines.
|
||||
*/
|
||||
static int
|
||||
getopt_internal(int nargc, char * const *nargv, const char *options,
|
||||
const struct option *long_options, int *idx, int flags)
|
||||
{
|
||||
char *oli; /* option letter list index */
|
||||
int optchar, short_too;
|
||||
static int posixly_correct = -1;
|
||||
|
||||
if (options == NULL)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* XXX Some GNU programs (like cvs) set optind to 0 instead of
|
||||
* XXX using optreset. Work around this braindamage.
|
||||
*/
|
||||
if (optind == 0)
|
||||
optind = optreset = 1;
|
||||
|
||||
/*
|
||||
* Disable GNU extensions if POSIXLY_CORRECT is set or options
|
||||
* string begins with a '+'.
|
||||
*/
|
||||
if (posixly_correct == -1 || optreset)
|
||||
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
|
||||
if (*options == '-')
|
||||
flags |= FLAG_ALLARGS;
|
||||
else if (posixly_correct || *options == '+')
|
||||
flags &= ~FLAG_PERMUTE;
|
||||
if (*options == '+' || *options == '-')
|
||||
options++;
|
||||
|
||||
optarg = NULL;
|
||||
if (optreset)
|
||||
nonopt_start = nonopt_end = -1;
|
||||
start:
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
if (optind >= nargc) { /* end of argument vector */
|
||||
place = EMSG;
|
||||
if (nonopt_end != -1) {
|
||||
/* do permutation, if we have to */
|
||||
permute_args(nonopt_start, nonopt_end,
|
||||
optind, nargv);
|
||||
optind -= nonopt_end - nonopt_start;
|
||||
}
|
||||
else if (nonopt_start != -1) {
|
||||
/*
|
||||
* If we skipped non-options, set optind
|
||||
* to the first of them.
|
||||
*/
|
||||
optind = nonopt_start;
|
||||
}
|
||||
nonopt_start = nonopt_end = -1;
|
||||
return (-1);
|
||||
}
|
||||
if (*(place = nargv[optind]) != '-' ||
|
||||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
|
||||
place = EMSG; /* found non-option */
|
||||
if (flags & FLAG_ALLARGS) {
|
||||
/*
|
||||
* GNU extension:
|
||||
* return non-option as argument to option 1
|
||||
*/
|
||||
optarg = nargv[optind++];
|
||||
return (INORDER);
|
||||
}
|
||||
if (!(flags & FLAG_PERMUTE)) {
|
||||
/*
|
||||
* If no permutation wanted, stop parsing
|
||||
* at first non-option.
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
/* do permutation */
|
||||
if (nonopt_start == -1)
|
||||
nonopt_start = optind;
|
||||
else if (nonopt_end != -1) {
|
||||
permute_args(nonopt_start, nonopt_end,
|
||||
optind, nargv);
|
||||
nonopt_start = optind -
|
||||
(nonopt_end - nonopt_start);
|
||||
nonopt_end = -1;
|
||||
}
|
||||
optind++;
|
||||
/* process next argument */
|
||||
goto start;
|
||||
}
|
||||
if (nonopt_start != -1 && nonopt_end == -1)
|
||||
nonopt_end = optind;
|
||||
|
||||
/*
|
||||
* If we have "-" do nothing, if "--" we are done.
|
||||
*/
|
||||
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
|
||||
optind++;
|
||||
place = EMSG;
|
||||
/*
|
||||
* We found an option (--), so if we skipped
|
||||
* non-options, we have to permute.
|
||||
*/
|
||||
if (nonopt_end != -1) {
|
||||
permute_args(nonopt_start, nonopt_end,
|
||||
optind, nargv);
|
||||
optind -= nonopt_end - nonopt_start;
|
||||
}
|
||||
nonopt_start = nonopt_end = -1;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check long options if:
|
||||
* 1) we were passed some
|
||||
* 2) the arg is not just "-"
|
||||
* 3) either the arg starts with -- we are getopt_long_only()
|
||||
*/
|
||||
if (long_options != NULL && place != nargv[optind] &&
|
||||
(*place == '-' || (flags & FLAG_LONGONLY))) {
|
||||
short_too = 0;
|
||||
if (*place == '-')
|
||||
place++; /* --foo long option */
|
||||
else if (*place != ':' && strchr(options, *place) != NULL)
|
||||
short_too = 1; /* could be short option too */
|
||||
|
||||
optchar = parse_long_options(nargv, options, long_options,
|
||||
idx, short_too);
|
||||
if (optchar != -1) {
|
||||
place = EMSG;
|
||||
return (optchar);
|
||||
}
|
||||
}
|
||||
|
||||
if ((optchar = (int)*place++) == (int)':' ||
|
||||
(optchar == (int)'-' && *place != '\0') ||
|
||||
(oli = strchr(options, optchar)) == NULL) {
|
||||
/*
|
||||
* If the user specified "-" and '-' isn't listed in
|
||||
* options, return -1 (non-option) as per POSIX.
|
||||
* Otherwise, it is an unknown option character (or ':').
|
||||
*/
|
||||
if (optchar == (int)'-' && *place == '\0')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (PRINT_ERROR)
|
||||
warnx(illoptchar, optchar);
|
||||
optopt = optchar;
|
||||
return (BADCH);
|
||||
}
|
||||
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
|
||||
/* -W long-option */
|
||||
if (*place) /* no space */
|
||||
/* NOTHING */;
|
||||
else if (++optind >= nargc) { /* no arg */
|
||||
place = EMSG;
|
||||
if (PRINT_ERROR)
|
||||
warnx(recargchar, optchar);
|
||||
optopt = optchar;
|
||||
return (BADARG);
|
||||
} else /* white space */
|
||||
place = nargv[optind];
|
||||
optchar = parse_long_options(nargv, options, long_options,
|
||||
idx, 0);
|
||||
place = EMSG;
|
||||
return (optchar);
|
||||
}
|
||||
if (*++oli != ':') { /* doesn't take argument */
|
||||
if (!*place)
|
||||
++optind;
|
||||
} else { /* takes (optional) argument */
|
||||
optarg = NULL;
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (oli[1] != ':') { /* arg not optional */
|
||||
if (++optind >= nargc) { /* no arg */
|
||||
place = EMSG;
|
||||
if (PRINT_ERROR)
|
||||
warnx(recargchar, optchar);
|
||||
optopt = optchar;
|
||||
return (BADARG);
|
||||
} else
|
||||
optarg = nargv[optind];
|
||||
}
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
/* dump back option letter */
|
||||
return (optchar);
|
||||
}
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*
|
||||
* [eventually this will replace the BSD getopt]
|
||||
*/
|
||||
int
|
||||
getopt(int nargc, char * const *nargv, const char *options)
|
||||
{
|
||||
|
||||
/*
|
||||
* We don't pass FLAG_PERMUTE to getopt_internal() since
|
||||
* the BSD getopt(3) (unlike GNU) has never done this.
|
||||
*
|
||||
* Furthermore, since many privileged programs call getopt()
|
||||
* before dropping privileges it makes sense to keep things
|
||||
* as simple (and bug-free) as possible.
|
||||
*/
|
||||
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* getopt_long --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt_long(int nargc, char * const *nargv, const char *options,
|
||||
const struct option *long_options, int *idx)
|
||||
{
|
||||
|
||||
return (getopt_internal(nargc, nargv, options, long_options, idx,
|
||||
FLAG_PERMUTE));
|
||||
}
|
||||
|
||||
/*
|
||||
* getopt_long_only --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt_long_only(int nargc, char * const *nargv, const char *options,
|
||||
const struct option *long_options, int *idx)
|
||||
{
|
||||
|
||||
return (getopt_internal(nargc, nargv, options, long_options, idx,
|
||||
FLAG_PERMUTE|FLAG_LONGONLY));
|
||||
}
|
||||
10
telldus-core/3rdparty/openbsd-getopt/machine/_types.h
vendored
Normal file
10
telldus-core/3rdparty/openbsd-getopt/machine/_types.h
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <windows.h>
|
||||
|
||||
typedef __int8 __int8_t;
|
||||
typedef unsigned __int8 __uint8_t;
|
||||
typedef __int16 __int16_t;
|
||||
typedef unsigned __int16 __uint16_t;
|
||||
typedef __int32 __int32_t;
|
||||
typedef unsigned __int32 __uint32_t;
|
||||
typedef __int64 __int64_t;
|
||||
typedef unsigned __int64 __uint64_t;
|
||||
12
telldus-core/3rdparty/openbsd-getopt/machine/cdefs.h
vendored
Normal file
12
telldus-core/3rdparty/openbsd-getopt/machine/cdefs.h
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <windows.h>
|
||||
|
||||
#define _ANSI_SOURCE 1
|
||||
#define NO_ANSI_KEYWORDS 1
|
||||
|
||||
#define _CLOCK_T_DEFINED_
|
||||
#define _CLOCKID_T_DEFINED_
|
||||
#define _SIZE_T_DEFINED_
|
||||
#define _SSIZE_T_DEFINED_
|
||||
#define _TIME_T_DEFINED_
|
||||
#define _TIMER_T_DEFINED_
|
||||
#define _OFF_T_DEFINED_
|
||||
0
telldus-core/3rdparty/openbsd-getopt/machine/endian.h
vendored
Normal file
0
telldus-core/3rdparty/openbsd-getopt/machine/endian.h
vendored
Normal file
71
telldus-core/3rdparty/openbsd-getopt/sys/_types.h
vendored
Normal file
71
telldus-core/3rdparty/openbsd-getopt/sys/_types.h
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/* $OpenBSD: _types.h,v 1.2 2008/03/16 19:42:57 otto Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)types.h 8.3 (Berkeley) 1/5/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS__TYPES_H_
|
||||
#define _SYS__TYPES_H_
|
||||
|
||||
#include <machine/_types.h>
|
||||
|
||||
typedef unsigned long __cpuid_t; /* CPU id */
|
||||
typedef __int32_t __dev_t; /* device number */
|
||||
typedef __uint32_t __fixpt_t; /* fixed point number */
|
||||
typedef __uint32_t __gid_t; /* group id */
|
||||
typedef __uint32_t __id_t; /* may contain pid, uid or gid */
|
||||
typedef __uint32_t __in_addr_t; /* base type for internet address */
|
||||
typedef __uint16_t __in_port_t; /* IP port type */
|
||||
typedef __uint32_t __ino_t; /* inode number */
|
||||
typedef long __key_t; /* IPC key (for Sys V IPC) */
|
||||
typedef __uint32_t __mode_t; /* permissions */
|
||||
typedef __uint32_t __nlink_t; /* link count */
|
||||
typedef __int32_t __pid_t; /* process id */
|
||||
typedef __uint64_t __rlim_t; /* resource limit */
|
||||
typedef __uint8_t __sa_family_t; /* sockaddr address family type */
|
||||
typedef __int32_t __segsz_t; /* segment size */
|
||||
typedef __uint32_t __socklen_t; /* length type for network syscalls */
|
||||
typedef __int32_t __swblk_t; /* swap offset */
|
||||
typedef __uint32_t __uid_t; /* user id */
|
||||
typedef __uint32_t __useconds_t; /* microseconds */
|
||||
typedef __int32_t __suseconds_t; /* microseconds (signed) */
|
||||
typedef __uint64_t __fsblkcnt_t; /* file system block count */
|
||||
typedef __uint64_t __fsfilcnt_t; /* file system file count */
|
||||
|
||||
/*
|
||||
* mbstate_t is an opaque object to keep conversion state, during multibyte
|
||||
* stream conversions. The content must not be referenced by user programs.
|
||||
*/
|
||||
typedef union {
|
||||
char __mbstate8[128];
|
||||
__int64_t __mbstateL; /* for alignment */
|
||||
} __mbstate_t;
|
||||
|
||||
#endif /* !_SYS__TYPES_H_ */
|
||||
388
telldus-core/3rdparty/openbsd-getopt/sys/cdefs.h
vendored
Normal file
388
telldus-core/3rdparty/openbsd-getopt/sys/cdefs.h
vendored
Normal file
@@ -0,0 +1,388 @@
|
||||
/* $OpenBSD: cdefs.h,v 1.32 2012/01/03 16:56:58 kettenis Exp $ */
|
||||
/* $NetBSD: cdefs.h,v 1.16 1996/04/03 20:46:39 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Berkeley Software Design, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cdefs.h 8.7 (Berkeley) 1/21/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CDEFS_H_
|
||||
#define _SYS_CDEFS_H_
|
||||
|
||||
#include <machine/cdefs.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#define __BEGIN_DECLS extern "C" {
|
||||
#define __END_DECLS }
|
||||
#else
|
||||
#define __BEGIN_DECLS
|
||||
#define __END_DECLS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro to test if we're using a specific version of gcc or later.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define __GNUC_PREREQ__(ma, mi) \
|
||||
((__GNUC__ > (ma)) || (__GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)))
|
||||
#else
|
||||
#define __GNUC_PREREQ__(ma, mi) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.
|
||||
* with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
|
||||
* The __CONCAT macro is a bit tricky -- make sure you don't put spaces
|
||||
* in between its arguments. __CONCAT can also concatenate double-quoted
|
||||
* strings produced by the __STRING macro, but this only works with ANSI C.
|
||||
*/
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
#define __P(protos) protos /* full-blown ANSI C */
|
||||
#define __CONCAT(x,y) x ## y
|
||||
#define __STRING(x) #x
|
||||
|
||||
#define __const const /* define reserved names to standard */
|
||||
#define __signed signed
|
||||
#define __volatile volatile
|
||||
#if defined(__cplusplus) || defined(__PCC__)
|
||||
#define __inline inline /* convert to C++ keyword */
|
||||
#else
|
||||
#if !defined(__GNUC__) && !defined(lint)
|
||||
#define __inline /* delete GCC keyword */
|
||||
#endif /* !__GNUC__ && !lint */
|
||||
#endif /* !__cplusplus */
|
||||
|
||||
#else /* !(__STDC__ || __cplusplus) */
|
||||
#define __P(protos) () /* traditional C preprocessor */
|
||||
#define __CONCAT(x,y) x/**/y
|
||||
#define __STRING(x) "x"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
#elif !defined(__GNUC__) && !defined(lint)
|
||||
#define __const /* delete pseudo-ANSI C keywords */
|
||||
#define __inline
|
||||
#define __signed
|
||||
#define __volatile
|
||||
#endif /* !__GNUC__ && !lint */
|
||||
|
||||
/*
|
||||
* In non-ANSI C environments, new programs will want ANSI-only C keywords
|
||||
* deleted from the program and old programs will want them left alone.
|
||||
* Programs using the ANSI C keywords const, inline etc. as normal
|
||||
* identifiers should define -DNO_ANSI_KEYWORDS.
|
||||
*/
|
||||
#ifndef NO_ANSI_KEYWORDS
|
||||
#define const __const /* convert ANSI C keywords */
|
||||
#define inline __inline
|
||||
#define signed __signed
|
||||
#define volatile __volatile
|
||||
#endif /* !NO_ANSI_KEYWORDS */
|
||||
#endif /* !(__STDC__ || __cplusplus) */
|
||||
|
||||
/*
|
||||
* GCC1 and some versions of GCC2 declare dead (non-returning) and
|
||||
* pure (no side effects) functions using "volatile" and "const";
|
||||
* unfortunately, these then cause warnings under "-ansi -pedantic".
|
||||
* GCC >= 2.5 uses the __attribute__((attrs)) style. All of these
|
||||
* work for GNU C++ (modulo a slight glitch in the C++ grammar in
|
||||
* the distribution version of 2.5.5).
|
||||
*/
|
||||
|
||||
#if !__GNUC_PREREQ__(2, 5) && !defined(__PCC__)
|
||||
#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define __dead __volatile
|
||||
#define __pure __const
|
||||
#elif defined(lint)
|
||||
#define __dead /* NORETURN */
|
||||
#endif
|
||||
#elif !defined(__STRICT_ANSI__)
|
||||
#define __dead __attribute__((__noreturn__))
|
||||
#define __pure __attribute__((__const__))
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ__(2, 7)
|
||||
#define __unused __attribute__((__unused__))
|
||||
#else
|
||||
#define __unused /* delete */
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ__(3, 1)
|
||||
#define __used __attribute__((__used__))
|
||||
#else
|
||||
#define __used __unused /* suppress -Wunused warnings */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* __returns_twice makes the compiler not assume the function
|
||||
* only returns once. This affects registerisation of variables:
|
||||
* even local variables need to be in memory across such a call.
|
||||
* Example: setjmp()
|
||||
*/
|
||||
#if __GNUC_PREREQ__(4, 1)
|
||||
#define __returns_twice __attribute__((returns_twice))
|
||||
#else
|
||||
#define __returns_twice
|
||||
#endif
|
||||
|
||||
/*
|
||||
* __only_inline makes the compiler only use this function definition
|
||||
* for inlining; references that can't be inlined will be left as
|
||||
* external references instead of generating a local copy. The
|
||||
* matching library should include a simple extern definition for
|
||||
* the function to handle those references. c.f. ctype.h
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
# if __GNUC_PREREQ__(4, 2)
|
||||
#define __only_inline extern __inline __attribute__((__gnu_inline__))
|
||||
# else
|
||||
#define __only_inline extern __inline
|
||||
# endif
|
||||
#else
|
||||
#define __only_inline static __inline
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GNU C version 2.96 adds explicit branch prediction so that
|
||||
* the CPU back-end can hint the processor and also so that
|
||||
* code blocks can be reordered such that the predicted path
|
||||
* sees a more linear flow, thus improving cache behavior, etc.
|
||||
*
|
||||
* The following two macros provide us with a way to utilize this
|
||||
* compiler feature. Use __predict_true() if you expect the expression
|
||||
* to evaluate to true, and __predict_false() if you expect the
|
||||
* expression to evaluate to false.
|
||||
*
|
||||
* A few notes about usage:
|
||||
*
|
||||
* * Generally, __predict_false() error condition checks (unless
|
||||
* you have some _strong_ reason to do otherwise, in which case
|
||||
* document it), and/or __predict_true() `no-error' condition
|
||||
* checks, assuming you want to optimize for the no-error case.
|
||||
*
|
||||
* * Other than that, if you don't know the likelihood of a test
|
||||
* succeeding from empirical or other `hard' evidence, don't
|
||||
* make predictions.
|
||||
*
|
||||
* * These are meant to be used in places that are run `a lot'.
|
||||
* It is wasteful to make predictions in code that is run
|
||||
* seldomly (e.g. at subsystem initialization time) as the
|
||||
* basic block reordering that this affects can often generate
|
||||
* larger code.
|
||||
*/
|
||||
#if __GNUC_PREREQ__(2, 96)
|
||||
#define __predict_true(exp) __builtin_expect(((exp) != 0), 1)
|
||||
#define __predict_false(exp) __builtin_expect(((exp) != 0), 0)
|
||||
#else
|
||||
#define __predict_true(exp) ((exp) != 0)
|
||||
#define __predict_false(exp) ((exp) != 0)
|
||||
#endif
|
||||
|
||||
/* Delete pseudo-keywords wherever they are not available or needed. */
|
||||
#ifndef __dead
|
||||
#define __dead
|
||||
#define __pure
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ__(2, 7) || defined(__PCC__)
|
||||
#define __packed __attribute__((__packed__))
|
||||
#elif defined(lint)
|
||||
#define __packed
|
||||
#endif
|
||||
|
||||
#if !__GNUC_PREREQ__(2, 8)
|
||||
#define __extension__
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ__(2, 8) || defined(__PCC__)
|
||||
#define __statement(x) __extension__(x)
|
||||
#elif defined(lint)
|
||||
#define __statement(x) (0)
|
||||
#else
|
||||
#define __statement(x) (x)
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ__(3, 0)
|
||||
#define __malloc __attribute__((__malloc__))
|
||||
#else
|
||||
#define __malloc
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "The nice thing about standards is that there are so many to choose from."
|
||||
* There are a number of "feature test macros" specified by (different)
|
||||
* standards that determine which interfaces and types the header files
|
||||
* should expose.
|
||||
*
|
||||
* Because of inconsistencies in these macros, we define our own
|
||||
* set in the private name space that end in _VISIBLE. These are
|
||||
* always defined and so headers can test their values easily.
|
||||
* Things can get tricky when multiple feature macros are defined.
|
||||
* We try to take the union of all the features requested.
|
||||
*
|
||||
* The following macros are guaranteed to have a value after cdefs.h
|
||||
* has been included:
|
||||
* __POSIX_VISIBLE
|
||||
* __XPG_VISIBLE
|
||||
* __ISO_C_VISIBLE
|
||||
* __BSD_VISIBLE
|
||||
*/
|
||||
|
||||
/*
|
||||
* X/Open Portability Guides and Single Unix Specifications.
|
||||
* _XOPEN_SOURCE XPG3
|
||||
* _XOPEN_SOURCE && _XOPEN_VERSION = 4 XPG4
|
||||
* _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED = 1 XPG4v2
|
||||
* _XOPEN_SOURCE == 500 XPG5
|
||||
* _XOPEN_SOURCE == 520 XPG5v2
|
||||
* _XOPEN_SOURCE == 600 POSIX 1003.1-2001 with XSI
|
||||
* _XOPEN_SOURCE == 700 POSIX 1003.1-2008 with XSI
|
||||
*
|
||||
* The XPG spec implies a specific value for _POSIX_C_SOURCE.
|
||||
*/
|
||||
#ifdef _XOPEN_SOURCE
|
||||
# if (_XOPEN_SOURCE - 0 >= 700)
|
||||
# define __XPG_VISIBLE 700
|
||||
# undef _POSIX_C_SOURCE
|
||||
# define _POSIX_C_SOURCE 200809L
|
||||
# elif (_XOPEN_SOURCE - 0 >= 600)
|
||||
# define __XPG_VISIBLE 600
|
||||
# undef _POSIX_C_SOURCE
|
||||
# define _POSIX_C_SOURCE 200112L
|
||||
# elif (_XOPEN_SOURCE - 0 >= 520)
|
||||
# define __XPG_VISIBLE 520
|
||||
# undef _POSIX_C_SOURCE
|
||||
# define _POSIX_C_SOURCE 199506L
|
||||
# elif (_XOPEN_SOURCE - 0 >= 500)
|
||||
# define __XPG_VISIBLE 500
|
||||
# undef _POSIX_C_SOURCE
|
||||
# define _POSIX_C_SOURCE 199506L
|
||||
# elif (_XOPEN_SOURCE_EXTENDED - 0 == 1)
|
||||
# define __XPG_VISIBLE 420
|
||||
# elif (_XOPEN_VERSION - 0 >= 4)
|
||||
# define __XPG_VISIBLE 400
|
||||
# else
|
||||
# define __XPG_VISIBLE 300
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* POSIX macros, these checks must follow the XOPEN ones above.
|
||||
*
|
||||
* _POSIX_SOURCE == 1 1003.1-1988 (superseded by _POSIX_C_SOURCE)
|
||||
* _POSIX_C_SOURCE == 1 1003.1-1990
|
||||
* _POSIX_C_SOURCE == 2 1003.2-1992
|
||||
* _POSIX_C_SOURCE == 199309L 1003.1b-1993
|
||||
* _POSIX_C_SOURCE == 199506L 1003.1c-1995, 1003.1i-1995,
|
||||
* and the omnibus ISO/IEC 9945-1:1996
|
||||
* _POSIX_C_SOURCE == 200112L 1003.1-2001
|
||||
* _POSIX_C_SOURCE == 200809L 1003.1-2008
|
||||
*
|
||||
* The POSIX spec implies a specific value for __ISO_C_VISIBLE, though
|
||||
* this may be overridden by the _ISOC99_SOURCE macro later.
|
||||
*/
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
# if (_POSIX_C_SOURCE - 0 >= 200809)
|
||||
# define __POSIX_VISIBLE 200809
|
||||
# define __ISO_C_VISIBLE 1999
|
||||
# elif (_POSIX_C_SOURCE - 0 >= 200112)
|
||||
# define __POSIX_VISIBLE 200112
|
||||
# define __ISO_C_VISIBLE 1999
|
||||
# elif (_POSIX_C_SOURCE - 0 >= 199506)
|
||||
# define __POSIX_VISIBLE 199506
|
||||
# define __ISO_C_VISIBLE 1990
|
||||
# elif (_POSIX_C_SOURCE - 0 >= 199309)
|
||||
# define __POSIX_VISIBLE 199309
|
||||
# define __ISO_C_VISIBLE 1990
|
||||
# elif (_POSIX_C_SOURCE - 0 >= 2)
|
||||
# define __POSIX_VISIBLE 199209
|
||||
# define __ISO_C_VISIBLE 1990
|
||||
# else
|
||||
# define __POSIX_VISIBLE 199009
|
||||
# define __ISO_C_VISIBLE 1990
|
||||
# endif
|
||||
#elif defined(_POSIX_SOURCE)
|
||||
# define __POSIX_VISIBLE 198808
|
||||
# define __ISO_C_VISIBLE 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* _ANSI_SOURCE means to expose ANSI C89 interfaces only.
|
||||
* If the user defines it in addition to one of the POSIX or XOPEN
|
||||
* macros, assume the POSIX/XOPEN macro(s) should take precedence.
|
||||
*/
|
||||
#if defined(_ANSI_SOURCE) && !defined(__POSIX_VISIBLE) && \
|
||||
!defined(__XPG_VISIBLE)
|
||||
# define __POSIX_VISIBLE 0
|
||||
# define __XPG_VISIBLE 0
|
||||
# define __ISO_C_VISIBLE 1990
|
||||
#endif
|
||||
|
||||
/*
|
||||
* _ISOC99_SOURCE and __STDC_VERSION__ override any of the other macros since
|
||||
* they are non-exclusive.
|
||||
*/
|
||||
#if defined(_ISOC99_SOURCE) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901) || \
|
||||
(defined(__cplusplus) && __cplusplus >= 201103)
|
||||
# undef __ISO_C_VISIBLE
|
||||
# define __ISO_C_VISIBLE 1999
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Finally deal with BSD-specific interfaces that are not covered
|
||||
* by any standards. We expose these when none of the POSIX or XPG
|
||||
* macros is defined or if the user explicitly asks for them.
|
||||
*/
|
||||
#if !defined(_BSD_SOURCE) && \
|
||||
(defined(_ANSI_SOURCE) || defined(__XPG_VISIBLE) || defined(__POSIX_VISIBLE))
|
||||
# define __BSD_VISIBLE 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default values.
|
||||
*/
|
||||
#ifndef __XPG_VISIBLE
|
||||
# define __XPG_VISIBLE 700
|
||||
#endif
|
||||
#ifndef __POSIX_VISIBLE
|
||||
# define __POSIX_VISIBLE 200809
|
||||
#endif
|
||||
#ifndef __ISO_C_VISIBLE
|
||||
# define __ISO_C_VISIBLE 1999
|
||||
#endif
|
||||
#ifndef __BSD_VISIBLE
|
||||
# define __BSD_VISIBLE 1
|
||||
#endif
|
||||
|
||||
#endif /* !_SYS_CDEFS_H_ */
|
||||
243
telldus-core/3rdparty/openbsd-getopt/sys/types.h
vendored
Normal file
243
telldus-core/3rdparty/openbsd-getopt/sys/types.h
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/* $OpenBSD: types.h,v 1.32 2011/03/19 18:26:06 deraadt Exp $ */
|
||||
/* $NetBSD: types.h,v 1.29 1996/11/15 22:48:25 jtc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)types.h 8.4 (Berkeley) 1/21/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TYPES_H_
|
||||
#define _SYS_TYPES_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_types.h>
|
||||
#include <machine/endian.h>
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned short u_short;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned long u_long;
|
||||
|
||||
typedef unsigned char unchar; /* Sys V compatibility */
|
||||
typedef unsigned short ushort; /* Sys V compatibility */
|
||||
typedef unsigned int uint; /* Sys V compatibility */
|
||||
typedef unsigned long ulong; /* Sys V compatibility */
|
||||
|
||||
typedef __cpuid_t cpuid_t; /* CPU id */
|
||||
typedef __register_t register_t; /* register-sized type */
|
||||
#endif /* __BSD_VISIBLE */
|
||||
|
||||
/*
|
||||
* XXX The exact-width bit types should only be exposed if __BSD_VISIBLE
|
||||
* but the rest of the includes are not ready for that yet.
|
||||
*/
|
||||
#ifndef __BIT_TYPES_DEFINED__
|
||||
#define __BIT_TYPES_DEFINED__
|
||||
#endif
|
||||
|
||||
#ifndef _INT8_T_DEFINED_
|
||||
#define _INT8_T_DEFINED_
|
||||
typedef __int8_t int8_t;
|
||||
#endif
|
||||
|
||||
#ifndef _UINT8_T_DEFINED_
|
||||
#define _UINT8_T_DEFINED_
|
||||
typedef __uint8_t uint8_t;
|
||||
#endif
|
||||
|
||||
#ifndef _INT16_T_DEFINED_
|
||||
#define _INT16_T_DEFINED_
|
||||
typedef __int16_t int16_t;
|
||||
#endif
|
||||
|
||||
#ifndef _UINT16_T_DEFINED_
|
||||
#define _UINT16_T_DEFINED_
|
||||
typedef __uint16_t uint16_t;
|
||||
#endif
|
||||
|
||||
#ifndef _INT32_T_DEFINED_
|
||||
#define _INT32_T_DEFINED_
|
||||
typedef __int32_t int32_t;
|
||||
#endif
|
||||
|
||||
#ifndef _UINT32_T_DEFINED_
|
||||
#define _UINT32_T_DEFINED_
|
||||
typedef __uint32_t uint32_t;
|
||||
#endif
|
||||
|
||||
#ifndef _INT64_T_DEFINED_
|
||||
#define _INT64_T_DEFINED_
|
||||
typedef __int64_t int64_t;
|
||||
#endif
|
||||
|
||||
#ifndef _UINT64_T_DEFINED_
|
||||
#define _UINT64_T_DEFINED_
|
||||
typedef __uint64_t uint64_t;
|
||||
#endif
|
||||
|
||||
/* BSD-style unsigned bits types */
|
||||
typedef __uint8_t u_int8_t;
|
||||
typedef __uint16_t u_int16_t;
|
||||
typedef __uint32_t u_int32_t;
|
||||
typedef __uint64_t u_int64_t;
|
||||
|
||||
/* quads, deprecated in favor of 64 bit int types */
|
||||
typedef __int64_t quad_t;
|
||||
typedef __uint64_t u_quad_t;
|
||||
typedef quad_t * qaddr_t;
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
/* VM system types */
|
||||
typedef __vaddr_t vaddr_t;
|
||||
typedef __paddr_t paddr_t;
|
||||
typedef __vsize_t vsize_t;
|
||||
typedef __psize_t psize_t;
|
||||
#endif /* __BSD_VISIBLE */
|
||||
|
||||
/* Standard system types */
|
||||
typedef char * caddr_t; /* core address */
|
||||
typedef __int32_t daddr32_t; /* 32-bit disk address */
|
||||
typedef __int64_t daddr_t; /* 64-bit disk address */
|
||||
typedef __int64_t daddr64_t; /* 64-bit disk address */
|
||||
typedef __dev_t dev_t; /* device number */
|
||||
typedef __fixpt_t fixpt_t; /* fixed point number */
|
||||
typedef __gid_t gid_t; /* group id */
|
||||
typedef __id_t id_t; /* may contain pid, uid or gid */
|
||||
typedef __ino_t ino_t; /* inode number */
|
||||
typedef __key_t key_t; /* IPC key (for Sys V IPC) */
|
||||
typedef __mode_t mode_t; /* permissions */
|
||||
typedef __nlink_t nlink_t; /* link count */
|
||||
typedef __pid_t pid_t; /* process id */
|
||||
typedef __rlim_t rlim_t; /* resource limit */
|
||||
typedef __segsz_t segsz_t; /* segment size */
|
||||
typedef __swblk_t swblk_t; /* swap offset */
|
||||
typedef __uid_t uid_t; /* user id */
|
||||
typedef __useconds_t useconds_t; /* microseconds */
|
||||
typedef __suseconds_t suseconds_t; /* microseconds (signed) */
|
||||
typedef __fsblkcnt_t fsblkcnt_t; /* file system block count */
|
||||
typedef __fsfilcnt_t fsfilcnt_t; /* file system file count */
|
||||
|
||||
/*
|
||||
* XPG4.2 states that inclusion of <netinet/in.h> must pull these
|
||||
* in and that inclusion of <sys/socket.h> must pull in sa_family_t.
|
||||
* We put these here because there are other headers that require
|
||||
* these types and <sys/socket.h> and <netinet/in.h> will indirectly
|
||||
* include <sys/types.h>.
|
||||
* XXX - now that we have protected versions these should move.
|
||||
*/
|
||||
typedef __in_addr_t in_addr_t; /* base type for internet address */
|
||||
typedef __in_port_t in_port_t; /* IP port type */
|
||||
typedef __sa_family_t sa_family_t; /* sockaddr address family type */
|
||||
typedef __socklen_t socklen_t; /* length type for network syscalls */
|
||||
|
||||
/*
|
||||
* The following types may be defined in multiple header files.
|
||||
*/
|
||||
#ifndef _CLOCK_T_DEFINED_
|
||||
#define _CLOCK_T_DEFINED_
|
||||
typedef __clock_t clock_t;
|
||||
#endif
|
||||
|
||||
#ifndef _CLOCKID_T_DEFINED_
|
||||
#define _CLOCKID_T_DEFINED_
|
||||
typedef __clockid_t clockid_t;
|
||||
#endif
|
||||
|
||||
#ifndef _SIZE_T_DEFINED_
|
||||
#define _SIZE_T_DEFINED_
|
||||
typedef __size_t size_t;
|
||||
#endif
|
||||
|
||||
#ifndef _SSIZE_T_DEFINED_
|
||||
#define _SSIZE_T_DEFINED_
|
||||
typedef __ssize_t ssize_t;
|
||||
#endif
|
||||
|
||||
#ifndef _TIME_T_DEFINED_
|
||||
#define _TIME_T_DEFINED_
|
||||
typedef __time_t time_t;
|
||||
#endif
|
||||
|
||||
#ifndef _TIMER_T_DEFINED_
|
||||
#define _TIMER_T_DEFINED_
|
||||
typedef __timer_t timer_t;
|
||||
#endif
|
||||
|
||||
#ifndef _OFF_T_DEFINED_
|
||||
#define _OFF_T_DEFINED_
|
||||
typedef __off_t off_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These belong in unistd.h, but are placed here too to ensure that
|
||||
* long arguments will be promoted to off_t if the program fails to
|
||||
* include that header or explicitly cast them to off_t.
|
||||
*/
|
||||
#if __BSD_VISIBLE && !defined(_KERNEL)
|
||||
__BEGIN_DECLS
|
||||
off_t lseek(int, off_t, int);
|
||||
int ftruncate(int, off_t);
|
||||
int truncate(const char *, off_t);
|
||||
__END_DECLS
|
||||
#endif /* __BSD_VISIBLE && !_KERNEL */
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
/* Major, minor numbers, dev_t's. */
|
||||
#define major(x) ((int32_t)(((u_int32_t)(x) >> 8) & 0xff))
|
||||
#define minor(x) ((int32_t)((x) & 0xff) | (((x) & 0xffff0000) >> 8))
|
||||
#define makedev(x,y) ((dev_t)((((x) & 0xff) << 8) | ((y) & 0xff) | (((y) & 0xffff00) << 8)))
|
||||
#endif
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
#include <sys/select.h> /* must be after type declarations */
|
||||
#endif
|
||||
|
||||
#if defined(__STDC__) && defined(_KERNEL)
|
||||
/*
|
||||
* Forward structure declarations for function prototypes. We include the
|
||||
* common structures that cross subsystem boundaries here; others are mostly
|
||||
* used in the same place that the structure is defined.
|
||||
*/
|
||||
struct proc;
|
||||
struct pgrp;
|
||||
struct ucred;
|
||||
struct rusage;
|
||||
struct file;
|
||||
struct buf;
|
||||
struct tty;
|
||||
struct uio;
|
||||
#endif
|
||||
|
||||
#endif /* !_SYS_TYPES_H_ */
|
||||
159
telldus-core/3rdparty/openbsd-getopt/sys/unistd.h
vendored
Normal file
159
telldus-core/3rdparty/openbsd-getopt/sys/unistd.h
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/* $OpenBSD: unistd.h,v 1.19 2011/10/15 23:35:29 guenther Exp $ */
|
||||
/* $NetBSD: unistd.h,v 1.10 1994/06/29 06:46:06 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)unistd.h 8.2 (Berkeley) 1/7/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_UNISTD_H_
|
||||
#define _SYS_UNISTD_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/* compile-time symbolic constants */
|
||||
/* implementation supports job control */
|
||||
#define _POSIX_JOB_CONTROL 1
|
||||
/* saved set-user-ID and set-group-ID */
|
||||
#define _POSIX_SAVED_IDS 1
|
||||
|
||||
#define _POSIX_VERSION 199009L
|
||||
#define _POSIX2_VERSION 199212L
|
||||
|
||||
/* execution-time symbolic constants */
|
||||
/* chown requires appropriate privileges */
|
||||
#define _POSIX_CHOWN_RESTRICTED 1
|
||||
/* too-long path components generate errors */
|
||||
#define _POSIX_NO_TRUNC 1
|
||||
/* may disable terminal special characters */
|
||||
#define _POSIX_VDISABLE (0377)
|
||||
/* file synchronization is available */
|
||||
#define _POSIX_FSYNC 1
|
||||
|
||||
/* access function */
|
||||
#define F_OK 0 /* test for existence of file */
|
||||
#define X_OK 0x01 /* test for execute or search permission */
|
||||
#define W_OK 0x02 /* test for write permission */
|
||||
#define R_OK 0x04 /* test for read permission */
|
||||
|
||||
/* whence values for lseek(2) */
|
||||
#define SEEK_SET 0 /* set file offset to offset */
|
||||
#define SEEK_CUR 1 /* set file offset to current plus offset */
|
||||
#define SEEK_END 2 /* set file offset to EOF plus offset */
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
/* old BSD whence values for lseek(2); renamed by POSIX 1003.1 */
|
||||
#define L_SET SEEK_SET
|
||||
#define L_INCR SEEK_CUR
|
||||
#define L_XTND SEEK_END
|
||||
|
||||
/* the parameters argument passed to the __tfork() syscall */
|
||||
struct __tfork {
|
||||
void *tf_tcb;
|
||||
pid_t *tf_tid;
|
||||
int tf_flags;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* configurable pathname variables */
|
||||
#define _PC_LINK_MAX 1
|
||||
#define _PC_MAX_CANON 2
|
||||
#define _PC_MAX_INPUT 3
|
||||
#define _PC_NAME_MAX 4
|
||||
#define _PC_PATH_MAX 5
|
||||
#define _PC_PIPE_BUF 6
|
||||
#define _PC_CHOWN_RESTRICTED 7
|
||||
#define _PC_NO_TRUNC 8
|
||||
#define _PC_VDISABLE 9
|
||||
|
||||
/* configurable system variables */
|
||||
#define _SC_ARG_MAX 1
|
||||
#define _SC_CHILD_MAX 2
|
||||
#define _SC_CLK_TCK 3
|
||||
#define _SC_NGROUPS_MAX 4
|
||||
#define _SC_OPEN_MAX 5
|
||||
#define _SC_JOB_CONTROL 6
|
||||
#define _SC_SAVED_IDS 7
|
||||
#define _SC_VERSION 8
|
||||
#define _SC_BC_BASE_MAX 9
|
||||
#define _SC_BC_DIM_MAX 10
|
||||
#define _SC_BC_SCALE_MAX 11
|
||||
#define _SC_BC_STRING_MAX 12
|
||||
#define _SC_COLL_WEIGHTS_MAX 13
|
||||
#define _SC_EXPR_NEST_MAX 14
|
||||
#define _SC_LINE_MAX 15
|
||||
#define _SC_RE_DUP_MAX 16
|
||||
#define _SC_2_VERSION 17
|
||||
#define _SC_2_C_BIND 18
|
||||
#define _SC_2_C_DEV 19
|
||||
#define _SC_2_CHAR_TERM 20
|
||||
#define _SC_2_FORT_DEV 21
|
||||
#define _SC_2_FORT_RUN 22
|
||||
#define _SC_2_LOCALEDEF 23
|
||||
#define _SC_2_SW_DEV 24
|
||||
#define _SC_2_UPE 25
|
||||
#define _SC_STREAM_MAX 26
|
||||
#define _SC_TZNAME_MAX 27
|
||||
#define _SC_PAGESIZE 28
|
||||
#define _SC_PAGE_SIZE _SC_PAGESIZE /* 1170 compatibility */
|
||||
#define _SC_FSYNC 29
|
||||
#define _SC_XOPEN_SHM 30
|
||||
#define _SC_SEM_NSEMS_MAX 31
|
||||
#define _SC_SEM_VALUE_MAX 32
|
||||
#define _SC_HOST_NAME_MAX 33
|
||||
|
||||
/* P1003.1c */
|
||||
#define _SC_GETGR_R_SIZE_MAX 100
|
||||
#define _SC_GETPW_R_SIZE_MAX 101
|
||||
#define _SC_LOGIN_NAME_MAX 102
|
||||
#define _SC_THREAD_SAFE_FUNCTIONS 103
|
||||
#ifdef notyet
|
||||
#define _SC_THREAD_DESTRUCTOR_ITERATIONS
|
||||
#define _SC_THREAD_KEYS_MAX
|
||||
#define _SC_THREAD_STACK_MIN
|
||||
#define _SC_THREAD_THREADS_MAX
|
||||
#define _SC_TTY_NAME_MAX
|
||||
#define _SC_THREADS
|
||||
#define _SC_THREAD_ATTR_STACKADDR
|
||||
#define _SC_THREAD_ATTR_STACKSIZE
|
||||
#define _SC_THREAD_PRIORITY_SCHEDULING
|
||||
#define _SC_THREAD_PRIO_INHERIT
|
||||
#define _SC_THREAD_PRIO_PROTECT
|
||||
#define _SC_THREAD_PROCESS_SHARED
|
||||
#endif
|
||||
|
||||
#define _SC_PHYS_PAGES 500
|
||||
#define _SC_AVPHYS_PAGES 501
|
||||
#define _SC_NPROCESSORS_CONF 502
|
||||
#define _SC_NPROCESSORS_ONLN 503
|
||||
|
||||
/* configurable system strings */
|
||||
#define _CS_PATH 1
|
||||
|
||||
#endif /* !_SYS_UNISTD_H_ */
|
||||
274
telldus-core/3rdparty/openbsd-getopt/unistd.h
vendored
Normal file
274
telldus-core/3rdparty/openbsd-getopt/unistd.h
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
/* $OpenBSD: unistd.h,v 1.67 2012/01/13 13:16:44 nigel Exp $ */
|
||||
/* $NetBSD: unistd.h,v 1.26.4.1 1996/05/28 02:31:51 mrg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)unistd.h 5.13 (Berkeley) 6/17/91
|
||||
*/
|
||||
|
||||
#ifndef _UNISTD_H_
|
||||
#define _UNISTD_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#define STDIN_FILENO 0 /* standard input file descriptor */
|
||||
#define STDOUT_FILENO 1 /* standard output file descriptor */
|
||||
#define STDERR_FILENO 2 /* standard error file descriptor */
|
||||
|
||||
#if __XPG_VISIBLE || __POSIX_VISIBLE >= 200112
|
||||
#define F_ULOCK 0 /* unlock locked section */
|
||||
#define F_LOCK 1 /* lock a section for exclusive use */
|
||||
#define F_TLOCK 2 /* test and lock a section for exclusive use */
|
||||
#define F_TEST 3 /* test a section for locks by other procs */
|
||||
#endif
|
||||
|
||||
#if __POSIX_VISIBLE
|
||||
#define _POSIX_REENTRANT_FUNCTIONS 1
|
||||
#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#ifdef __GNUG__
|
||||
#define NULL __null
|
||||
#elif defined(__cplusplus)
|
||||
#define NULL 0L
|
||||
#else
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
//__dead void _exit(int);
|
||||
//int access(const char *, int);
|
||||
unsigned int alarm(unsigned int);
|
||||
//int chdir(const char *);
|
||||
//int chown(const char *, uid_t, gid_t);
|
||||
int close(int);
|
||||
int dup(int);
|
||||
int dup2(int, int);
|
||||
//int execl(const char *, const char *, ...)
|
||||
// __attribute__((sentinel));
|
||||
//int execle(const char *, const char *, ...);
|
||||
//int execlp(const char *, const char *, ...)
|
||||
// __attribute__((sentinel));
|
||||
//int execv(const char *, char * const *);
|
||||
//int execve(const char *, char * const *, char * const *);
|
||||
//int execvp(const char *, char * const *);
|
||||
pid_t fork(void);
|
||||
long fpathconf(int, int);
|
||||
char *getcwd(char *, size_t)
|
||||
__attribute__((__bounded__(__string__,1,2)));
|
||||
gid_t getegid(void);
|
||||
uid_t geteuid(void);
|
||||
gid_t getgid(void);
|
||||
int getgroups(int, gid_t *);
|
||||
char *getlogin(void);
|
||||
pid_t getpgrp(void);
|
||||
pid_t getpid(void);
|
||||
pid_t getppid(void);
|
||||
uid_t getuid(void);
|
||||
int isatty(int);
|
||||
//int link(const char *, const char *);
|
||||
//off_t lseek(int, off_t, int);
|
||||
//long pathconf(const char *, int);
|
||||
int pause(void);
|
||||
int pipe(int *);
|
||||
//ssize_t read(int, void *, size_t)
|
||||
// __attribute__((__bounded__(__buffer__,2,3)));
|
||||
//int rmdir(const char *);
|
||||
int setgid(gid_t);
|
||||
int setuid(uid_t);
|
||||
unsigned int sleep(unsigned int);
|
||||
long sysconf(int);
|
||||
pid_t tcgetpgrp(int);
|
||||
int tcsetpgrp(int, pid_t);
|
||||
char *ttyname(int);
|
||||
//int unlink(const char *);
|
||||
//ssize_t write(int, const void *, size_t)
|
||||
// __attribute__((__bounded__(__buffer__,2,3)));
|
||||
|
||||
#if __POSIX_VISIBLE || __XPG_VISIBLE >= 300
|
||||
pid_t setsid(void);
|
||||
int setpgid(pid_t, pid_t);
|
||||
#endif
|
||||
|
||||
#if __POSIX_VISIBLE >= 199209 || __XPG_VISIBLE
|
||||
size_t confstr(int, char *, size_t)
|
||||
__attribute__((__bounded__(__string__,2,3)));
|
||||
#ifndef _GETOPT_DEFINED_
|
||||
#define _GETOPT_DEFINED_
|
||||
int getopt(int, char * const *, const char *);
|
||||
extern char *optarg; /* getopt(3) external variables */
|
||||
extern int opterr, optind, optopt, optreset;
|
||||
/* XXX - getsubopt does not belong here */
|
||||
int getsubopt(char **, char * const *, char **);
|
||||
extern char *suboptarg; /* getsubopt(3) external variable */
|
||||
#endif /* _GETOPT_DEFINED_ */
|
||||
#endif
|
||||
|
||||
#if __POSIX_VISIBLE >= 199506 || __XPG_VISIBLE
|
||||
int fsync(int);
|
||||
int ftruncate(int, off_t);
|
||||
int getlogin_r(char *, size_t)
|
||||
__attribute__((__bounded__(__string__,1,2)));
|
||||
#endif
|
||||
|
||||
#if __XPG_VISIBLE || __BSD_VISIBLE
|
||||
char *crypt(const char *, const char *);
|
||||
int encrypt(char *, int);
|
||||
int fchdir(int);
|
||||
int fchown(int, uid_t, gid_t);
|
||||
long gethostid(void);
|
||||
char *getwd(char *)
|
||||
__attribute__ ((__bounded__(__minbytes__,1,1024)));
|
||||
int lchown(const char *, uid_t, gid_t);
|
||||
int mkstemp(char *);
|
||||
char *mktemp(char *);
|
||||
int nice(int);
|
||||
int readlink(const char *, char *, size_t)
|
||||
__attribute__ ((__bounded__(__string__,2,3)));
|
||||
int setkey(const char *);
|
||||
int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */
|
||||
int setregid(gid_t, gid_t);
|
||||
int setreuid(uid_t, uid_t);
|
||||
void swab(const void *, void *, size_t);
|
||||
void sync(void);
|
||||
int truncate(const char *, off_t);
|
||||
unsigned int ualarm(unsigned int, unsigned int);
|
||||
int usleep(useconds_t);
|
||||
pid_t vfork(void);
|
||||
#endif
|
||||
|
||||
#if __XPG_VISIBLE >= 420
|
||||
pid_t getpgid(pid_t);
|
||||
pid_t getsid(pid_t);
|
||||
#endif
|
||||
|
||||
#if __XPG_VISIBLE >= 500
|
||||
ssize_t pread(int, void *, size_t, off_t);
|
||||
ssize_t pwrite(int, const void *, size_t, off_t);
|
||||
int ttyname_r(int, char *, size_t)
|
||||
__attribute__((__bounded__(__string__,2,3)));
|
||||
#endif
|
||||
|
||||
#if __BSD_VISIBLE || __XPG_VISIBLE <= 500
|
||||
/* Interfaces withdrawn by X/Open Issue 5 Version 0 */
|
||||
int brk(void *);
|
||||
//int chroot(const char *);
|
||||
int getdtablesize(void);
|
||||
int getpagesize(void);
|
||||
//char *getpass(const char *);
|
||||
void *sbrk(int);
|
||||
#endif
|
||||
|
||||
#if __POSIX_VISIBLE >= 200112 || __XPG_VISIBLE >= 420
|
||||
int lockf(int, int, off_t);
|
||||
#endif
|
||||
|
||||
#if __POSIX_VISIBLE >= 200112 || __XPG_VISIBLE >= 420 || __BSD_VISIBLE
|
||||
int symlink(const char *, const char *);
|
||||
int gethostname(char *, size_t)
|
||||
__attribute__ ((__bounded__(__string__,1,2)));
|
||||
int setegid(gid_t);
|
||||
int seteuid(uid_t);
|
||||
#endif
|
||||
|
||||
#if __POSIX_VISIBLE >= 200809
|
||||
int faccessat(int, const char *, int, int);
|
||||
int fchownat(int, const char *, uid_t, gid_t, int);
|
||||
int linkat(int, const char *, int, const char *, int);
|
||||
ssize_t readlinkat(int, const char *, char *, size_t);
|
||||
int symlinkat(const char *, int, const char *);
|
||||
int unlinkat(int, const char *, int);
|
||||
#endif
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
int acct(const char *);
|
||||
int closefrom(int);
|
||||
int des_cipher(const char *, char *, int32_t, int);
|
||||
int des_setkey(const char *);
|
||||
void endusershell(void);
|
||||
int exect(const char *, char * const *, char * const *);
|
||||
char *fflagstostr(u_int32_t);
|
||||
int getdomainname(char *, size_t)
|
||||
__attribute__ ((__bounded__(__string__,1,2)));
|
||||
int getgrouplist(const char *, gid_t, gid_t *, int *);
|
||||
mode_t getmode(const void *, mode_t);
|
||||
int getresgid(gid_t *, gid_t *, gid_t *);
|
||||
int getresuid(uid_t *, uid_t *, uid_t *);
|
||||
char *getusershell(void);
|
||||
int initgroups(const char *, gid_t);
|
||||
int iruserok(u_int32_t, int, const char *, const char *);
|
||||
int iruserok_sa(const void *, int, int, const char *, const char *);
|
||||
int issetugid(void);
|
||||
char *mkdtemp(char *);
|
||||
int mkstemps(char *, int);
|
||||
int nfssvc(int, void *);
|
||||
int profil(char *, size_t, unsigned long, unsigned int)
|
||||
__attribute__ ((__bounded__(__string__,1,2)));
|
||||
int quotactl(const char *, int, int, char *);
|
||||
int rcmd(char **, int, const char *,
|
||||
const char *, const char *, int *);
|
||||
int rcmd_af(char **, int, const char *,
|
||||
const char *, const char *, int *, int);
|
||||
int rcmdsh(char **, int, const char *,
|
||||
const char *, const char *, char *);
|
||||
char *re_comp(const char *);
|
||||
int re_exec(const char *);
|
||||
int reboot(int);
|
||||
int revoke(const char *);
|
||||
int rfork(int opts);
|
||||
int rresvport(int *);
|
||||
int rresvport_af(int *, int);
|
||||
int ruserok(const char *, int, const char *, const char *);
|
||||
#ifndef _SELECT_DEFINED_
|
||||
#define _SELECT_DEFINED_
|
||||
struct timeval;
|
||||
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
|
||||
#endif
|
||||
int setdomainname(const char *, size_t);
|
||||
int setgroups(int, const gid_t *);
|
||||
int sethostid(long);
|
||||
int sethostname(const char *, size_t);
|
||||
int setlogin(const char *);
|
||||
void *setmode(const char *);
|
||||
int setresgid(gid_t, gid_t, gid_t);
|
||||
int setresuid(uid_t, uid_t, uid_t);
|
||||
int setrgid(gid_t);
|
||||
int setruid(uid_t);
|
||||
void setusershell(void);
|
||||
int strtofflags(char **, u_int32_t *, u_int32_t *);
|
||||
int swapctl(int cmd, const void *arg, int misc);
|
||||
int syscall(int, ...);
|
||||
#endif /* __BSD_VISIBLE */
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_UNISTD_H_ */
|
||||
7
telldus-core/AUTHORS
Normal file
7
telldus-core/AUTHORS
Normal file
@@ -0,0 +1,7 @@
|
||||
telldus-core has been developed by :
|
||||
|
||||
Micke Prag <micke.prag@telldus.se>
|
||||
Fredrik Jacobsson <fredrik.jacobsson@telldus.se>
|
||||
Stefan Persson <stefan.persson@telldus.se>
|
||||
|
||||
The package is maintained by Micke Prag <micke.prag@telldus.se>
|
||||
75
telldus-core/CMakeLists.txt
Normal file
75
telldus-core/CMakeLists.txt
Normal file
@@ -0,0 +1,75 @@
|
||||
PROJECT( telldus-core )
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.6.0 )
|
||||
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
|
||||
SET(PACKAGE_MAJOR_VERSION 2)
|
||||
SET(PACKAGE_MINOR_VERSION 1)
|
||||
SET(PACKAGE_PATCH_VERSION 2)
|
||||
SET(PACKAGE_VERSION "${PACKAGE_MAJOR_VERSION}.${PACKAGE_MINOR_VERSION}.${PACKAGE_PATCH_VERSION}")
|
||||
SET(PACKAGE_SUBVERSION "")
|
||||
SET(PACKAGE_SOVERSION 2)
|
||||
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
IF (PACKAGE_SUBVERSION)
|
||||
SET(DISPLAYED_VERSION "${PACKAGE_VERSION}_${PACKAGE_SUBVERSION}")
|
||||
ELSE (PACKAGE_SUBVERSION)
|
||||
SET(DISPLAYED_VERSION ${PACKAGE_VERSION})
|
||||
ENDIF(PACKAGE_SUBVERSION)
|
||||
|
||||
SET(BUILD_LIBTELLDUS-CORE TRUE CACHE BOOL "Build libtelldus-core")
|
||||
|
||||
IF (WIN32)
|
||||
SET(TDADMIN_DEFAULT FALSE)
|
||||
ELSEIF(APPLE)
|
||||
SET(TDADMIN_DEFAULT FALSE)
|
||||
ELSE (WIN32)
|
||||
SET(TDADMIN_DEFAULT TRUE)
|
||||
ENDIF (WIN32)
|
||||
|
||||
IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
INCLUDE_DIRECTORIES(/usr/local/include)
|
||||
LINK_DIRECTORIES(/usr/local/lib)
|
||||
ENDIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
|
||||
SET(BUILD_TDTOOL TRUE CACHE BOOL "Build tdtool")
|
||||
SET(BUILD_TDADMIN ${TDADMIN_DEFAULT} CACHE BOOL "Build tdadmin")
|
||||
|
||||
SET(GENERATE_MAN FALSE CACHE BOOL "Enable generation of man-files")
|
||||
|
||||
ADD_SUBDIRECTORY(common)
|
||||
ADD_SUBDIRECTORY(service)
|
||||
ADD_SUBDIRECTORY(client)
|
||||
|
||||
IF(BUILD_TDTOOL)
|
||||
IF(WIN32)
|
||||
ADD_SUBDIRECTORY(3rdparty/openbsd-getopt)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(tdtool)
|
||||
ENDIF(BUILD_TDTOOL)
|
||||
IF(BUILD_TDADMIN)
|
||||
ADD_SUBDIRECTORY(tdadmin)
|
||||
ENDIF(BUILD_TDADMIN)
|
||||
|
||||
ENABLE_TESTING()
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
|
||||
FIND_PACKAGE(Doxygen)
|
||||
|
||||
IF(DOXYGEN_FOUND)
|
||||
SET(DOXY_CONFIG ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
||||
|
||||
CONFIGURE_FILE(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in"
|
||||
${DOXY_CONFIG} @ONLY
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(docs
|
||||
${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG}
|
||||
DEPENDS ${DOXY_CONFIG}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Generating doxygen documentation" VERBATIM
|
||||
)
|
||||
ENDIF()
|
||||
80
telldus-core/CMakeLists.txt.orig
Normal file
80
telldus-core/CMakeLists.txt.orig
Normal file
@@ -0,0 +1,80 @@
|
||||
PROJECT( telldus-core )
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.6.0 )
|
||||
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
|
||||
OPTION(FORCE_COMPILE_FROM_TRUNK FALSE "Accept compiling source from trunk. This is unsupported and highly unrecommended")
|
||||
IF(NOT FORCE_COMPILE_FROM_TRUNK)
|
||||
MESSAGE(FATAL_ERROR "You are compiling sources from trunk. Don't do that!")
|
||||
ENDIF(NOT FORCE_COMPILE_FROM_TRUNK)
|
||||
|
||||
SET(PACKAGE_MAJOR_VERSION 2)
|
||||
SET(PACKAGE_MINOR_VERSION 1)
|
||||
SET(PACKAGE_PATCH_VERSION 2)
|
||||
SET(PACKAGE_VERSION "${PACKAGE_MAJOR_VERSION}.${PACKAGE_MINOR_VERSION}.${PACKAGE_PATCH_VERSION}")
|
||||
SET(PACKAGE_SUBVERSION "")
|
||||
SET(PACKAGE_SOVERSION 2)
|
||||
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
IF (PACKAGE_SUBVERSION)
|
||||
SET(DISPLAYED_VERSION "${PACKAGE_VERSION}_${PACKAGE_SUBVERSION}")
|
||||
ELSE (PACKAGE_SUBVERSION)
|
||||
SET(DISPLAYED_VERSION ${PACKAGE_VERSION})
|
||||
ENDIF(PACKAGE_SUBVERSION)
|
||||
|
||||
SET(BUILD_LIBTELLDUS-CORE TRUE CACHE BOOL "Build libtelldus-core")
|
||||
|
||||
IF (WIN32)
|
||||
SET(TDADMIN_DEFAULT FALSE)
|
||||
ELSEIF(APPLE)
|
||||
SET(TDADMIN_DEFAULT FALSE)
|
||||
ELSE (WIN32)
|
||||
SET(TDADMIN_DEFAULT TRUE)
|
||||
ENDIF (WIN32)
|
||||
|
||||
IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
INCLUDE_DIRECTORIES(/usr/local/include)
|
||||
LINK_DIRECTORIES(/usr/local/lib)
|
||||
ENDIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
|
||||
SET(BUILD_TDTOOL TRUE CACHE BOOL "Build tdtool")
|
||||
SET(BUILD_TDADMIN ${TDADMIN_DEFAULT} CACHE BOOL "Build tdadmin")
|
||||
|
||||
SET(GENERATE_MAN FALSE CACHE BOOL "Enable generation of man-files")
|
||||
|
||||
ADD_SUBDIRECTORY(common)
|
||||
ADD_SUBDIRECTORY(service)
|
||||
ADD_SUBDIRECTORY(client)
|
||||
|
||||
IF(BUILD_TDTOOL)
|
||||
IF(WIN32)
|
||||
ADD_SUBDIRECTORY(3rdparty/openbsd-getopt)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(tdtool)
|
||||
ENDIF(BUILD_TDTOOL)
|
||||
IF(BUILD_TDADMIN)
|
||||
ADD_SUBDIRECTORY(tdadmin)
|
||||
ENDIF(BUILD_TDADMIN)
|
||||
|
||||
ENABLE_TESTING()
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
|
||||
FIND_PACKAGE(Doxygen)
|
||||
|
||||
IF(DOXYGEN_FOUND)
|
||||
SET(DOXY_CONFIG ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
||||
|
||||
CONFIGURE_FILE(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in"
|
||||
${DOXY_CONFIG} @ONLY
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(docs
|
||||
${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG}
|
||||
DEPENDS ${DOXY_CONFIG}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Generating doxygen documentation" VERBATIM
|
||||
)
|
||||
ENDIF()
|
||||
51
telldus-core/INSTALL
Normal file
51
telldus-core/INSTALL
Normal file
@@ -0,0 +1,51 @@
|
||||
Unpacking
|
||||
---------
|
||||
|
||||
Unpack the archive if you have not done so already:
|
||||
|
||||
cd /usr/src
|
||||
gunzip telldus-core-{version}.tar.gz #Change {version} to the downloaded version
|
||||
tar xvf telldus-core-{version}.tar
|
||||
|
||||
This creates the directory /usr/src/telldus-core-{version} containing the files
|
||||
from the archive. We only support the GNU version of tar archiving utility. Note
|
||||
on some systems it is called gtar.
|
||||
|
||||
Configuring
|
||||
-----------
|
||||
|
||||
Telldus Core is built using CMake (http://www.cmake.org), version 2.4.0 is the
|
||||
minimum required version. This means there is no configure-script, but you
|
||||
need to run cmake.
|
||||
|
||||
To configure telldus-core for your machine type:
|
||||
|
||||
cmake .
|
||||
|
||||
in the package directory.
|
||||
|
||||
By default, Telldus Core is configured for installation in the /usr/local
|
||||
directory, but this can be changed by using the -DCMAKE_INSTALL_PREFIX=/usr
|
||||
option. Alternatively, the DESTDIR="/opt" option can be used to specify a "local"
|
||||
installation within the source directory when running "make install".
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
To create the library and compile all the tools type:
|
||||
|
||||
make
|
||||
|
||||
If you did not configure Telldus Core using the -DCMAKE_INSTALL_PREFIX=/usr
|
||||
option, you need to install the library and tools in the appropriate place. To
|
||||
do this, type:
|
||||
|
||||
su -c "make install"
|
||||
|
||||
and enter the root password.
|
||||
|
||||
If you want to install in another directory, type:
|
||||
|
||||
su -c "make DESTDIR=/opt install"
|
||||
|
||||
Note that on some systems the make utility is named differently, e.g. gmake.
|
||||
502
telldus-core/LICENSE
Normal file
502
telldus-core/LICENSE
Normal file
@@ -0,0 +1,502 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
30
telldus-core/README
Normal file
30
telldus-core/README
Normal file
@@ -0,0 +1,30 @@
|
||||
This is Telldus Core version {version}
|
||||
|
||||
Telldus Core is the driver and tools for controlling a Telldus Technologies
|
||||
TellStick. It does not containing any GUI tools which makes it suitable for
|
||||
server use.
|
||||
|
||||
|
||||
INSTALLING Telldus Core
|
||||
|
||||
On Windows, if you want to install the precompiles binary packages, simply
|
||||
launch the package and follow the instructions in the installation wizard.
|
||||
|
||||
If you have a source package (a .tar.gz file), follow the instruction in the
|
||||
INSTALL file.
|
||||
|
||||
|
||||
CONFIGURATION AND TOOLS
|
||||
|
||||
Once Telldus Core is installed, we suggest that you start by adding the devices
|
||||
you want to control.
|
||||
|
||||
On Windows, this is done by installing TelldusCenter. On Linux it's done by
|
||||
editing the file /etc/tellstick.conf directly, or in TelldusCenter.
|
||||
|
||||
Telldus Core installs the tool tdtool for controlling devices with TellStick.
|
||||
Have a look in the man page for a description how to use it:
|
||||
|
||||
man tdtool
|
||||
|
||||
TellStick is a trademark of Telldus Technologies AB
|
||||
131
telldus-core/client/CMakeLists.txt
Normal file
131
telldus-core/client/CMakeLists.txt
Normal file
@@ -0,0 +1,131 @@
|
||||
IF(COMMAND cmake_policy)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
ENDIF(COMMAND cmake_policy)
|
||||
|
||||
FIND_PACKAGE( SignTool REQUIRED )
|
||||
|
||||
######## Non configurable options ########
|
||||
SET( telldus-core_SRCS
|
||||
CallbackDispatcher.cpp
|
||||
CallbackMainDispatcher.cpp
|
||||
Client.cpp
|
||||
telldus-core.cpp
|
||||
)
|
||||
|
||||
SET( telldus-core_HDRS
|
||||
CallbackDispatcher.h
|
||||
CallbackMainDispatcher.cpp
|
||||
Client.h
|
||||
)
|
||||
SET( telldus-core_PUB_HDRS
|
||||
telldus-core.h
|
||||
)
|
||||
|
||||
FIND_PACKAGE(Threads)
|
||||
LIST(APPEND telldus-core_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
|
||||
|
||||
######## Configurable options for the platform ########
|
||||
|
||||
|
||||
|
||||
######## Platforms-specific, non configurable ########
|
||||
|
||||
IF (APPLE)
|
||||
#### Mac OS X ####
|
||||
SET( telldus-core_TARGET TelldusCore )
|
||||
ADD_DEFINITIONS(
|
||||
-D_MACOSX
|
||||
)
|
||||
LIST(APPEND telldus-core_LIBRARIES
|
||||
TelldusCommon
|
||||
)
|
||||
ELSEIF (WIN32)
|
||||
#### Windows ####
|
||||
ADD_DEFINITIONS( -DUNICODE )
|
||||
ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No
|
||||
SET( telldus-core_TARGET TelldusCore )
|
||||
LIST(APPEND telldus-core_LIBRARIES
|
||||
TelldusCommon
|
||||
)
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/telldus-core.rc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/telldus-core.rc
|
||||
)
|
||||
LIST(APPEND telldus-core_SRCS
|
||||
libtelldus-core.def
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/telldus-core.rc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/telldus-core.rc
|
||||
)
|
||||
ADD_DEFINITIONS(
|
||||
-D_WINDOWS
|
||||
-DTELLDUSCORE_EXPORTS
|
||||
)
|
||||
IF (CMAKE_CL_64)
|
||||
ADD_DEFINITIONS(-D_CL64)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
ELSE (APPLE)
|
||||
#### Linux ####
|
||||
SET( telldus-core_TARGET telldus-core )
|
||||
LIST(APPEND telldus-core_LIBRARIES
|
||||
TelldusCommon
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(
|
||||
-D_LINUX
|
||||
)
|
||||
ENDIF (APPLE)
|
||||
|
||||
|
||||
|
||||
######## Configuring ########
|
||||
|
||||
ADD_LIBRARY(${telldus-core_TARGET} SHARED
|
||||
${telldus-core_SRCS}
|
||||
${telldus-core_HDRS}
|
||||
${telldus-core_PUB_HDRS}
|
||||
)
|
||||
|
||||
#Copy public headers files on windows
|
||||
IF (WIN32)
|
||||
FOREACH(_FILE ${telldus-core_PUB_HDRS})
|
||||
ADD_CUSTOM_COMMAND( TARGET ${telldus-core_TARGET}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy \"${CMAKE_CURRENT_SOURCE_DIR}/${_FILE}\" \"${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}\"
|
||||
COMMENT "Copy ${_FILE}"
|
||||
)
|
||||
ENDFOREACH(_FILE)
|
||||
ENDIF ()
|
||||
|
||||
ADD_DEPENDENCIES(${telldus-core_TARGET} TelldusCommon)
|
||||
|
||||
IF (UNIX)
|
||||
SET_TARGET_PROPERTIES( ${telldus-core_TARGET} PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden")
|
||||
ENDIF (UNIX)
|
||||
|
||||
TARGET_LINK_LIBRARIES( ${telldus-core_TARGET} ${telldus-core_LIBRARIES} )
|
||||
|
||||
SET(telldus-core_TARGET ${telldus-core_TARGET} PARENT_SCOPE)
|
||||
SET_TARGET_PROPERTIES(${telldus-core_TARGET} PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
INSTALL_NAME_DIR "/Library/Frameworks"
|
||||
PUBLIC_HEADER ${telldus-core_PUB_HDRS}
|
||||
VERSION ${PACKAGE_VERSION}
|
||||
SOVERSION ${PACKAGE_SOVERSION}
|
||||
)
|
||||
SIGN(${telldus-core_TARGET})
|
||||
|
||||
IF (NOT LIB_INSTALL_DIR)
|
||||
SET(LIB_INSTALL_DIR "lib")
|
||||
ENDIF (NOT LIB_INSTALL_DIR)
|
||||
|
||||
IF (UNIX)
|
||||
INSTALL(TARGETS ${telldus-core_TARGET}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
FRAMEWORK DESTINATION "/Library/Frameworks"
|
||||
PUBLIC_HEADER DESTINATION include
|
||||
)
|
||||
ENDIF (UNIX)
|
||||
|
||||
139
telldus-core/client/CallbackDispatcher.cpp
Normal file
139
telldus-core/client/CallbackDispatcher.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* CallbackDispatcher.cpp
|
||||
* telldus-core
|
||||
*
|
||||
* Created by Micke Prag on 2010-11-02.
|
||||
* Copyright 2010 Telldus Technologies AB. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "client/CallbackDispatcher.h"
|
||||
#include "common/Event.h"
|
||||
#include "common/EventHandler.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class TDEventDispatcher::PrivateData {
|
||||
public:
|
||||
EventHandler eventHandler;
|
||||
EventRef stopEvent, callbackEvent;
|
||||
int id;
|
||||
void *func, *context;
|
||||
};
|
||||
|
||||
TDEventDispatcher::TDEventDispatcher(int id, void *func, void *context)
|
||||
:Thread() {
|
||||
d = new PrivateData;
|
||||
d->stopEvent = d->eventHandler.addEvent();
|
||||
d->callbackEvent = d->eventHandler.addEvent();
|
||||
d->id = id;
|
||||
d->func = func;
|
||||
d->context = context;
|
||||
this->start();
|
||||
}
|
||||
|
||||
TDEventDispatcher::~TDEventDispatcher() {
|
||||
d->stopEvent->signal();
|
||||
this->wait();
|
||||
delete d;
|
||||
}
|
||||
|
||||
int TDEventDispatcher::id() const {
|
||||
return d->id;
|
||||
}
|
||||
|
||||
void TDEventDispatcher::queue(EventDataRef eventData) {
|
||||
d->callbackEvent->signal(eventData);
|
||||
}
|
||||
|
||||
void TDEventDispatcher::run() {
|
||||
while (!d->stopEvent->isSignaled()) {
|
||||
d->eventHandler.waitForAny();
|
||||
if (d->callbackEvent->isSignaled()) {
|
||||
TelldusCore::EventDataRef eventData = d->callbackEvent->takeSignal();
|
||||
this->execute(eventData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TDDeviceEventDispatcher::TDDeviceEventDispatcher(int id, void *func, void *context)
|
||||
:TDEventDispatcher(id, func, context)
|
||||
{}
|
||||
|
||||
void TDDeviceEventDispatcher::execute(EventDataRef eventData) {
|
||||
DeviceEventCallbackData *data = dynamic_cast<DeviceEventCallbackData *>(eventData.get());
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
((TDDeviceEvent)d->func)(data->deviceId, data->deviceState, data->deviceStateValue.c_str(), d->id, d->context);
|
||||
}
|
||||
|
||||
CallbackStruct::CallbackType TDDeviceEventDispatcher::type() {
|
||||
return CallbackStruct::DeviceEvent;
|
||||
}
|
||||
|
||||
TDDeviceChangeEventDispatcher::TDDeviceChangeEventDispatcher(int id, void *func, void *context)
|
||||
:TDEventDispatcher(id, func, context)
|
||||
{}
|
||||
|
||||
void TDDeviceChangeEventDispatcher::execute(EventDataRef eventData) {
|
||||
DeviceChangeEventCallbackData *data = dynamic_cast<DeviceChangeEventCallbackData *>(eventData.get());
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
((TDDeviceChangeEvent)d->func)(data->deviceId, data->changeEvent, data->changeType, d->id, d->context);
|
||||
}
|
||||
|
||||
CallbackStruct::CallbackType TDDeviceChangeEventDispatcher::type() {
|
||||
return CallbackStruct::DeviceChangeEvent;
|
||||
}
|
||||
|
||||
TDRawDeviceEventDispatcher::TDRawDeviceEventDispatcher(int id, void *func, void *context)
|
||||
:TDEventDispatcher(id, func, context)
|
||||
{}
|
||||
|
||||
void TDRawDeviceEventDispatcher::execute(EventDataRef eventData) {
|
||||
RawDeviceEventCallbackData *data = dynamic_cast<RawDeviceEventCallbackData *>(eventData.get());
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
((TDRawDeviceEvent)d->func)(data->data.c_str(), data->controllerId, d->id, d->context);
|
||||
}
|
||||
|
||||
CallbackStruct::CallbackType TDRawDeviceEventDispatcher::type() {
|
||||
return CallbackStruct::RawDeviceEvent;
|
||||
}
|
||||
|
||||
TDSensorEventDispatcher::TDSensorEventDispatcher(int id, void *func, void *context)
|
||||
:TDEventDispatcher(id, func, context)
|
||||
{}
|
||||
|
||||
void TDSensorEventDispatcher::execute(EventDataRef eventData) {
|
||||
SensorEventCallbackData *data = dynamic_cast<SensorEventCallbackData *>(eventData.get());
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
((TDSensorEvent)d->func)(data->protocol.c_str(), data->model.c_str(), data->id, data->dataType, data->value.c_str(), data->timestamp, d->id, d->context);
|
||||
}
|
||||
|
||||
CallbackStruct::CallbackType TDSensorEventDispatcher::type() {
|
||||
return CallbackStruct::SensorEvent;
|
||||
}
|
||||
|
||||
TDControllerEventDispatcher::TDControllerEventDispatcher(int id, void *func, void *context)
|
||||
:TDEventDispatcher(id, func, context)
|
||||
{}
|
||||
|
||||
void TDControllerEventDispatcher::execute(EventDataRef eventData) {
|
||||
ControllerEventCallbackData *data = dynamic_cast<ControllerEventCallbackData *>(eventData.get());
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
((TDControllerEvent)d->func)(data->controllerId, data->changeEvent, data->changeType, data->newValue.c_str(), d->id, d->context);
|
||||
}
|
||||
|
||||
CallbackStruct::CallbackType TDControllerEventDispatcher::type() {
|
||||
return CallbackStruct::ControllerEvent;
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
129
telldus-core/client/CallbackDispatcher.h
Normal file
129
telldus-core/client/CallbackDispatcher.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* CallbackDispatcher.h
|
||||
* telldus-core
|
||||
*
|
||||
* Created by Micke Prag on 2010-11-02.
|
||||
* Copyright 2010 Telldus Technologies AB. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TELLDUS_CORE_CLIENT_CALLBACKDISPATCHER_H_
|
||||
#define TELLDUS_CORE_CLIENT_CALLBACKDISPATCHER_H_
|
||||
|
||||
#include <string>
|
||||
#include "common/common.h"
|
||||
#include "common/Event.h"
|
||||
#include "common/Thread.h"
|
||||
#include "common/Mutex.h"
|
||||
#include "client/telldus-core.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
struct CallbackStruct {
|
||||
enum CallbackType { DeviceEvent, DeviceChangeEvent, RawDeviceEvent, SensorEvent, ControllerEvent };
|
||||
CallbackType type;
|
||||
void *event;
|
||||
int id;
|
||||
void *context;
|
||||
TelldusCore::Mutex mutex;
|
||||
};
|
||||
|
||||
class CallbackData: public EventDataBase {
|
||||
public:
|
||||
explicit CallbackData(CallbackStruct::CallbackType t) : EventDataBase(), type(t) {}
|
||||
CallbackStruct::CallbackType type;
|
||||
};
|
||||
|
||||
class DeviceEventCallbackData : public CallbackData {
|
||||
public:
|
||||
DeviceEventCallbackData() : CallbackData(CallbackStruct::DeviceEvent) {}
|
||||
int deviceId;
|
||||
int deviceState;
|
||||
std::string deviceStateValue;
|
||||
};
|
||||
class DeviceChangeEventCallbackData : public CallbackData {
|
||||
public:
|
||||
DeviceChangeEventCallbackData() : CallbackData(CallbackStruct::DeviceChangeEvent) {}
|
||||
int deviceId;
|
||||
int changeEvent;
|
||||
int changeType;
|
||||
};
|
||||
|
||||
class RawDeviceEventCallbackData : public CallbackData {
|
||||
public:
|
||||
RawDeviceEventCallbackData() : CallbackData(CallbackStruct::RawDeviceEvent) {}
|
||||
std::string data;
|
||||
int controllerId;
|
||||
};
|
||||
|
||||
class SensorEventCallbackData : public CallbackData {
|
||||
public:
|
||||
SensorEventCallbackData() : CallbackData(CallbackStruct::SensorEvent) {}
|
||||
std::string protocol;
|
||||
std::string model;
|
||||
int id;
|
||||
int dataType;
|
||||
std::string value;
|
||||
int timestamp;
|
||||
};
|
||||
class ControllerEventCallbackData : public CallbackData {
|
||||
public:
|
||||
ControllerEventCallbackData() : CallbackData(CallbackStruct::ControllerEvent) {}
|
||||
int controllerId;
|
||||
int changeEvent;
|
||||
int changeType;
|
||||
std::string newValue;
|
||||
};
|
||||
|
||||
class TDEventDispatcher : public Thread {
|
||||
public:
|
||||
TDEventDispatcher(int id, void *func, void *context);
|
||||
virtual ~TDEventDispatcher();
|
||||
int id() const;
|
||||
void queue(EventDataRef eventData);
|
||||
virtual CallbackStruct::CallbackType type() = 0;
|
||||
protected:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
|
||||
virtual void run();
|
||||
virtual void execute(EventDataRef eventData) = 0;
|
||||
};
|
||||
class TDDeviceEventDispatcher : public TDEventDispatcher {
|
||||
public:
|
||||
TDDeviceEventDispatcher(int id, void *func, void *context);
|
||||
virtual CallbackStruct::CallbackType type();
|
||||
protected:
|
||||
virtual void execute(EventDataRef eventData);
|
||||
};
|
||||
class TDDeviceChangeEventDispatcher : public TDEventDispatcher {
|
||||
public:
|
||||
TDDeviceChangeEventDispatcher(int id, void *func, void *context);
|
||||
virtual CallbackStruct::CallbackType type();
|
||||
protected:
|
||||
virtual void execute(EventDataRef eventData);
|
||||
};
|
||||
class TDRawDeviceEventDispatcher : public TDEventDispatcher {
|
||||
public:
|
||||
TDRawDeviceEventDispatcher(int id, void *func, void *context);
|
||||
virtual CallbackStruct::CallbackType type();
|
||||
protected:
|
||||
virtual void execute(EventDataRef eventData);
|
||||
};
|
||||
class TDSensorEventDispatcher : public TDEventDispatcher {
|
||||
public:
|
||||
TDSensorEventDispatcher(int id, void *func, void *context);
|
||||
virtual CallbackStruct::CallbackType type();
|
||||
protected:
|
||||
virtual void execute(EventDataRef eventData);
|
||||
};
|
||||
class TDControllerEventDispatcher : public TDEventDispatcher {
|
||||
public:
|
||||
TDControllerEventDispatcher(int id, void *func, void *context);
|
||||
virtual CallbackStruct::CallbackType type();
|
||||
protected:
|
||||
virtual void execute(EventDataRef eventData);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_CLIENT_CALLBACKDISPATCHER_H_
|
||||
95
telldus-core/client/CallbackMainDispatcher.cpp
Normal file
95
telldus-core/client/CallbackMainDispatcher.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* CallbackMainDispatcher.cpp
|
||||
* telldus-core
|
||||
*
|
||||
* Created by Stefan Persson on 2012-02-23.
|
||||
* Copyright 2012 Telldus Technologies AB. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "client/CallbackMainDispatcher.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
typedef std::list<TelldusCore::TDEventDispatcher *> CallbackList;
|
||||
|
||||
class CallbackMainDispatcher::PrivateData {
|
||||
public:
|
||||
Mutex mutex;
|
||||
CallbackList callbackList;
|
||||
int lastCallbackId;
|
||||
};
|
||||
|
||||
CallbackMainDispatcher::CallbackMainDispatcher() {
|
||||
d = new PrivateData;
|
||||
d->lastCallbackId = 0;
|
||||
}
|
||||
|
||||
CallbackMainDispatcher::~CallbackMainDispatcher(void) {
|
||||
{
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
for(CallbackList::iterator it = d->callbackList.begin(); it != d->callbackList.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void CallbackMainDispatcher::execute(CallbackStruct::CallbackType type, EventData *eventData) {
|
||||
{
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
EventDataRef eventDataRef(eventData);
|
||||
for(CallbackList::iterator callback_it = d->callbackList.begin(); callback_it != d->callbackList.end(); ++callback_it) {
|
||||
if ( (*callback_it)->type() != type ) {
|
||||
continue;
|
||||
}
|
||||
(*callback_it)->queue(eventDataRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CallbackMainDispatcher::registerCallback(CallbackStruct::CallbackType type, void *eventFunction, void *context) {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
int id = ++d->lastCallbackId;
|
||||
TelldusCore::TDEventDispatcher *callback;
|
||||
if (type == CallbackStruct::DeviceEvent) {
|
||||
callback = new TelldusCore::TDDeviceEventDispatcher(id, eventFunction, context);
|
||||
} else if (type == CallbackStruct::DeviceChangeEvent) {
|
||||
callback = new TelldusCore::TDDeviceChangeEventDispatcher(id, eventFunction, context);
|
||||
} else if (type == CallbackStruct::RawDeviceEvent) {
|
||||
callback = new TelldusCore::TDRawDeviceEventDispatcher(id, eventFunction, context);
|
||||
} else if (type == CallbackStruct::SensorEvent) {
|
||||
callback = new TelldusCore::TDSensorEventDispatcher(id, eventFunction, context);
|
||||
} else if (type == CallbackStruct::ControllerEvent) {
|
||||
callback = new TelldusCore::TDControllerEventDispatcher(id, eventFunction, context);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
d->callbackList.push_back(callback);
|
||||
return id;
|
||||
}
|
||||
|
||||
int CallbackMainDispatcher::unregisterCallback(int callbackId) {
|
||||
CallbackList newEventList;
|
||||
{
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
for(CallbackList::iterator callback_it = d->callbackList.begin(); callback_it != d->callbackList.end(); ++callback_it) {
|
||||
if ( (*callback_it)->id() != callbackId ) {
|
||||
continue;
|
||||
}
|
||||
newEventList.splice(newEventList.begin(), d->callbackList, callback_it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newEventList.size()) {
|
||||
CallbackList::iterator it = newEventList.begin();
|
||||
delete (*it);
|
||||
newEventList.erase(it);
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
return TELLSTICK_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
35
telldus-core/client/CallbackMainDispatcher.h
Normal file
35
telldus-core/client/CallbackMainDispatcher.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* CallbackMainDispatcher.h
|
||||
* telldus-core
|
||||
*
|
||||
* Created by Stefan Persson on 2012-02-23.
|
||||
* Copyright 2012 Telldus Technologies AB. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALLBACKMAINDISPATCHER_H
|
||||
#define CALLBACKMAINDISPATCHER_H
|
||||
|
||||
#include "client/CallbackDispatcher.h"
|
||||
#include "common/Thread.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class CallbackMainDispatcher
|
||||
{
|
||||
public:
|
||||
CallbackMainDispatcher(void);
|
||||
~CallbackMainDispatcher(void);
|
||||
|
||||
void execute(TelldusCore::CallbackStruct::CallbackType type, EventData *eventData);
|
||||
|
||||
int registerCallback( TelldusCore::CallbackStruct::CallbackType type, void *eventFunction, void *context );
|
||||
int unregisterCallback( int callbackId );
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //CALLBACKMAINDISPATCHER_H
|
||||
269
telldus-core/client/Client.cpp
Normal file
269
telldus-core/client/Client.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "client/Client.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "client/CallbackDispatcher.h"
|
||||
#include "client/CallbackMainDispatcher.h"
|
||||
#include "common/Socket.h"
|
||||
#include "common/Strings.h"
|
||||
#include "common/Mutex.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class Client::PrivateData {
|
||||
public:
|
||||
Socket eventSocket;
|
||||
bool running, sensorCached, controllerCached;
|
||||
std::wstring sensorCache, controllerCache;
|
||||
TelldusCore::Mutex mutex;
|
||||
CallbackMainDispatcher callbackMainDispatcher;
|
||||
};
|
||||
|
||||
Client *Client::instance = 0;
|
||||
|
||||
Client::Client()
|
||||
: Thread() {
|
||||
d = new PrivateData;
|
||||
d->running = true;
|
||||
d->sensorCached = false;
|
||||
d->controllerCached = false;
|
||||
start();
|
||||
}
|
||||
|
||||
Client::~Client(void) {
|
||||
stopThread();
|
||||
wait();
|
||||
{
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Client::close() {
|
||||
if (Client::instance != 0) {
|
||||
delete Client::instance;
|
||||
Client::instance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Client *Client::getInstance() {
|
||||
if (Client::instance == 0) {
|
||||
Client::instance = new Client();
|
||||
}
|
||||
return Client::instance;
|
||||
}
|
||||
|
||||
bool Client::getBoolFromService(const Message &msg) {
|
||||
return getIntegerFromService(msg) == TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
int Client::getIntegerFromService(const Message &msg) {
|
||||
std::wstring response = sendToService(msg);
|
||||
if (response.compare(L"") == 0) {
|
||||
return TELLSTICK_ERROR_COMMUNICATING_SERVICE;
|
||||
}
|
||||
return Message::takeInt(&response);
|
||||
}
|
||||
|
||||
std::wstring Client::getWStringFromService(const Message &msg) {
|
||||
std::wstring response = sendToService(msg);
|
||||
return Message::takeString(&response);
|
||||
}
|
||||
|
||||
int Client::registerEvent( CallbackStruct::CallbackType type, void *eventFunction, void *context ) {
|
||||
return d->callbackMainDispatcher.registerCallback(type, eventFunction, context );
|
||||
}
|
||||
|
||||
void Client::run() {
|
||||
// listen here
|
||||
d->eventSocket.connect(L"TelldusEvents");
|
||||
|
||||
while(d->running) {
|
||||
if(!d->eventSocket.isConnected()) {
|
||||
d->eventSocket.connect(L"TelldusEvents"); // try to reconnect to service
|
||||
if(!d->eventSocket.isConnected()) {
|
||||
// reconnect didn't succeed, wait a while and try again
|
||||
msleep(2000);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring clientMessage = d->eventSocket.read(1000); // testing 5 second timeout
|
||||
|
||||
while(clientMessage != L"") {
|
||||
// a message arrived
|
||||
std::wstring type = Message::takeString(&clientMessage);
|
||||
if(type == L"TDDeviceChangeEvent") {
|
||||
DeviceChangeEventCallbackData *data = new DeviceChangeEventCallbackData();
|
||||
data->deviceId = Message::takeInt(&clientMessage);
|
||||
data->changeEvent = Message::takeInt(&clientMessage);
|
||||
data->changeType = Message::takeInt(&clientMessage);
|
||||
d->callbackMainDispatcher.execute(CallbackStruct::DeviceChangeEvent, data);
|
||||
|
||||
} else if(type == L"TDDeviceEvent") {
|
||||
DeviceEventCallbackData *data = new DeviceEventCallbackData();
|
||||
data->deviceId = Message::takeInt(&clientMessage);
|
||||
data->deviceState = Message::takeInt(&clientMessage);
|
||||
data->deviceStateValue = TelldusCore::wideToString(Message::takeString(&clientMessage));
|
||||
d->callbackMainDispatcher.execute(CallbackStruct::DeviceEvent, data);
|
||||
|
||||
} else if(type == L"TDRawDeviceEvent") {
|
||||
RawDeviceEventCallbackData *data = new RawDeviceEventCallbackData();
|
||||
data->data = TelldusCore::wideToString(Message::takeString(&clientMessage));
|
||||
data->controllerId = Message::takeInt(&clientMessage);
|
||||
d->callbackMainDispatcher.execute(CallbackStruct::RawDeviceEvent, data);
|
||||
|
||||
} else if(type == L"TDSensorEvent") {
|
||||
SensorEventCallbackData *data = new SensorEventCallbackData();
|
||||
data->protocol = TelldusCore::wideToString(Message::takeString(&clientMessage));
|
||||
data->model = TelldusCore::wideToString(Message::takeString(&clientMessage));
|
||||
data->id = Message::takeInt(&clientMessage);
|
||||
data->dataType = Message::takeInt(&clientMessage);
|
||||
data->value = TelldusCore::wideToString(Message::takeString(&clientMessage));
|
||||
data->timestamp = Message::takeInt(&clientMessage);
|
||||
d->callbackMainDispatcher.execute(CallbackStruct::SensorEvent, data);
|
||||
|
||||
} else if(type == L"TDControllerEvent") {
|
||||
ControllerEventCallbackData *data = new ControllerEventCallbackData();
|
||||
data->controllerId = Message::takeInt(&clientMessage);
|
||||
data->changeEvent = Message::takeInt(&clientMessage);
|
||||
data->changeType = Message::takeInt(&clientMessage);
|
||||
data->newValue = TelldusCore::wideToString(Message::takeString(&clientMessage));
|
||||
d->callbackMainDispatcher.execute(CallbackStruct::ControllerEvent, data);
|
||||
|
||||
} else {
|
||||
clientMessage = L""; // cleanup, if message contained garbage/unhandled data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring Client::sendToService(const Message &msg) {
|
||||
int tries = 0;
|
||||
std::wstring readData;
|
||||
while(tries < 20) {
|
||||
tries++;
|
||||
if(tries == 20) {
|
||||
TelldusCore::Message msg;
|
||||
msg.addArgument(TELLSTICK_ERROR_CONNECTING_SERVICE);
|
||||
return msg;
|
||||
}
|
||||
Socket s;
|
||||
s.connect(L"TelldusClient");
|
||||
if (!s.isConnected()) { // sConnection failed
|
||||
msleep(500);
|
||||
continue; // retry
|
||||
}
|
||||
s.write(msg.data());
|
||||
if (!s.isConnected()) { // Connection failed sometime during operation... (better check here, instead of 5 seconds timeout later)
|
||||
msleep(500);
|
||||
continue; // retry
|
||||
}
|
||||
readData = s.read(1000);
|
||||
if(readData == L"") {
|
||||
msleep(500);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!s.isConnected()) { // Connection failed sometime during operation...
|
||||
msleep(500);
|
||||
continue; // retry
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return readData;
|
||||
}
|
||||
|
||||
void Client::stopThread() {
|
||||
d->running = false;
|
||||
d->eventSocket.stopReadWait();
|
||||
}
|
||||
|
||||
int Client::unregisterCallback( int callbackId ) {
|
||||
return d->callbackMainDispatcher.unregisterCallback(callbackId);
|
||||
}
|
||||
|
||||
int Client::getSensor(char *protocol, int protocolLen, char *model, int modelLen, int *sensorId, int *dataTypes) {
|
||||
if (!d->sensorCached) {
|
||||
Message msg(L"tdSensor");
|
||||
std::wstring response = Client::getWStringFromService(msg);
|
||||
int count = Message::takeInt(&response);
|
||||
d->sensorCached = true;
|
||||
d->sensorCache = L"";
|
||||
if (count > 0) {
|
||||
d->sensorCache = response;
|
||||
}
|
||||
}
|
||||
|
||||
if (d->sensorCache == L"") {
|
||||
d->sensorCached = false;
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
std::wstring p = Message::takeString(&d->sensorCache);
|
||||
std::wstring m = Message::takeString(&d->sensorCache);
|
||||
int id = Message::takeInt(&d->sensorCache);
|
||||
int dt = Message::takeInt(&d->sensorCache);
|
||||
|
||||
if (protocol && protocolLen) {
|
||||
strncpy(protocol, TelldusCore::wideToString(p).c_str(), protocolLen);
|
||||
}
|
||||
if (model && modelLen) {
|
||||
strncpy(model, TelldusCore::wideToString(m).c_str(), modelLen);
|
||||
}
|
||||
if (sensorId) {
|
||||
(*sensorId) = id;
|
||||
}
|
||||
if (dataTypes) {
|
||||
(*dataTypes) = dt;
|
||||
}
|
||||
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
int Client::getController(int *controllerId, int *controllerType, char *name, int nameLen, int *available) {
|
||||
if (!d->controllerCached) {
|
||||
Message msg(L"tdController");
|
||||
std::wstring response = Client::getWStringFromService(msg);
|
||||
int count = Message::takeInt(&response);
|
||||
d->controllerCached = true;
|
||||
d->controllerCache = L"";
|
||||
if (count > 0) {
|
||||
d->controllerCache = response;
|
||||
}
|
||||
}
|
||||
|
||||
if (d->controllerCache == L"") {
|
||||
d->controllerCached = false;
|
||||
return TELLSTICK_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int id = Message::takeInt(&d->controllerCache);
|
||||
int type = Message::takeInt(&d->controllerCache);
|
||||
std::wstring n = Message::takeString(&d->controllerCache);
|
||||
int a = Message::takeInt(&d->controllerCache);
|
||||
|
||||
if (controllerId) {
|
||||
(*controllerId) = id;
|
||||
}
|
||||
if (controllerType) {
|
||||
(*controllerType) = type;
|
||||
}
|
||||
if (name && nameLen) {
|
||||
strncpy(name, TelldusCore::wideToString(n).c_str(), nameLen);
|
||||
}
|
||||
if (available) {
|
||||
(*available) = a;
|
||||
}
|
||||
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
47
telldus-core/client/Client.h
Normal file
47
telldus-core/client/Client.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_CLIENT_CLIENT_H_
|
||||
#define TELLDUS_CORE_CLIENT_CLIENT_H_
|
||||
|
||||
#include "client/telldus-core.h"
|
||||
#include "client/CallbackDispatcher.h"
|
||||
#include "common/Message.h"
|
||||
#include "common/Thread.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
class Client : public Thread {
|
||||
public:
|
||||
~Client(void);
|
||||
|
||||
static Client *getInstance();
|
||||
static void close();
|
||||
|
||||
int registerEvent(CallbackStruct::CallbackType type, void *eventFunction, void *context );
|
||||
void stopThread(void);
|
||||
int unregisterCallback( int callbackId );
|
||||
|
||||
int getSensor(char *protocol, int protocolLen, char *model, int modelLen, int *id, int *dataTypes);
|
||||
int getController(int *controllerId, int *controllerType, char *name, int nameLen, int *available);
|
||||
|
||||
static bool getBoolFromService(const Message &msg);
|
||||
static int getIntegerFromService(const Message &msg);
|
||||
static std::wstring getWStringFromService(const Message &msg);
|
||||
|
||||
protected:
|
||||
void run(void);
|
||||
|
||||
private:
|
||||
Client();
|
||||
static std::wstring sendToService(const Message &msg);
|
||||
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
static Client *instance;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_CLIENT_CLIENT_H_
|
||||
60
telldus-core/client/libtelldus-core.def
Normal file
60
telldus-core/client/libtelldus-core.def
Normal file
@@ -0,0 +1,60 @@
|
||||
LIBRARY tellduscore
|
||||
EXPORTS
|
||||
tdGetNumberOfDevices @1
|
||||
tdGetDeviceId @2
|
||||
|
||||
tdGetName @3
|
||||
tdGetProtocol @4
|
||||
tdGetModel @5
|
||||
tdGetDeviceParameter @6
|
||||
|
||||
tdSetName @7
|
||||
tdSetProtocol @8
|
||||
tdSetModel @9
|
||||
tdSetDeviceParameter @10
|
||||
|
||||
tdAddDevice @11
|
||||
tdRemoveDevice @12
|
||||
|
||||
tdMethods @13
|
||||
tdTurnOn @14
|
||||
tdTurnOff @15
|
||||
tdBell @16
|
||||
tdDim @17
|
||||
|
||||
tdGetErrorString @18
|
||||
|
||||
tdClose @19
|
||||
|
||||
tdInit @20
|
||||
tdRegisterDeviceEvent @21
|
||||
tdLastSentCommand @22
|
||||
tdGetDeviceType @23
|
||||
|
||||
tdSendRawCommand @24
|
||||
tdRegisterRawDeviceEvent @25
|
||||
|
||||
tdLearn @26
|
||||
tdLastSentValue @27
|
||||
|
||||
tdReleaseString @28
|
||||
tdUnregisterCallback @29
|
||||
|
||||
tdConnectTellStickController @30
|
||||
tdDisconnectTellStickController @31
|
||||
|
||||
tdRegisterDeviceChangeEvent @32
|
||||
tdExecute @33
|
||||
tdUp @34
|
||||
tdDown @35
|
||||
tdStop @36
|
||||
|
||||
tdRegisterSensorEvent @37
|
||||
tdSensor @38
|
||||
tdSensorValue @39
|
||||
|
||||
tdController @40
|
||||
tdControllerValue @41
|
||||
tdSetControllerValue @42
|
||||
tdRemoveController @43
|
||||
tdRegisterControllerEvent @44
|
||||
1296
telldus-core/client/telldus-core.cpp
Normal file
1296
telldus-core/client/telldus-core.cpp
Normal file
File diff suppressed because it is too large
Load Diff
166
telldus-core/client/telldus-core.h
Normal file
166
telldus-core/client/telldus-core.h
Normal file
@@ -0,0 +1,166 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_CLIENT_TELLDUS_CORE_H_
|
||||
#define TELLDUS_CORE_CLIENT_TELLDUS_CORE_H_
|
||||
|
||||
// The following ifdef block is the standard way of creating macros
|
||||
// which make exporting from a DLL simpler. All files within this DLL
|
||||
// are compiled with the TELLDUSCORE_EXPORTS symbol defined on the command line.
|
||||
// This symbol should not be defined on any project that uses this DLL.
|
||||
// This way any other project whose source files include this file see
|
||||
// TELLSTICK_API functions as being imported from a DLL, whereas this DLL
|
||||
// sees symbols defined with this macro as being exported.
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#if defined(TELLDUSCORE_EXPORTS)
|
||||
#if defined(_CL64)
|
||||
#define TELLSTICK_API
|
||||
#else
|
||||
#define TELLSTICK_API __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
#define TELLSTICK_API __declspec(dllimport)
|
||||
#endif
|
||||
#define WINAPI __stdcall
|
||||
#else
|
||||
#define WINAPI
|
||||
#define TELLSTICK_API __attribute__ ((visibility("default")))
|
||||
#endif
|
||||
|
||||
typedef void (WINAPI *TDDeviceEvent)(int deviceId, int method, const char *data, int callbackId, void *context);
|
||||
typedef void (WINAPI *TDDeviceChangeEvent)(int deviceId, int changeEvent, int changeType, int callbackId, void *context);
|
||||
typedef void (WINAPI *TDRawDeviceEvent)(const char *data, int controllerId, int callbackId, void *context);
|
||||
typedef void (WINAPI *TDSensorEvent)(const char *protocol, const char *model, int id, int dataType, const char *value, int timestamp, int callbackId, void *context);
|
||||
typedef void (WINAPI *TDControllerEvent)(int controllerId, int changeEvent, int changeType, const char *newValue, int callbackId, void *context);
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define bool char
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
TELLSTICK_API void WINAPI tdInit(void);
|
||||
TELLSTICK_API int WINAPI tdRegisterDeviceEvent( TDDeviceEvent eventFunction, void *context );
|
||||
TELLSTICK_API int WINAPI tdRegisterDeviceChangeEvent( TDDeviceChangeEvent eventFunction, void *context);
|
||||
TELLSTICK_API int WINAPI tdRegisterRawDeviceEvent( TDRawDeviceEvent eventFunction, void *context );
|
||||
TELLSTICK_API int WINAPI tdRegisterSensorEvent( TDSensorEvent eventFunction, void *context );
|
||||
TELLSTICK_API int WINAPI tdRegisterControllerEvent( TDControllerEvent eventFunction, void *context);
|
||||
TELLSTICK_API int WINAPI tdUnregisterCallback( int callbackId );
|
||||
TELLSTICK_API void WINAPI tdClose(void);
|
||||
TELLSTICK_API void WINAPI tdReleaseString(char *thestring);
|
||||
|
||||
TELLSTICK_API int WINAPI tdTurnOn(int intDeviceId);
|
||||
TELLSTICK_API int WINAPI tdTurnOff(int intDeviceId);
|
||||
TELLSTICK_API int WINAPI tdBell(int intDeviceId);
|
||||
TELLSTICK_API int WINAPI tdDim(int intDeviceId, unsigned char level);
|
||||
TELLSTICK_API int WINAPI tdExecute(int intDeviceId);
|
||||
TELLSTICK_API int WINAPI tdUp(int intDeviceId);
|
||||
TELLSTICK_API int WINAPI tdDown(int intDeviceId);
|
||||
TELLSTICK_API int WINAPI tdStop(int intDeviceId);
|
||||
TELLSTICK_API int WINAPI tdLearn(int intDeviceId);
|
||||
TELLSTICK_API int WINAPI tdMethods(int id, int methodsSupported);
|
||||
TELLSTICK_API int WINAPI tdLastSentCommand( int intDeviceId, int methodsSupported );
|
||||
TELLSTICK_API char *WINAPI tdLastSentValue( int intDeviceId );
|
||||
|
||||
TELLSTICK_API int WINAPI tdGetNumberOfDevices();
|
||||
TELLSTICK_API int WINAPI tdGetDeviceId(int intDeviceIndex);
|
||||
TELLSTICK_API int WINAPI tdGetDeviceType(int intDeviceId);
|
||||
|
||||
TELLSTICK_API char * WINAPI tdGetErrorString(int intErrorNo);
|
||||
|
||||
TELLSTICK_API char * WINAPI tdGetName(int intDeviceId);
|
||||
TELLSTICK_API bool WINAPI tdSetName(int intDeviceId, const char* chNewName);
|
||||
TELLSTICK_API char * WINAPI tdGetProtocol(int intDeviceId);
|
||||
TELLSTICK_API bool WINAPI tdSetProtocol(int intDeviceId, const char* strProtocol);
|
||||
TELLSTICK_API char * WINAPI tdGetModel(int intDeviceId);
|
||||
TELLSTICK_API bool WINAPI tdSetModel(int intDeviceId, const char *intModel);
|
||||
|
||||
TELLSTICK_API char * WINAPI tdGetDeviceParameter(int intDeviceId, const char *strName, const char *defaultValue);
|
||||
TELLSTICK_API bool WINAPI tdSetDeviceParameter(int intDeviceId, const char *strName, const char* strValue);
|
||||
|
||||
TELLSTICK_API int WINAPI tdAddDevice();
|
||||
TELLSTICK_API bool WINAPI tdRemoveDevice(int intDeviceId);
|
||||
|
||||
TELLSTICK_API int WINAPI tdSendRawCommand(const char *command, int reserved);
|
||||
|
||||
TELLSTICK_API void WINAPI tdConnectTellStickController(int vid, int pid, const char *serial);
|
||||
TELLSTICK_API void WINAPI tdDisconnectTellStickController(int vid, int pid, const char *serial);
|
||||
|
||||
TELLSTICK_API int WINAPI tdSensor(char *protocol, int protocolLen, char *model, int modelLen, int *id, int *dataTypes);
|
||||
TELLSTICK_API int WINAPI tdSensorValue(const char *protocol, const char *model, int id, int dataType, char *value, int len, int *timestamp);
|
||||
|
||||
TELLSTICK_API int WINAPI tdController(int *controllerId, int *controllerType, char *name, int nameLen, int *available);
|
||||
TELLSTICK_API int WINAPI tdControllerValue(int controllerId, const char *name, char *value, int valueLen);
|
||||
TELLSTICK_API int WINAPI tdSetControllerValue(int controllerId, const char *name, const char *value);
|
||||
TELLSTICK_API int WINAPI tdRemoveController(int controllerId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Device methods
|
||||
#define TELLSTICK_TURNON 1
|
||||
#define TELLSTICK_TURNOFF 2
|
||||
#define TELLSTICK_BELL 4
|
||||
#define TELLSTICK_TOGGLE 8
|
||||
#define TELLSTICK_DIM 16
|
||||
#define TELLSTICK_LEARN 32
|
||||
#define TELLSTICK_EXECUTE 64
|
||||
#define TELLSTICK_UP 128
|
||||
#define TELLSTICK_DOWN 256
|
||||
#define TELLSTICK_STOP 512
|
||||
|
||||
// Sensor value types
|
||||
#define TELLSTICK_TEMPERATURE 1
|
||||
#define TELLSTICK_HUMIDITY 2
|
||||
#define TELLSTICK_RAINRATE 4
|
||||
#define TELLSTICK_RAINTOTAL 8
|
||||
#define TELLSTICK_WINDDIRECTION 16
|
||||
#define TELLSTICK_WINDAVERAGE 32
|
||||
#define TELLSTICK_WINDGUST 64
|
||||
|
||||
// Error codes
|
||||
#define TELLSTICK_SUCCESS 0
|
||||
#define TELLSTICK_ERROR_NOT_FOUND -1
|
||||
#define TELLSTICK_ERROR_PERMISSION_DENIED -2
|
||||
#define TELLSTICK_ERROR_DEVICE_NOT_FOUND -3
|
||||
#define TELLSTICK_ERROR_METHOD_NOT_SUPPORTED -4
|
||||
#define TELLSTICK_ERROR_COMMUNICATION -5
|
||||
#define TELLSTICK_ERROR_CONNECTING_SERVICE -6
|
||||
#define TELLSTICK_ERROR_UNKNOWN_RESPONSE -7
|
||||
#define TELLSTICK_ERROR_SYNTAX -8
|
||||
#define TELLSTICK_ERROR_BROKEN_PIPE -9
|
||||
#define TELLSTICK_ERROR_COMMUNICATING_SERVICE -10
|
||||
#define TELLSTICK_ERROR_CONFIG_SYNTAX -11
|
||||
#define TELLSTICK_ERROR_UNKNOWN -99
|
||||
|
||||
// Device typedef
|
||||
#define TELLSTICK_TYPE_DEVICE 1
|
||||
#define TELLSTICK_TYPE_GROUP 2
|
||||
#define TELLSTICK_TYPE_SCENE 3
|
||||
|
||||
// Controller typedef
|
||||
#define TELLSTICK_CONTROLLER_TELLSTICK 1
|
||||
#define TELLSTICK_CONTROLLER_TELLSTICK_DUO 2
|
||||
#define TELLSTICK_CONTROLLER_TELLSTICK_NET 3
|
||||
|
||||
// Device changes
|
||||
#define TELLSTICK_DEVICE_ADDED 1
|
||||
#define TELLSTICK_DEVICE_CHANGED 2
|
||||
#define TELLSTICK_DEVICE_REMOVED 3
|
||||
#define TELLSTICK_DEVICE_STATE_CHANGED 4
|
||||
|
||||
// Change types
|
||||
#define TELLSTICK_CHANGE_NAME 1
|
||||
#define TELLSTICK_CHANGE_PROTOCOL 2
|
||||
#define TELLSTICK_CHANGE_MODEL 3
|
||||
#define TELLSTICK_CHANGE_METHOD 4
|
||||
#define TELLSTICK_CHANGE_AVAILABLE 5
|
||||
#define TELLSTICK_CHANGE_FIRMWARE 6
|
||||
|
||||
#endif // TELLDUS_CORE_CLIENT_TELLDUS_CORE_H_
|
||||
18
telldus-core/client/telldus-core.rc.in
Normal file
18
telldus-core/client/telldus-core.rc.in
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <winresrc.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION ${PACKAGE_MAJOR_VERSION},${PACKAGE_MINOR_VERSION},${PACKAGE_PATCH_VERSION},0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "04090000"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "Utilities and driver to control wireless receivers through a TellStick"
|
||||
VALUE "FileVersion", "${PACKAGE_VERSION}"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2010 Telldus Technologies AB"
|
||||
VALUE "OriginalFilename", "TelldusCore.dll"
|
||||
VALUE "ProductName", "TelldusCore"
|
||||
VALUE "ProductVersion", "${PACKAGE_MAJOR_VERSION}.${PACKAGE_MINOR_VERSION}"
|
||||
END
|
||||
END
|
||||
END
|
||||
19
telldus-core/cmake/FindSignTool.cmake
Normal file
19
telldus-core/cmake/FindSignTool.cmake
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
IF(WIN32)
|
||||
SET(SIGN_FILES FALSE CACHE BOOL "Sign the generated files. This requires a certificate to be installed on the computer!")
|
||||
ENDIF()
|
||||
|
||||
FUNCTION(SIGN TARGET)
|
||||
IF (NOT WIN32)
|
||||
RETURN()
|
||||
ENDIF()
|
||||
IF (NOT SIGN_FILES)
|
||||
RETURN()
|
||||
ENDIF()
|
||||
GET_TARGET_PROPERTY(file ${TARGET} LOCATION)
|
||||
GET_FILENAME_COMPONENT(filename ${file} NAME)
|
||||
ADD_CUSTOM_COMMAND( TARGET ${TARGET} POST_BUILD
|
||||
COMMAND signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll ${file}
|
||||
COMMENT "Signing file ${filename}"
|
||||
)
|
||||
ENDFUNCTION()
|
||||
89
telldus-core/common/CMakeLists.txt
Normal file
89
telldus-core/common/CMakeLists.txt
Normal file
@@ -0,0 +1,89 @@
|
||||
IF(COMMAND cmake_policy)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
ENDIF(COMMAND cmake_policy)
|
||||
|
||||
######## Non configurable options ########
|
||||
SET( telldus-common_SRCS
|
||||
Event.cpp
|
||||
Message.cpp
|
||||
Mutex.cpp
|
||||
Strings.cpp
|
||||
Thread.cpp
|
||||
)
|
||||
|
||||
SET( telldus-common_HDRS
|
||||
common.h
|
||||
Event.h
|
||||
EventHandler.h
|
||||
Message.h
|
||||
Mutex.h
|
||||
Socket.h
|
||||
Strings.h
|
||||
Thread.h
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} )
|
||||
|
||||
######## Configurable options for the platform ########
|
||||
|
||||
|
||||
######## Platforms-specific, non configurable ########
|
||||
|
||||
IF (APPLE)
|
||||
#### Mac OS X ####
|
||||
FIND_LIBRARY(ICONV_LIBRARY iconv)
|
||||
ADD_DEFINITIONS( -D_MACOSX )
|
||||
LIST(APPEND telldus-common_SRCS
|
||||
Event_unix.cpp
|
||||
EventHandler_unix.cpp
|
||||
Socket_unix.cpp
|
||||
stdlibc_workaround.cpp #Remove this when we drop support for 10.5
|
||||
)
|
||||
LIST(APPEND telldus-common_LIBRARIES
|
||||
${ICONV_LIBRARY}
|
||||
)
|
||||
ELSEIF (WIN32)
|
||||
#### Windows ####
|
||||
ADD_DEFINITIONS( -DUNICODE )
|
||||
ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No
|
||||
ADD_DEFINITIONS( -D_WINDOWS )
|
||||
LIST(APPEND telldus-common_SRCS
|
||||
Event_win.cpp
|
||||
EventHandler_win.cpp
|
||||
Socket_win.cpp
|
||||
)
|
||||
ELSEIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
#### FreeBSD ####
|
||||
FIND_LIBRARY(ICONV_LIBRARY iconv)
|
||||
ADD_DEFINITIONS( -D_FREEBSD )
|
||||
LIST(APPEND telldus-common_SRCS
|
||||
Event_unix.cpp
|
||||
EventHandler_unix.cpp
|
||||
Socket_unix.cpp
|
||||
)
|
||||
LIST(APPEND telldus-common_LIBRARIES
|
||||
${ICONV_LIBRARY}
|
||||
)
|
||||
ELSE (APPLE)
|
||||
#### Linux ####
|
||||
ADD_DEFINITIONS( -D_LINUX )
|
||||
LIST(APPEND telldus-common_SRCS
|
||||
Event_unix.cpp
|
||||
EventHandler_unix.cpp
|
||||
Socket_unix.cpp
|
||||
)
|
||||
ENDIF (APPLE)
|
||||
|
||||
|
||||
######## Configuring ########
|
||||
|
||||
ADD_LIBRARY(TelldusCommon STATIC
|
||||
${telldus-common_SRCS}
|
||||
${telldus-common_HDRS}
|
||||
)
|
||||
|
||||
IF (UNIX)
|
||||
SET_TARGET_PROPERTIES( TelldusCommon PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden")
|
||||
ENDIF (UNIX)
|
||||
|
||||
TARGET_LINK_LIBRARIES( TelldusCommon ${telldus-common_LIBRARIES} )
|
||||
88
telldus-core/common/Event.cpp
Normal file
88
telldus-core/common/Event.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "common/Event.h"
|
||||
#include <list>
|
||||
#include "common/EventHandler.h"
|
||||
#include "common/Mutex.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
EventData::~EventData() {
|
||||
}
|
||||
|
||||
bool EventData::isValid() const {
|
||||
return false;
|
||||
};
|
||||
|
||||
bool EventDataBase::isValid() const {
|
||||
return true;
|
||||
};
|
||||
|
||||
class EventBase::PrivateData {
|
||||
public:
|
||||
TelldusCore::Mutex mutex;
|
||||
EventHandler *handler;
|
||||
std::list<EventDataRef> eventDataList;
|
||||
};
|
||||
|
||||
EventBase::EventBase(TelldusCore::EventHandler *handler) {
|
||||
d = new PrivateData;
|
||||
d->handler = handler;
|
||||
}
|
||||
|
||||
EventBase::~EventBase(void) {
|
||||
delete d;
|
||||
}
|
||||
|
||||
void EventBase::clearHandler() {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
d->handler = 0;
|
||||
}
|
||||
|
||||
void EventBase::popSignal() {
|
||||
this->takeSignal();
|
||||
}
|
||||
|
||||
EventHandler *EventBase::handler() const {
|
||||
return d->handler;
|
||||
}
|
||||
|
||||
bool EventBase::isSignaled() {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
return (d->eventDataList.size() > 0);
|
||||
}
|
||||
|
||||
void EventBase::signal() {
|
||||
signal(new EventData());
|
||||
}
|
||||
|
||||
void EventBase::signal(EventData *eventData) {
|
||||
this->signal(EventDataRef(eventData));
|
||||
}
|
||||
|
||||
void EventBase::signal(EventDataRef eventData) {
|
||||
{
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
d->eventDataList.push_back(eventData);
|
||||
}
|
||||
sendSignal();
|
||||
}
|
||||
|
||||
EventDataRef EventBase::takeSignal() {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
if (d->eventDataList.size() == 0) {
|
||||
return EventDataRef(new EventData());
|
||||
}
|
||||
EventDataRef data = d->eventDataList.front();
|
||||
d->eventDataList.pop_front();
|
||||
if (d->eventDataList.size() == 0) {
|
||||
this->clearSignal();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
80
telldus-core/common/Event.h
Normal file
80
telldus-core/common/Event.h
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_COMMON_EVENT_H_
|
||||
#define TELLDUS_CORE_COMMON_EVENT_H_
|
||||
|
||||
|
||||
#ifndef _WINDOWS
|
||||
#include <tr1/memory>
|
||||
typedef void* EVENT_T;
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <memory>
|
||||
typedef HANDLE EVENT_T;
|
||||
#endif
|
||||
#include "common/Thread.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
class EventHandler;
|
||||
|
||||
class EventData {
|
||||
public:
|
||||
virtual ~EventData();
|
||||
virtual bool isValid() const;
|
||||
};
|
||||
|
||||
class EventDataBase : public EventData {
|
||||
public:
|
||||
virtual bool isValid() const;
|
||||
};
|
||||
|
||||
typedef std::tr1::shared_ptr<EventData> EventDataRef;
|
||||
|
||||
class EventBase {
|
||||
public:
|
||||
virtual ~EventBase();
|
||||
|
||||
void popSignal();
|
||||
bool isSignaled();
|
||||
void signal();
|
||||
void signal(EventData *eventData);
|
||||
void signal(EventDataRef eventData);
|
||||
EventDataRef takeSignal();
|
||||
|
||||
protected:
|
||||
explicit EventBase(EventHandler *handler);
|
||||
void clearHandler();
|
||||
virtual void clearSignal() = 0;
|
||||
EventHandler *handler() const;
|
||||
virtual void sendSignal() = 0;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
class Event : public EventBase {
|
||||
public:
|
||||
virtual ~Event();
|
||||
|
||||
protected:
|
||||
explicit Event(EventHandler *handler);
|
||||
EVENT_T retrieveNative();
|
||||
virtual void clearSignal();
|
||||
virtual void sendSignal();
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
|
||||
friend class EventHandler;
|
||||
};
|
||||
|
||||
typedef std::tr1::shared_ptr<Event> EventRef;
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_COMMON_EVENT_H_
|
||||
39
telldus-core/common/EventHandler.h
Normal file
39
telldus-core/common/EventHandler.h
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_COMMON_EVENTHANDLER_H_
|
||||
#define TELLDUS_CORE_COMMON_EVENTHANDLER_H_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include "common/Event.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class EventHandler {
|
||||
public:
|
||||
EventHandler();
|
||||
virtual ~EventHandler(void);
|
||||
|
||||
EventRef addEvent();
|
||||
|
||||
bool waitForAny();
|
||||
|
||||
protected:
|
||||
void signal(Event *event);
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
bool listIsSignalled();
|
||||
friend class Event;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_COMMON_EVENTHANDLER_H_
|
||||
96
telldus-core/common/EventHandler_unix.cpp
Normal file
96
telldus-core/common/EventHandler_unix.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <list>
|
||||
#include "common/EventHandler.h"
|
||||
#include "common/Event.h"
|
||||
#include "common/Mutex.h"
|
||||
#include "common/Thread.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class EventHandler::PrivateData {
|
||||
public:
|
||||
pthread_cond_t event;
|
||||
pthread_mutex_t mutex;
|
||||
std::list<EventRef> eventList;
|
||||
TelldusCore::Mutex listMutex;
|
||||
bool isSignalled;
|
||||
};
|
||||
|
||||
EventHandler::EventHandler() {
|
||||
d = new PrivateData;
|
||||
pthread_cond_init(&d->event, NULL);
|
||||
pthread_cond_init(&d->event, NULL);
|
||||
pthread_mutex_init(&d->mutex, NULL);
|
||||
d->isSignalled = false;
|
||||
}
|
||||
|
||||
EventHandler::~EventHandler(void) {
|
||||
pthread_mutex_destroy(&d->mutex);
|
||||
pthread_cond_destroy(&d->event);
|
||||
|
||||
std::list<EventRef>::const_iterator it = d->eventList.begin();
|
||||
for(; it != d->eventList.end(); ++it) {
|
||||
// We clear the handler if someone else still has a reference to the event
|
||||
(*it)->clearHandler();
|
||||
}
|
||||
|
||||
delete d;
|
||||
}
|
||||
|
||||
EventRef EventHandler::addEvent() {
|
||||
EventRef event(new Event(this));
|
||||
TelldusCore::MutexLocker locker(&d->listMutex);
|
||||
d->eventList.push_back(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
bool EventHandler::listIsSignalled() {
|
||||
TelldusCore::MutexLocker locker(&d->listMutex);
|
||||
|
||||
std::list<EventRef>::const_iterator it = d->eventList.begin();
|
||||
for(; it != d->eventList.end(); ++it) {
|
||||
if((*it)->isSignaled()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EventHandler::signal(Event *event) {
|
||||
pthread_mutex_lock(&d->mutex);
|
||||
d->isSignalled = true;
|
||||
// event->setSignaled();
|
||||
pthread_cond_signal(&d->event);
|
||||
pthread_mutex_unlock(&d->mutex);
|
||||
}
|
||||
|
||||
bool EventHandler::waitForAny() {
|
||||
pthread_mutex_lock(&d->mutex);
|
||||
int ret;
|
||||
while (!d->isSignalled) {
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
uint64_t abstime_ns_large = now.tv_usec*1000 + 60000000000; // add 60 seconds wait (5 seconds before)?
|
||||
timespec abstime = { now.tv_sec + (abstime_ns_large / 1000000000), abstime_ns_large % 1000000000 };
|
||||
ret = pthread_cond_timedwait(&d->event, &d->mutex, &abstime);
|
||||
if (ret == ETIMEDOUT) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!listIsSignalled()) {
|
||||
d->isSignalled = false;
|
||||
}
|
||||
pthread_mutex_unlock(&d->mutex);
|
||||
return listIsSignalled();
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
76
telldus-core/common/EventHandler_win.cpp
Normal file
76
telldus-core/common/EventHandler_win.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "common/EventHandler.h"
|
||||
#include <windows.h>
|
||||
#include <list>
|
||||
|
||||
#include "common/Event.h"
|
||||
#include "common/Mutex.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class EventHandler::PrivateData {
|
||||
public:
|
||||
HANDLE *eventArray;
|
||||
EventRef *eventObjectArray;
|
||||
TelldusCore::Mutex mutex;
|
||||
int eventCount;
|
||||
};
|
||||
|
||||
EventHandler::EventHandler() {
|
||||
d = new PrivateData;
|
||||
d->eventCount = 0;
|
||||
d->eventArray = new HANDLE[0];
|
||||
d->eventObjectArray = new EventRef[0];
|
||||
}
|
||||
|
||||
EventHandler::~EventHandler(void) {
|
||||
delete[] d->eventObjectArray;
|
||||
delete[] d->eventArray;
|
||||
delete d;
|
||||
}
|
||||
|
||||
EventRef EventHandler::addEvent() {
|
||||
EventRef event(new Event(this));
|
||||
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
|
||||
HANDLE *newArray = new HANDLE[d->eventCount+1];
|
||||
EventRef *newObjectArray = new EventRef[d->eventCount+1];
|
||||
for (int i = 0; i < d->eventCount; ++i) {
|
||||
newArray[i] = d->eventArray[i];
|
||||
newObjectArray[i] = d->eventObjectArray[i];
|
||||
}
|
||||
delete[] d->eventArray;
|
||||
delete[] d->eventObjectArray;
|
||||
d->eventArray = newArray;
|
||||
d->eventObjectArray = newObjectArray;
|
||||
d->eventArray[d->eventCount] = event->retrieveNative();
|
||||
d->eventObjectArray[d->eventCount] = event;
|
||||
++d->eventCount;
|
||||
return event;
|
||||
}
|
||||
|
||||
void EventHandler::signal(Event *event) {
|
||||
}
|
||||
|
||||
bool EventHandler::waitForAny() {
|
||||
while(1) {
|
||||
int result = WaitForMultipleObjects(d->eventCount, d->eventArray, FALSE, 1000);
|
||||
if (result == WAIT_TIMEOUT) {
|
||||
continue;
|
||||
}
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
int eventIndex = result - WAIT_OBJECT_0;
|
||||
if (eventIndex >= d->eventCount) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
36
telldus-core/common/Event_unix.cpp
Normal file
36
telldus-core/common/Event_unix.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "common/Event.h"
|
||||
#include "common/EventHandler.h"
|
||||
#include "common/Thread.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class Event::PrivateData {
|
||||
public:
|
||||
};
|
||||
|
||||
Event::Event(EventHandler *handler)
|
||||
:EventBase(handler) {
|
||||
d = new PrivateData;
|
||||
}
|
||||
|
||||
Event::~Event(void) {
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Event::clearSignal() {
|
||||
}
|
||||
|
||||
void Event::sendSignal() {
|
||||
EventHandler *handler = this->handler();
|
||||
if (handler) {
|
||||
handler->signal(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
40
telldus-core/common/Event_win.cpp
Normal file
40
telldus-core/common/Event_win.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "common/Event.h"
|
||||
#include "common/Thread.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class Event::PrivateData {
|
||||
public:
|
||||
EVENT_T event;
|
||||
};
|
||||
|
||||
Event::Event(EventHandler *handler)
|
||||
:EventBase(handler) {
|
||||
d = new PrivateData;
|
||||
d->event = CreateEvent(NULL, true, false, NULL);
|
||||
}
|
||||
|
||||
Event::~Event(void) {
|
||||
CloseHandle(d->event);
|
||||
delete d;
|
||||
}
|
||||
|
||||
EVENT_T Event::retrieveNative() {
|
||||
return d->event;
|
||||
}
|
||||
|
||||
void Event::clearSignal() {
|
||||
ResetEvent(d->event);
|
||||
}
|
||||
|
||||
void Event::sendSignal() {
|
||||
SetEvent(d->event);
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
131
telldus-core/common/Message.cpp
Normal file
131
telldus-core/common/Message.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "common/Message.h"
|
||||
#include <wctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
#include "common/Socket.h"
|
||||
#include "common/Strings.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
Message::Message()
|
||||
: std::wstring() {
|
||||
}
|
||||
|
||||
Message::Message(const std::wstring &functionName)
|
||||
:std::wstring() {
|
||||
this->addArgument(functionName);
|
||||
}
|
||||
|
||||
Message::~Message(void) {
|
||||
}
|
||||
|
||||
void Message::addArgument(const std::wstring &value) {
|
||||
// std::wstringstream st;
|
||||
// st << (int)value.size();
|
||||
this->append(TelldusCore::intToWstring(value.size())); // st.str());
|
||||
this->append(L":");
|
||||
this->append(value);
|
||||
}
|
||||
|
||||
void Message::addArgument(int value) {
|
||||
// std::wstringstream st;
|
||||
// st << (int)value;
|
||||
this->append(L"i");
|
||||
this->append(TelldusCore::intToWstring(value)); // st.str());
|
||||
this->append(L"s");
|
||||
}
|
||||
|
||||
/*
|
||||
void Message::addSpecialArgument(const std::wstring &value){
|
||||
int i = 0;
|
||||
while(i<1000000){
|
||||
i++;
|
||||
|
||||
char numstr[21]; // enough to hold all numbers up to 64-bits
|
||||
//sprintf(numstr, "%d", value.size());
|
||||
//this->append(TelldusCore::charToWstring(numstr)); //.str());
|
||||
|
||||
itoa(value.size(), numstr, 10);
|
||||
std::string test(numstr);
|
||||
std::wstring temp(test.length(), L' ');
|
||||
std::copy(test.begin(), test.end(), temp.begin());
|
||||
|
||||
this->append(temp);
|
||||
this->append(L":");
|
||||
this->append(value);
|
||||
|
||||
|
||||
std::wstringstream st;
|
||||
st << (int)value.size();
|
||||
this->append(st.str());
|
||||
this->append(L":");
|
||||
this->append(value);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Message::addSpecialArgument(int value){
|
||||
int i = 0;
|
||||
while(i<1000000){
|
||||
i++;
|
||||
//std::wstringstream st;
|
||||
//st << (int)value;
|
||||
this->append(L"i");
|
||||
//this->append(st.str());
|
||||
this->append(L"s");
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void Message::addSpecialArgument(const char *value){
|
||||
this->addSpecialArgument(TelldusCore::charToWstring(value));
|
||||
}
|
||||
*/
|
||||
|
||||
void Message::addArgument(const char *value) {
|
||||
this->addArgument(TelldusCore::charToWstring(value));
|
||||
}
|
||||
|
||||
bool Message::nextIsInt(const std::wstring &message) {
|
||||
if (message.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
return (message.at(0) == 'i');
|
||||
}
|
||||
|
||||
bool Message::nextIsString(const std::wstring &message) {
|
||||
if (message.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
return (iswdigit(message.at(0)) != 0);
|
||||
}
|
||||
|
||||
std::wstring Message::takeString(std::wstring *message) {
|
||||
if (!Message::nextIsString(*message)) {
|
||||
return L"";
|
||||
}
|
||||
size_t index = message->find(':');
|
||||
int length = wideToInteger(message->substr(0, index));
|
||||
std::wstring retval(message->substr(index+1, length));
|
||||
message->erase(0, index+length+1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int Message::takeInt(std::wstring *message) {
|
||||
if (!Message::nextIsInt(*message)) {
|
||||
return 0;
|
||||
}
|
||||
size_t index = message->find('s');
|
||||
int value = wideToInteger(message->substr(1, index - 1));
|
||||
message->erase(0, index+1);
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
36
telldus-core/common/Message.h
Normal file
36
telldus-core/common/Message.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_COMMON_MESSAGE_H_
|
||||
#define TELLDUS_CORE_COMMON_MESSAGE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace TelldusCore {
|
||||
class Message : public std::wstring {
|
||||
public:
|
||||
Message();
|
||||
explicit Message(const std::wstring &functionName);
|
||||
~Message(void);
|
||||
|
||||
void addArgument(const std::wstring &value);
|
||||
// void addSpecialArgument(const std::wstring &);
|
||||
// void addSpecialArgument(int);
|
||||
// void addSpecialArgument(const char *);
|
||||
void addArgument(int value);
|
||||
void addArgument(const char *value);
|
||||
|
||||
static bool nextIsInt(const std::wstring &message);
|
||||
static bool nextIsString(const std::wstring &message);
|
||||
|
||||
static std::wstring takeString(std::wstring *message);
|
||||
static int takeInt(std::wstring *message);
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_COMMON_MESSAGE_H_
|
||||
88
telldus-core/common/Mutex.cpp
Normal file
88
telldus-core/common/Mutex.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// C++ Implementation: Thread
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
|
||||
#include "common/Mutex.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
typedef HANDLE MUTEX_T;
|
||||
#else
|
||||
#include <pthread.h>
|
||||
typedef pthread_mutex_t MUTEX_T;
|
||||
#endif
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class Mutex::PrivateData {
|
||||
public:
|
||||
MUTEX_T mutex;
|
||||
};
|
||||
|
||||
Mutex::Mutex() {
|
||||
d = new PrivateData;
|
||||
#ifdef _WINDOWS
|
||||
d->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
#else
|
||||
pthread_mutex_init(&d->mutex, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
Mutex::~Mutex() {
|
||||
#ifdef _WINDOWS
|
||||
CloseHandle(d->mutex);
|
||||
#else
|
||||
pthread_mutex_destroy(&d->mutex);
|
||||
#endif
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Mutex::lock() {
|
||||
#ifdef _WINDOWS
|
||||
WaitForSingleObject(d->mutex, INFINITE);
|
||||
#else
|
||||
pthread_mutex_lock(&d->mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Mutex::unlock() {
|
||||
#ifdef _WINDOWS
|
||||
ReleaseMutex(d->mutex);
|
||||
#else
|
||||
pthread_mutex_unlock(&d->mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void LoggedMutex::lock() {
|
||||
debuglog(0, "Locking");
|
||||
Mutex::lock();
|
||||
debuglog(0, "Locked");
|
||||
}
|
||||
|
||||
void LoggedMutex::unlock() {
|
||||
debuglog(0, "Unlocking");
|
||||
Mutex::unlock();
|
||||
debuglog(0, "Unlocked");
|
||||
}
|
||||
|
||||
MutexLocker::MutexLocker(Mutex *m)
|
||||
:mutex(m) {
|
||||
mutex->lock();
|
||||
}
|
||||
|
||||
MutexLocker::~MutexLocker() {
|
||||
mutex->unlock();
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
45
telldus-core/common/Mutex.h
Normal file
45
telldus-core/common/Mutex.h
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// C++ Interface: Thread
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2010
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_COMMON_MUTEX_H_
|
||||
#define TELLDUS_CORE_COMMON_MUTEX_H_
|
||||
|
||||
namespace TelldusCore {
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex();
|
||||
virtual ~Mutex();
|
||||
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
|
||||
private:
|
||||
Mutex(const Mutex&); // Disable copy
|
||||
Mutex& operator = (const Mutex&);
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
class LoggedMutex : public Mutex {
|
||||
public:
|
||||
void lock();
|
||||
void unlock();
|
||||
};
|
||||
|
||||
class MutexLocker {
|
||||
public:
|
||||
explicit MutexLocker(Mutex *m);
|
||||
~MutexLocker();
|
||||
private:
|
||||
Mutex *mutex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_COMMON_MUTEX_H_
|
||||
39
telldus-core/common/Socket.h
Normal file
39
telldus-core/common/Socket.h
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_COMMON_SOCKET_H_
|
||||
#define TELLDUS_CORE_COMMON_SOCKET_H_
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
typedef HANDLE SOCKET_T;
|
||||
#else
|
||||
typedef int SOCKET_T;
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace TelldusCore {
|
||||
class Socket {
|
||||
public:
|
||||
Socket();
|
||||
explicit Socket(SOCKET_T hPipe);
|
||||
virtual ~Socket(void);
|
||||
|
||||
void connect(const std::wstring &server);
|
||||
bool isConnected();
|
||||
std::wstring read();
|
||||
std::wstring read(int timeout);
|
||||
void stopReadWait();
|
||||
void write(const std::wstring &msg);
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_COMMON_SOCKET_H_
|
||||
144
telldus-core/common/Socket_unix.cpp
Normal file
144
telldus-core/common/Socket_unix.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
|
||||
#include "common/Socket.h"
|
||||
#include "common/Mutex.h"
|
||||
#include "common/Strings.h"
|
||||
|
||||
#define BUFSIZE 512
|
||||
#if defined(_MACOSX) && !defined(SOCK_CLOEXEC)
|
||||
#define SOCK_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
int connectWrapper(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
return connect(sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
class Socket::PrivateData {
|
||||
public:
|
||||
SOCKET_T socket;
|
||||
bool connected;
|
||||
fd_set infds;
|
||||
Mutex mutex;
|
||||
};
|
||||
|
||||
Socket::Socket() {
|
||||
d = new PrivateData;
|
||||
d->socket = 0;
|
||||
d->connected = false;
|
||||
FD_ZERO(&d->infds);
|
||||
}
|
||||
|
||||
Socket::Socket(SOCKET_T socket) {
|
||||
d = new PrivateData;
|
||||
d->socket = socket;
|
||||
FD_ZERO(&d->infds);
|
||||
d->connected = true;
|
||||
}
|
||||
|
||||
Socket::~Socket(void) {
|
||||
if(d->socket) {
|
||||
close(d->socket);
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Socket::connect(const std::wstring &server) {
|
||||
struct sockaddr_un remote;
|
||||
socklen_t len;
|
||||
|
||||
if ((d->socket = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) {
|
||||
return;
|
||||
}
|
||||
#if defined(_MACOSX)
|
||||
int op = fcntl(d->socket, F_GETFD);
|
||||
fcntl(d->socket, F_SETFD, op | FD_CLOEXEC); // OS X doesn't support SOCK_CLOEXEC yet
|
||||
#endif
|
||||
std::string name = "/tmp/" + std::string(server.begin(), server.end());
|
||||
remote.sun_family = AF_UNIX;
|
||||
snprintf(remote.sun_path, sizeof(remote.sun_path), "%s", name.c_str());
|
||||
|
||||
len = SUN_LEN(&remote);
|
||||
if (connectWrapper(d->socket, (struct sockaddr *)&remote, len) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
d->connected = true;
|
||||
}
|
||||
|
||||
bool Socket::isConnected() {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
return d->connected;
|
||||
}
|
||||
|
||||
std::wstring Socket::read() {
|
||||
return this->read(0);
|
||||
}
|
||||
|
||||
std::wstring Socket::read(int timeout) {
|
||||
struct timeval tv;
|
||||
char inbuf[BUFSIZE];
|
||||
|
||||
FD_SET(d->socket, &d->infds);
|
||||
std::string msg;
|
||||
while(isConnected()) {
|
||||
tv.tv_sec = floor(timeout / 1000.0);
|
||||
tv.tv_usec = timeout % 1000;
|
||||
|
||||
int response = select(d->socket+1, &d->infds, NULL, NULL, &tv);
|
||||
if (response == 0 && timeout > 0) {
|
||||
return L"";
|
||||
} else if (response <= 0) {
|
||||
FD_SET(d->socket, &d->infds);
|
||||
continue;
|
||||
}
|
||||
|
||||
int received = BUFSIZE;
|
||||
while(received >= (BUFSIZE - 1)) {
|
||||
memset(inbuf, '\0', sizeof(inbuf));
|
||||
received = recv(d->socket, inbuf, BUFSIZE - 1, 0);
|
||||
if(received > 0) {
|
||||
msg.append(std::string(inbuf));
|
||||
}
|
||||
}
|
||||
if (received < 0) {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
d->connected = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return TelldusCore::charToWstring(msg.c_str());
|
||||
}
|
||||
|
||||
void Socket::stopReadWait() {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
d->connected = false;
|
||||
// TODO(stefan): somehow signal the socket here?
|
||||
}
|
||||
|
||||
void Socket::write(const std::wstring &msg) {
|
||||
std::string newMsg(TelldusCore::wideToString(msg));
|
||||
int sent = send(d->socket, newMsg.c_str(), newMsg.length(), 0);
|
||||
if (sent < 0) {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
d->connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
187
telldus-core/common/Socket_win.cpp
Normal file
187
telldus-core/common/Socket_win.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include <AccCtrl.h>
|
||||
#include <Aclapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/Socket.h"
|
||||
|
||||
#define BUFSIZE 512
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class Socket::PrivateData {
|
||||
public:
|
||||
HANDLE hPipe;
|
||||
HANDLE readEvent;
|
||||
bool connected;
|
||||
bool running;
|
||||
};
|
||||
|
||||
Socket::Socket() {
|
||||
d = new PrivateData;
|
||||
d->hPipe = INVALID_HANDLE_VALUE;
|
||||
d->connected = false;
|
||||
d->running = true;
|
||||
}
|
||||
|
||||
Socket::Socket(SOCKET_T hPipe) {
|
||||
d = new PrivateData;
|
||||
d->hPipe = hPipe;
|
||||
d->connected = true;
|
||||
d->running = true;
|
||||
}
|
||||
|
||||
|
||||
Socket::~Socket(void) {
|
||||
d->running = false;
|
||||
SetEvent(d->readEvent); // signal for break
|
||||
if (d->hPipe != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(d->hPipe);
|
||||
d->hPipe = 0;
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Socket::connect(const std::wstring &server) {
|
||||
BOOL fSuccess = false;
|
||||
|
||||
std::wstring name(L"\\\\.\\pipe\\" + server);
|
||||
d->hPipe = CreateFile(
|
||||
(const wchar_t *)name.c_str(), // pipe name
|
||||
GENERIC_READ | // read and write access
|
||||
GENERIC_WRITE,
|
||||
0, // no sharing
|
||||
NULL, // default security attributes
|
||||
OPEN_EXISTING, // opens existing pipe
|
||||
FILE_FLAG_OVERLAPPED, // default attributes
|
||||
NULL); // no template file
|
||||
|
||||
if (d->hPipe == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD dwMode = PIPE_READMODE_MESSAGE;
|
||||
fSuccess = SetNamedPipeHandleState(
|
||||
d->hPipe, // pipe handle
|
||||
&dwMode, // new pipe mode
|
||||
NULL, // don't set maximum bytes
|
||||
NULL); // don't set maximum time
|
||||
|
||||
if (!fSuccess) {
|
||||
return;
|
||||
}
|
||||
d->connected = true;
|
||||
}
|
||||
|
||||
void Socket::stopReadWait() {
|
||||
d->running = false;
|
||||
SetEvent(d->readEvent);
|
||||
}
|
||||
|
||||
std::wstring Socket::read() {
|
||||
return read(INFINITE);
|
||||
}
|
||||
|
||||
std::wstring Socket::read(int timeout) {
|
||||
wchar_t buf[BUFSIZE];
|
||||
int result;
|
||||
DWORD cbBytesRead = 0;
|
||||
OVERLAPPED oOverlap;
|
||||
|
||||
memset(&oOverlap, 0, sizeof(OVERLAPPED));
|
||||
|
||||
d->readEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
oOverlap.hEvent = d->readEvent;
|
||||
BOOL fSuccess = false;
|
||||
std::wstring returnString;
|
||||
bool moreData = true;
|
||||
|
||||
while(moreData) {
|
||||
moreData = false;
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
ReadFile( d->hPipe, &buf, sizeof(buf)-sizeof(wchar_t), &cbBytesRead, &oOverlap);
|
||||
|
||||
result = WaitForSingleObject(oOverlap.hEvent, timeout);
|
||||
|
||||
if(!d->running) {
|
||||
CancelIo(d->hPipe);
|
||||
WaitForSingleObject(oOverlap.hEvent, INFINITE);
|
||||
d->readEvent = 0;
|
||||
CloseHandle(oOverlap.hEvent);
|
||||
return L"";
|
||||
}
|
||||
|
||||
if (result == WAIT_TIMEOUT) {
|
||||
CancelIo(d->hPipe);
|
||||
// Cancel, we still need to cleanup
|
||||
}
|
||||
fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &cbBytesRead, true);
|
||||
|
||||
if (!fSuccess) {
|
||||
DWORD err = GetLastError();
|
||||
|
||||
if(err == ERROR_MORE_DATA) {
|
||||
moreData = true;
|
||||
} else {
|
||||
buf[0] = 0;
|
||||
}
|
||||
if (err == ERROR_BROKEN_PIPE) {
|
||||
d->connected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
returnString.append(buf);
|
||||
}
|
||||
d->readEvent = 0;
|
||||
CloseHandle(oOverlap.hEvent);
|
||||
return returnString;
|
||||
}
|
||||
|
||||
void Socket::write(const std::wstring &msg) {
|
||||
OVERLAPPED oOverlap;
|
||||
DWORD bytesWritten = 0;
|
||||
int result;
|
||||
BOOL fSuccess = false;
|
||||
|
||||
memset(&oOverlap, 0, sizeof(OVERLAPPED));
|
||||
|
||||
HANDLE writeEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
oOverlap.hEvent = writeEvent;
|
||||
|
||||
BOOL writeSuccess = WriteFile(d->hPipe, msg.data(), (DWORD)msg.length()*sizeof(wchar_t), &bytesWritten, &oOverlap);
|
||||
result = GetLastError();
|
||||
if (writeSuccess || result == ERROR_IO_PENDING) {
|
||||
result = WaitForSingleObject(writeEvent, 30000);
|
||||
if (result == WAIT_TIMEOUT) {
|
||||
CancelIo(d->hPipe);
|
||||
WaitForSingleObject(oOverlap.hEvent, INFINITE);
|
||||
CloseHandle(writeEvent);
|
||||
CloseHandle(d->hPipe);
|
||||
d->hPipe = 0;
|
||||
d->connected = false;
|
||||
return;
|
||||
}
|
||||
fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &bytesWritten, TRUE);
|
||||
}
|
||||
|
||||
CloseHandle(writeEvent);
|
||||
if (!fSuccess) {
|
||||
CloseHandle(d->hPipe);
|
||||
d->hPipe = 0;
|
||||
d->connected = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool Socket::isConnected() {
|
||||
return d->connected;
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
276
telldus-core/common/Strings.cpp
Normal file
276
telldus-core/common/Strings.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
|
||||
#include "common/Strings.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
#ifdef _MACOSX
|
||||
#define WCHAR_T_ENCODING "UCS-4-INTERNAL"
|
||||
#else
|
||||
#define WCHAR_T_ENCODING "WCHAR_T"
|
||||
#endif
|
||||
|
||||
#ifndef va_copy
|
||||
#ifdef __va_copy
|
||||
#define va_copy(a, b) __va_copy(a, b)
|
||||
#else /* !__va_copy */
|
||||
#define va_copy(a, b) ((a)=(b))
|
||||
#endif /* __va_copy */
|
||||
#endif /* va_copy */
|
||||
|
||||
std::wstring TelldusCore::charToWstring(const char *value) {
|
||||
#ifdef _WINDOWS
|
||||
// Determine size
|
||||
int size = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
|
||||
if (size == 0) {
|
||||
return L"";
|
||||
}
|
||||
wchar_t *buffer;
|
||||
buffer = new wchar_t[size];
|
||||
memset(buffer, 0, sizeof(wchar_t)*(size));
|
||||
|
||||
int bytes = MultiByteToWideChar(CP_UTF8, 0, value, -1, buffer, size);
|
||||
std::wstring retval(buffer);
|
||||
delete[] buffer;
|
||||
return retval;
|
||||
|
||||
#else
|
||||
size_t utf8Length = strlen(value);
|
||||
size_t outbytesLeft = utf8Length*sizeof(wchar_t);
|
||||
|
||||
// Copy the instring
|
||||
char *inString = new char[utf8Length+1];
|
||||
snprintf(inString, utf8Length+1, "%s", value);
|
||||
|
||||
// Create buffer for output
|
||||
char *outString = reinterpret_cast<char*>(new wchar_t[utf8Length+1]);
|
||||
memset(outString, 0, sizeof(wchar_t)*(utf8Length+1));
|
||||
|
||||
#ifdef _FREEBSD
|
||||
const char *inPointer = inString;
|
||||
#else
|
||||
char *inPointer = inString;
|
||||
#endif
|
||||
char *outPointer = outString;
|
||||
|
||||
iconv_t convDesc = iconv_open(WCHAR_T_ENCODING, "UTF-8");
|
||||
iconv(convDesc, &inPointer, &utf8Length, &outPointer, &outbytesLeft);
|
||||
iconv_close(convDesc);
|
||||
|
||||
std::wstring retval( reinterpret_cast<wchar_t *>(outString) );
|
||||
|
||||
// Cleanup
|
||||
delete[] inString;
|
||||
delete[] outString;
|
||||
|
||||
return retval;
|
||||
#endif
|
||||
}
|
||||
|
||||
int TelldusCore::charToInteger(const char *input) {
|
||||
std::stringstream inputstream;
|
||||
inputstream << input;
|
||||
int retval;
|
||||
inputstream >> retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::wstring TelldusCore::charUnsignedToWstring(const unsigned char value) {
|
||||
std::wstringstream st;
|
||||
st << value;
|
||||
return st.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method doesn't support all locales
|
||||
*/
|
||||
bool TelldusCore::comparei(std::wstring stringA, std::wstring stringB) {
|
||||
transform(stringA.begin(), stringA.end(), stringA.begin(), toupper);
|
||||
transform(stringB.begin(), stringB.end(), stringB.begin(), toupper);
|
||||
|
||||
return stringA == stringB;
|
||||
}
|
||||
|
||||
std::wstring TelldusCore::intToWstring(int value) {
|
||||
#ifdef _WINDOWS
|
||||
// no stream used
|
||||
// TODO(stefan): Make effective and safe...
|
||||
wchar_t numstr[21]; // enough to hold all numbers up to 64-bits
|
||||
_itow_s(value, numstr, sizeof(numstr), 10);
|
||||
std::wstring newstring(numstr);
|
||||
return newstring;
|
||||
// return TelldusCore::charToWstring(stdstring.c_str());
|
||||
// std::wstring temp = TelldusCore::charToWstring(stdstring.c_str());
|
||||
// std::wstring temp(stdstring.length(), L' ');
|
||||
// std::copy(stdstring.begin(), stdstring.end(), temp.begin());
|
||||
// return temp;
|
||||
#else
|
||||
std::wstringstream st;
|
||||
st << value;
|
||||
return st.str();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string TelldusCore::intToString(int value) {
|
||||
// Not sure if this is neecssary (for ordinary stringstream that is)
|
||||
#ifdef _WINDOWS
|
||||
char numstr[21]; // enough to hold all numbers up to 64-bits
|
||||
_itoa_s(value, numstr, sizeof(numstr), 10);
|
||||
std::string stdstring(numstr);
|
||||
return stdstring;
|
||||
#else
|
||||
std::stringstream st;
|
||||
st << value;
|
||||
return st.str();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
std::wstring TelldusCore::intToWStringSafe(int value){
|
||||
#ifdef _WINDOWS
|
||||
//no stream used
|
||||
//TODO! Make effective and safe...
|
||||
char numstr[21]; // enough to hold all numbers up to 64-bits
|
||||
itoa(value, numstr, 10);
|
||||
std::string stdstring(numstr);
|
||||
return TelldusCore::charToWstring(stdstring.c_str());
|
||||
//std::wstring temp = TelldusCore::charToWstring(stdstring.c_str());
|
||||
//std::wstring temp(stdstring.length(), L' ');
|
||||
//std::copy(stdstring.begin(), stdstring.end(), temp.begin());
|
||||
//return temp;
|
||||
#else
|
||||
return TelldusCore::intToWString(value);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
uint64_t TelldusCore::hexTo64l(const std::string data) {
|
||||
#ifdef _WINDOWS
|
||||
return _strtoui64(data.c_str(), NULL, 16);
|
||||
#elif defined(_MACOSX)
|
||||
return strtoq(data.c_str(), NULL, 16);
|
||||
#else
|
||||
return strtoull(data.c_str(), NULL, 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
int TelldusCore::wideToInteger(const std::wstring &input) {
|
||||
std::wstringstream inputstream;
|
||||
inputstream << input;
|
||||
int retval;
|
||||
inputstream >> retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::string TelldusCore::wideToString(const std::wstring &input) {
|
||||
#ifdef _WINDOWS
|
||||
// Determine size
|
||||
int size = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
if (size == 0) {
|
||||
return "";
|
||||
}
|
||||
char *buffer;
|
||||
buffer = new char[size];
|
||||
memset(buffer, 0, sizeof(*buffer)*size);
|
||||
|
||||
int bytes = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, buffer, size, NULL, NULL);
|
||||
std::string retval(buffer);
|
||||
delete[] buffer;
|
||||
return retval;
|
||||
|
||||
#else
|
||||
size_t wideSize = sizeof(wchar_t)*input.length();
|
||||
// We cannot know how many wide character there is yet
|
||||
size_t outbytesLeft = wideSize+sizeof(char); // NOLINT(runtime/sizeof)
|
||||
|
||||
// Copy the instring
|
||||
char *inString = reinterpret_cast<char*>(new wchar_t[input.length()+1]);
|
||||
memcpy(inString, input.c_str(), wideSize+sizeof(wchar_t));
|
||||
|
||||
// Create buffer for output
|
||||
char *outString = new char[outbytesLeft];
|
||||
memset(outString, 0, sizeof(*outString)*(outbytesLeft));
|
||||
|
||||
#ifdef _FREEBSD
|
||||
const char *inPointer = inString;
|
||||
#else
|
||||
char *inPointer = inString;
|
||||
#endif
|
||||
char *outPointer = outString;
|
||||
|
||||
iconv_t convDesc = iconv_open("UTF-8", WCHAR_T_ENCODING);
|
||||
iconv(convDesc, &inPointer, &wideSize, &outPointer, &outbytesLeft);
|
||||
iconv_close(convDesc);
|
||||
|
||||
std::string retval(outString);
|
||||
|
||||
// Cleanup
|
||||
delete[] inString;
|
||||
delete[] outString;
|
||||
|
||||
return retval;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string TelldusCore::formatf(const char *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
std::string retval = sformatf(format, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::string TelldusCore::sformatf(const char *format, va_list ap) {
|
||||
// This code is based on code from the Linux man-pages project (man vsprintf)
|
||||
int n;
|
||||
int size = 100; /* Guess we need no more than 100 bytes. */
|
||||
char *p, *np;
|
||||
|
||||
if ((p = reinterpret_cast<char*>(malloc(size))) == NULL) {
|
||||
return "";
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* Try to print in the allocated space. */
|
||||
va_list ap2;
|
||||
va_copy(ap2, ap);
|
||||
n = vsnprintf(p, size, format, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
/* If that worked, return the string. */
|
||||
if (n > -1 && n < size) {
|
||||
std::string retval(p);
|
||||
free(p);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Else try again with more space. */
|
||||
|
||||
if (n > -1) { /* glibc 2.1 */
|
||||
size = n+1; /* precisely what is needed */
|
||||
} else { /* glibc 2.0 */
|
||||
size *= 2; /* twice the old size */
|
||||
}
|
||||
if ((np = reinterpret_cast<char *>(realloc (p, size))) == NULL) {
|
||||
free(p);
|
||||
return "";
|
||||
} else {
|
||||
p = np;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
telldus-core/common/Strings.h
Normal file
39
telldus-core/common/Strings.h
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_COMMON_STRINGS_H_
|
||||
#define TELLDUS_CORE_COMMON_STRINGS_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
namespace TelldusCore {
|
||||
std::wstring charToWstring(const char *value);
|
||||
int charToInteger(const char *value);
|
||||
std::wstring charUnsignedToWstring(const unsigned char value);
|
||||
|
||||
bool comparei(std::wstring stringA, std::wstring stringB);
|
||||
std::wstring intToWstring(int value);
|
||||
// std::wstring intToWStringSafe(int value);
|
||||
std::string intToString(int value);
|
||||
uint64_t hexTo64l(const std::string data);
|
||||
std::string wideToString(const std::wstring &input);
|
||||
|
||||
int wideToInteger(const std::wstring &input);
|
||||
|
||||
std::string formatf(const char *format, ...);
|
||||
std::string sformatf(const char *format, va_list ap);
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_COMMON_STRINGS_H_
|
||||
98
telldus-core/common/Thread.cpp
Normal file
98
telldus-core/common/Thread.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// C++ Implementation: Thread
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
|
||||
#include "common/Thread.h"
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "common/EventHandler.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
|
||||
class ThreadPrivate {
|
||||
public:
|
||||
bool running;
|
||||
EventRef threadStarted;
|
||||
Mutex *mutex;
|
||||
#ifdef _WINDOWS
|
||||
HANDLE thread;
|
||||
DWORD threadId;
|
||||
#else
|
||||
pthread_t thread;
|
||||
#endif
|
||||
};
|
||||
|
||||
Thread::Thread() {
|
||||
d = new ThreadPrivate;
|
||||
d->thread = 0;
|
||||
d->mutex = 0;
|
||||
}
|
||||
|
||||
Thread::~Thread() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Thread::start() {
|
||||
#ifdef _WINDOWS
|
||||
d->running = true;
|
||||
d->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&Thread::exec, this, 0, &d->threadId);
|
||||
#else
|
||||
pthread_create(&d->thread, NULL, &Thread::exec, this );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Thread::startAndLock(Mutex *lock) {
|
||||
EventHandler handler;
|
||||
d->threadStarted = handler.addEvent();
|
||||
d->mutex = lock;
|
||||
this->start();
|
||||
while (!handler.waitForAny()) {
|
||||
continue;
|
||||
}
|
||||
d->threadStarted.reset();
|
||||
}
|
||||
|
||||
bool Thread::wait() {
|
||||
if (!d->thread) {
|
||||
return true;
|
||||
}
|
||||
#ifdef _WINDOWS
|
||||
while(d->running) {
|
||||
WaitForSingleObject(d->thread, 200);
|
||||
}
|
||||
CloseHandle(d->thread);
|
||||
#else
|
||||
pthread_join(d->thread, 0);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void *Thread::exec( void *ptr ) {
|
||||
Thread *t = reinterpret_cast<Thread *>(ptr);
|
||||
if (t) {
|
||||
if (t->d->threadStarted) {
|
||||
t->d->mutex->lock();
|
||||
t->d->threadStarted->signal();
|
||||
}
|
||||
t->run();
|
||||
if (t->d->mutex) {
|
||||
t->d->mutex->unlock();
|
||||
}
|
||||
t->d->running = false;
|
||||
}
|
||||
#ifdef _WINDOWS
|
||||
ExitThread(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace TelldusCore
|
||||
37
telldus-core/common/Thread.h
Normal file
37
telldus-core/common/Thread.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// C++ Interface: Thread
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_COMMON_THREAD_H_
|
||||
#define TELLDUS_CORE_COMMON_THREAD_H_
|
||||
|
||||
#include <string>
|
||||
#include "common/Mutex.h"
|
||||
|
||||
namespace TelldusCore {
|
||||
class ThreadPrivate;
|
||||
class Thread {
|
||||
public:
|
||||
Thread();
|
||||
virtual ~Thread();
|
||||
void start();
|
||||
void startAndLock(Mutex *lock);
|
||||
bool wait();
|
||||
|
||||
protected:
|
||||
virtual void run() = 0;
|
||||
|
||||
private:
|
||||
static void* exec( void *ptr );
|
||||
ThreadPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_COMMON_THREAD_H_
|
||||
108
telldus-core/common/common.h
Normal file
108
telldus-core/common/common.h
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef TELLDUS_CORE_COMMON_COMMON_H_
|
||||
#define TELLDUS_CORE_COMMON_COMMON_H_
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#include <ole2.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <fstream> // NOLINT(readability/streams)
|
||||
#endif
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
|
||||
inline void msleep( const int msec) {
|
||||
#ifdef _WINDOWS
|
||||
Sleep(msec);
|
||||
#else
|
||||
usleep(msec*1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void dlog(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
inline void debuglogfilename(const int intMessage, const std::string strMessage, const std::string filename) {
|
||||
#ifdef _WINDOWS
|
||||
static bool firstRun = true;
|
||||
std::ofstream file;
|
||||
|
||||
if (firstRun) {
|
||||
file.open(filename.c_str(), std::ios::out);
|
||||
firstRun = false;
|
||||
} else {
|
||||
file.open(filename.c_str(), std::ios::out | std::ios::app);
|
||||
}
|
||||
|
||||
__time32_t now = _time32(0);
|
||||
|
||||
// Convert now to tm struct for local timezone
|
||||
struct tm localtm;
|
||||
_localtime32_s(&localtm, &now);
|
||||
char thetime[32];
|
||||
errno_t err = asctime_s(thetime, 32, &localtm);
|
||||
if (!err) {
|
||||
file << thetime << " [" << GetCurrentThreadId() << "] " << intMessage << " - " << strMessage << "\n";
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
|
||||
#elif !defined(_MACOSX) && !defined(__FreeBSD__)
|
||||
pthread_t thread = pthread_self();
|
||||
printf("[%i] %i - %s\n", static_cast<int>(thread), intMessage, strMessage.c_str());
|
||||
fflush(stdout);
|
||||
#else
|
||||
printf("%i - %s\n", intMessage, strMessage.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void debuglogservice(const int intMessage, const std::string strMessage) {
|
||||
std::string filename("C:/telldus_service_debug.txt");
|
||||
debuglogfilename(intMessage, strMessage, filename);
|
||||
}
|
||||
|
||||
inline void debuglog(const int intMessage, const std::string strMessage) {
|
||||
std::string filename("C:/telldus_client_debug.txt");
|
||||
debuglogfilename(intMessage, strMessage, filename);
|
||||
}
|
||||
|
||||
inline char *wrapStdString( const std::string &string) {
|
||||
#ifdef _WINDOWS
|
||||
return reinterpret_cast<char *>(SysAllocStringByteLen(string.c_str(), (unsigned int)string.size()));
|
||||
#else
|
||||
char *returnVal;
|
||||
returnVal = reinterpret_cast<char *>(malloc(sizeof(*returnVal) * (string.size()+1)));
|
||||
snprintf(returnVal, string.size()+1, "%s", string.c_str());
|
||||
return returnVal;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline char *wrapStdWstring( const std::wstring &wstring) {
|
||||
return wrapStdString(TelldusCore::wideToString(wstring));
|
||||
}
|
||||
|
||||
#endif // TELLDUS_CORE_COMMON_COMMON_H_
|
||||
73
telldus-core/common/stdlibc_workaround.cpp
Normal file
73
telldus-core/common/stdlibc_workaround.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include <istream> // NOLINT(readability/streams)
|
||||
// Workarounds for symbols that are missing from Leopard stdlibc++.dylib.
|
||||
_GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
// From ostream_insert.h
|
||||
template ostream& __ostream_insert(ostream&, const char*, streamsize);
|
||||
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize);
|
||||
#endif
|
||||
|
||||
// From ostream.tcc
|
||||
template ostream& ostream::_M_insert(long); // NOLINT(runtime/int)
|
||||
template ostream& ostream::_M_insert(unsigned long); // NOLINT(runtime/int)
|
||||
template ostream& ostream::_M_insert(bool); // NOLINT(readability/function)
|
||||
#ifdef _GLIBCXX_USE_LONG_LONG
|
||||
template ostream& ostream::_M_insert(long long); // NOLINT(runtime/int)
|
||||
template ostream& ostream::_M_insert(unsigned long long); // NOLINT(runtime/int)
|
||||
#endif
|
||||
template ostream& ostream::_M_insert(double); // NOLINT(readability/function)
|
||||
template ostream& ostream::_M_insert(long double);
|
||||
template ostream& ostream::_M_insert(const void*);
|
||||
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
template wostream& wostream::_M_insert(long); // NOLINT(runtime/int)
|
||||
template wostream& wostream::_M_insert(unsigned long); // NOLINT(runtime/int)
|
||||
template wostream& wostream::_M_insert(bool); // NOLINT(readability/function)
|
||||
#ifdef _GLIBCXX_USE_LONG_LONG
|
||||
template wostream& wostream::_M_insert(long long); // NOLINT(runtime/int)
|
||||
template wostream& wostream::_M_insert(unsigned long long); // NOLINT(runtime/int)
|
||||
#endif
|
||||
template wostream& wostream::_M_insert(double); // NOLINT(readability/function)
|
||||
template wostream& wostream::_M_insert(long double);
|
||||
template wostream& wostream::_M_insert(const void*);
|
||||
#endif
|
||||
|
||||
// From istream.tcc
|
||||
template istream& istream::_M_extract(unsigned short&); // NOLINT(runtime/int)
|
||||
template istream& istream::_M_extract(unsigned int&);
|
||||
template istream& istream::_M_extract(long&); // NOLINT(runtime/int)
|
||||
template istream& istream::_M_extract(unsigned long&); // NOLINT(runtime/int)
|
||||
template istream& istream::_M_extract(bool&);
|
||||
#ifdef _GLIBCXX_USE_LONG_LONG
|
||||
template istream& istream::_M_extract(long long&); // NOLINT(runtime/int)
|
||||
template istream& istream::_M_extract(unsigned long long&); // NOLINT(runtime/int)
|
||||
#endif
|
||||
template istream& istream::_M_extract(float&);
|
||||
template istream& istream::_M_extract(double&);
|
||||
template istream& istream::_M_extract(long double&);
|
||||
template istream& istream::_M_extract(void*&);
|
||||
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
template wistream& wistream::_M_extract(unsigned short&); // NOLINT(runtime/int)
|
||||
template wistream& wistream::_M_extract(unsigned int&);
|
||||
template wistream& wistream::_M_extract(long&); // NOLINT(runtime/int)
|
||||
template wistream& wistream::_M_extract(unsigned long&); // NOLINT(runtime/int)
|
||||
template wistream& wistream::_M_extract(bool&);
|
||||
#ifdef _GLIBCXX_USE_LONG_LONG
|
||||
template wistream& wistream::_M_extract(long long&); // NOLINT(runtime/int)
|
||||
template wistream& wistream::_M_extract(unsigned long long&); // NOLINT(runtime/int)
|
||||
#endif
|
||||
template wistream& wistream::_M_extract(float&);
|
||||
template wistream& wistream::_M_extract(double&);
|
||||
template wistream& wistream::_M_extract(long double&);
|
||||
template wistream& wistream::_M_extract(void*&);
|
||||
#endif
|
||||
|
||||
_GLIBCXX_END_NAMESPACE
|
||||
5
telldus-core/debian/changelog
Normal file
5
telldus-core/debian/changelog
Normal file
@@ -0,0 +1,5 @@
|
||||
telldus-core (2.1.2-1) UNRELEASED; urgency=low
|
||||
|
||||
* Initial release (Closes: #xxxx)
|
||||
|
||||
-- Ruben Undheim <ruben.undheim@gmail.com> Sat, 25 Oct 2014 19:42:44 +0200
|
||||
1
telldus-core/debian/compat
Normal file
1
telldus-core/debian/compat
Normal file
@@ -0,0 +1 @@
|
||||
9
|
||||
40
telldus-core/debian/control
Normal file
40
telldus-core/debian/control
Normal file
@@ -0,0 +1,40 @@
|
||||
Source: telldus-core
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Ruben Undheim <ruben.undheim@gmail.com>
|
||||
Build-Depends: debhelper (>= 9), libftdi-dev, libconfuse-dev, doxygen
|
||||
Standards-Version: 3.9.6
|
||||
Vcs-Git: git://github.com/rubund/telldus-core.git
|
||||
Vcs-Browser: https://github.com/rubund/telldus-core/tree/debian
|
||||
Homepage: http://developer.telldus.com/wiki/TellStick_installation_Linux
|
||||
|
||||
|
||||
Package: libtelldus0
|
||||
Architecture: any
|
||||
Section: libs
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Description: Library for tellstick control
|
||||
|
||||
Package: libtelldus-dev
|
||||
Architecture: any
|
||||
Section: libdevel
|
||||
Depends: libtelldus0 (= ${binary:Version}),
|
||||
libftdi-dev,
|
||||
libconfuse-dev,
|
||||
${misc:Depends}
|
||||
Description: Library for tellstick control - development files
|
||||
|
||||
Package: libtelldus0-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: libtelldus0 (= ${binary:Version}),
|
||||
${misc:Depends}
|
||||
Description: Library for tellstick control - debug symbols
|
||||
|
||||
Package: tdtool
|
||||
Architecture: any
|
||||
Depends: libtelldus0 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: TellStick control software
|
||||
44
telldus-core/debian/copyright
Normal file
44
telldus-core/debian/copyright
Normal file
@@ -0,0 +1,44 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: telldus-core
|
||||
Source: http://download.telldus.se/TellStick/Software/telldus-core/
|
||||
|
||||
Files: *
|
||||
Copyright: Copyright (C) 2012 Telldus Technologies AB
|
||||
License: LGPL-2.1
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
.
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License version 2.1 can be found in
|
||||
"/usr/share/common-licenses/LGPL-2.1".
|
||||
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2014 Ruben Undheim <ruben.undheim@gmail.com>
|
||||
License: GPL-2+
|
||||
This package 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package 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/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
2
telldus-core/debian/libtelldus-dev.install
Normal file
2
telldus-core/debian/libtelldus-dev.install
Normal file
@@ -0,0 +1,2 @@
|
||||
usr/include/*
|
||||
usr/lib/lib*.so
|
||||
1
telldus-core/debian/libtelldus0.install
Normal file
1
telldus-core/debian/libtelldus0.install
Normal file
@@ -0,0 +1 @@
|
||||
usr/lib/lib*.so.*
|
||||
1740
telldus-core/debian/patches/01_add_missing_doxyfile.patch
Normal file
1740
telldus-core/debian/patches/01_add_missing_doxyfile.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
||||
Description: <short summary of the patch>
|
||||
TODO: Put a short summary on the line above and replace this paragraph
|
||||
with a longer explanation of this change. Complete the meta-information
|
||||
with other relevant fields (see below for details). To make it easier, the
|
||||
information below has been extracted from the changelog. Adjust it or drop
|
||||
it.
|
||||
.
|
||||
telldus-core (2.1.2-1) UNRELEASED; urgency=low
|
||||
.
|
||||
* Initial release (Closes: #xxxx)
|
||||
Author: Ruben Undheim <ruben.undheim@gmail.com>
|
||||
|
||||
---
|
||||
The information above should follow the Patch Tagging Guidelines, please
|
||||
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
|
||||
are templates for supplementary fields that you might want to add:
|
||||
|
||||
Origin: <vendor|upstream|other>, <url of original patch>
|
||||
Bug: <url in upstream bugtracker>
|
||||
Bug-Debian: http://bugs.debian.org/<bugnumber>
|
||||
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
|
||||
Forwarded: <no|not-needed|url proving that it has been forwarded>
|
||||
Reviewed-By: <name and email of someone who approved the patch>
|
||||
Last-Update: <YYYY-MM-DD>
|
||||
|
||||
--- telldus-core-2.1.2.orig/client/CMakeLists.txt
|
||||
+++ telldus-core-2.1.2/client/CMakeLists.txt
|
||||
@@ -21,8 +21,6 @@ SET( telldus-core_PUB_HDRS
|
||||
telldus-core.h
|
||||
)
|
||||
|
||||
-FIND_PACKAGE(Threads)
|
||||
-LIST(APPEND telldus-core_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
|
||||
|
||||
@@ -100,6 +98,9 @@ ENDIF ()
|
||||
|
||||
ADD_DEPENDENCIES(${telldus-core_TARGET} TelldusCommon)
|
||||
|
||||
+FIND_PACKAGE(Threads)
|
||||
+LIST(APPEND telldus-core_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
+
|
||||
IF (UNIX)
|
||||
SET_TARGET_PROPERTIES( ${telldus-core_TARGET} PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden")
|
||||
ENDIF (UNIX)
|
||||
2
telldus-core/debian/patches/series
Normal file
2
telldus-core/debian/patches/series
Normal file
@@ -0,0 +1,2 @@
|
||||
01_add_missing_doxyfile.patch
|
||||
02_fix_link_ordering_problem.patch
|
||||
15
telldus-core/debian/rules
Executable file
15
telldus-core/debian/rules
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip -plibtelldus0 --keep-debug --dbg-package=libtelldus0-dbg
|
||||
dh_strip -ptdtool
|
||||
|
||||
1
telldus-core/debian/source/format
Normal file
1
telldus-core/debian/source/format
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
1
telldus-core/debian/tdtool.docs
Normal file
1
telldus-core/debian/tdtool.docs
Normal file
@@ -0,0 +1 @@
|
||||
README
|
||||
5
telldus-core/debian/tdtool.install
Normal file
5
telldus-core/debian/tdtool.install
Normal file
@@ -0,0 +1,5 @@
|
||||
usr/bin/*
|
||||
usr/sbin/*
|
||||
etc/*
|
||||
var/state/*
|
||||
usr/share/telldus-core/*
|
||||
278
telldus-core/service/CMakeLists.txt
Normal file
278
telldus-core/service/CMakeLists.txt
Normal file
@@ -0,0 +1,278 @@
|
||||
IF(COMMAND cmake_policy)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
ENDIF(COMMAND cmake_policy)
|
||||
|
||||
FIND_PACKAGE( SignTool REQUIRED )
|
||||
|
||||
SET (telldusd_DESCRIPTION
|
||||
"background service for Telldus TellStick, must be running to control TellStick"
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS( -DVERSION="${DISPLAYED_VERSION}" )
|
||||
|
||||
######## Non configurable options ########
|
||||
SET( telldus-service_SRCS
|
||||
ClientCommunicationHandler.cpp
|
||||
Controller.cpp
|
||||
ControllerManager.cpp
|
||||
ControllerMessage.cpp
|
||||
Device.cpp
|
||||
DeviceManager.cpp
|
||||
Log.cpp
|
||||
Sensor.cpp
|
||||
Settings.cpp
|
||||
TelldusMain.cpp
|
||||
TellStick.cpp
|
||||
Timer.cpp
|
||||
EventUpdateManager.cpp
|
||||
)
|
||||
SET( telldus-service_protocol_SRCS
|
||||
Protocol.h
|
||||
Protocol.cpp
|
||||
ProtocolBrateck.h
|
||||
ProtocolBrateck.cpp
|
||||
ProtocolComen.h
|
||||
ProtocolComen.cpp
|
||||
ProtocolEverflourish.h
|
||||
ProtocolEverflourish.cpp
|
||||
ProtocolFineoffset.h
|
||||
ProtocolFineoffset.cpp
|
||||
ProtocolFuhaote.h
|
||||
ProtocolFuhaote.cpp
|
||||
ProtocolGroup.h
|
||||
ProtocolGroup.cpp
|
||||
ProtocolHasta.h
|
||||
ProtocolHasta.cpp
|
||||
ProtocolIkea.h
|
||||
ProtocolIkea.cpp
|
||||
ProtocolMandolyn.h
|
||||
ProtocolMandolyn.cpp
|
||||
ProtocolNexa.h
|
||||
ProtocolNexa.cpp
|
||||
ProtocolOregon.h
|
||||
ProtocolOregon.cpp
|
||||
ProtocolRisingSun.h
|
||||
ProtocolRisingSun.cpp
|
||||
ProtocolSartano.h
|
||||
ProtocolSartano.cpp
|
||||
ProtocolScene.h
|
||||
ProtocolScene.cpp
|
||||
ProtocolSilvanChip.h
|
||||
ProtocolSilvanChip.cpp
|
||||
ProtocolUpm.h
|
||||
ProtocolUpm.cpp
|
||||
ProtocolWaveman.h
|
||||
ProtocolWaveman.cpp
|
||||
ProtocolX10.h
|
||||
ProtocolX10.cpp
|
||||
ProtocolYidong.h
|
||||
ProtocolYidong.cpp
|
||||
)
|
||||
SET( telldus-service_HDRS
|
||||
ClientCommunicationHandler.h
|
||||
ConnectionListener.h
|
||||
Controller.h
|
||||
ControllerListener.h
|
||||
ControllerManager.h
|
||||
ControllerMessage.h
|
||||
Device.h
|
||||
DeviceManager.h
|
||||
EventUpdateManager.h
|
||||
Log.h
|
||||
Sensor.h
|
||||
Settings.h
|
||||
TelldusMain.h
|
||||
TellStick.h
|
||||
Timer.h
|
||||
)
|
||||
FIND_PACKAGE(Threads REQUIRED)
|
||||
LIST(APPEND telldus-service_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
|
||||
|
||||
######## Configurable options for the platform ########
|
||||
|
||||
IF (UNIX AND NOT APPLE)
|
||||
SET(SCRIPT_PATH "/usr/local/share/telldus/scripts" CACHE PATH "The paths for scripts to execute on sensor events")
|
||||
SET(SYSCONF_INSTALL_DIR "/etc" CACHE PATH "The sysconfig install dir (default prefix/etc)" )
|
||||
IF (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
SET(DEFAULT_STATE_INSTALL_DIR "/var/spool")
|
||||
ELSE ()
|
||||
SET(DEFAULT_STATE_INSTALL_DIR "/var/state")
|
||||
ENDIF ()
|
||||
SET(STATE_INSTALL_DIR "${DEFAULT_STATE_INSTALL_DIR}" CACHE PATH "The directory to store state information of the devices")
|
||||
|
||||
ENDIF()
|
||||
|
||||
######## Platforms-specific, non configurable ########
|
||||
|
||||
IF (APPLE) #### Mac OS X ####
|
||||
SET(DEFAULT_FTDI_ENGINE "ftd2xx")
|
||||
SET( telldus-service_TARGET TelldusService )
|
||||
ADD_DEFINITIONS( -D_MACOSX )
|
||||
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
FIND_LIBRARY(IOKIT_LIBRARY IOKit)
|
||||
|
||||
SET( telldus-service_LIBRARIES
|
||||
${telldus-service_LIBRARIES}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${IOKIT_LIBRARY}
|
||||
TelldusCommon
|
||||
)
|
||||
LIST(APPEND telldus-service_SRCS
|
||||
main_mac.cpp
|
||||
ConnectionListener_unix.cpp
|
||||
ControllerListener_mac.cpp
|
||||
SettingsCoreFoundationPreferences.cpp
|
||||
)
|
||||
|
||||
ELSEIF (WIN32) #### Windows ####
|
||||
SET(DEFAULT_FTDI_ENGINE "ftd2xx")
|
||||
SET( telldus-service_TARGET TelldusService )
|
||||
ADD_DEFINITIONS( -DUNICODE )
|
||||
ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No
|
||||
SET(CMAKE_EXE_LINKER_FLAGS
|
||||
"${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE"
|
||||
)
|
||||
LIST(APPEND telldus-service_LIBRARIES
|
||||
TelldusCommon
|
||||
)
|
||||
LIST(APPEND telldus-service_SRCS
|
||||
ConnectionListener_win.cpp
|
||||
main_win.cpp
|
||||
SettingsWinRegistry.cpp
|
||||
TelldusWinService_win.cpp
|
||||
Messages.mc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Messages.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/service/Messages.h
|
||||
)
|
||||
LIST(APPEND telldus-service_HDRS
|
||||
TelldusWinService_win.h
|
||||
)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT Messages.rc service/Messages.h
|
||||
COMMAND mc.exe -u -r \"${CMAKE_CURRENT_BINARY_DIR}\" -h \"${CMAKE_CURRENT_BINARY_DIR}/service\" \"${CMAKE_CURRENT_SOURCE_DIR}/Messages.mc\"
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Messages.mc
|
||||
DEPENDS Messages.rc
|
||||
COMMENT "Compiling Messages Resource"
|
||||
)
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
|
||||
ELSE (APPLE) #### Linux ####
|
||||
SET(DEFAULT_FTDI_ENGINE "libftdi")
|
||||
FIND_LIBRARY(CONFUSE_LIBRARY confuse)
|
||||
ADD_DEFINITIONS( -D_CONFUSE )
|
||||
ADD_DEFINITIONS( -D_LINUX )
|
||||
|
||||
SET( telldus-service_TARGET telldusd )
|
||||
LIST(APPEND telldus-service_SRCS
|
||||
ConnectionListener_unix.cpp
|
||||
main_unix.cpp
|
||||
SettingsConfuse.cpp
|
||||
)
|
||||
|
||||
LIST(APPEND telldus-service_LIBRARIES
|
||||
${CONFUSE_LIBRARY}
|
||||
TelldusCommon
|
||||
)
|
||||
ENDIF (APPLE)
|
||||
|
||||
SET(FTDI_ENGINE ${DEFAULT_FTDI_ENGINE} CACHE STRING "Which FTDI engine to use. This could be either 'libftdi' or 'ftd2xx'")
|
||||
IF (FTDI_ENGINE STREQUAL "ftd2xx")
|
||||
FIND_LIBRARY(FTD2XX_LIBRARY ftd2xx)
|
||||
ADD_DEFINITIONS( -DLIBFTD2XX )
|
||||
LIST(APPEND telldus-service_SRCS TellStick_ftd2xx.cpp )
|
||||
LIST(APPEND telldus-service_LIBRARIES ${FTD2XX_LIBRARY})
|
||||
ELSE (FTDI_ENGINE STREQUAL "ftd2xx")
|
||||
FIND_LIBRARY(FTDI_LIBRARY ftdi)
|
||||
INCLUDE(FindPkgConfig)
|
||||
PKG_SEARCH_MODULE(FTDI libftdi)
|
||||
INCLUDE_DIRECTORIES( ${FTDI_INCLUDEDIR} )
|
||||
ADD_DEFINITIONS( -DLIBFTDI )
|
||||
LIST(APPEND telldus-service_SRCS TellStick_libftdi.cpp )
|
||||
LIST(APPEND telldus-service_LIBRARIES ${FTDI_LIBRARY})
|
||||
ENDIF (FTDI_ENGINE STREQUAL "ftd2xx")
|
||||
|
||||
######## Configuring ########
|
||||
|
||||
SOURCE_GROUP("Protocol Files" FILES ${telldus-service_protocol_SRCS})
|
||||
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/service/config.h)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
SET(telldus-service_TARGET ${telldus-service_TARGET} PARENT_SCOPE)
|
||||
ADD_EXECUTABLE(${telldus-service_TARGET}
|
||||
${telldus-service_SRCS}
|
||||
${telldus-service_protocol_SRCS}
|
||||
${telldus-service_HDRS}
|
||||
)
|
||||
ADD_DEPENDENCIES(${telldus-service_TARGET} TelldusCommon)
|
||||
SET_SOURCE_FILES_PROPERTIES(${telldus-service_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
TARGET_LINK_LIBRARIES( ${telldus-service_TARGET} ${telldus-service_LIBRARIES} )
|
||||
|
||||
SIGN(${telldus-service_TARGET})
|
||||
|
||||
SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
|
||||
)
|
||||
IF (APPLE)
|
||||
SET(TELLDUS_SERVICE_TARGET_PATH "/Library/Telldus" CACHE STRING "Path to install TelldusService")
|
||||
SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
INSTALL(TARGETS ${telldus-service_TARGET}
|
||||
RUNTIME DESTINATION ${TELLDUS_SERVICE_TARGET_PATH}
|
||||
)
|
||||
INSTALL(CODE "
|
||||
INCLUDE(GetPrerequisites)
|
||||
GET_FILENAME_COMPONENT(DESTDIR \$ENV{DESTDIR} ABSOLUTE)
|
||||
GET_PREREQUISITES(\"\${DESTDIR}/${TELLDUS_SERVICE_TARGET_PATH}/${telldus-service_TARGET}\" prereqs 1 0 \"\$\" \"\$\")
|
||||
FOREACH(pr \${prereqs})
|
||||
GET_FILENAME_COMPONENT(lib \${pr} NAME)
|
||||
FILE(INSTALL \${pr} DESTINATION ${TELLDUS_SERVICE_TARGET_PATH})
|
||||
EXECUTE_PROCESS(COMMAND install_name_tool
|
||||
-change \"\${pr}\" \"${TELLDUS_SERVICE_TARGET_PATH}/\${lib}\" \"\${DESTDIR}/${TELLDUS_SERVICE_TARGET_PATH}/${telldus-service_TARGET}\"
|
||||
)
|
||||
ENDFOREACH ()
|
||||
")
|
||||
INSTALL(FILES com.telldus.service.plist DESTINATION /Library/LaunchDaemons)
|
||||
ENDIF (APPLE)
|
||||
|
||||
IF (UNIX)
|
||||
IF (GENERATE_MAN)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${telldus-service_TARGET}
|
||||
POST_BUILD
|
||||
COMMAND help2man -n ${telldusd_DESCRIPTION} ./telldusd > telldusd.1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating man file telldusd.1"
|
||||
)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/telldusd.1 DESTINATION share/man/man1)
|
||||
ENDIF (GENERATE_MAN)
|
||||
ENDIF (UNIX)
|
||||
|
||||
IF (UNIX AND NOT APPLE)
|
||||
INSTALL(TARGETS ${telldus-service_TARGET} RUNTIME DESTINATION sbin)
|
||||
INSTALL(FILES tellstick.conf
|
||||
DESTINATION ${SYSCONF_INSTALL_DIR}
|
||||
)
|
||||
INSTALL(FILES telldus-core.conf
|
||||
DESTINATION ${STATE_INSTALL_DIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE WORLD_READ WORLD_WRITE
|
||||
)
|
||||
ENDIF (UNIX AND NOT APPLE)
|
||||
|
||||
IF(ENABLE_TESTING)
|
||||
# Build it once more, but as static library so it can be linked by the test-tool
|
||||
ADD_LIBRARY(TelldusServiceStatic STATIC
|
||||
${telldus-service_SRCS}
|
||||
${telldus-service_protocol_SRCS}
|
||||
${telldus-service_HDRS}
|
||||
)
|
||||
TARGET_LINK_LIBRARIES( TelldusServiceStatic ${telldus-service_LIBRARIES} )
|
||||
IF (UNIX)
|
||||
SET_TARGET_PROPERTIES( TelldusServiceStatic PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
ENDIF (UNIX)
|
||||
ENDIF()
|
||||
266
telldus-core/service/ClientCommunicationHandler.cpp
Normal file
266
telldus-core/service/ClientCommunicationHandler.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ClientCommunicationHandler.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
#include "common/Message.h"
|
||||
#include "common/Strings.h"
|
||||
|
||||
class ClientCommunicationHandler::PrivateData {
|
||||
public:
|
||||
TelldusCore::Socket *clientSocket;
|
||||
TelldusCore::EventRef event, deviceUpdateEvent;
|
||||
bool done;
|
||||
DeviceManager *deviceManager;
|
||||
ControllerManager *controllerManager;
|
||||
};
|
||||
|
||||
ClientCommunicationHandler::ClientCommunicationHandler() {
|
||||
}
|
||||
|
||||
ClientCommunicationHandler::ClientCommunicationHandler(TelldusCore::Socket *clientSocket, TelldusCore::EventRef event, DeviceManager *deviceManager, TelldusCore::EventRef deviceUpdateEvent, ControllerManager *controllerManager)
|
||||
:Thread() {
|
||||
d = new PrivateData;
|
||||
d->clientSocket = clientSocket;
|
||||
d->event = event;
|
||||
d->done = false;
|
||||
d->deviceManager = deviceManager;
|
||||
d->deviceUpdateEvent = deviceUpdateEvent;
|
||||
d->controllerManager = controllerManager;
|
||||
}
|
||||
|
||||
ClientCommunicationHandler::~ClientCommunicationHandler(void) {
|
||||
wait();
|
||||
delete(d->clientSocket);
|
||||
delete d;
|
||||
}
|
||||
|
||||
void ClientCommunicationHandler::run() {
|
||||
// run thread
|
||||
|
||||
std::wstring clientMessage = d->clientSocket->read(2000);
|
||||
|
||||
int intReturn;
|
||||
std::wstring strReturn;
|
||||
strReturn = L"";
|
||||
parseMessage(clientMessage, &intReturn, &strReturn);
|
||||
|
||||
TelldusCore::Message msg;
|
||||
|
||||
if(strReturn == L"") {
|
||||
msg.addArgument(intReturn);
|
||||
} else {
|
||||
msg.addArgument(strReturn);
|
||||
}
|
||||
msg.append(L"\n");
|
||||
d->clientSocket->write(msg);
|
||||
|
||||
// We are done, signal for removal
|
||||
d->done = true;
|
||||
d->event->signal();
|
||||
}
|
||||
|
||||
bool ClientCommunicationHandler::isDone() {
|
||||
return d->done;
|
||||
}
|
||||
|
||||
|
||||
void ClientCommunicationHandler::parseMessage(const std::wstring &clientMessage, int *intReturn, std::wstring *wstringReturn) {
|
||||
(*intReturn) = 0;
|
||||
(*wstringReturn) = L"";
|
||||
std::wstring msg(clientMessage); // Copy
|
||||
std::wstring function(TelldusCore::Message::takeString(&msg));
|
||||
|
||||
if (function == L"tdTurnOn") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_TURNON, 0);
|
||||
|
||||
} else if (function == L"tdTurnOff") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_TURNOFF, 0);
|
||||
|
||||
} else if (function == L"tdBell") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_BELL, 0);
|
||||
|
||||
} else if (function == L"tdDim") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
int level = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_DIM, level);
|
||||
|
||||
} else if (function == L"tdExecute") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_EXECUTE, 0);
|
||||
|
||||
} else if (function == L"tdUp") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_UP, 0);
|
||||
|
||||
} else if (function == L"tdDown") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_DOWN, 0);
|
||||
|
||||
} else if (function == L"tdStop") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_STOP, 0);
|
||||
|
||||
} else if (function == L"tdLearn") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_LEARN, 0);
|
||||
|
||||
} else if (function == L"tdLastSentCommand") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
int methodsSupported = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->getDeviceLastSentCommand(deviceId, methodsSupported);
|
||||
|
||||
} else if (function == L"tdLastSentValue") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*wstringReturn) = d->deviceManager->getDeviceStateValue(deviceId);
|
||||
|
||||
} else if(function == L"tdGetNumberOfDevices") {
|
||||
(*intReturn) = d->deviceManager->getNumberOfDevices();
|
||||
|
||||
} else if (function == L"tdGetDeviceId") {
|
||||
int deviceIndex = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->getDeviceId(deviceIndex);
|
||||
|
||||
} else if (function == L"tdGetDeviceType") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->getDeviceType(deviceId);
|
||||
|
||||
} else if (function == L"tdGetName") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*wstringReturn) = d->deviceManager->getDeviceName(deviceId);
|
||||
|
||||
} else if (function == L"tdSetName") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
std::wstring name = TelldusCore::Message::takeString(&msg);
|
||||
(*intReturn) = d->deviceManager->setDeviceName(deviceId, name);
|
||||
sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_NAME);
|
||||
|
||||
} else if (function == L"tdGetProtocol") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*wstringReturn) = d->deviceManager->getDeviceProtocol(deviceId);
|
||||
|
||||
} else if (function == L"tdSetProtocol") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
std::wstring protocol = TelldusCore::Message::takeString(&msg);
|
||||
int oldMethods = d->deviceManager->getDeviceMethods(deviceId);
|
||||
(*intReturn) = d->deviceManager->setDeviceProtocol(deviceId, protocol);
|
||||
sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_PROTOCOL);
|
||||
if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)) {
|
||||
sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD);
|
||||
}
|
||||
|
||||
} else if (function == L"tdGetModel") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*wstringReturn) = d->deviceManager->getDeviceModel(deviceId);
|
||||
|
||||
} else if (function == L"tdSetModel") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
std::wstring model = TelldusCore::Message::takeString(&msg);
|
||||
int oldMethods = d->deviceManager->getDeviceMethods(deviceId);
|
||||
(*intReturn) = d->deviceManager->setDeviceModel(deviceId, model);
|
||||
sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_MODEL);
|
||||
if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)) {
|
||||
sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD);
|
||||
}
|
||||
|
||||
} else if (function == L"tdGetDeviceParameter") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
std::wstring name = TelldusCore::Message::takeString(&msg);
|
||||
std::wstring defaultValue = TelldusCore::Message::takeString(&msg);
|
||||
(*wstringReturn) = d->deviceManager->getDeviceParameter(deviceId, name, defaultValue);
|
||||
|
||||
} else if (function == L"tdSetDeviceParameter") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
std::wstring name = TelldusCore::Message::takeString(&msg);
|
||||
std::wstring value = TelldusCore::Message::takeString(&msg);
|
||||
int oldMethods = d->deviceManager->getDeviceMethods(deviceId);
|
||||
(*intReturn) = d->deviceManager->setDeviceParameter(deviceId, name, value);
|
||||
if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)) {
|
||||
sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD);
|
||||
}
|
||||
|
||||
} else if (function == L"tdAddDevice") {
|
||||
(*intReturn) = d->deviceManager->addDevice();
|
||||
if((*intReturn) >= 0) {
|
||||
sendDeviceSignal((*intReturn), TELLSTICK_DEVICE_ADDED, 0);
|
||||
}
|
||||
|
||||
} else if (function == L"tdRemoveDevice") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->removeDevice(deviceId);
|
||||
if((*intReturn) == TELLSTICK_SUCCESS) {
|
||||
sendDeviceSignal(deviceId, TELLSTICK_DEVICE_REMOVED, 0);
|
||||
}
|
||||
|
||||
} else if (function == L"tdMethods") {
|
||||
int deviceId = TelldusCore::Message::takeInt(&msg);
|
||||
int intMethodsSupported = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->getDeviceMethods(deviceId, intMethodsSupported);
|
||||
|
||||
} else if (function == L"tdSendRawCommand") {
|
||||
std::wstring command = TelldusCore::Message::takeString(&msg);
|
||||
int reserved = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->deviceManager->sendRawCommand(command, reserved);
|
||||
|
||||
} else if (function == L"tdConnectTellStickController") {
|
||||
int vid = TelldusCore::Message::takeInt(&msg);
|
||||
int pid = TelldusCore::Message::takeInt(&msg);
|
||||
std::string serial = TelldusCore::wideToString(TelldusCore::Message::takeString(&msg));
|
||||
d->deviceManager->connectTellStickController(vid, pid, serial);
|
||||
|
||||
} else if (function == L"tdDisconnectTellStickController") {
|
||||
int vid = TelldusCore::Message::takeInt(&msg);
|
||||
int pid = TelldusCore::Message::takeInt(&msg);
|
||||
std::string serial = TelldusCore::wideToString(TelldusCore::Message::takeString(&msg));
|
||||
d->deviceManager->disconnectTellStickController(vid, pid, serial);
|
||||
|
||||
} else if (function == L"tdSensor") {
|
||||
(*wstringReturn) = d->deviceManager->getSensors();
|
||||
|
||||
} else if (function == L"tdSensorValue") {
|
||||
std::wstring protocol = TelldusCore::Message::takeString(&msg);
|
||||
std::wstring model = TelldusCore::Message::takeString(&msg);
|
||||
int id = TelldusCore::Message::takeInt(&msg);
|
||||
int dataType = TelldusCore::Message::takeInt(&msg);
|
||||
(*wstringReturn) = d->deviceManager->getSensorValue(protocol, model, id, dataType);
|
||||
|
||||
} else if (function == L"tdController") {
|
||||
(*wstringReturn) = d->controllerManager->getControllers();
|
||||
|
||||
} else if (function == L"tdControllerValue") {
|
||||
int id = TelldusCore::Message::takeInt(&msg);
|
||||
std::wstring name = TelldusCore::Message::takeString(&msg);
|
||||
(*wstringReturn) = d->controllerManager->getControllerValue(id, name);
|
||||
|
||||
} else if (function == L"tdSetControllerValue") {
|
||||
int id = TelldusCore::Message::takeInt(&msg);
|
||||
std::wstring name = TelldusCore::Message::takeString(&msg);
|
||||
std::wstring value = TelldusCore::Message::takeString(&msg);
|
||||
(*intReturn) = d->controllerManager->setControllerValue(id, name, value);
|
||||
|
||||
} else if (function == L"tdRemoveController") {
|
||||
int controllerId = TelldusCore::Message::takeInt(&msg);
|
||||
(*intReturn) = d->controllerManager->removeController(controllerId);
|
||||
|
||||
} else {
|
||||
(*intReturn) = TELLSTICK_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientCommunicationHandler::sendDeviceSignal(int deviceId, int eventDeviceChanges, int eventChangeType) {
|
||||
EventUpdateData *eventData = new EventUpdateData();
|
||||
eventData->messageType = L"TDDeviceChangeEvent";
|
||||
eventData->deviceId = deviceId;
|
||||
eventData->eventDeviceChanges = eventDeviceChanges;
|
||||
eventData->eventChangeType = eventChangeType;
|
||||
d->deviceUpdateEvent->signal(eventData);
|
||||
}
|
||||
41
telldus-core/service/ClientCommunicationHandler.h
Normal file
41
telldus-core/service/ClientCommunicationHandler.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_CLIENTCOMMUNICATIONHANDLER_H_
|
||||
#define TELLDUS_CORE_SERVICE_CLIENTCOMMUNICATIONHANDLER_H_
|
||||
|
||||
#include <string>
|
||||
#include "common/Thread.h"
|
||||
#include "common/Socket.h"
|
||||
#include "common/Event.h"
|
||||
#include "service/DeviceManager.h"
|
||||
#include "service/ControllerManager.h"
|
||||
|
||||
class ClientCommunicationHandler : public TelldusCore::Thread {
|
||||
public:
|
||||
ClientCommunicationHandler();
|
||||
ClientCommunicationHandler(
|
||||
TelldusCore::Socket *clientSocket,
|
||||
TelldusCore::EventRef event,
|
||||
DeviceManager *deviceManager,
|
||||
TelldusCore::EventRef deviceUpdateEvent,
|
||||
ControllerManager *controllerManager
|
||||
);
|
||||
~ClientCommunicationHandler(void);
|
||||
|
||||
bool isDone();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
void parseMessage(const std::wstring &clientMessage, int *intReturn, std::wstring *wstringReturn);
|
||||
void sendDeviceSignal(int deviceId, int eventDeviceChanges, int eventChangeType);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_CLIENTCOMMUNICATIONHANDLER_H_
|
||||
37
telldus-core/service/ConnectionListener.h
Normal file
37
telldus-core/service/ConnectionListener.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_CONNECTIONLISTENER_H_
|
||||
#define TELLDUS_CORE_SERVICE_CONNECTIONLISTENER_H_
|
||||
|
||||
#include <string>
|
||||
#include "common/Thread.h"
|
||||
#include "common/Event.h"
|
||||
|
||||
class Event;
|
||||
namespace TelldusCore {
|
||||
class Socket;
|
||||
};
|
||||
|
||||
class ConnectionListenerEventData : public TelldusCore::EventDataBase {
|
||||
public:
|
||||
TelldusCore::Socket *socket;
|
||||
};
|
||||
|
||||
class ConnectionListener : public TelldusCore::Thread {
|
||||
public:
|
||||
ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent);
|
||||
virtual ~ConnectionListener(void);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_CONNECTIONLISTENER_H_
|
||||
100
telldus-core/service/ConnectionListener_unix.cpp
Normal file
100
telldus-core/service/ConnectionListener_unix.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
|
||||
#include "service/ConnectionListener.h"
|
||||
#include "common/Socket.h"
|
||||
|
||||
#if defined(_MACOSX) && !defined(SOCK_CLOEXEC)
|
||||
#define SOCK_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
class ConnectionListener::PrivateData {
|
||||
public:
|
||||
TelldusCore::EventRef waitEvent;
|
||||
std::string name;
|
||||
bool running;
|
||||
};
|
||||
|
||||
ConnectionListener::ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent) {
|
||||
d = new PrivateData;
|
||||
d->waitEvent = waitEvent;
|
||||
|
||||
d->name = "/tmp/" + std::string(name.begin(), name.end());
|
||||
d->running = true;
|
||||
|
||||
this->start();
|
||||
}
|
||||
|
||||
ConnectionListener::~ConnectionListener(void) {
|
||||
d->running = false;
|
||||
this->wait();
|
||||
unlink(d->name.c_str());
|
||||
delete d;
|
||||
}
|
||||
|
||||
void ConnectionListener::run() {
|
||||
struct timeval tv = { 0, 0 };
|
||||
|
||||
// Timeout for select
|
||||
|
||||
SOCKET_T serverSocket;
|
||||
struct sockaddr_un name;
|
||||
serverSocket = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (serverSocket < 0) {
|
||||
return;
|
||||
}
|
||||
#if defined(_MACOSX)
|
||||
int op = fcntl(serverSocket, F_GETFD);
|
||||
fcntl(serverSocket, F_SETFD, op | FD_CLOEXEC); // OS X doesn't support SOCK_CLOEXEC yet
|
||||
#endif
|
||||
name.sun_family = AF_LOCAL;
|
||||
memset(name.sun_path, '\0', sizeof(name.sun_path));
|
||||
strncpy(name.sun_path, d->name.c_str(), sizeof(name.sun_path));
|
||||
unlink(name.sun_path);
|
||||
int size = SUN_LEN(&name);
|
||||
bind(serverSocket, (struct sockaddr *)&name, size);
|
||||
listen(serverSocket, 5);
|
||||
|
||||
// Change permissions to allow everyone
|
||||
chmod(d->name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
|
||||
fd_set infds;
|
||||
FD_ZERO(&infds);
|
||||
FD_SET(serverSocket, &infds);
|
||||
|
||||
while(d->running) {
|
||||
tv.tv_sec = 5;
|
||||
|
||||
int response = select(serverSocket+1, &infds, NULL, NULL, &tv);
|
||||
if (response == 0) {
|
||||
FD_SET(serverSocket, &infds);
|
||||
continue;
|
||||
} else if (response < 0 ) {
|
||||
continue;
|
||||
}
|
||||
// Make sure it is a new connection
|
||||
if (!FD_ISSET(serverSocket, &infds)) {
|
||||
continue;
|
||||
}
|
||||
SOCKET_T clientSocket = accept(serverSocket, NULL, NULL);
|
||||
|
||||
ConnectionListenerEventData *data = new ConnectionListenerEventData();
|
||||
data->socket = new TelldusCore::Socket(clientSocket);
|
||||
d->waitEvent->signal(data);
|
||||
}
|
||||
close(serverSocket);
|
||||
}
|
||||
|
||||
153
telldus-core/service/ConnectionListener_win.cpp
Normal file
153
telldus-core/service/ConnectionListener_win.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ConnectionListener.h"
|
||||
|
||||
#include <AccCtrl.h>
|
||||
#include <Aclapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "common/Event.h"
|
||||
#include "common/Socket.h"
|
||||
|
||||
#define BUFSIZE 512
|
||||
|
||||
class ConnectionListener::PrivateData {
|
||||
public:
|
||||
std::wstring pipename;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
HANDLE hEvent;
|
||||
bool running;
|
||||
TelldusCore::EventRef waitEvent;
|
||||
};
|
||||
|
||||
ConnectionListener::ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent) {
|
||||
d = new PrivateData;
|
||||
d->hEvent = 0;
|
||||
|
||||
d->running = true;
|
||||
d->waitEvent = waitEvent;
|
||||
d->pipename = L"\\\\.\\pipe\\" + name;
|
||||
|
||||
PSECURITY_DESCRIPTOR pSD = NULL;
|
||||
PACL pACL = NULL;
|
||||
EXPLICIT_ACCESS ea;
|
||||
PSID pEveryoneSID = NULL;
|
||||
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
|
||||
|
||||
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
if (pSD == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
|
||||
LocalFree(pSD);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) {
|
||||
LocalFree(pSD);
|
||||
}
|
||||
|
||||
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
|
||||
ea.grfAccessPermissions = STANDARD_RIGHTS_ALL;
|
||||
ea.grfAccessMode = SET_ACCESS;
|
||||
ea.grfInheritance= NO_INHERITANCE;
|
||||
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
|
||||
ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID;
|
||||
|
||||
// Add the ACL to the security descriptor.
|
||||
if (!SetSecurityDescriptorDacl(pSD,
|
||||
TRUE, // bDaclPresent flag
|
||||
pACL,
|
||||
FALSE)) { // not a default DACL
|
||||
LocalFree(pSD);
|
||||
FreeSid(pEveryoneSID);
|
||||
}
|
||||
|
||||
|
||||
d->sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
d->sa.lpSecurityDescriptor = pSD;
|
||||
d->sa.bInheritHandle = false;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
ConnectionListener::~ConnectionListener(void) {
|
||||
d->running = false;
|
||||
if (d->hEvent) {
|
||||
SetEvent(d->hEvent);
|
||||
}
|
||||
wait();
|
||||
delete d;
|
||||
}
|
||||
|
||||
void ConnectionListener::run() {
|
||||
HANDLE hPipe;
|
||||
OVERLAPPED oOverlap;
|
||||
DWORD cbBytesRead;
|
||||
|
||||
memset(&oOverlap, 0, sizeof(OVERLAPPED));
|
||||
|
||||
d->hEvent = CreateEvent(NULL, true, false, NULL);
|
||||
oOverlap.hEvent = d->hEvent;
|
||||
bool recreate = true;
|
||||
|
||||
while (1) {
|
||||
BOOL alreadyConnected = false;
|
||||
if (recreate) {
|
||||
hPipe = CreateNamedPipe(
|
||||
(const wchar_t *)d->pipename.c_str(), // pipe name
|
||||
PIPE_ACCESS_DUPLEX | // read/write access
|
||||
FILE_FLAG_OVERLAPPED, // Overlapped mode
|
||||
PIPE_TYPE_MESSAGE | // message type pipe
|
||||
PIPE_READMODE_MESSAGE | // message-read mode
|
||||
PIPE_WAIT, // blocking mode
|
||||
PIPE_UNLIMITED_INSTANCES, // max. instances
|
||||
BUFSIZE, // output buffer size
|
||||
BUFSIZE, // input buffer size
|
||||
0, // client time-out
|
||||
&d->sa); // default security attribute
|
||||
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectNamedPipe(hPipe, &oOverlap);
|
||||
alreadyConnected = GetLastError() == ERROR_PIPE_CONNECTED;
|
||||
recreate = false;
|
||||
}
|
||||
if(!alreadyConnected) {
|
||||
DWORD result = WaitForSingleObject(oOverlap.hEvent, 1000);
|
||||
if (!d->running) {
|
||||
CancelIo(hPipe);
|
||||
WaitForSingleObject(oOverlap.hEvent, INFINITE);
|
||||
break;
|
||||
}
|
||||
|
||||
if(result == WAIT_TIMEOUT) {
|
||||
// CloseHandle(hPipe);
|
||||
continue;
|
||||
}
|
||||
BOOL connected = GetOverlappedResult(hPipe, &oOverlap, &cbBytesRead, false);
|
||||
|
||||
if (!connected) {
|
||||
CloseHandle(hPipe);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ConnectionListenerEventData *data = new ConnectionListenerEventData();
|
||||
ResetEvent(oOverlap.hEvent);
|
||||
data->socket = new TelldusCore::Socket(hPipe);
|
||||
d->waitEvent->signal(data);
|
||||
|
||||
recreate = true;
|
||||
}
|
||||
|
||||
CloseHandle(d->hEvent);
|
||||
CloseHandle(hPipe);
|
||||
}
|
||||
99
telldus-core/service/Controller.cpp
Normal file
99
telldus-core/service/Controller.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#define _CRT_RAND_S
|
||||
#include "service/Controller.h"
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/EventUpdateManager.h"
|
||||
#include "common/Strings.h"
|
||||
|
||||
inline int random( unsigned int* seed ) {
|
||||
#ifdef _WINDOWS
|
||||
unsigned int randomNumber;
|
||||
rand_s( &randomNumber ); // no seed needed
|
||||
return randomNumber;
|
||||
#else
|
||||
return rand_r( seed );
|
||||
#endif
|
||||
}
|
||||
|
||||
class Controller::PrivateData {
|
||||
public:
|
||||
TelldusCore::EventRef event, updateEvent;
|
||||
int id, firmwareVersion;
|
||||
unsigned int randSeed;
|
||||
std::map<std::string, time_t> duplicates;
|
||||
};
|
||||
|
||||
Controller::Controller(int id, TelldusCore::EventRef event, TelldusCore::EventRef updateEvent) {
|
||||
d = new PrivateData;
|
||||
d->event = event;
|
||||
d->updateEvent = updateEvent;
|
||||
d->id = id;
|
||||
d->firmwareVersion = 0;
|
||||
d->randSeed = time(NULL);
|
||||
}
|
||||
|
||||
Controller::~Controller() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Controller::publishData(const std::string &msg) const {
|
||||
ControllerEventData *data = new ControllerEventData;
|
||||
data->msg = msg;
|
||||
data->controllerId = d->id;
|
||||
d->event->signal(data);
|
||||
}
|
||||
|
||||
void Controller::decodePublishData(const std::string &data) const {
|
||||
// Garbange collect?
|
||||
if (random(&d->randSeed) % 1000 == 1) {
|
||||
time_t t = time(NULL);
|
||||
// Standard associative-container erase idiom
|
||||
for (std::map<std::string, time_t>::iterator it = d->duplicates.begin(); it != d->duplicates.end(); /* no increment */) {
|
||||
if ((*it).second != t) {
|
||||
d->duplicates.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Duplicate check
|
||||
if (d->duplicates.count(data) > 0) {
|
||||
time_t t = d->duplicates[data];
|
||||
if (t == time(NULL)) {
|
||||
// Duplicate message
|
||||
return;
|
||||
}
|
||||
}
|
||||
d->duplicates[data] = time(NULL);
|
||||
|
||||
std::list<std::string> msgList = Protocol::decodeData(data);
|
||||
|
||||
for (std::list<std::string>::iterator msgIt = msgList.begin(); msgIt != msgList.end(); ++msgIt) {
|
||||
this->publishData(*msgIt);
|
||||
}
|
||||
}
|
||||
|
||||
int Controller::firmwareVersion() const {
|
||||
return d->firmwareVersion;
|
||||
}
|
||||
|
||||
void Controller::setFirmwareVersion(int version) {
|
||||
d->firmwareVersion = version;
|
||||
EventUpdateData *eventData = new EventUpdateData();
|
||||
eventData->messageType = L"TDControllerEvent";
|
||||
eventData->controllerId = d->id;
|
||||
eventData->eventState = TELLSTICK_DEVICE_CHANGED;
|
||||
eventData->eventChangeType = TELLSTICK_CHANGE_FIRMWARE;
|
||||
eventData->eventValue = TelldusCore::intToWstring(version);
|
||||
d->updateEvent->signal(eventData);
|
||||
}
|
||||
38
telldus-core/service/Controller.h
Normal file
38
telldus-core/service/Controller.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_CONTROLLER_H_
|
||||
#define TELLDUS_CORE_SERVICE_CONTROLLER_H_
|
||||
|
||||
#include <string>
|
||||
#include "common/Event.h"
|
||||
|
||||
class ControllerEventData : public TelldusCore::EventDataBase {
|
||||
public:
|
||||
std::string msg;
|
||||
int controllerId;
|
||||
};
|
||||
|
||||
class Controller {
|
||||
public:
|
||||
virtual ~Controller();
|
||||
|
||||
virtual int firmwareVersion() const;
|
||||
virtual int send( const std::string &message ) = 0;
|
||||
virtual int reset() = 0;
|
||||
|
||||
protected:
|
||||
Controller(int id, TelldusCore::EventRef event, TelldusCore::EventRef updateEvent);
|
||||
void publishData(const std::string &data) const;
|
||||
void decodePublishData(const std::string &data) const;
|
||||
void setFirmwareVersion(int version);
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_CONTROLLER_H_
|
||||
32
telldus-core/service/ControllerListener.h
Normal file
32
telldus-core/service/ControllerListener.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_CONTROLLERLISTENER_H_
|
||||
#define TELLDUS_CORE_SERVICE_CONTROLLERLISTENER_H_
|
||||
|
||||
#include "common/Thread.h"
|
||||
#include "common/Event.h"
|
||||
|
||||
class ControllerChangeEventData : public TelldusCore::EventDataBase {
|
||||
public:
|
||||
int vid, pid;
|
||||
bool inserted;
|
||||
};
|
||||
|
||||
class ControllerListener : public TelldusCore::Thread {
|
||||
public:
|
||||
explicit ControllerListener(TelldusCore::EventRef event);
|
||||
virtual ~ControllerListener();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_CONTROLLERLISTENER_H_
|
||||
187
telldus-core/service/ControllerListener_mac.cpp
Normal file
187
telldus-core/service/ControllerListener_mac.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ControllerListener.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/IOMessage.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
#include <IOKit/usb/IOUSBLib.h>
|
||||
#include <string>
|
||||
|
||||
class TellStickData {
|
||||
public:
|
||||
io_object_t notification;
|
||||
CFStringRef serialNumber;
|
||||
UInt32 vid;
|
||||
UInt32 pid;
|
||||
TelldusCore::EventRef event;
|
||||
};
|
||||
|
||||
class ControllerListener::PrivateData {
|
||||
public:
|
||||
IONotificationPortRef gNotifyPort;
|
||||
CFRunLoopRef gRunLoop;
|
||||
io_iterator_t gAddedIter;
|
||||
TelldusCore::EventRef event;
|
||||
bool running;
|
||||
|
||||
void addUsbFilter(int vid, int pid);
|
||||
static void DeviceAdded(void *refCon, io_iterator_t iterator);
|
||||
static void DeviceNotification(void *refCon, io_service_t service, natural_t messageType, void *messageArgument);
|
||||
};
|
||||
|
||||
ControllerListener::ControllerListener(TelldusCore::EventRef event)
|
||||
:Thread() {
|
||||
d = new PrivateData;
|
||||
d->event = event;
|
||||
d->running = true;
|
||||
d->gRunLoop = NULL;
|
||||
this->start();
|
||||
}
|
||||
|
||||
ControllerListener::~ControllerListener() {
|
||||
d->running = false;
|
||||
if(d->gRunLoop != NULL)
|
||||
CFRunLoopStop(d->gRunLoop);
|
||||
|
||||
this->wait();
|
||||
delete d;
|
||||
}
|
||||
|
||||
void ControllerListener::run() {
|
||||
CFRunLoopSourceRef runLoopSource;
|
||||
|
||||
d->gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);
|
||||
runLoopSource = IONotificationPortGetRunLoopSource(d->gNotifyPort);
|
||||
|
||||
d->gRunLoop = CFRunLoopGetCurrent();
|
||||
CFRunLoopAddSource(d->gRunLoop, runLoopSource, kCFRunLoopDefaultMode);
|
||||
|
||||
d->addUsbFilter(0x1781, 0x0c30);
|
||||
d->addUsbFilter(0x1781, 0x0c31);
|
||||
|
||||
// Race check, if destructor was called really close to thread init,
|
||||
// running might have gone false. Make sure we don't get stuck
|
||||
if (d->running) {
|
||||
CFRunLoopRun();
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerListener::PrivateData::addUsbFilter(int vid, int pid) {
|
||||
CFNumberRef numberRef;
|
||||
CFMutableDictionaryRef matchingDict;
|
||||
|
||||
matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Interested in instances of class
|
||||
// IOUSBDevice and its subclasses
|
||||
if (matchingDict == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a CFNumber for the idVendor and set the value in the dictionary
|
||||
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vid);
|
||||
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
|
||||
CFRelease(numberRef);
|
||||
|
||||
// Create a CFNumber for the idProduct and set the value in the dictionary
|
||||
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pid);
|
||||
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
|
||||
CFRelease(numberRef);
|
||||
|
||||
// Now set up a notification to be called when a device is first matched by I/O Kit.
|
||||
IOServiceAddMatchingNotification(gNotifyPort, // notifyPort
|
||||
kIOFirstMatchNotification, // notificationType
|
||||
matchingDict, // matching
|
||||
PrivateData::DeviceAdded, // callback
|
||||
this, // refCon
|
||||
&gAddedIter // notification
|
||||
);
|
||||
// Iterate once to get already-present devices and arm the notification
|
||||
PrivateData::DeviceAdded(this, gAddedIter);
|
||||
}
|
||||
|
||||
void ControllerListener::PrivateData::DeviceNotification(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) {
|
||||
if (messageType != kIOMessageServiceIsTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
TellStickData *tsd = reinterpret_cast<TellStickData*> (refCon);
|
||||
if (!tsd) {
|
||||
return;
|
||||
}
|
||||
|
||||
CFIndex size = CFStringGetLength(tsd->serialNumber);
|
||||
char *s = new char[size+1];
|
||||
CFStringGetCString(tsd->serialNumber, s, size+1, kCFStringEncodingASCII);
|
||||
std::string serial(s); // Copy the string to the stack
|
||||
delete[] s;
|
||||
|
||||
ControllerChangeEventData *data = new ControllerChangeEventData;
|
||||
data->vid = tsd->vid;
|
||||
data->pid = tsd->pid;
|
||||
data->inserted = false;
|
||||
tsd->event->signal(data);
|
||||
|
||||
// Free the data we're no longer using now that the device is going away
|
||||
CFRelease(tsd->serialNumber);
|
||||
|
||||
IOObjectRelease(tsd->notification);
|
||||
|
||||
delete tsd;
|
||||
}
|
||||
|
||||
void ControllerListener::PrivateData::DeviceAdded(void *refCon, io_iterator_t iterator) {
|
||||
io_service_t usbDevice;
|
||||
|
||||
PrivateData *pd = reinterpret_cast<PrivateData*> (refCon);
|
||||
|
||||
while ((usbDevice = IOIteratorNext(iterator))) {
|
||||
TellStickData *tsd = new TellStickData;
|
||||
tsd->event = pd->event;
|
||||
|
||||
// Get the serial number
|
||||
CFStringRef serialRef = reinterpret_cast<CFStringRef>(IORegistryEntryCreateCFProperty( usbDevice, CFSTR("USB Serial Number" ), kCFAllocatorDefault, 0 ));
|
||||
if (serialRef == NULL) {
|
||||
// No serial number, we cannot continue. Sorry
|
||||
continue;
|
||||
}
|
||||
|
||||
CFNumberRef vidRef = reinterpret_cast<CFNumberRef> (IORegistryEntryCreateCFProperty(usbDevice, CFSTR("idVendor"), kCFAllocatorDefault, 0));
|
||||
if (vidRef) {
|
||||
CFNumberGetValue(vidRef, kCFNumberIntType, &(tsd->vid));
|
||||
CFRelease(vidRef);
|
||||
}
|
||||
|
||||
CFNumberRef pidRef = reinterpret_cast<CFNumberRef> (IORegistryEntryCreateCFProperty(usbDevice, CFSTR("idProduct"), kCFAllocatorDefault, 0));
|
||||
if (pidRef) {
|
||||
CFNumberGetValue(pidRef, kCFNumberIntType, &(tsd->pid));
|
||||
CFRelease(pidRef);
|
||||
}
|
||||
|
||||
CFStringRef serialNumberAsCFString = CFStringCreateCopy(kCFAllocatorDefault, serialRef);
|
||||
tsd->serialNumber = serialNumberAsCFString;
|
||||
CFRelease(serialRef);
|
||||
|
||||
// Register for an interest notification of this device being removed. Use a reference to our
|
||||
// private data as the refCon which will be passed to the notification callback.
|
||||
IOServiceAddInterestNotification(pd->gNotifyPort, usbDevice, kIOGeneralInterest, DeviceNotification, tsd, &(tsd->notification));
|
||||
|
||||
CFIndex size = CFStringGetLength(serialNumberAsCFString);
|
||||
char *s = new char[size+1];
|
||||
CFStringGetCString(serialNumberAsCFString, s, size+1, kCFStringEncodingASCII);
|
||||
std::string serial(s); // Copy the string to the stack
|
||||
delete[] s;
|
||||
|
||||
IOObjectRelease(usbDevice);
|
||||
|
||||
ControllerChangeEventData *data = new ControllerChangeEventData;
|
||||
data->vid = tsd->vid;
|
||||
data->pid = tsd->pid;
|
||||
data->inserted = true;
|
||||
tsd->event->signal(data);
|
||||
}
|
||||
}
|
||||
374
telldus-core/service/ControllerManager.cpp
Normal file
374
telldus-core/service/ControllerManager.cpp
Normal file
@@ -0,0 +1,374 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ControllerManager.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "service/Controller.h"
|
||||
#include "common/Mutex.h"
|
||||
#include "service/TellStick.h"
|
||||
#include "service/Log.h"
|
||||
#include "common/Message.h"
|
||||
#include "common/Strings.h"
|
||||
#include "service/Settings.h"
|
||||
#include "service/EventUpdateManager.h"
|
||||
#include "client/telldus-core.h"
|
||||
|
||||
class ControllerDescriptor {
|
||||
public:
|
||||
std::wstring name, serial;
|
||||
int type;
|
||||
Controller *controller;
|
||||
};
|
||||
|
||||
typedef std::map<int, ControllerDescriptor> ControllerMap;
|
||||
|
||||
class ControllerManager::PrivateData {
|
||||
public:
|
||||
int lastControllerId;
|
||||
Settings settings;
|
||||
ControllerMap controllers;
|
||||
TelldusCore::EventRef event, updateEvent;
|
||||
TelldusCore::Mutex mutex;
|
||||
};
|
||||
|
||||
ControllerManager::ControllerManager(TelldusCore::EventRef event, TelldusCore::EventRef updateEvent) {
|
||||
d = new PrivateData;
|
||||
d->lastControllerId = 0;
|
||||
d->event = event;
|
||||
d->updateEvent = updateEvent;
|
||||
this->loadStoredControllers();
|
||||
this->loadControllers();
|
||||
}
|
||||
|
||||
ControllerManager::~ControllerManager() {
|
||||
for (ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) {
|
||||
if (it->second.controller) {
|
||||
delete( it->second.controller );
|
||||
}
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
int ControllerManager::count() {
|
||||
unsigned int count = 0;
|
||||
{
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
// Find all available controllers
|
||||
for(ControllerMap::const_iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) {
|
||||
if (it->second.controller) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
this->loadControllers();
|
||||
// Try again
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
// Find all available controllers
|
||||
for(ControllerMap::const_iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) {
|
||||
if (it->second.controller) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void ControllerManager::deviceInsertedOrRemoved(int vid, int pid, const std::string &serial, bool inserted) {
|
||||
if (vid == 0x0 && pid == 0x0) { // All
|
||||
if (inserted) {
|
||||
loadControllers();
|
||||
} else {
|
||||
// Disconnect all
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
while(d->controllers.size()) {
|
||||
ControllerMap::iterator it = d->controllers.begin();
|
||||
delete it->second.controller;
|
||||
it->second.controller = 0;
|
||||
signalControllerEvent(it->first, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"0");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (vid != 0x1781) {
|
||||
return;
|
||||
}
|
||||
if (pid != 0x0C30 && pid != 0x0C31) {
|
||||
return;
|
||||
}
|
||||
if (inserted) {
|
||||
loadControllers();
|
||||
} else {
|
||||
// Autodetect which has been disconnected
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) {
|
||||
if (!it->second.controller) {
|
||||
continue;
|
||||
}
|
||||
TellStick *tellstick = reinterpret_cast<TellStick*>(it->second.controller);
|
||||
if (!tellstick) {
|
||||
continue;
|
||||
}
|
||||
if (serial.compare("") != 0) {
|
||||
TellStickDescriptor tsd;
|
||||
tsd.vid = vid;
|
||||
tsd.pid = pid;
|
||||
tsd.serial = serial;
|
||||
if (!tellstick->isSameAsDescriptor(tsd)) {
|
||||
continue;
|
||||
}
|
||||
} else if (tellstick->stillConnected()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
it->second.controller = 0;
|
||||
delete tellstick;
|
||||
signalControllerEvent(it->first, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller *ControllerManager::getBestControllerById(int id) {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
if (!d->controllers.size()) {
|
||||
return 0;
|
||||
}
|
||||
ControllerMap::const_iterator it = d->controllers.find(id);
|
||||
if (it != d->controllers.end() && it->second.controller) {
|
||||
return it->second.controller;
|
||||
}
|
||||
// Find first available controller
|
||||
for(it = d->controllers.begin(); it != d->controllers.end(); ++it) {
|
||||
if (it->second.controller) {
|
||||
return it->second.controller;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ControllerManager::loadControllers() {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
|
||||
std::list<TellStickDescriptor> list = TellStick::findAll();
|
||||
|
||||
std::list<TellStickDescriptor>::iterator it = list.begin();
|
||||
for(; it != list.end(); ++it) {
|
||||
// Most backend only report non-opened devices.
|
||||
// If they don't make sure we don't open them twice
|
||||
bool found = false;
|
||||
ControllerMap::const_iterator cit = d->controllers.begin();
|
||||
for(; cit != d->controllers.end(); ++cit) {
|
||||
if (!cit->second.controller) {
|
||||
continue;
|
||||
}
|
||||
TellStick *tellstick = reinterpret_cast<TellStick*>(cit->second.controller);
|
||||
if (!tellstick) {
|
||||
continue;
|
||||
}
|
||||
if (tellstick->isSameAsDescriptor(*it)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int type = TELLSTICK_CONTROLLER_TELLSTICK;
|
||||
if ((*it).pid == 0x0c31) {
|
||||
type = TELLSTICK_CONTROLLER_TELLSTICK_DUO;
|
||||
}
|
||||
int controllerId = 0;
|
||||
// See if the controller matches one of the loaded, non available controllers
|
||||
std::wstring serial = TelldusCore::charToWstring((*it).serial.c_str());
|
||||
for(cit = d->controllers.begin(); cit != d->controllers.end(); ++cit) {
|
||||
if (cit->second.type == type && cit->second.serial.compare(serial) == 0) {
|
||||
controllerId = cit->first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool isNew = false;
|
||||
if (!controllerId) {
|
||||
controllerId = d->settings.addNode(Settings::Controller);
|
||||
if(controllerId < 0) {
|
||||
// TODO(micke): How to handle this?
|
||||
continue;
|
||||
}
|
||||
isNew = true;
|
||||
d->controllers[controllerId].type = type;
|
||||
d->settings.setControllerType(controllerId, type);
|
||||
d->controllers[controllerId].serial = TelldusCore::charToWstring((*it).serial.c_str());
|
||||
d->settings.setControllerSerial(controllerId, d->controllers[controllerId].serial);
|
||||
}
|
||||
|
||||
// int controllerId = d->lastControllerId+1;
|
||||
TellStick *controller = new TellStick(controllerId, d->event, d->updateEvent, *it);
|
||||
if (!controller->isOpen()) {
|
||||
delete controller;
|
||||
continue;
|
||||
}
|
||||
d->controllers[controllerId].controller = controller;
|
||||
if (isNew) {
|
||||
signalControllerEvent(controllerId, TELLSTICK_DEVICE_ADDED, type, L"");
|
||||
} else {
|
||||
signalControllerEvent(controllerId, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerManager::loadStoredControllers() {
|
||||
int numberOfControllers = d->settings.getNumberOfNodes(Settings::Controller);
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
|
||||
for (int i = 0; i < numberOfControllers; ++i) {
|
||||
int id = d->settings.getNodeId(Settings::Controller, i);
|
||||
d->controllers[id].controller = NULL;
|
||||
d->controllers[id].name = d->settings.getName(Settings::Controller, id);
|
||||
const int type = d->settings.getControllerType(id);
|
||||
d->controllers[id].type = type;
|
||||
d->controllers[id].serial = d->settings.getControllerSerial(id);
|
||||
signalControllerEvent(id, TELLSTICK_DEVICE_ADDED, type, L"");
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerManager::queryControllerStatus() {
|
||||
std::list<TellStick *> tellStickControllers;
|
||||
|
||||
{
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) {
|
||||
if (!it->second.controller) {
|
||||
continue;
|
||||
}
|
||||
TellStick *tellstick = reinterpret_cast<TellStick*>(it->second.controller);
|
||||
if (tellstick) {
|
||||
tellStickControllers.push_back(tellstick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool reloadControllers = false;
|
||||
std::string noop = "N+";
|
||||
for(std::list<TellStick *>::iterator it = tellStickControllers.begin(); it != tellStickControllers.end(); ++it) {
|
||||
int success = (*it)->send(noop);
|
||||
if(success == TELLSTICK_ERROR_BROKEN_PIPE) {
|
||||
Log::warning("TellStick query: Error in communication with TellStick, resetting USB");
|
||||
resetController(*it);
|
||||
}
|
||||
if(success == TELLSTICK_ERROR_BROKEN_PIPE || success == TELLSTICK_ERROR_NOT_FOUND) {
|
||||
reloadControllers = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!tellStickControllers.size() || reloadControllers) {
|
||||
// no tellstick at all found, or controller was reset
|
||||
Log::debug("TellStick query: Rescanning USB ports"); // only log as debug, since this will happen all the time if no TellStick is connected
|
||||
loadControllers();
|
||||
}
|
||||
}
|
||||
|
||||
int ControllerManager::resetController(Controller *controller) {
|
||||
TellStick *tellstick = reinterpret_cast<TellStick*>(controller);
|
||||
if (!tellstick) {
|
||||
return true; // not tellstick, nothing to reset at the moment, just return true
|
||||
}
|
||||
int success = tellstick->reset();
|
||||
deviceInsertedOrRemoved(tellstick->vid(), tellstick->pid(), tellstick->serial(), false); // remove from list and delete
|
||||
return success;
|
||||
}
|
||||
|
||||
std::wstring ControllerManager::getControllers() const {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
|
||||
TelldusCore::Message msg;
|
||||
|
||||
msg.addArgument(static_cast<int>(d->controllers.size()));
|
||||
|
||||
for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) {
|
||||
msg.addArgument(it->first);
|
||||
msg.addArgument(it->second.type);
|
||||
msg.addArgument(it->second.name.c_str());
|
||||
msg.addArgument(it->second.controller ? 1 : 0);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
std::wstring ControllerManager::getControllerValue(int id, const std::wstring &name) {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
|
||||
ControllerMap::iterator it = d->controllers.find(id);
|
||||
if (it == d->controllers.end()) {
|
||||
return L"";
|
||||
}
|
||||
if (name == L"serial") {
|
||||
return it->second.serial;
|
||||
} else if (name == L"name") {
|
||||
return it->second.name;
|
||||
} else if (name == L"available") {
|
||||
return it->second.controller ? L"1" : L"0";
|
||||
} else if (name == L"firmware") {
|
||||
if (!it->second.controller) {
|
||||
return L"-1";
|
||||
}
|
||||
return TelldusCore::intToWstring(it->second.controller->firmwareVersion());
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
int ControllerManager::removeController(int id) {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
|
||||
ControllerMap::iterator it = d->controllers.find(id);
|
||||
if (it == d->controllers.end()) {
|
||||
return TELLSTICK_ERROR_NOT_FOUND;
|
||||
}
|
||||
if (it->second.controller) {
|
||||
// Still connected
|
||||
return TELLSTICK_ERROR_PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
int ret = d->settings.removeNode(Settings::Controller, id);
|
||||
if (ret != TELLSTICK_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
d->controllers.erase(it);
|
||||
|
||||
signalControllerEvent(id, TELLSTICK_DEVICE_REMOVED, 0, L"");
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
int ControllerManager::setControllerValue(int id, const std::wstring &name, const std::wstring &value) {
|
||||
TelldusCore::MutexLocker locker(&d->mutex);
|
||||
|
||||
ControllerMap::iterator it = d->controllers.find(id);
|
||||
if (it == d->controllers.end()) {
|
||||
return TELLSTICK_ERROR_NOT_FOUND;
|
||||
}
|
||||
if (name == L"name") {
|
||||
it->second.name = value;
|
||||
d->settings.setName(Settings::Controller, id, value);
|
||||
signalControllerEvent(id, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_NAME, value);
|
||||
} else {
|
||||
return TELLSTICK_ERROR_SYNTAX; // TODO(micke): Is this the best error?
|
||||
}
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
void ControllerManager::signalControllerEvent(int controllerId, int changeEvent, int changeType, const std::wstring &newValue) {
|
||||
EventUpdateData *eventData = new EventUpdateData();
|
||||
eventData->messageType = L"TDControllerEvent";
|
||||
eventData->controllerId = controllerId;
|
||||
eventData->eventState = changeEvent;
|
||||
eventData->eventChangeType = changeType;
|
||||
eventData->eventValue = newValue;
|
||||
d->updateEvent->signal(eventData);
|
||||
}
|
||||
40
telldus-core/service/ControllerManager.h
Normal file
40
telldus-core/service/ControllerManager.h
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_CONTROLLERMANAGER_H_
|
||||
#define TELLDUS_CORE_SERVICE_CONTROLLERMANAGER_H_
|
||||
|
||||
#include <string>
|
||||
#include "common/Event.h"
|
||||
class Controller;
|
||||
|
||||
|
||||
class ControllerManager {
|
||||
public:
|
||||
ControllerManager(TelldusCore::EventRef event, TelldusCore::EventRef updateEvent);
|
||||
~ControllerManager(void);
|
||||
|
||||
void deviceInsertedOrRemoved(int vid, int pid, const std::string &serial, bool inserted);
|
||||
|
||||
int count();
|
||||
Controller *getBestControllerById(int id);
|
||||
void loadControllers();
|
||||
void loadStoredControllers();
|
||||
void queryControllerStatus();
|
||||
int resetController(Controller *controller);
|
||||
|
||||
std::wstring getControllers() const;
|
||||
std::wstring getControllerValue(int id, const std::wstring &name);
|
||||
int removeController(int id);
|
||||
int setControllerValue(int id, const std::wstring &name, const std::wstring &value);
|
||||
|
||||
private:
|
||||
void signalControllerEvent(int controllerId, int changeEvent, int changeType, const std::wstring &newValue);
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_CONTROLLERMANAGER_H_
|
||||
95
telldus-core/service/ControllerMessage.cpp
Normal file
95
telldus-core/service/ControllerMessage.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ControllerMessage.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "service/Device.h"
|
||||
#include "common/Strings.h"
|
||||
#include "common/common.h"
|
||||
|
||||
class ControllerMessage::PrivateData {
|
||||
public:
|
||||
std::map<std::string, std::string> parameters;
|
||||
std::string protocol, model, msgClass;
|
||||
int method;
|
||||
};
|
||||
|
||||
ControllerMessage::ControllerMessage(const std::string &message) {
|
||||
d = new PrivateData;
|
||||
|
||||
// Process our message into bits
|
||||
size_t prevPos = 0;
|
||||
size_t pos = message.find(";");
|
||||
while(pos != std::string::npos) {
|
||||
std::string param = message.substr(prevPos, pos-prevPos);
|
||||
prevPos = pos+1;
|
||||
size_t delim = param.find(":");
|
||||
if (delim == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
if (param.substr(0, delim).compare("class") == 0) {
|
||||
d->msgClass = param.substr(delim+1, param.length()-delim);
|
||||
} else if (param.substr(0, delim).compare("protocol") == 0) {
|
||||
d->protocol = param.substr(delim+1, param.length()-delim);
|
||||
} else if (param.substr(0, delim).compare("model") == 0) {
|
||||
d->model = param.substr(delim+1, param.length()-delim);
|
||||
} else if (param.substr(0, delim).compare("method") == 0) {
|
||||
d->method = Device::methodId(param.substr(delim+1, param.length()-delim));
|
||||
} else {
|
||||
d->parameters[param.substr(0, delim)] = param.substr(delim+1, param.length()-delim);
|
||||
}
|
||||
pos = message.find(";", pos+1);
|
||||
}
|
||||
}
|
||||
|
||||
ControllerMessage::~ControllerMessage() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
std::string ControllerMessage::msgClass() const {
|
||||
return d->msgClass;
|
||||
}
|
||||
|
||||
int ControllerMessage::method() const {
|
||||
return d->method;
|
||||
}
|
||||
|
||||
std::wstring ControllerMessage::protocol() const {
|
||||
return TelldusCore::charToWstring(d->protocol.c_str());
|
||||
}
|
||||
|
||||
std::wstring ControllerMessage::model() const {
|
||||
return TelldusCore::charToWstring(d->model.c_str());
|
||||
}
|
||||
|
||||
uint64_t ControllerMessage::getInt64Parameter(const std::string &key) const {
|
||||
std::string strValue = getParameter(key);
|
||||
if (strValue.compare("") == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (strValue.substr(0, 2).compare("0x") == 0) {
|
||||
return TelldusCore::hexTo64l(strValue);
|
||||
}
|
||||
// TODO(micke): strtol() does not return uint64_t. Create a platform independent version similar to hexTo64l()
|
||||
return strtol(strValue.c_str(), NULL, 10);
|
||||
}
|
||||
|
||||
std::string ControllerMessage::getParameter(const std::string &key) const {
|
||||
std::map<std::string, std::string>::iterator it = d->parameters.find(key);
|
||||
if (it == d->parameters.end()) {
|
||||
return "";
|
||||
}
|
||||
return d->parameters[key];
|
||||
}
|
||||
|
||||
bool ControllerMessage::hasParameter(const std::string &key) const {
|
||||
std::map<std::string, std::string>::iterator it = d->parameters.find(key);
|
||||
if (it == d->parameters.end()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
36
telldus-core/service/ControllerMessage.h
Normal file
36
telldus-core/service/ControllerMessage.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_CONTROLLERMESSAGE_H_
|
||||
#define TELLDUS_CORE_SERVICE_CONTROLLERMESSAGE_H_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
class ControllerMessage {
|
||||
public:
|
||||
explicit ControllerMessage(const std::string &rawMessage);
|
||||
virtual ~ControllerMessage();
|
||||
|
||||
std::string msgClass() const;
|
||||
uint64_t getInt64Parameter(const std::string &key) const;
|
||||
std::string getParameter(const std::string &key) const;
|
||||
int method() const;
|
||||
std::wstring protocol() const;
|
||||
std::wstring model() const;
|
||||
|
||||
bool hasParameter(const std::string &key) const;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_CONTROLLERMESSAGE_H_
|
||||
272
telldus-core/service/Device.cpp
Normal file
272
telldus-core/service/Device.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/Device.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "service/Settings.h"
|
||||
#include "service/TellStick.h"
|
||||
|
||||
class Device::PrivateData {
|
||||
public:
|
||||
std::wstring model;
|
||||
std::wstring name;
|
||||
ParameterMap parameterList;
|
||||
Protocol *protocol;
|
||||
std::wstring protocolName;
|
||||
int preferredControllerId;
|
||||
int state;
|
||||
std::wstring stateValue;
|
||||
};
|
||||
|
||||
Device::Device(int id)
|
||||
:Mutex() {
|
||||
d = new PrivateData;
|
||||
d->protocol = 0;
|
||||
d->preferredControllerId = 0;
|
||||
d->state = 0;
|
||||
}
|
||||
|
||||
Device::~Device(void) {
|
||||
delete d->protocol;
|
||||
delete d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get-/Set-methods
|
||||
*/
|
||||
|
||||
int Device::getLastSentCommand(int methodsSupported) {
|
||||
int lastSentCommand = Device::maskUnsupportedMethods(d->state, methodsSupported);
|
||||
|
||||
if (lastSentCommand == TELLSTICK_BELL) {
|
||||
// Bell is not a state
|
||||
lastSentCommand = TELLSTICK_TURNOFF;
|
||||
}
|
||||
if (lastSentCommand == 0) {
|
||||
lastSentCommand = TELLSTICK_TURNOFF;
|
||||
}
|
||||
return lastSentCommand;
|
||||
}
|
||||
|
||||
int Device::getMethods() const {
|
||||
Protocol *p = this->retrieveProtocol();
|
||||
if (p) {
|
||||
return p->methods();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Device::setLastSentCommand(int command, std::wstring value) {
|
||||
d->state = command;
|
||||
d->stateValue = value;
|
||||
}
|
||||
|
||||
std::wstring Device::getModel() {
|
||||
return d->model;
|
||||
}
|
||||
|
||||
void Device::setModel(const std::wstring &model) {
|
||||
if(d->protocol) {
|
||||
delete(d->protocol);
|
||||
d->protocol = 0;
|
||||
}
|
||||
d->model = model;
|
||||
}
|
||||
|
||||
std::wstring Device::getName() {
|
||||
return d->name;
|
||||
}
|
||||
|
||||
void Device::setName(const std::wstring &name) {
|
||||
d->name = name;
|
||||
}
|
||||
|
||||
std::wstring Device::getParameter(const std::wstring &key) {
|
||||
ParameterMap::iterator it = d->parameterList.find(key);
|
||||
if (it == d->parameterList.end()) {
|
||||
return L"";
|
||||
}
|
||||
return d->parameterList[key];
|
||||
}
|
||||
|
||||
std::list<std::string> Device::getParametersForProtocol() const {
|
||||
return Protocol::getParametersForProtocol(getProtocolName());
|
||||
}
|
||||
|
||||
void Device::setParameter(const std::wstring &key, const std::wstring &value) {
|
||||
d->parameterList[key] = value;
|
||||
if(d->protocol) {
|
||||
d->protocol->setParameters(d->parameterList);
|
||||
}
|
||||
}
|
||||
|
||||
int Device::getPreferredControllerId() {
|
||||
return d->preferredControllerId;
|
||||
}
|
||||
|
||||
void Device::setPreferredControllerId(int controllerId) {
|
||||
d->preferredControllerId = controllerId;
|
||||
}
|
||||
|
||||
std::wstring Device::getProtocolName() const {
|
||||
return d->protocolName;
|
||||
}
|
||||
|
||||
void Device::setProtocolName(const std::wstring &protocolName) {
|
||||
if(d->protocol) {
|
||||
delete(d->protocol);
|
||||
d->protocol = 0;
|
||||
}
|
||||
d->protocolName = protocolName;
|
||||
}
|
||||
|
||||
std::wstring Device::getStateValue() {
|
||||
return d->stateValue;
|
||||
}
|
||||
|
||||
int Device::getType() {
|
||||
if(d->protocolName == L"group") {
|
||||
return TELLSTICK_TYPE_GROUP;
|
||||
} else if(d->protocolName == L"scene") {
|
||||
return TELLSTICK_TYPE_SCENE;
|
||||
}
|
||||
return TELLSTICK_TYPE_DEVICE;
|
||||
}
|
||||
|
||||
/**
|
||||
* End Get-/Set
|
||||
*/
|
||||
|
||||
int Device::doAction(int action, unsigned char data, Controller *controller) {
|
||||
Protocol *p = this->retrieveProtocol();
|
||||
if (!p) {
|
||||
// Syntax error in configuration, no such protocol
|
||||
return TELLSTICK_ERROR_CONFIG_SYNTAX;
|
||||
}
|
||||
// Try to determine if we need to call another method due to masking
|
||||
int method = this->isMethodSupported(action);
|
||||
if (method <= 0) {
|
||||
return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED;
|
||||
}
|
||||
std::string code = p->getStringForMethod(method, data, controller);
|
||||
if (code == "") {
|
||||
return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED;
|
||||
}
|
||||
if (code[0] != 'S' && code[0] != 'T' && code[0] != 'P' && code[0] != 'R') {
|
||||
// Try autodetect sendtype
|
||||
TellStick *tellstick = reinterpret_cast<TellStick *>(controller);
|
||||
if (!tellstick) {
|
||||
return TELLSTICK_ERROR_UNKNOWN;
|
||||
}
|
||||
unsigned int maxlength = 80;
|
||||
if (tellstick->pid() == 0x0c31) {
|
||||
maxlength = 512;
|
||||
}
|
||||
if (code.length() <= maxlength) {
|
||||
// S is enough
|
||||
code.insert(0, 1, 'S');
|
||||
code.append(1, '+');
|
||||
} else {
|
||||
code = TellStick::createTPacket(code);
|
||||
}
|
||||
}
|
||||
return controller->send(code);
|
||||
}
|
||||
|
||||
int Device::isMethodSupported(int method) const {
|
||||
Protocol *p = this->retrieveProtocol();
|
||||
if (!p) {
|
||||
// Syntax error in configuration, no such protocol
|
||||
return TELLSTICK_ERROR_CONFIG_SYNTAX;
|
||||
}
|
||||
// Try to determine if we need to call another method due to masking
|
||||
int methods = p->methods();
|
||||
if ((method & methods) == 0) {
|
||||
// Loop all methods an see if any method masks to this one
|
||||
for(int i = 1; i <= methods; i <<= 1) {
|
||||
if ((i & methods) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (this->maskUnsupportedMethods(i, method)) {
|
||||
method = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((method & methods) == 0) {
|
||||
return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
Protocol* Device::retrieveProtocol() const {
|
||||
if (d->protocol) {
|
||||
return d->protocol;
|
||||
}
|
||||
|
||||
d->protocol = Protocol::getProtocolInstance(d->protocolName);
|
||||
if(d->protocol) {
|
||||
d->protocol->setModel(d->model);
|
||||
d->protocol->setParameters(d->parameterList);
|
||||
return d->protocol;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Device::maskUnsupportedMethods(int methods, int supportedMethods) {
|
||||
// Bell -> On
|
||||
if ((methods & TELLSTICK_BELL) && !(supportedMethods & TELLSTICK_BELL)) {
|
||||
methods |= TELLSTICK_TURNON;
|
||||
}
|
||||
|
||||
// Execute -> On
|
||||
if ((methods & TELLSTICK_EXECUTE) && !(supportedMethods & TELLSTICK_EXECUTE)) {
|
||||
methods |= TELLSTICK_TURNON;
|
||||
}
|
||||
|
||||
// Up -> Off
|
||||
if ((methods & TELLSTICK_UP) && !(supportedMethods & TELLSTICK_UP)) {
|
||||
methods |= TELLSTICK_TURNOFF;
|
||||
}
|
||||
|
||||
// Down -> On
|
||||
if ((methods & TELLSTICK_DOWN) && !(supportedMethods & TELLSTICK_DOWN)) {
|
||||
methods |= TELLSTICK_TURNON;
|
||||
}
|
||||
|
||||
// Cut of the rest of the unsupported methods we don't have a fallback for
|
||||
return methods & supportedMethods;
|
||||
}
|
||||
|
||||
int Device::methodId( const std::string &methodName ) {
|
||||
if (methodName.compare("turnon") == 0) {
|
||||
return TELLSTICK_TURNON;
|
||||
}
|
||||
if (methodName.compare("turnoff") == 0) {
|
||||
return TELLSTICK_TURNOFF;
|
||||
}
|
||||
if (methodName.compare("bell") == 0) {
|
||||
return TELLSTICK_BELL;
|
||||
}
|
||||
if (methodName.compare("dim") == 0) {
|
||||
return TELLSTICK_DIM;
|
||||
}
|
||||
if (methodName.compare("execute") == 0) {
|
||||
return TELLSTICK_EXECUTE;
|
||||
}
|
||||
if (methodName.compare("up") == 0) {
|
||||
return TELLSTICK_UP;
|
||||
}
|
||||
if (methodName.compare("down") == 0) {
|
||||
return TELLSTICK_DOWN;
|
||||
}
|
||||
if (methodName.compare("stop") == 0) {
|
||||
return TELLSTICK_STOP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
51
telldus-core/service/Device.h
Normal file
51
telldus-core/service/Device.h
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_DEVICE_H_
|
||||
#define TELLDUS_CORE_SERVICE_DEVICE_H_
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "service/Controller.h"
|
||||
#include "common/Mutex.h"
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class Device : public TelldusCore::Mutex {
|
||||
public:
|
||||
explicit Device(int id);
|
||||
~Device(void);
|
||||
|
||||
int doAction(int action, unsigned char data, Controller *controller);
|
||||
int isMethodSupported(int method) const;
|
||||
std::wstring getStateValue();
|
||||
int getLastSentCommand(int methodsSupported);
|
||||
int getMethods() const;
|
||||
std::wstring getModel();
|
||||
void setModel(const std::wstring &model);
|
||||
std::wstring getName();
|
||||
void setName(const std::wstring &name);
|
||||
std::wstring getParameter(const std::wstring &key);
|
||||
std::list<std::string> getParametersForProtocol() const;
|
||||
void setParameter(const std::wstring &key, const std::wstring &value);
|
||||
int getPreferredControllerId();
|
||||
void setPreferredControllerId(int controllerId);
|
||||
std::wstring getProtocolName() const;
|
||||
void setProtocolName(const std::wstring &name);
|
||||
void setStateValue(int stateValue);
|
||||
void setLastSentCommand(int command, std::wstring value);
|
||||
int getType();
|
||||
|
||||
static int maskUnsupportedMethods(int methods, int supportedMethods);
|
||||
static int methodId( const std::string &methodName );
|
||||
|
||||
private:
|
||||
Protocol *retrieveProtocol() const;
|
||||
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_DEVICE_H_
|
||||
790
telldus-core/service/DeviceManager.cpp
Normal file
790
telldus-core/service/DeviceManager.cpp
Normal file
@@ -0,0 +1,790 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/DeviceManager.h"
|
||||
#include <time.h>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "service/ControllerMessage.h"
|
||||
#include "common/Mutex.h"
|
||||
#include "service/Sensor.h"
|
||||
#include "service/Settings.h"
|
||||
#include "common/Strings.h"
|
||||
#include "common/Message.h"
|
||||
#include "service/Log.h"
|
||||
|
||||
typedef std::map<int, Device *> DeviceMap;
|
||||
|
||||
class DeviceManager::PrivateData {
|
||||
public:
|
||||
DeviceMap devices;
|
||||
std::list<Sensor *> sensorList;
|
||||
Settings set;
|
||||
TelldusCore::Mutex lock;
|
||||
ControllerManager *controllerManager;
|
||||
TelldusCore::EventRef deviceUpdateEvent, executeActionEvent;
|
||||
};
|
||||
|
||||
class ExecuteActionEventData : public TelldusCore::EventDataBase {
|
||||
public:
|
||||
int deviceId;
|
||||
int method;
|
||||
unsigned char data;
|
||||
};
|
||||
|
||||
|
||||
DeviceManager::DeviceManager(ControllerManager *controllerManager, TelldusCore::EventRef deviceUpdateEvent) {
|
||||
d = new PrivateData;
|
||||
d->controllerManager = controllerManager;
|
||||
d->deviceUpdateEvent = deviceUpdateEvent;
|
||||
fillDevices();
|
||||
}
|
||||
|
||||
DeviceManager::~DeviceManager(void) {
|
||||
{
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) {
|
||||
{TelldusCore::MutexLocker deviceLocker(it->second);} // aquire lock, and release it, just to see that the device it's not in use anywhere
|
||||
delete(it->second);
|
||||
}
|
||||
for (std::list<Sensor *>::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) {
|
||||
{TelldusCore::MutexLocker sensorLocker(*it);} // aquire lock, and release it, just to see that the device it's not in use anywhere
|
||||
delete(*it);
|
||||
}
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void DeviceManager::executeActionEvent() {
|
||||
Device *device = 0;
|
||||
TelldusCore::EventDataRef eventData = d->executeActionEvent->takeSignal();
|
||||
ExecuteActionEventData *data = dynamic_cast<ExecuteActionEventData*>(eventData.get());
|
||||
if (!data) {
|
||||
Log::error("Could not cast executeAction data");
|
||||
return;
|
||||
}
|
||||
Log::notice("Execute a TellStick Action for device %i", data->deviceId);
|
||||
|
||||
std::auto_ptr<TelldusCore::MutexLocker> deviceLocker(0);
|
||||
{
|
||||
// devicelist locked
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
|
||||
DeviceMap::iterator it = d->devices.find(data->deviceId);
|
||||
if (it == d->devices.end()) {
|
||||
return;
|
||||
}
|
||||
// device locked
|
||||
deviceLocker = std::auto_ptr<TelldusCore::MutexLocker>(new TelldusCore::MutexLocker(it->second));
|
||||
device = it->second;
|
||||
} // devicelist unlocked
|
||||
|
||||
Controller *controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId());
|
||||
if(!controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
int retval = device->doAction(data->method, data->data, controller);
|
||||
if(retval == TELLSTICK_ERROR_BROKEN_PIPE) {
|
||||
Log::warning("Error in communication with TellStick when executing action. Resetting USB");
|
||||
d->controllerManager->resetController(controller);
|
||||
}
|
||||
if(retval == TELLSTICK_ERROR_BROKEN_PIPE || retval == TELLSTICK_ERROR_NOT_FOUND) {
|
||||
Log::warning("Rescanning USB ports");
|
||||
d->controllerManager->loadControllers();
|
||||
controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId());
|
||||
if(!controller) {
|
||||
Log::error("No contoller (TellStick) found, even after reset. Giving up.");
|
||||
return;
|
||||
}
|
||||
retval = device->doAction(data->method, data->data, controller); // retry one more time
|
||||
}
|
||||
|
||||
if(retval == TELLSTICK_SUCCESS && device->getMethods() & data->method) {
|
||||
// if method isn't explicitly supported by device, but used anyway as a fallback (i.e. bell), don't change state
|
||||
std::wstring datastring = TelldusCore::charUnsignedToWstring(data->data);
|
||||
if (this->triggerDeviceStateChange(data->deviceId, data->method, datastring)) {
|
||||
device->setLastSentCommand(data->method, datastring);
|
||||
d->set.setDeviceState(data->deviceId, data->method, datastring);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::setExecuteActionEvent(TelldusCore::EventRef event) {
|
||||
d->executeActionEvent = event;
|
||||
}
|
||||
|
||||
void DeviceManager::fillDevices() {
|
||||
int numberOfDevices = d->set.getNumberOfNodes(Settings::Device);
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
|
||||
for (int i = 0; i < numberOfDevices; ++i) {
|
||||
int id = d->set.getNodeId(Settings::Device, i);
|
||||
d->devices[id] = new Device(id);
|
||||
d->devices[id]->setName(d->set.getName(Settings::Device, id));
|
||||
d->devices[id]->setModel(d->set.getModel(id));
|
||||
d->devices[id]->setProtocolName(d->set.getProtocol(id));
|
||||
d->devices[id]->setPreferredControllerId(d->set.getPreferredControllerId(id));
|
||||
d->devices[id]->setLastSentCommand(d->set.getDeviceState(id), d->set.getDeviceStateValue(id));
|
||||
d->devices[id]->setParameter(L"house", d->set.getDeviceParameter(id, L"house"));
|
||||
d->devices[id]->setParameter(L"unit", d->set.getDeviceParameter(id, L"unit"));
|
||||
d->devices[id]->setParameter(L"code", d->set.getDeviceParameter(id, L"code"));
|
||||
d->devices[id]->setParameter(L"units", d->set.getDeviceParameter(id, L"units"));
|
||||
d->devices[id]->setParameter(L"fade", d->set.getDeviceParameter(id, L"fade"));
|
||||
d->devices[id]->setParameter(L"system", d->set.getDeviceParameter(id, L"system"));
|
||||
d->devices[id]->setParameter(L"devices", d->set.getDeviceParameter(id, L"devices"));
|
||||
}
|
||||
}
|
||||
|
||||
int DeviceManager::getDeviceLastSentCommand(int deviceId, int methodsSupported) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
return it->second->getLastSentCommand(methodsSupported);
|
||||
}
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
int DeviceManager::setDeviceLastSentCommand(int deviceId, int command, const std::wstring &value) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
d->set.setDeviceState(deviceId, command, value);
|
||||
it->second->setLastSentCommand(command, value);
|
||||
} else {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
std::wstring DeviceManager::getDeviceStateValue(int deviceId) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return L"UNKNOWN";
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
return it->second->getStateValue();
|
||||
}
|
||||
return L"UNKNOWN";
|
||||
}
|
||||
|
||||
int DeviceManager::getDeviceMethods(int deviceId, int methodsSupported) {
|
||||
return Device::maskUnsupportedMethods(DeviceManager::getDeviceMethods(deviceId), methodsSupported);
|
||||
}
|
||||
|
||||
int DeviceManager::getDeviceMethods(int deviceId) {
|
||||
std::set<int> duplicateDeviceIds;
|
||||
return DeviceManager::getDeviceMethods(deviceId, &duplicateDeviceIds);
|
||||
}
|
||||
|
||||
int DeviceManager::getDeviceMethods(int deviceId, std::set<int> *duplicateDeviceIds) {
|
||||
int type = 0;
|
||||
int methods = 0;
|
||||
std::wstring deviceIds;
|
||||
std::wstring protocol;
|
||||
|
||||
{
|
||||
// devices locked
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
{
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
type = it->second->getType();
|
||||
methods = it->second->getMethods();
|
||||
deviceIds = it->second->getParameter(L"devices");
|
||||
protocol = it->second->getProtocolName();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(type == 0) {
|
||||
return 0;
|
||||
}
|
||||
if(type == TELLSTICK_TYPE_GROUP) {
|
||||
// get all methods that some device in the groups supports
|
||||
std::wstring deviceIdBuffer;
|
||||
std::wstringstream devicesstream(deviceIds);
|
||||
methods = 0;
|
||||
|
||||
duplicateDeviceIds->insert(deviceId);
|
||||
|
||||
while(std::getline(devicesstream, deviceIdBuffer, L',')) {
|
||||
int deviceIdInGroup = TelldusCore::wideToInteger(deviceIdBuffer);
|
||||
if(duplicateDeviceIds->count(deviceIdInGroup) == 1) {
|
||||
// action for device already executed, or will execute, do nothing to avoid infinite loop
|
||||
continue;
|
||||
}
|
||||
|
||||
duplicateDeviceIds->insert(deviceIdInGroup);
|
||||
|
||||
int deviceMethods = getDeviceMethods(deviceIdInGroup, duplicateDeviceIds);
|
||||
if(deviceMethods > 0) {
|
||||
methods |= deviceMethods;
|
||||
}
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
std::wstring DeviceManager::getDeviceModel(int deviceId) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return L"UNKNOWN";
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
return it->second->getModel();
|
||||
}
|
||||
return L"UNKNOWN";
|
||||
}
|
||||
|
||||
int DeviceManager::setDeviceModel(int deviceId, const std::wstring &model) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
int ret = d->set.setModel(deviceId, model);
|
||||
if (ret != TELLSTICK_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
it->second->setModel(model);
|
||||
} else {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
std::wstring DeviceManager::getDeviceName(int deviceId) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return L"UNKNOWN";
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
return it->second->getName();
|
||||
}
|
||||
return L"UNKNOWN";
|
||||
}
|
||||
|
||||
int DeviceManager::setDeviceName(int deviceId, const std::wstring &name) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
int ret = d->set.setName(Settings::Device, deviceId, name);
|
||||
if (ret != TELLSTICK_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
it->second->setName(name);
|
||||
} else {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
std::wstring DeviceManager::getDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &defaultValue) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return defaultValue;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
std::wstring returnString = it->second->getParameter(name);
|
||||
if(returnString != L"") {
|
||||
return returnString;
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
int DeviceManager::setDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &value) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
int ret = d->set.setDeviceParameter(deviceId, name, value);
|
||||
if (ret != TELLSTICK_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
it->second->setParameter(name, value);
|
||||
} else {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
std::wstring DeviceManager::getDeviceProtocol(int deviceId) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return L"UNKNOWN";
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
return it->second->getProtocolName();
|
||||
}
|
||||
return L"UNKNOWN";
|
||||
}
|
||||
|
||||
int DeviceManager::setDeviceProtocol(int deviceId, const std::wstring &protocol) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
int ret = d->set.setProtocol(deviceId, protocol);
|
||||
if (ret != TELLSTICK_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
it->second->setProtocolName(protocol);
|
||||
} else {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
int DeviceManager::getNumberOfDevices() {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
return static_cast<int>(d->devices.size());
|
||||
}
|
||||
|
||||
int DeviceManager::addDevice() {
|
||||
int id = d->set.addNode(Settings::Device);
|
||||
if(id < 0) {
|
||||
return id;
|
||||
}
|
||||
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
d->devices[id] = new Device(id);
|
||||
if(!d->devices[id]) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
int DeviceManager::getDeviceId(int deviceIndex) {
|
||||
return d->set.getNodeId(Settings::Device, deviceIndex);
|
||||
}
|
||||
|
||||
int DeviceManager::getDeviceType(int deviceId) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
return it->second->getType();
|
||||
}
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
int DeviceManager::getPreferredControllerId(int deviceId) {
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
return it->second->getPreferredControllerId();
|
||||
}
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
void DeviceManager::connectTellStickController(int vid, int pid, const std::string &serial) {
|
||||
d->controllerManager->deviceInsertedOrRemoved(vid, pid, serial, true);
|
||||
}
|
||||
|
||||
void DeviceManager::disconnectTellStickController(int vid, int pid, const std::string &serial) {
|
||||
d->controllerManager->deviceInsertedOrRemoved(vid, pid, serial, false);
|
||||
}
|
||||
|
||||
int DeviceManager::doAction(int deviceId, int action, unsigned char data) {
|
||||
int deviceType = 0;
|
||||
{
|
||||
// devicelist locked
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it == d->devices.end()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND; // not found
|
||||
}
|
||||
// device locked
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
|
||||
deviceType = it->second->getType();
|
||||
if (it->second->isMethodSupported(action) <= 0) {
|
||||
return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (d->controllerManager->count() == 0) {
|
||||
return TELLSTICK_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
// The device exists and there is at least one connected controller
|
||||
|
||||
if(deviceType == TELLSTICK_TYPE_GROUP || deviceType == TELLSTICK_TYPE_SCENE) {
|
||||
return this->doGroupSceneAction(deviceId, action, data);
|
||||
}
|
||||
|
||||
ExecuteActionEventData *eventData = new ExecuteActionEventData();
|
||||
eventData->deviceId = deviceId;
|
||||
eventData->method = action;
|
||||
eventData->data = data;
|
||||
d->executeActionEvent->signal(eventData);
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
int DeviceManager::doGroupSceneAction(int deviceId, int action, unsigned char data) {
|
||||
std::set<int> parsedDevices;
|
||||
std::queue<int> devicesToParse;
|
||||
|
||||
devicesToParse.push(deviceId);
|
||||
while (!devicesToParse.empty()) {
|
||||
int deviceId = devicesToParse.front();
|
||||
devicesToParse.pop();
|
||||
if (parsedDevices.count(deviceId)) {
|
||||
continue;
|
||||
}
|
||||
parsedDevices.insert(deviceId);
|
||||
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it == d->devices.end()) {
|
||||
// Not found
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it->second->isMethodSupported(action) <= 0) {
|
||||
return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
if (it->second->getType() == TELLSTICK_TYPE_DEVICE) {
|
||||
ExecuteActionEventData *eventData = new ExecuteActionEventData();
|
||||
eventData->deviceId = deviceId;
|
||||
eventData->method = action;
|
||||
eventData->data = data;
|
||||
d->executeActionEvent->signal(eventData);
|
||||
continue;
|
||||
}
|
||||
if (it->second->getType() == TELLSTICK_TYPE_GROUP) {
|
||||
std::string devices = TelldusCore::wideToString(it->second->getParameter(L"devices"));
|
||||
std::stringstream devicesstream(devices);
|
||||
std::string singledevice;
|
||||
while(std::getline(devicesstream, singledevice, ',')) {
|
||||
devicesToParse.push(TelldusCore::charToInteger(singledevice.c_str()));
|
||||
}
|
||||
// Update state
|
||||
if(it->second->getMethods() & action) {
|
||||
// if method isn't explicitly supported by device, but used anyway as a fallback (i.e. bell), don't change state
|
||||
std::wstring datastring = TelldusCore::charUnsignedToWstring(data);
|
||||
if (this->triggerDeviceStateChange(deviceId, action, datastring)) {
|
||||
it->second->setLastSentCommand(action, datastring);
|
||||
d->set.setDeviceState(deviceId, action, datastring);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (it->second->getType() == TELLSTICK_TYPE_SCENE) {
|
||||
// TODO(micke): Not supported yet
|
||||
Log::warning("Scenes are not supported yet!");
|
||||
}
|
||||
}
|
||||
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
int DeviceManager::executeScene(std::wstring singledevice, int groupDeviceId) {
|
||||
std::wstringstream devicestream(singledevice);
|
||||
|
||||
const int deviceParameterLength = 3;
|
||||
std::wstring deviceParts[deviceParameterLength] = {L"", L"", L""};
|
||||
std::wstring devicePart = L"";
|
||||
int i = 0;
|
||||
while(std::getline(devicestream, devicePart, L':') && i < deviceParameterLength) {
|
||||
deviceParts[i] = devicePart;
|
||||
i++;
|
||||
}
|
||||
|
||||
if(deviceParts[0] == L"" || deviceParts[1] == L"") {
|
||||
return TELLSTICK_ERROR_UNKNOWN; // malformed or missing parameter
|
||||
}
|
||||
|
||||
int deviceId = TelldusCore::wideToInteger(deviceParts[0]);
|
||||
if(deviceId == groupDeviceId) {
|
||||
return TELLSTICK_ERROR_UNKNOWN; // the scene itself has been added to its devices, avoid infinite loop
|
||||
}
|
||||
int method = Device::methodId(TelldusCore::wideToString(deviceParts[1])); // support methodparts both in the form of integers (e.g. TELLSTICK_TURNON) or text (e.g. "turnon")
|
||||
if(method == 0) {
|
||||
method = TelldusCore::wideToInteger(deviceParts[1]);
|
||||
}
|
||||
unsigned char devicedata = 0;
|
||||
if(deviceParts[2] != L"") {
|
||||
devicedata = TelldusCore::wideToInteger(deviceParts[2]);
|
||||
}
|
||||
|
||||
if(deviceId > 0 && method > 0) { // check for format error in parameter "devices"
|
||||
return doAction(deviceId, method, devicedata);
|
||||
}
|
||||
|
||||
return TELLSTICK_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
int DeviceManager::removeDevice(int deviceId) {
|
||||
Device *device = 0;
|
||||
{
|
||||
int ret = d->set.removeNode(Settings::Device, deviceId); // remove from register/settings
|
||||
if (ret != TELLSTICK_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
if (!d->devices.size()) {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
DeviceMap::iterator it = d->devices.find(deviceId);
|
||||
if (it != d->devices.end()) {
|
||||
device = it->second;
|
||||
d->devices.erase(it); // remove from list, keep reference
|
||||
} else {
|
||||
return TELLSTICK_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
{TelldusCore::MutexLocker lock(device);} // waiting for device lock, if it's aquired, just unlock again. Device is removed from list, and cannot be accessed from anywhere else
|
||||
delete device;
|
||||
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
std::wstring DeviceManager::getSensors() const {
|
||||
TelldusCore::MutexLocker sensorListLocker(&d->lock);
|
||||
|
||||
TelldusCore::Message msg;
|
||||
|
||||
msg.addArgument(static_cast<int>(d->sensorList.size()));
|
||||
|
||||
for (std::list<Sensor *>::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) {
|
||||
TelldusCore::MutexLocker sensorLocker(*it);
|
||||
msg.addArgument((*it)->protocol());
|
||||
msg.addArgument((*it)->model());
|
||||
msg.addArgument((*it)->id());
|
||||
msg.addArgument((*it)->dataTypes());
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
std::wstring DeviceManager::getSensorValue(const std::wstring &protocol, const std::wstring &model, int id, int dataType) const {
|
||||
TelldusCore::MutexLocker sensorListLocker(&d->lock);
|
||||
Sensor *sensor = 0;
|
||||
for (std::list<Sensor *>::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) {
|
||||
TelldusCore::MutexLocker sensorLocker(*it);
|
||||
if (!TelldusCore::comparei((*it)->protocol(), protocol)) {
|
||||
continue;
|
||||
}
|
||||
if (!TelldusCore::comparei((*it)->model(), model)) {
|
||||
continue;
|
||||
}
|
||||
if ((*it)->id() != id) {
|
||||
continue;
|
||||
}
|
||||
sensor = *it;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sensor) {
|
||||
return L"";
|
||||
}
|
||||
TelldusCore::MutexLocker sensorLocker(sensor);
|
||||
TelldusCore::Message msg;
|
||||
std::string value = sensor->value(dataType);
|
||||
if (value.length() > 0) {
|
||||
msg.addArgument(TelldusCore::charToWstring(value.c_str()));
|
||||
msg.addArgument(static_cast<int>(sensor->timestamp()));
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
void DeviceManager::handleControllerMessage(const ControllerEventData &eventData) {
|
||||
// Trigger raw-event
|
||||
EventUpdateData *eventUpdateData = new EventUpdateData();
|
||||
eventUpdateData->messageType = L"TDRawDeviceEvent";
|
||||
eventUpdateData->controllerId = eventData.controllerId;
|
||||
eventUpdateData->eventValue = TelldusCore::charToWstring(eventData.msg.c_str());
|
||||
d->deviceUpdateEvent->signal(eventUpdateData);
|
||||
|
||||
ControllerMessage msg(eventData.msg);
|
||||
if (msg.msgClass().compare("sensor") == 0) {
|
||||
handleSensorMessage(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
TelldusCore::MutexLocker deviceListLocker(&d->lock);
|
||||
for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) {
|
||||
TelldusCore::MutexLocker deviceLocker(it->second);
|
||||
if (!TelldusCore::comparei(it->second->getProtocolName(), msg.protocol())) {
|
||||
continue;
|
||||
}
|
||||
if ( !(it->second->getMethods() & msg.method()) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::list<std::string> parameters = it->second->getParametersForProtocol();
|
||||
bool thisDevice = true;
|
||||
for (std::list<std::string>::iterator paramIt = parameters.begin(); paramIt != parameters.end(); ++paramIt) {
|
||||
if(!TelldusCore::comparei(it->second->getParameter(TelldusCore::charToWstring((*paramIt).c_str())), TelldusCore::charToWstring(msg.getParameter(*paramIt).c_str()))) {
|
||||
thisDevice = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!thisDevice) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this->triggerDeviceStateChange(it->first, msg.method(), L"")) {
|
||||
d->set.setDeviceState(it->first, msg.method(), L"");
|
||||
it->second->setLastSentCommand(msg.method(), L"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::handleSensorMessage(const ControllerMessage &msg) {
|
||||
TelldusCore::MutexLocker sensorListLocker(&d->lock);
|
||||
Sensor *sensor = 0;
|
||||
for (std::list<Sensor *>::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) {
|
||||
TelldusCore::MutexLocker sensorLocker(*it);
|
||||
if (!TelldusCore::comparei((*it)->protocol(), msg.protocol())) {
|
||||
continue;
|
||||
}
|
||||
if (!TelldusCore::comparei((*it)->model(), msg.model())) {
|
||||
continue;
|
||||
}
|
||||
if ((*it)->id() != msg.getInt64Parameter("id")) {
|
||||
continue;
|
||||
}
|
||||
sensor = *it;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sensor) {
|
||||
sensor = new Sensor(msg.protocol(), msg.model(), msg.getInt64Parameter("id"));
|
||||
d->sensorList.push_back(sensor);
|
||||
}
|
||||
TelldusCore::MutexLocker sensorLocker(sensor);
|
||||
|
||||
time_t t = time(NULL);
|
||||
|
||||
setSensorValueAndSignal("temp", TELLSTICK_TEMPERATURE, sensor, msg, t);
|
||||
setSensorValueAndSignal("humidity", TELLSTICK_HUMIDITY, sensor, msg, t);
|
||||
setSensorValueAndSignal("rainrate", TELLSTICK_RAINRATE, sensor, msg, t);
|
||||
setSensorValueAndSignal("raintotal", TELLSTICK_RAINTOTAL, sensor, msg, t);
|
||||
setSensorValueAndSignal("winddirection", TELLSTICK_WINDDIRECTION, sensor, msg, t);
|
||||
setSensorValueAndSignal("windaverage", TELLSTICK_WINDAVERAGE, sensor, msg, t);
|
||||
setSensorValueAndSignal("windgust", TELLSTICK_WINDGUST, sensor, msg, t);
|
||||
}
|
||||
|
||||
void DeviceManager::setSensorValueAndSignal( const std::string &dataType, int dataTypeId, Sensor *sensor, const ControllerMessage &msg, time_t timestamp) const {
|
||||
if (!msg.hasParameter(dataType)) {
|
||||
return;
|
||||
}
|
||||
sensor->setValue(dataTypeId, msg.getParameter(dataType), timestamp);
|
||||
|
||||
EventUpdateData *eventData = new EventUpdateData();
|
||||
eventData->messageType = L"TDSensorEvent";
|
||||
eventData->protocol = sensor->protocol();
|
||||
eventData->model = sensor->model();
|
||||
eventData->sensorId = sensor->id();
|
||||
eventData->dataType = dataTypeId;
|
||||
eventData->value = TelldusCore::charToWstring(sensor->value(dataTypeId).c_str());
|
||||
eventData->timestamp = static_cast<int>(timestamp);
|
||||
d->deviceUpdateEvent->signal(eventData);
|
||||
}
|
||||
|
||||
int DeviceManager::sendRawCommand(const std::wstring &command, int reserved) {
|
||||
Controller *controller = d->controllerManager->getBestControllerById(-1);
|
||||
|
||||
if(!controller) {
|
||||
// no controller found, scan for one, and retry once
|
||||
d->controllerManager->loadControllers();
|
||||
controller = d->controllerManager->getBestControllerById(-1);
|
||||
}
|
||||
|
||||
int retval = TELLSTICK_ERROR_UNKNOWN;
|
||||
if(controller) {
|
||||
retval = controller->send(TelldusCore::wideToString(command));
|
||||
if(retval == TELLSTICK_ERROR_BROKEN_PIPE) {
|
||||
d->controllerManager->resetController(controller);
|
||||
}
|
||||
if(retval == TELLSTICK_ERROR_BROKEN_PIPE || retval == TELLSTICK_ERROR_NOT_FOUND) {
|
||||
d->controllerManager->loadControllers();
|
||||
controller = d->controllerManager->getBestControllerById(-1);
|
||||
if(!controller) {
|
||||
return TELLSTICK_ERROR_NOT_FOUND;
|
||||
}
|
||||
retval = controller->send(TelldusCore::wideToString(command)); // retry one more time
|
||||
}
|
||||
return retval;
|
||||
} else {
|
||||
return TELLSTICK_ERROR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceManager::triggerDeviceStateChange(int deviceId, int intDeviceState, const std::wstring &strDeviceStateValue ) {
|
||||
if ( intDeviceState == TELLSTICK_BELL || intDeviceState == TELLSTICK_LEARN || intDeviceState == TELLSTICK_EXECUTE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EventUpdateData *eventData = new EventUpdateData();
|
||||
eventData->messageType = L"TDDeviceEvent";
|
||||
eventData->eventState = intDeviceState;
|
||||
eventData->deviceId = deviceId;
|
||||
eventData->eventValue = strDeviceStateValue;
|
||||
d->deviceUpdateEvent->signal(eventData);
|
||||
return true;
|
||||
}
|
||||
68
telldus-core/service/DeviceManager.h
Normal file
68
telldus-core/service/DeviceManager.h
Normal file
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_DEVICEMANAGER_H_
|
||||
#define TELLDUS_CORE_SERVICE_DEVICEMANAGER_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "service/Device.h"
|
||||
#include "service/ControllerManager.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
#include "service/EventUpdateManager.h"
|
||||
|
||||
class Sensor;
|
||||
|
||||
class DeviceManager {
|
||||
public:
|
||||
DeviceManager(ControllerManager *controllerManager, TelldusCore::EventRef deviceUpdateEvent);
|
||||
~DeviceManager(void);
|
||||
int getNumberOfDevices(void);
|
||||
int addDevice();
|
||||
void connectTellStickController(int vid, int pid, const std::string &serial);
|
||||
void disconnectTellStickController(int vid, int pid, const std::string &serial);
|
||||
void executeActionEvent();
|
||||
int getDeviceId(int deviceIndex);
|
||||
int getDeviceLastSentCommand(int deviceId, int methodsSupported);
|
||||
int setDeviceLastSentCommand(int deviceId, int command, const std::wstring &value);
|
||||
int getDeviceMethods(int deviceId);
|
||||
int getDeviceMethods(int deviceId, int methodsSupported);
|
||||
std::wstring getDeviceModel(int deviceId);
|
||||
int setDeviceModel(int deviceId, const std::wstring &model);
|
||||
std::wstring getDeviceName(int deviceId);
|
||||
int setDeviceName(int deviceId, const std::wstring &name);
|
||||
std::wstring getDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &defauleValue);
|
||||
int setDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &value);
|
||||
std::wstring getDeviceProtocol(int deviceId);
|
||||
int setDeviceProtocol(int deviceId, const std::wstring &name);
|
||||
std::wstring getDeviceStateValue(int deviceId);
|
||||
int getDeviceType(int deviceId);
|
||||
int getPreferredControllerId(int deviceId);
|
||||
int doAction(int deviceId, int action, unsigned char data);
|
||||
int removeDevice(int deviceId);
|
||||
int sendRawCommand(const std::wstring &command, int reserved);
|
||||
|
||||
void setExecuteActionEvent(TelldusCore::EventRef event);
|
||||
|
||||
std::wstring getSensors() const;
|
||||
std::wstring getSensorValue(const std::wstring &protocol, const std::wstring &model, int id, int dataType) const;
|
||||
|
||||
void handleControllerMessage(const ControllerEventData &event);
|
||||
|
||||
private:
|
||||
void handleSensorMessage(const ControllerMessage &msg);
|
||||
void setSensorValueAndSignal( const std::string &dataType, int dataTypeId, Sensor *sensor, const ControllerMessage &msg, time_t timestamp) const;
|
||||
int getDeviceMethods(int deviceId, std::set<int> *duplicateDeviceIds);
|
||||
int doGroupSceneAction(int deviceId, int action, unsigned char data);
|
||||
int executeScene(std::wstring singledevice, int groupDeviceId);
|
||||
bool triggerDeviceStateChange(int deviceId, int intDeviceState, const std::wstring &strDeviceStateValue );
|
||||
void fillDevices(void);
|
||||
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_DEVICEMANAGER_H_
|
||||
259
telldus-core/service/EventUpdateManager.cpp
Normal file
259
telldus-core/service/EventUpdateManager.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/EventUpdateManager.h"
|
||||
|
||||
#ifdef _LINUX
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#endif // _LINUX
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#ifdef _LINUX
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#endif // _LINUX
|
||||
|
||||
#include "common/EventHandler.h"
|
||||
#include "common/Message.h"
|
||||
#include "common/Socket.h"
|
||||
#include "common/Strings.h"
|
||||
#include "service/config.h"
|
||||
#include "service/ConnectionListener.h"
|
||||
#include "service/Log.h"
|
||||
|
||||
typedef std::list<TelldusCore::Socket *> SocketList;
|
||||
typedef std::list<std::string> StringList;
|
||||
|
||||
class EventUpdateManager::PrivateData {
|
||||
public:
|
||||
TelldusCore::EventHandler eventHandler;
|
||||
TelldusCore::EventRef stopEvent, updateEvent, clientConnectEvent;
|
||||
SocketList clients;
|
||||
ConnectionListener *eventUpdateClientListener;
|
||||
#ifdef _LINUX
|
||||
std::map<std::string, StringList> fileList;
|
||||
#endif // _LINUX
|
||||
};
|
||||
|
||||
EventUpdateManager::EventUpdateManager()
|
||||
:Thread() {
|
||||
d = new PrivateData;
|
||||
d->stopEvent = d->eventHandler.addEvent();
|
||||
d->updateEvent = d->eventHandler.addEvent();
|
||||
d->clientConnectEvent = d->eventHandler.addEvent();
|
||||
d->eventUpdateClientListener = new ConnectionListener(L"TelldusEvents", d->clientConnectEvent);
|
||||
#ifdef _LINUX
|
||||
loadScripts("deviceevent");
|
||||
loadScripts("devicechangeevent");
|
||||
loadScripts("rawdeviceevent");
|
||||
loadScripts("sensorevent");
|
||||
loadScripts("controllerevent");
|
||||
#endif // _LINUX
|
||||
}
|
||||
|
||||
EventUpdateManager::~EventUpdateManager(void) {
|
||||
d->stopEvent->signal();
|
||||
wait();
|
||||
delete d->eventUpdateClientListener;
|
||||
|
||||
for (SocketList::iterator it = d->clients.begin(); it != d->clients.end(); ++it) {
|
||||
delete(*it);
|
||||
}
|
||||
|
||||
delete d;
|
||||
}
|
||||
|
||||
TelldusCore::EventRef EventUpdateManager::retrieveUpdateEvent() {
|
||||
return d->updateEvent;
|
||||
}
|
||||
|
||||
void EventUpdateManager::run() {
|
||||
while(!d->stopEvent->isSignaled()) {
|
||||
if (!d->eventHandler.waitForAny()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(d->clientConnectEvent->isSignaled()) {
|
||||
// new client added
|
||||
TelldusCore::EventDataRef eventData = d->clientConnectEvent->takeSignal();
|
||||
ConnectionListenerEventData *data = dynamic_cast<ConnectionListenerEventData*>(eventData.get());
|
||||
if(data) {
|
||||
d->clients.push_back(data->socket);
|
||||
}
|
||||
} else if(d->updateEvent->isSignaled()) {
|
||||
// device event, signal all clients
|
||||
TelldusCore::EventDataRef eventData = d->updateEvent->takeSignal();
|
||||
EventUpdateData *data = reinterpret_cast<EventUpdateData*>(eventData.get());
|
||||
if(data) {
|
||||
sendMessageToClients(data);
|
||||
executeScripts(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventUpdateManager::loadScripts(const std::string &folder) {
|
||||
#ifdef _LINUX
|
||||
std::string path = TelldusCore::formatf("%s/%s", SCRIPT_PATH, folder.c_str());
|
||||
struct dirent **namelist;
|
||||
int count = scandir(path.c_str(), &namelist, NULL, alphasort);
|
||||
if (count < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < count; ++i) {
|
||||
if (strcmp(namelist[i]->d_name, ".") != 0 && strcmp(namelist[i]->d_name, "..") != 0) {
|
||||
d->fileList[folder].push_back(namelist[i]->d_name);
|
||||
}
|
||||
free(namelist[i]);
|
||||
}
|
||||
free(namelist);
|
||||
#endif // _LINUX
|
||||
}
|
||||
|
||||
void EventUpdateManager::sendMessageToClients(EventUpdateData *data) {
|
||||
int connected = 0;
|
||||
for(SocketList::iterator it = d->clients.begin(); it != d->clients.end();) {
|
||||
if((*it)->isConnected()) {
|
||||
connected++;
|
||||
TelldusCore::Message msg;
|
||||
|
||||
if(data->messageType == L"TDDeviceEvent") {
|
||||
msg.addArgument("TDDeviceEvent");
|
||||
msg.addArgument(data->deviceId);
|
||||
msg.addArgument(data->eventState);
|
||||
msg.addArgument(data->eventValue); // string
|
||||
} else if(data->messageType == L"TDDeviceChangeEvent") {
|
||||
msg.addArgument("TDDeviceChangeEvent");
|
||||
msg.addArgument(data->deviceId);
|
||||
msg.addArgument(data->eventDeviceChanges);
|
||||
msg.addArgument(data->eventChangeType);
|
||||
} else if(data->messageType == L"TDRawDeviceEvent") {
|
||||
msg.addArgument("TDRawDeviceEvent");
|
||||
msg.addArgument(data->eventValue); // string
|
||||
msg.addArgument(data->controllerId);
|
||||
} else if(data->messageType == L"TDSensorEvent") {
|
||||
msg.addArgument("TDSensorEvent");
|
||||
msg.addArgument(data->protocol);
|
||||
msg.addArgument(data->model);
|
||||
msg.addArgument(data->sensorId);
|
||||
msg.addArgument(data->dataType);
|
||||
msg.addArgument(data->value);
|
||||
msg.addArgument(data->timestamp);
|
||||
} else if(data->messageType == L"TDControllerEvent") {
|
||||
msg.addArgument("TDControllerEvent");
|
||||
msg.addArgument(data->controllerId);
|
||||
msg.addArgument(data->eventState);
|
||||
msg.addArgument(data->eventChangeType);
|
||||
msg.addArgument(data->eventValue);
|
||||
}
|
||||
|
||||
(*it)->write(msg);
|
||||
|
||||
it++;
|
||||
} else {
|
||||
// connection is dead, remove it
|
||||
delete *it;
|
||||
it = d->clients.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventUpdateManager::executeScripts(EventUpdateData *data) {
|
||||
#ifdef _LINUX
|
||||
std::string dir;
|
||||
std::vector<std::string> env;
|
||||
|
||||
// Create a copy of the environment
|
||||
unsigned int size = 0;
|
||||
for(; ; ++size) {
|
||||
if (environ[size] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
env.reserve(size + 6); // 6 is the most used extra environmental variables any event uses
|
||||
for(unsigned int i = 0; i < size; ++i) {
|
||||
env.push_back(environ[i]);
|
||||
}
|
||||
|
||||
if(data->messageType == L"TDDeviceEvent") {
|
||||
dir = "deviceevent";
|
||||
env.push_back(TelldusCore::formatf("DEVICEID=%i", data->deviceId));
|
||||
env.push_back(TelldusCore::formatf("METHOD=%i", data->eventState));
|
||||
env.push_back(TelldusCore::formatf("METHODDATA=%s", TelldusCore::wideToString(data->eventValue).c_str()));
|
||||
} else if(data->messageType == L"TDDeviceChangeEvent") {
|
||||
dir = "devicechangeevent";
|
||||
env.push_back(TelldusCore::formatf("DEVICEID=%i", data->deviceId));
|
||||
env.push_back(TelldusCore::formatf("CHANGEEVENT=%i", data->eventDeviceChanges));
|
||||
env.push_back(TelldusCore::formatf("CHANGETYPE=%i", data->eventChangeType));
|
||||
} else if(data->messageType == L"TDRawDeviceEvent") {
|
||||
dir = "rawdeviceevent";
|
||||
env.push_back(TelldusCore::formatf("RAWDATA=%s", TelldusCore::wideToString(data->eventValue).c_str())); // string
|
||||
env.push_back(TelldusCore::formatf("CONTROLLERID=%i", data->controllerId));
|
||||
} else if (data->messageType == L"TDSensorEvent") {
|
||||
dir = "sensorevent";
|
||||
env.push_back(TelldusCore::formatf("PROTOCOL=%s", TelldusCore::wideToString(data->protocol).c_str()));
|
||||
env.push_back(TelldusCore::formatf("MODEL=%s", TelldusCore::wideToString(data->model).c_str()));
|
||||
env.push_back(TelldusCore::formatf("SENSORID=%i", data->sensorId));
|
||||
env.push_back(TelldusCore::formatf("DATATYPE=%i", data->dataType));
|
||||
env.push_back(TelldusCore::formatf("VALUE=%s", TelldusCore::wideToString(data->value).c_str()));
|
||||
env.push_back(TelldusCore::formatf("TIMESTAMP=%i", data->timestamp));
|
||||
} else if(data->messageType == L"TDControllerEvent") {
|
||||
dir = "controllerevent";
|
||||
env.push_back(TelldusCore::formatf("CONTROLLERID=%i", data->controllerId));
|
||||
env.push_back(TelldusCore::formatf("CHANGEEVENT=%i", data->eventState));
|
||||
env.push_back(TelldusCore::formatf("CHANGETYPE=%i", data->eventChangeType));
|
||||
env.push_back(TelldusCore::formatf("VALUE=%s", TelldusCore::wideToString(data->eventValue).c_str()));
|
||||
} else {
|
||||
// Unknown event, should not happen
|
||||
return;
|
||||
}
|
||||
|
||||
char *newEnv[env.size()+1]; // +1 for the last stop element
|
||||
for(int i = 0; i < env.size(); ++i) {
|
||||
newEnv[i] = new char[env.at(i).length()+1];
|
||||
snprintf(newEnv[i], env.at(i).length()+1, "%s", env.at(i).c_str());
|
||||
}
|
||||
newEnv[env.size()] = NULL; // Mark end of array
|
||||
|
||||
for(StringList::iterator it = d->fileList[dir].begin(); it != d->fileList[dir].end(); ++it) {
|
||||
executeScript(TelldusCore::formatf("%s/%s/%s", SCRIPT_PATH, dir.c_str(), (*it).c_str()), (*it), newEnv);
|
||||
}
|
||||
// Cleanup
|
||||
for(int i = 0; newEnv[i] != 0; ++i) {
|
||||
delete[] newEnv[i];
|
||||
}
|
||||
#endif // _LINUX
|
||||
}
|
||||
|
||||
void EventUpdateManager::executeScript(std::string script, const std::string &name, char ** env) {
|
||||
#ifdef _LINUX
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
Log::error("Could not fork() to execute script %s", script.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
char *n = new char[name.length()+1];
|
||||
snprintf(n, name.length()+1, "%s", name.c_str());
|
||||
static char * argv[] = { n, NULL };
|
||||
execve(script.c_str(), argv, env);
|
||||
delete[] n;
|
||||
Log::error("Could not execute %s (%i): %s", script.c_str(), errno, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
#endif // _LINUX
|
||||
}
|
||||
53
telldus-core/service/EventUpdateManager.h
Normal file
53
telldus-core/service/EventUpdateManager.h
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_EVENTUPDATEMANAGER_H_
|
||||
#define TELLDUS_CORE_SERVICE_EVENTUPDATEMANAGER_H_
|
||||
|
||||
#include <string>
|
||||
#include "common/Thread.h"
|
||||
#include "common/Event.h"
|
||||
|
||||
class EventUpdateData : public TelldusCore::EventDataBase {
|
||||
public:
|
||||
std::wstring messageType;
|
||||
int controllerId;
|
||||
int deviceId;
|
||||
int eventChangeType;
|
||||
int eventDeviceChanges;
|
||||
int eventState;
|
||||
std::wstring eventValue;
|
||||
|
||||
// Sensor event
|
||||
std::wstring protocol;
|
||||
std::wstring model;
|
||||
int sensorId;
|
||||
int dataType;
|
||||
std::wstring value;
|
||||
int timestamp;
|
||||
};
|
||||
|
||||
class EventUpdateManager : public TelldusCore::Thread {
|
||||
public:
|
||||
EventUpdateManager(void);
|
||||
~EventUpdateManager(void);
|
||||
|
||||
TelldusCore::EventRef retrieveUpdateEvent();
|
||||
TelldusCore::EventRef retrieveClientConnectEvent();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
void loadScripts(const std::string &folder);
|
||||
void sendMessageToClients(EventUpdateData *data);
|
||||
void executeScripts(EventUpdateData *data);
|
||||
static void executeScript(std::string script, const std::string &name, char **env);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_EVENTUPDATEMANAGER_H_
|
||||
183
telldus-core/service/Log.cpp
Normal file
183
telldus-core/service/Log.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/Log.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(_LINUX)
|
||||
#include <syslog.h>
|
||||
#elif defined(_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include "common/Strings.h"
|
||||
#include "service/Messages.h"
|
||||
#endif
|
||||
|
||||
class Log::PrivateData {
|
||||
public:
|
||||
PrivateData() : logOutput(Log::System), debug(false) {}
|
||||
|
||||
Log::LogOutput logOutput;
|
||||
bool debug;
|
||||
|
||||
static Log *instance;
|
||||
#ifdef _WINDOWS
|
||||
HANDLE eventSource;
|
||||
#endif
|
||||
};
|
||||
|
||||
Log *Log::PrivateData::instance = 0;
|
||||
|
||||
Log::Log()
|
||||
:d(new PrivateData) {
|
||||
#if defined(_LINUX)
|
||||
setlogmask(LOG_UPTO(LOG_INFO));
|
||||
openlog("telldusd", LOG_CONS, LOG_USER);
|
||||
#elif defined(_MACOSX)
|
||||
d->logOutput = Log::StdOut;
|
||||
#elif defined(_WINDOWS)
|
||||
// Add ourselves to the registy
|
||||
HKEY hRegKey = NULL;
|
||||
DWORD dwError = 0;
|
||||
TCHAR filePath[MAX_PATH];
|
||||
|
||||
std::wstring path(L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\TelldusService");
|
||||
dwError = RegCreateKey( HKEY_LOCAL_MACHINE, path.c_str(), &hRegKey );
|
||||
|
||||
GetModuleFileName( NULL, filePath, MAX_PATH );
|
||||
dwError = RegSetValueEx( hRegKey, L"EventMessageFile", 0, REG_EXPAND_SZ, (PBYTE) filePath, (DWORD)(wcslen(filePath) + 1) * sizeof TCHAR );
|
||||
|
||||
DWORD dwTypes = LOG_DEBUG | LOG_NOTICE | LOG_WARNING | LOG_ERR;
|
||||
dwError = RegSetValueEx( hRegKey, L"TypesSupported", 0, REG_DWORD, (LPBYTE) &dwTypes, sizeof dwTypes );
|
||||
|
||||
RegCloseKey(hRegKey);
|
||||
|
||||
d->eventSource = RegisterEventSource(NULL, L"TelldusService");
|
||||
#endif
|
||||
}
|
||||
|
||||
Log::~Log() {
|
||||
#if defined(_LINUX)
|
||||
closelog();
|
||||
#elif defined(_WINDOWS)
|
||||
if (d->eventSource != NULL) {
|
||||
DeregisterEventSource(d->eventSource);
|
||||
}
|
||||
#endif
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Log::destroy() {
|
||||
if (PrivateData::instance == 0) {
|
||||
return;
|
||||
}
|
||||
delete PrivateData::instance;
|
||||
PrivateData::instance = 0;
|
||||
}
|
||||
|
||||
void Log::debug(const char *fmt, ...) {
|
||||
Log *log = Log::instance();
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
log->message(Debug, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Log::notice(const char *fmt, ...) {
|
||||
Log *log = Log::instance();
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
log->message(Notice, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Log::warning(const char *fmt, ...) {
|
||||
Log *log = Log::instance();
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
log->message(Warning, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Log::error(const char *fmt, ...) {
|
||||
Log *log = Log::instance();
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
log->message(Error, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Log::setDebug() {
|
||||
Log *log = Log::instance();
|
||||
log->d->debug = true;
|
||||
Log::debug("Debug message output enabled");
|
||||
}
|
||||
|
||||
void Log::setLogOutput(LogOutput logOutput) {
|
||||
#ifdef _MACOSX
|
||||
// Always stdout
|
||||
return;
|
||||
#endif
|
||||
Log *log = Log::instance();
|
||||
log->d->logOutput = logOutput;
|
||||
}
|
||||
|
||||
void Log::message(Log::LogLevel logLevel, const char *format, va_list ap) const {
|
||||
if (logLevel == Debug && d->debug == false) {
|
||||
return;
|
||||
}
|
||||
if (d->logOutput == StdOut) {
|
||||
FILE *stream = stdout;
|
||||
if (logLevel == Warning || logLevel == Error) {
|
||||
stream = stderr;
|
||||
}
|
||||
vfprintf(stream, format, ap);
|
||||
fprintf(stream, "\n");
|
||||
fflush(stream);
|
||||
} else {
|
||||
#if defined(_LINUX)
|
||||
switch (logLevel) {
|
||||
case Debug:
|
||||
vsyslog(LOG_DEBUG, format, ap);
|
||||
break;
|
||||
case Notice:
|
||||
vsyslog(LOG_NOTICE, format, ap);
|
||||
break;
|
||||
case Warning:
|
||||
vsyslog(LOG_WARNING, format, ap);
|
||||
break;
|
||||
case Error:
|
||||
vsyslog(LOG_ERR, format, ap);
|
||||
break;
|
||||
}
|
||||
#elif defined(_WINDOWS)
|
||||
LPWSTR pInsertStrings[2] = {NULL, NULL};
|
||||
std::wstring str = TelldusCore::charToWstring(TelldusCore::sformatf(format, ap).c_str());
|
||||
pInsertStrings[0] = (LPWSTR)str.c_str();
|
||||
|
||||
switch (logLevel) {
|
||||
case Debug:
|
||||
ReportEvent(d->eventSource, EVENTLOG_SUCCESS, NULL, LOG_DEBUG, NULL, 1, 0, reinterpret_cast<LPCWSTR*>(&pInsertStrings), NULL);
|
||||
break;
|
||||
case Notice:
|
||||
ReportEvent(d->eventSource, EVENTLOG_INFORMATION_TYPE, NULL, LOG_NOTICE, NULL, 1, 0, reinterpret_cast<LPCWSTR*>(&pInsertStrings), NULL);
|
||||
break;
|
||||
case Warning:
|
||||
ReportEvent(d->eventSource, EVENTLOG_WARNING_TYPE, NULL, LOG_WARNING, NULL, 1, 0, reinterpret_cast<LPCWSTR*>(&pInsertStrings), NULL);
|
||||
break;
|
||||
case Error:
|
||||
ReportEvent(d->eventSource, EVENTLOG_ERROR_TYPE, NULL, LOG_ERR, NULL, 1, 0, reinterpret_cast<LPCWSTR*>(&pInsertStrings), NULL);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Log *Log::instance() {
|
||||
if (PrivateData::instance == 0) {
|
||||
PrivateData::instance = new Log();
|
||||
}
|
||||
return PrivateData::instance;
|
||||
}
|
||||
40
telldus-core/service/Log.h
Normal file
40
telldus-core/service/Log.h
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_LOG_H_
|
||||
#define TELLDUS_CORE_SERVICE_LOG_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
class Log {
|
||||
public:
|
||||
enum LogLevel { Debug, Notice, Warning, Error };
|
||||
enum LogOutput { StdOut, System };
|
||||
virtual ~Log();
|
||||
|
||||
static void destroy();
|
||||
|
||||
static void debug(const char *fmt, ...);
|
||||
static void notice(const char *fmt, ...);
|
||||
static void warning(const char *fmt, ...);
|
||||
static void error(const char *fmt, ...);
|
||||
|
||||
static void setDebug();
|
||||
static void setLogOutput(LogOutput logOutput);
|
||||
|
||||
protected:
|
||||
Log();
|
||||
void message(LogLevel logLevel, const char *format, va_list ap) const;
|
||||
static Log *instance();
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_LOG_H_
|
||||
BIN
telldus-core/service/Messages.mc
Normal file
BIN
telldus-core/service/Messages.mc
Normal file
Binary file not shown.
267
telldus-core/service/Protocol.cpp
Normal file
267
telldus-core/service/Protocol.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/Protocol.h"
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "client/telldus-core.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
#include "service/ProtocolBrateck.h"
|
||||
#include "service/ProtocolComen.h"
|
||||
#include "service/ProtocolEverflourish.h"
|
||||
#include "service/ProtocolFineoffset.h"
|
||||
#include "service/ProtocolFuhaote.h"
|
||||
#include "service/ProtocolGroup.h"
|
||||
#include "service/ProtocolHasta.h"
|
||||
#include "service/ProtocolIkea.h"
|
||||
#include "service/ProtocolMandolyn.h"
|
||||
#include "service/ProtocolNexa.h"
|
||||
#include "service/ProtocolOregon.h"
|
||||
#include "service/ProtocolRisingSun.h"
|
||||
#include "service/ProtocolSartano.h"
|
||||
#include "service/ProtocolScene.h"
|
||||
#include "service/ProtocolSilvanChip.h"
|
||||
#include "service/ProtocolUpm.h"
|
||||
#include "service/ProtocolWaveman.h"
|
||||
#include "service/ProtocolX10.h"
|
||||
#include "service/ProtocolYidong.h"
|
||||
#include "common/Strings.h"
|
||||
|
||||
class Protocol::PrivateData {
|
||||
public:
|
||||
ParameterMap parameterList;
|
||||
std::wstring model;
|
||||
};
|
||||
|
||||
Protocol::Protocol() {
|
||||
d = new PrivateData;
|
||||
}
|
||||
|
||||
Protocol::~Protocol(void) {
|
||||
delete d;
|
||||
}
|
||||
|
||||
std::wstring Protocol::model() const {
|
||||
std::wstring strModel = d->model;
|
||||
// Strip anything after : if it is found
|
||||
size_t pos = strModel.find(L":");
|
||||
if (pos != std::wstring::npos) {
|
||||
strModel = strModel.substr(0, pos);
|
||||
}
|
||||
|
||||
return strModel;
|
||||
}
|
||||
|
||||
void Protocol::setModel(const std::wstring &model) {
|
||||
d->model = model;
|
||||
}
|
||||
|
||||
void Protocol::setParameters(const ParameterMap ¶meterList) {
|
||||
d->parameterList = parameterList;
|
||||
}
|
||||
|
||||
std::wstring Protocol::getStringParameter(const std::wstring &name, const std::wstring &defaultValue) const {
|
||||
ParameterMap::const_iterator it = d->parameterList.find(name);
|
||||
if (it == d->parameterList.end()) {
|
||||
return defaultValue;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int Protocol::getIntParameter(const std::wstring &name, int min, int max) const {
|
||||
std::wstring value = getStringParameter(name, L"");
|
||||
if (value == L"") {
|
||||
return min;
|
||||
}
|
||||
std::wstringstream st;
|
||||
st << value;
|
||||
int intValue = 0;
|
||||
st >> intValue;
|
||||
if (intValue < min) {
|
||||
return min;
|
||||
}
|
||||
if (intValue > max) {
|
||||
return max;
|
||||
}
|
||||
return intValue;
|
||||
}
|
||||
|
||||
bool Protocol::checkBit(int data, int bitno) {
|
||||
return ((data >> bitno)&0x01);
|
||||
}
|
||||
|
||||
|
||||
Protocol *Protocol::getProtocolInstance(const std::wstring &protocolname) {
|
||||
if(TelldusCore::comparei(protocolname, L"arctech")) {
|
||||
return new ProtocolNexa();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"brateck")) {
|
||||
return new ProtocolBrateck();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"comen")) {
|
||||
return new ProtocolComen();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"everflourish")) {
|
||||
return new ProtocolEverflourish();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"fuhaote")) {
|
||||
return new ProtocolFuhaote();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"hasta")) {
|
||||
return new ProtocolHasta();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"ikea")) {
|
||||
return new ProtocolIkea();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"risingsun")) {
|
||||
return new ProtocolRisingSun();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"sartano")) {
|
||||
return new ProtocolSartano();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"silvanchip")) {
|
||||
return new ProtocolSilvanChip();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"upm")) {
|
||||
return new ProtocolUpm();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"waveman")) {
|
||||
return new ProtocolWaveman();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"x10")) {
|
||||
return new ProtocolX10();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"yidong")) {
|
||||
return new ProtocolYidong();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"group")) {
|
||||
return new ProtocolGroup();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"scene")) {
|
||||
return new ProtocolScene();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::list<std::string> Protocol::getParametersForProtocol(const std::wstring &protocolName) {
|
||||
std::list<std::string> parameters;
|
||||
if(TelldusCore::comparei(protocolName, L"arctech")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"brateck")) {
|
||||
parameters.push_back("house");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"comen")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"everflourish")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"fuhaote")) {
|
||||
parameters.push_back("code");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"hasta")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"ikea")) {
|
||||
parameters.push_back("system");
|
||||
parameters.push_back("units");
|
||||
// parameters.push_back("fade");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"risingsun")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"sartano")) {
|
||||
parameters.push_back("code");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"silvanchip")) {
|
||||
parameters.push_back("house");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"upm")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"waveman")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"x10")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"yidong")) {
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"group")) {
|
||||
parameters.push_back("devices");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"scene")) {
|
||||
parameters.push_back("devices");
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
std::list<std::string> Protocol::decodeData(const std::string &fullData) {
|
||||
std::list<std::string> retval;
|
||||
std::string decoded = "";
|
||||
|
||||
ControllerMessage dataMsg(fullData);
|
||||
if( TelldusCore::comparei(dataMsg.protocol(), L"arctech") ) {
|
||||
decoded = ProtocolNexa::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
decoded = ProtocolWaveman::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
decoded = ProtocolSartano::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if(TelldusCore::comparei(dataMsg.protocol(), L"everflourish") ) {
|
||||
decoded = ProtocolEverflourish::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if(TelldusCore::comparei(dataMsg.protocol(), L"fineoffset") ) {
|
||||
decoded = ProtocolFineoffset::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if(TelldusCore::comparei(dataMsg.protocol(), L"mandolyn") ) {
|
||||
decoded = ProtocolMandolyn::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if(TelldusCore::comparei(dataMsg.protocol(), L"oregon") ) {
|
||||
decoded = ProtocolOregon::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if(TelldusCore::comparei(dataMsg.protocol(), L"x10") ) {
|
||||
decoded = ProtocolX10::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if(TelldusCore::comparei(dataMsg.protocol(), L"hasta") ) {
|
||||
decoded = ProtocolHasta::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
46
telldus-core/service/Protocol.h
Normal file
46
telldus-core/service/Protocol.h
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOL_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOL_H_
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "client/telldus-core.h"
|
||||
|
||||
typedef std::map<std::wstring, std::wstring> ParameterMap;
|
||||
|
||||
class Controller;
|
||||
|
||||
class Protocol {
|
||||
public:
|
||||
Protocol();
|
||||
virtual ~Protocol(void);
|
||||
|
||||
static Protocol *getProtocolInstance(const std::wstring &protocolname);
|
||||
static std::list<std::string> getParametersForProtocol(const std::wstring &protocolName);
|
||||
static std::list<std::string> decodeData(const std::string &fullData);
|
||||
|
||||
virtual int methods() const = 0;
|
||||
std::wstring model() const;
|
||||
void setModel(const std::wstring &model);
|
||||
void setParameters(const ParameterMap ¶meterList);
|
||||
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller) = 0;
|
||||
|
||||
protected:
|
||||
virtual std::wstring getStringParameter(const std::wstring &name, const std::wstring &defaultValue = L"") const;
|
||||
virtual int getIntParameter(const std::wstring &name, int min, int max) const;
|
||||
|
||||
static bool checkBit(int data, int bit);
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOL_H_
|
||||
53
telldus-core/service/ProtocolBrateck.cpp
Normal file
53
telldus-core/service/ProtocolBrateck.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolBrateck.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolBrateck::methods() const {
|
||||
return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP;
|
||||
}
|
||||
|
||||
std::string ProtocolBrateck::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
const char S = '!';
|
||||
const char L = 'V';
|
||||
const char B1[] = {L, S, L, S, 0};
|
||||
const char BX[] = {S, L, L, S, 0};
|
||||
const char B0[] = {S, L, S, L, 0};
|
||||
const char BUP[] = {L, S, L, S, S, L, S, L, S, L, S, L, S, L, S, L, S, 0};
|
||||
const char BSTOP[] = {S, L, S, L, L, S, L, S, S, L, S, L, S, L, S, L, S, 0};
|
||||
const char BDOWN[] = {S, L, S, L, S, L, S, L, S, L, S, L, L, S, L, S, S, 0};
|
||||
|
||||
std::string strReturn;
|
||||
std::wstring strHouse = this->getStringParameter(L"house", L"");
|
||||
if (strHouse == L"") {
|
||||
return "";
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < strHouse.length(); ++i ) {
|
||||
if (strHouse[i] == '1') {
|
||||
strReturn.insert(0, B1);
|
||||
} else if (strHouse[i] == '-') {
|
||||
strReturn.insert(0, BX);
|
||||
} else if (strHouse[i] == '0') {
|
||||
strReturn.insert(0, B0);
|
||||
}
|
||||
}
|
||||
|
||||
strReturn.insert(0, "S");
|
||||
if (method == TELLSTICK_UP) {
|
||||
strReturn.append(BUP);
|
||||
} else if (method == TELLSTICK_DOWN) {
|
||||
strReturn.append(BDOWN);
|
||||
} else if (method == TELLSTICK_STOP) {
|
||||
strReturn.append(BSTOP);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
strReturn.append("+");
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
19
telldus-core/service/ProtocolBrateck.h
Normal file
19
telldus-core/service/ProtocolBrateck.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolBrateck : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_
|
||||
23
telldus-core/service/ProtocolComen.cpp
Normal file
23
telldus-core/service/ProtocolComen.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolComen.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolComen::methods() const {
|
||||
return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN);
|
||||
}
|
||||
|
||||
int ProtocolComen::getIntParameter(const std::wstring &name, int min, int max) const {
|
||||
if (name.compare(L"house") == 0) {
|
||||
int intHouse = Protocol::getIntParameter(L"house", 1, 16777215);
|
||||
// The last two bits must be hardcoded
|
||||
intHouse <<= 2;
|
||||
intHouse += 2;
|
||||
return intHouse;
|
||||
}
|
||||
return Protocol::getIntParameter(name, min, max);
|
||||
}
|
||||
21
telldus-core/service/ProtocolComen.h
Normal file
21
telldus-core/service/ProtocolComen.h
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/ProtocolNexa.h"
|
||||
|
||||
class ProtocolComen : public ProtocolNexa {
|
||||
public:
|
||||
virtual int methods() const;
|
||||
|
||||
protected:
|
||||
virtual int getIntParameter(const std::wstring &name, int min, int max) const;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_
|
||||
133
telldus-core/service/ProtocolEverflourish.cpp
Normal file
133
telldus-core/service/ProtocolEverflourish.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolEverflourish.h"
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
int ProtocolEverflourish::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN;
|
||||
}
|
||||
|
||||
std::string ProtocolEverflourish::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
unsigned int deviceCode = this->getIntParameter(L"house", 0, 16383);
|
||||
unsigned int intCode = this->getIntParameter(L"unit", 1, 4)-1;
|
||||
unsigned char action;
|
||||
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
action = 15;
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
action = 0;
|
||||
} else if (method == TELLSTICK_LEARN) {
|
||||
action = 10;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
const char ssss = 85;
|
||||
const char sssl = 84; // 0
|
||||
const char slss = 69; // 1
|
||||
|
||||
const char bits[2] = {sssl, slss};
|
||||
int i, check;
|
||||
|
||||
std::string strCode;
|
||||
|
||||
deviceCode = (deviceCode << 2) | intCode;
|
||||
|
||||
check = calculateChecksum(deviceCode);
|
||||
|
||||
char preamble[] = {'R', 5, 'T', 114, 60, 1, 1, 105, ssss, ssss, 0};
|
||||
strCode.append(preamble);
|
||||
|
||||
for(i = 15; i >= 0; i--) {
|
||||
strCode.append(1, bits[(deviceCode >> i)&0x01]);
|
||||
}
|
||||
for(i = 3; i >= 0; i--) {
|
||||
strCode.append(1, bits[(check >> i)&0x01]);
|
||||
}
|
||||
for(i = 3; i >= 0; i--) {
|
||||
strCode.append(1, bits[(action >> i)&0x01]);
|
||||
}
|
||||
|
||||
strCode.append(1, ssss);
|
||||
strCode.append(1, '+');
|
||||
|
||||
return strCode;
|
||||
}
|
||||
|
||||
// The calculation used in this function is provided by Frank Stevenson
|
||||
unsigned int ProtocolEverflourish::calculateChecksum(unsigned int x) {
|
||||
unsigned int bits[16] = {
|
||||
0xf, 0xa, 0x7, 0xe,
|
||||
0xf, 0xd, 0x9, 0x1,
|
||||
0x1, 0x2, 0x4, 0x8,
|
||||
0x3, 0x6, 0xc, 0xb
|
||||
};
|
||||
unsigned int bit = 1;
|
||||
unsigned int res = 0x5;
|
||||
int i;
|
||||
unsigned int lo, hi;
|
||||
|
||||
if ((x & 0x3) == 3) {
|
||||
lo = x & 0x00ff;
|
||||
hi = x & 0xff00;
|
||||
lo += 4;
|
||||
if (lo>0x100) {
|
||||
lo = 0x12;
|
||||
}
|
||||
x = lo | hi;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++) {
|
||||
if (x & bit) {
|
||||
res = res ^ bits[i];
|
||||
}
|
||||
bit = bit << 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string ProtocolEverflourish::decodeData(const ControllerMessage &dataMsg) {
|
||||
uint64_t allData;
|
||||
unsigned int house = 0;
|
||||
unsigned int unit = 0;
|
||||
unsigned int method = 0;
|
||||
|
||||
allData = dataMsg.getInt64Parameter("data");
|
||||
|
||||
house = allData & 0xFFFC00;
|
||||
house >>= 10;
|
||||
|
||||
unit = allData & 0x300;
|
||||
unit >>= 8;
|
||||
unit++; // unit from 1 to 4
|
||||
|
||||
method = allData & 0xF;
|
||||
|
||||
if(house > 16383 || unit < 1 || unit > 4) {
|
||||
// not everflourish
|
||||
return "";
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:command;protocol:everflourish;model:selflearning;house:" << house << ";unit:" << unit << ";method:";
|
||||
if(method == 0) {
|
||||
retString << "turnoff;";
|
||||
} else if(method == 15) {
|
||||
retString << "turnon;";
|
||||
} else if(method == 10) {
|
||||
retString << "learn;";
|
||||
} else {
|
||||
// not everflourish
|
||||
return "";
|
||||
}
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
24
telldus-core/service/ProtocolEverflourish.h
Normal file
24
telldus-core/service/ProtocolEverflourish.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
class ProtocolEverflourish : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
|
||||
private:
|
||||
static unsigned int calculateChecksum(unsigned int x);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_
|
||||
52
telldus-core/service/ProtocolFineoffset.cpp
Normal file
52
telldus-core/service/ProtocolFineoffset.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolFineoffset.h"
|
||||
#include <stdlib.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
|
||||
std::string ProtocolFineoffset::decodeData(const ControllerMessage &dataMsg) {
|
||||
std::string data = dataMsg.getParameter("data");
|
||||
if (data.length() < 8) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Checksum currently not used
|
||||
// uint8_t checksum = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2));
|
||||
data = data.substr(0, data.length()-2);
|
||||
|
||||
uint8_t humidity = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2));
|
||||
data = data.substr(0, data.length()-2);
|
||||
|
||||
uint16_t value = (uint16_t)TelldusCore::hexTo64l(data.substr(data.length()-3));
|
||||
double temperature = (value & 0x7FF)/10.0;
|
||||
|
||||
value >>= 11;
|
||||
if (value & 1) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
data = data.substr(0, data.length()-3);
|
||||
|
||||
uint16_t id = (uint16_t)TelldusCore::hexTo64l(data) & 0xFF;
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:fineoffset;id:" << id << ";model:";
|
||||
|
||||
if (humidity <= 100) {
|
||||
retString << "temperaturehumidity;humidity:" << static_cast<int>(humidity) << ";";
|
||||
} else if (humidity == 0xFF) {
|
||||
retString << "temperature;";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
retString << "temp:" << std::fixed << std::setprecision(1) << temperature << ";";
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
19
telldus-core/service/ProtocolFineoffset.h
Normal file
19
telldus-core/service/ProtocolFineoffset.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
class ProtocolFineoffset : public Protocol {
|
||||
public:
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_
|
||||
60
telldus-core/service/ProtocolFuhaote.cpp
Normal file
60
telldus-core/service/ProtocolFuhaote.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolFuhaote.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolFuhaote::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
|
||||
}
|
||||
|
||||
std::string ProtocolFuhaote::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
const char S = 19;
|
||||
const char L = 58;
|
||||
const char B0[] = {S, L, L, S, 0};
|
||||
const char B1[] = {L, S, L, S, 0};
|
||||
const char OFF[] = {S, L, S, L, S, L, L, S, 0};
|
||||
const char ON[] = {S, L, L, S, S, L, S, L, 0};
|
||||
|
||||
std::string strReturn = "S";
|
||||
std::wstring strCode = this->getStringParameter(L"code", L"");
|
||||
if (strCode == L"") {
|
||||
return "";
|
||||
}
|
||||
|
||||
// House code
|
||||
for(size_t i = 0; i < 5; ++i) {
|
||||
if (strCode[i] == '0') {
|
||||
strReturn.append(B0);
|
||||
} else if (strCode[i] == '1') {
|
||||
strReturn.append(B1);
|
||||
}
|
||||
}
|
||||
// Unit code
|
||||
for(size_t i = 5; i < 10; ++i) {
|
||||
if (strCode[i] == '0') {
|
||||
strReturn.append(B0);
|
||||
} else if (strCode[i] == '1') {
|
||||
strReturn.append(1, S);
|
||||
strReturn.append(1, L);
|
||||
strReturn.append(1, S);
|
||||
strReturn.append(1, L);
|
||||
}
|
||||
}
|
||||
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
strReturn.append(ON);
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
strReturn.append(OFF);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
strReturn.append(1, S);
|
||||
strReturn.append("+");
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
19
telldus-core/service/ProtocolFuhaote.h
Normal file
19
telldus-core/service/ProtocolFuhaote.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolFuhaote : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_
|
||||
16
telldus-core/service/ProtocolGroup.cpp
Normal file
16
telldus-core/service/ProtocolGroup.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolGroup.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolGroup::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_BELL | TELLSTICK_LEARN | TELLSTICK_EXECUTE | TELLSTICK_TOGGLE | TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP;
|
||||
}
|
||||
|
||||
std::string ProtocolGroup::getStringForMethod(int method, unsigned char data, Controller *) {
|
||||
return "";
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user