random ai stuff

This commit is contained in:
matst80
2025-11-21 18:12:55 +01:00
commit 60f5783a26
187 changed files with 25197 additions and 0 deletions

View 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}
)

View 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);
}

View 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_ */

View 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));
}

View 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;

View 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_

View File

View 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_ */

View 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_ */

View 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_ */

View 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_ */

View 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
View 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>

View 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()

View 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
View 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
View 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
View 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

View 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)

View 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

View 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_

View 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

View 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

View 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

View 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_

View 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

File diff suppressed because it is too large Load Diff

View 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_

View 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

View 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()

View 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} )

View 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

View 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_

View 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_

View 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

View 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

View 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

View 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

View 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

View 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_

View 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

View 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_

View 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_

View 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

View 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

View 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;
}
}
}

View 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_

View 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

View 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_

View 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_

View 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

View 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

View File

@@ -0,0 +1 @@
9

View 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

View 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".

View File

@@ -0,0 +1,2 @@
usr/include/*
usr/lib/lib*.so

View File

@@ -0,0 +1 @@
usr/lib/lib*.so.*

File diff suppressed because it is too large Load Diff

View File

@@ -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)

View File

@@ -0,0 +1,2 @@
01_add_missing_doxyfile.patch
02_fix_link_ordering_problem.patch

15
telldus-core/debian/rules Executable file
View 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

View File

@@ -0,0 +1 @@
3.0 (quilt)

View File

@@ -0,0 +1 @@
README

View File

@@ -0,0 +1,5 @@
usr/bin/*
usr/sbin/*
etc/*
var/state/*
usr/share/telldus-core/*

View 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()

View 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);
}

View 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_

View 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_

View 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);
}

View 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);
}

View 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);
}

View 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_

View 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_

View 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);
}
}

View 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);
}

View 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_

View 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;
}

View 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_

View 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;
}

View 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_

View 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;
}

View 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_

View 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
}

View 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_

View 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;
}

View 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_

Binary file not shown.

View 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 &parameterList) {
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;
}

View 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 &parameterList);
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_

View 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;
}

View 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_

View 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);
}

View 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_

View 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();
}

View 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_

View 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();
}

View 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_

View 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;
}

View 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_

View 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