diff options
author | Lars Heer <l.heer@gmx.de> | 2013-09-18 05:50:03 +0200 |
---|---|---|
committer | Lars Heer <l.heer@gmx.de> | 2013-09-18 05:50:03 +0200 |
commit | ccf6e0f9c6b0481ed13e0f4794e3fbead750f385 (patch) | |
tree | ed86efb54f7ee41edfba5c89ca519b5fd10aa0d5 /mcast/client/.svn | |
download | vdr-plugin-mcli-ccf6e0f9c6b0481ed13e0f4794e3fbead750f385.tar.gz vdr-plugin-mcli-ccf6e0f9c6b0481ed13e0f4794e3fbead750f385.tar.bz2 |
added vdr-plugin-mcli-0.0.1+svn20120927
Diffstat (limited to 'mcast/client/.svn')
53 files changed, 5728 insertions, 0 deletions
diff --git a/mcast/client/.svn/entries b/mcast/client/.svn/entries new file mode 100644 index 0000000..11f10fe --- /dev/null +++ b/mcast/client/.svn/entries @@ -0,0 +1,1357 @@ +10 + +dir +18963 +svn://reelbox.org/testing/src/vdr-plugins/src/mcli-1/mcast/client +svn://reelbox.org + + + +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + +12be777f-adf9-0310-842f-e37ecc4c7426 + +dvblo_handler.c +file + + + + +2012-09-27T17:22:49.690848Z +c4b6b1eb8cd3a18164b5e331f0a38e66 +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +20024 + +recv_ccpp.c +file + + + + +2012-09-27T17:22:49.690848Z +5f878ec9ebd38288cfcc82ee5020c35f +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +21 + +api_server.h +file + + + + +2012-09-27T17:22:49.690848Z +b8b3a949bf3dd399db5549c95421ddcb +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +1357 + +tca_handler.c +file + + + + +2012-09-27T17:22:49.690848Z +2b508aed689369915aa2901edb11ac20 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +1840 + +satlists.c +file + + + + +2012-09-27T17:22:49.690848Z +d3b50554e8c693cfd4af919fad07fbc0 +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +5049 + +api_test.c +file + + + + +2012-09-27T17:22:49.690848Z +fce170fc6462af495657d8669b043b41 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +4459 + +dvblo_handler.h +file + + + + +2012-09-27T17:22:49.690848Z +9adb433e99e33b9e2d694ff475b740de +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +743 + +tca_handler.h +file + + + + +2012-09-27T17:22:49.690848Z +3a3b79eee5e1dba852b69f2000a3ccee +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +405 + +mld_client.c +file + + + + +2012-09-27T17:22:49.690848Z +e05bdc7ebc621c510360568867dfdecf +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +22 + +.indent.pro +file + + + + +2012-09-27T17:22:49.690848Z +536d6397e801893325c24ec292dee74f +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +22 + +mmi_handler.c +file + + + + +2012-09-27T17:22:49.690848Z +f85ea2246efdb5607ee9a20366bfcd51 +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +9851 + +inet_aton.c +file + + + + +2012-09-27T17:22:49.690848Z +48b37f322a2ae164aa3fb4204c83f6a3 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +27 + +headers.h +file + + + + +2012-09-27T17:22:49.690848Z +aeaf120e1dfc0892b0c49cdf722c9fef +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +638 + +interfaces.c +file + + + + +2012-09-27T17:22:49.690848Z +bd70360e68db12e0e2fe335bc92ad0e3 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +22 + +mmi_handler.h +file + + + + +2012-09-27T17:22:49.690848Z +ed868ea810d05d4fe0ea795cad357faa +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +1225 + +ci_handler.c +file + + + + +2012-09-27T17:22:49.690848Z +d8f14df45e26ee759bb661076b00df2f +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +8218 + +dummy_client.c +file + + + + +2012-09-27T17:22:49.690848Z +c109d8ba8e2dec6b0b5b519c605148f5 +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +2677 + +Makefile +file + + + + +2012-09-27T17:22:49.690848Z +ece098cc6788e85c17ce068287a98921 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +4977 + +ci_handler.h +file + + + + +2012-09-27T17:22:49.690848Z +fefcc7f7895850402b2326d8801c41c7 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +859 + +dummy_client.h +file + + + + +2012-09-27T17:22:49.690848Z +1d353edb3158ed94c160c71b499b6591 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +180 + +mld_reporter.c +file + + + + +2012-09-27T17:22:49.690848Z +e3965ad4570cff659778eec00fbb7e4c +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +6670 + +input.c +file + + + + +2012-09-27T17:22:49.694848Z +d1e761e12f3e1dec2a559289cb35cde8 +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +3730 + +tools.c +file + + + + +2012-09-27T17:22:49.694848Z +c0906e8f658e6d84d4e12dca1e3ffc57 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +17 + +mingw +dir + +mld_reporter.h +file + + + + +2012-09-27T17:22:49.694848Z +d2eab4a0ce39c3aa79acf912f5bdf7ae +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +239 + +mcast.c +file + + + + +2012-09-27T17:22:49.694848Z +b6c289caaedfc9f9a24d597c72a5d8ce +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +17 + +recv_tv.c +file + + + + +2012-09-27T17:22:49.694848Z +e7bafc54679736def7ce798acacea0e7 +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +25663 + +ciparser.c +file + + + + +2012-09-27T17:22:49.694848Z +0cc85089fb87cd0fd0e240e4163510ae +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +20 + +recv_tv.h +file + + + + +2012-09-27T17:22:49.694848Z +e270bffd77d17ca32d976a57be19ea2c +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +2396 + +api_shm_test.c +file + + + + +2012-09-27T17:22:49.694848Z +3be100d9064c5186f90d3efe17ae5e0a +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +10 + +win32 +file + + + + +2012-09-27T17:22:49.694848Z +7e2c1fbd0a7ddc76a7a55f662d59e6e3 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +15 + +tra_handler.c +file + + + + +2012-09-27T17:22:49.694848Z +720a9b9450e8d072850a8632f9efb3bc +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +1121 + +mld_common.c +file + + + + +2012-09-27T17:22:49.694848Z +d0224283be18ec0774fb34c10667634a +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +22 + +main.c +file + + + + +2012-09-27T17:22:49.694848Z +f1a5585bbe9a3711ad03bc10cb2def5a +2011-08-18T10:09:14.813360Z +17158 +dirk + + + + + + + + + + + + + + + + + + + + + +1599 + +api_sock_test.c +file + + + + +2012-09-27T17:22:49.694848Z +3be100d9064c5186f90d3efe17ae5e0a +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +10 + +tra_handler.h +file + + + + +2012-09-27T17:22:49.694848Z +694293ed706ea26dc96111413def41d4 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +234 + +sock_test.c +file + + + + +2012-09-27T17:22:49.686848Z +7d714bc587133294a02cb2edf0e6a841 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +2911 + +inet_pton.c +file + + + + +2012-09-27T17:22:49.686848Z +935bd6f5bff2d3724e7e1913bf6f0b81 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +27 + +inet_ntop.c +file + + + + +2012-09-27T17:22:49.690848Z +04380ba6685b175467f790aba9963a01 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster +has-props + + +svn:special + + + + + + + + + + + + + + + + + +27 + +api_server.c +file + + + + +2012-09-27T17:22:49.690848Z +853f06ad8aec7ec15e6fda43b1f66a77 +2011-07-12T13:36:23.313379Z +16905 +rollercoaster + + + + + + + + + + + + + + + + + + + + + +10766 + diff --git a/mcast/client/.svn/prop-base/api_shm_test.c.svn-base b/mcast/client/.svn/prop-base/api_shm_test.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/api_shm_test.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/api_sock_test.c.svn-base b/mcast/client/.svn/prop-base/api_sock_test.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/api_sock_test.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/ciparser.c.svn-base b/mcast/client/.svn/prop-base/ciparser.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/ciparser.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/inet_aton.c.svn-base b/mcast/client/.svn/prop-base/inet_aton.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/inet_aton.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/inet_ntop.c.svn-base b/mcast/client/.svn/prop-base/inet_ntop.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/inet_ntop.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/inet_pton.c.svn-base b/mcast/client/.svn/prop-base/inet_pton.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/inet_pton.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/interfaces.c.svn-base b/mcast/client/.svn/prop-base/interfaces.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/interfaces.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/mcast.c.svn-base b/mcast/client/.svn/prop-base/mcast.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/mcast.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/mld_client.c.svn-base b/mcast/client/.svn/prop-base/mld_client.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/mld_client.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/mld_common.c.svn-base b/mcast/client/.svn/prop-base/mld_common.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/mld_common.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/recv_ccpp.c.svn-base b/mcast/client/.svn/prop-base/recv_ccpp.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/recv_ccpp.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/tools.c.svn-base b/mcast/client/.svn/prop-base/tools.c.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/tools.c.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/prop-base/win32.svn-base b/mcast/client/.svn/prop-base/win32.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/mcast/client/.svn/prop-base/win32.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/mcast/client/.svn/text-base/.indent.pro.svn-base b/mcast/client/.svn/text-base/.indent.pro.svn-base new file mode 100644 index 0000000..2faef85 --- /dev/null +++ b/mcast/client/.svn/text-base/.indent.pro.svn-base @@ -0,0 +1 @@ +-i8 -br -l0 -ce -npsl diff --git a/mcast/client/.svn/text-base/Makefile.svn-base b/mcast/client/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..1ea0844 --- /dev/null +++ b/mcast/client/.svn/text-base/Makefile.svn-base @@ -0,0 +1,210 @@ +#Comment this out to disable debugging output +#DEBUG=1 +#VERBOSE=1 +#WIN32=1 +#API_SOCK=1 +#VERBOSE=1 +#BACKTRACE=1 + +ifdef RBMINI + ARMEL=1 +endif + +ARCH= $(shell $(CC) -dumpmachine) +APPLE_DARWIN = $(shell echo $(ARCH) | grep -q 'apple-darwin' && echo "1" || echo "0") +CYGWIN = $(shell echo $(ARCH) | grep -q 'cygwin' && echo "1" || echo "0") +MIPSEL = $(shell echo $(ARCH) | grep -q 'mipsel' && echo "1" || echo "0") + +DEFS=-DCLIENT -DLIBRARY -D_REENTRANT -D_GNU_SOURCE + +ifeq ($(CYGWIN), 1) +WIN32=1 +else +API_SOCK=1 +endif + +ifeq ($(APPLE_DARWIN), 1) +DEFS:=$(DEFS) -I../common/darwin/include/ -DAPPLE +APPLE=1 +endif + +VDRDIR=../../../../.. +-include $(VDRDIR)/Make.config + +ifdef ARMEL + XML_INC := -I/usr/arm-linux-gnueabi/include/libxml2 + XML_LIB := -lxml2 + CROSS = arm-linux-gnueabi- +else +ifeq ($(MIPSEL),1) +DEFS:=$(DEFS) -DMIPSEL +XML_INC:=-I../../libxml2/include +XML_LIB:=-L../../libxml2/lib +else +XML_INC:=`xml2-config --cflags` +XML_LIB:=`xml2-config --libs` +LIBRARY_PATH=/usr/lib +endif +endif +ifeq ($(APPLE_DARWIN), 1) +CFLAGS:= $(CFLAGS) -fPIC -fno-common -Wall -I../common $(DEFS) +else +CFLAGS:= $(CFLAGS) -fPIC -Wall -I../common $(DEFS) +endif + +ifdef BACKTRACE +CFLAGS:= $(CFLAGS) -DBACKTRACE -g +endif + +ifdef API_SHM +LDFLAGS:= $(LDFLAGS) -lrt +CFLAGS:= $(CFLAGS) -DAPI_SHM +endif +ifdef API_SOCK +CFLAGS:= $(CFLAGS) -DAPI_SOCK +endif + +ifdef VERBOSE +CFLAGS:= $(CFLAGS) -DDEBUG +DEBUG=1 +endif + +ifdef WIN32 +CFLAGS:= -Iwin32/include $(CFLAGS) -mno-cygwin -fPIC -DWIN32 +LDFLAGS:= -Lwin32/lib $(LDFLAGS) -mno-cygwin +LDLIBS:= -lpthreadGC2 -lxml2 -lz -lws2_32 -liphlpapi +else +CFLAGS:= $(CFLAGS) -I../dvbloop $(XML_INC) +LDFLAGS:=$(LDFLAGS) +LDLIBS:=$(XML_LIB) -lpthread -lz -lm +endif + +ifdef DEBUG +LDFLAGS:= $(LDFLAGS) -g -rdynamic +CFLAGS:= $(CFLAGS) -g -O0 +else +CFLAGS:= $(CFLAGS) -O3 +endif + +MCLI = mcli + +MCLI_OBJS= mld_common.o mld_client.o mld_reporter.o mcast.o recv_tv.o recv_ccpp.o tools.o tca_handler.o tra_handler.o satlists.o interfaces.o api_server.o ciparser.o ci_handler.o mmi_handler.o +ifdef WIN32 +MCLI_OBJS := $(MCLI_OBJS) inet_pton.o inet_ntop.o inet_aton.o +else +MCLI_OBJS := $(MCLI_OBJS) +endif + +MCLI_SOBJS = main.o +ifdef WIN32 +MCLI_SOBJS := $(MCLI_SOBJS) dummy_client.o +else +ifdef APPLE +MCLI_SOBJS := $(MCLI_SOBJS) dummy_client.o input.o +else +MCLI_SOBJS := $(MCLI_SOBJS) dvblo_handler.o input.o +endif +endif + +all: lib$(MCLI) + +static: $(MCLI)-static + + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + $(MAKEDEP) $(CFLAGS) $(MCLI_OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + + +$(MCLI): $(MCLI_OBJS) $(MCLI_SOBJS) + $(CC) $(LDFLAGS) -o $@ $(MCLI_OBJS) $(MCLI_SOBJS) $(LDLIBS) +ifndef DEBUG +ifndef WIN32 + strip $(MCLI) +endif +endif + +lib$(MCLI): $(MCLI_OBJS) +ifdef WIN32 + $(CC) $(LDFLAGS) -shared -o $@.dll $(MCLI_OBJS) $(LDLIBS) -Wl,--out-implib,$@.a -Wl,--output-def,$@.def + lib /def:$@.def /machine:x86 /out:..\\common\\win32\\lib\\$@.lib +# dlltool -k --dllname $@.dll --output-lib win32/lib/$@.lib --def $@.def + cp -a $@.dll win32/lib/ + cp -a $@.a win32/lib/ + cp -a $@.def win32/lib/ +endif +ifdef APPLE + $(CC) $(LDFLAGS) -dynamiclib -o $@.dylib $(MCLI_OBJS) $(LDLIBS) + $(AR) $(ARFLAGS) $@.a $(MCLI_OBJS) +else + $(CC) $(LDFLAGS) -shared -o $@.so $(MCLI_OBJS) $(LDLIBS) + $(AR) $(ARFLAGS) $@.a $(MCLI_OBJS) +endif + + +$(MCLI)-shared: lib$(MCLI) + $(CC) -c $(CFLAGS) -ULIBRARY -o main.o main.c +ifdef WIN32 + $(CC) -c $(CFLAGS) -ULIBRARY -o dummy_client.o dummy_client.c +else +ifdef APPLE + $(CC) -c $(CFLAGS) -ULIBRARY -o input.o input.c + $(CC) -c $(CFLAGS) -ULIBRARY -o dummy_client.o dummy_client.c +else + $(CC) -c $(CFLAGS) -ULIBRARY -o input.o input.c + $(CC) -c $(CFLAGS) -ULIBRARY -o dvblo_handler.o dvblo_handler.c +endif +endif + $(CC) $(LDFLAGS) -o $@ $(MCLI_SOBJS) $(LDLIBS) -L. -lmcli + +$(MCLI)-static: $(MCLI_OBJS) $(MCLI_SOBJS) + $(CC) $(LDFLAGS) -static -static-libgcc -o $@ $(MCLI_OBJS) $(MCLI_SOBJS) $(LDLIBS) $(LIBRARY_PATH)/libxml2.a $(LIBRARY_PATH)/libz.a $(LIBRARY_PATH)/libm.a $(LIBRARY_PATH)/libpthread.a +ifndef DEBUG +ifndef WIN32 + strip $(MCLI)-static +endif +endif + +api_shm_test.o: api_shm_test.c + $(CC) -c $(CFLAGS) -DUSE_SHM_API -o $@ $< + +api_sock_test.o:api_sock_test.c + $(CC) -c $(CFLAGS) -DUSE_SOCK_API -o $@ $< + +$(MCLI)-shmtest: api_shm_test.o + $(CC) $(LDFLAGS) -o $@ api_shm_test.o $(LDLIBS) -lrt + +$(MCLI)-socktest: api_sock_test.o + $(CC) $(LDFLAGS) -o $@ api_sock_test.o + +install: mcli + install -p $< /usr/sbin/$< + +install-lib: libmcli.la + libtool --mode=install install $< /usr/local/lib/ + +install-shared: mcli-shared + libtool --mode=install install $< /usr/local/bin + +depend: .dependencies + #makedepend -Y -- $(CFLAGS) -- *c >/dev/null 2>&1 + +clean: + rm -f $(MCLI) $(MCLI)-* *.elf *.gdb *.o *.lo *.la *~ *.so *.a *.def *.dll *.dylib out.ts + +mingw32: + rm -rf mingw/*.c mingw/*.h mingw/win32 + cp *.c *.h mingw/ + mkdir mingw/win32 + cp -a win32/lib mingw/win32/ + cp -a win32/include mingw/win32/ + @echo "Created mingw directory - now ready to rumble... (call build.cmd)" + +%.o: %.c + $(CC) -c $(CFLAGS) -o $@ $< + +%.lo: %.c + $(CC) -c $(CFLAGS) -o $@ $< diff --git a/mcast/client/.svn/text-base/api_server.c.svn-base b/mcast/client/.svn/text-base/api_server.c.svn-base new file mode 100644 index 0000000..c3d7617 --- /dev/null +++ b/mcast/client/.svn/text-base/api_server.c.svn-base @@ -0,0 +1,397 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" + +#if defined(API_SOCK) || defined(API_SHM) || defined (API_WIN) + +static int process_cmd (api_cmd_t * api_cmd, tra_info_t * trl, netceiver_info_list_t * nci) +{ + if(api_cmd->magic != MCLI_MAGIC || api_cmd->version != MCLI_VERSION) { + api_cmd->magic = MCLI_MAGIC; + api_cmd->version = MCLI_VERSION; + api_cmd->state = API_RESPONSE; + return 0; + } + if (api_cmd->state != API_REQUEST) { + return 0; + } + + switch (api_cmd->cmd) { + case API_GET_NC_NUM: + api_cmd->parm[API_PARM_NC_NUM] = nci->nci_num; + api_cmd->state = API_RESPONSE; + break; + + case API_GET_NC_INFO: + if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) { + api_cmd->u.nc_info = nci->nci[api_cmd->parm[API_PARM_NC_NUM]]; + api_cmd->state = API_RESPONSE; + } else { + api_cmd->state = API_ERROR; + } + break; + case API_GET_TUNER_INFO: + if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) { + if (api_cmd->parm[API_PARM_TUNER_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].tuner_num) { + api_cmd->u.tuner_info = nci->nci[api_cmd->parm[API_PARM_NC_NUM]].tuner[api_cmd->parm[API_PARM_TUNER_NUM]]; + api_cmd->state = API_RESPONSE; + } else { + api_cmd->state = API_ERROR; + } + } else { + api_cmd->state = API_ERROR; + } + break; + case API_GET_SAT_LIST_INFO: + if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) { + if (api_cmd->parm[API_PARM_SAT_LIST_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list_num) { + api_cmd->u.sat_list = nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]]; + api_cmd->state = API_RESPONSE; + } else { + api_cmd->state = API_ERROR; + } + } else { + api_cmd->state = API_ERROR; + } + break; + case API_GET_SAT_INFO: + if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) { + if (api_cmd->parm[API_PARM_SAT_LIST_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list_num) { + if (api_cmd->parm[API_PARM_SAT_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat_num) { + api_cmd->u.sat_info = nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat[api_cmd->parm[API_PARM_SAT_NUM]]; + api_cmd->state = API_RESPONSE; + } else { + api_cmd->state = API_ERROR; + } + } else { + api_cmd->state = API_ERROR; + } + } else { + api_cmd->state = API_ERROR; + } + break; + + case API_GET_SAT_COMP_INFO: + if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) { + if (api_cmd->parm[API_PARM_SAT_LIST_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list_num) { + if (api_cmd->parm[API_PARM_SAT_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat_num) { + if (api_cmd->parm[API_PARM_SAT_COMP_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat[api_cmd->parm[API_PARM_SAT_NUM]].comp_num) { + api_cmd->u.sat_comp = nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat[api_cmd->parm[API_PARM_SAT_NUM]].comp[api_cmd->parm[API_PARM_SAT_COMP_NUM]]; + api_cmd->state = API_RESPONSE; + } else { + api_cmd->state = API_ERROR; + } + } else { + api_cmd->state = API_ERROR; + } + } else { + api_cmd->state = API_ERROR; + } + } else { + api_cmd->state = API_ERROR; + } + break; + case API_GET_TRA_NUM: + api_cmd->parm[API_PARM_TRA_NUM] = trl->tra_num; + api_cmd->state = API_RESPONSE; + break; + case API_GET_TRA_INFO: + if (api_cmd->parm[API_PARM_TRA_NUM] < trl->tra_num) { + api_cmd->u.tra = trl->tra[api_cmd->parm[API_PARM_TRA_NUM]]; + api_cmd->state = API_RESPONSE; + } else { + api_cmd->state = API_ERROR; + } + break; + default: + api_cmd->state = API_ERROR; + } + return 1; +} +#endif +#ifdef API_SOCK +typedef struct +{ + pthread_t thread; + int fd; + struct sockaddr_un addr; + socklen_t len; + int run; +} sock_t; + +static void *sock_cmd_loop (void *p) +{ + sock_t *s = (sock_t *) p; + api_cmd_t sock_cmd; + int n; + netceiver_info_list_t *nc_list=nc_get_list(); + tra_info_t *tra_list=tra_get_list(); + + dbg ("new api client connected\n"); + s->run = 1; + while (s->run){ + n = recv (s->fd, &sock_cmd, sizeof (api_cmd_t), 0); + if (n == sizeof (api_cmd_t)) { + nc_lock_list(); + process_cmd (&sock_cmd, tra_list, nc_list); + nc_unlock_list(); + send (s->fd, &sock_cmd, sizeof (api_cmd_t), 0); + } else { + sock_cmd.magic = MCLI_MAGIC; + sock_cmd.version = MCLI_VERSION; + sock_cmd.state = API_RESPONSE; + send (s->fd, &sock_cmd, sizeof (api_cmd_t), 0); + break; + } + pthread_testcancel(); + } + + close (s->fd); + pthread_detach (s->thread); + free (s); + return NULL; +} + +static void *sock_cmd_listen_loop (void *p) +{ + sock_t tmp; + sock_t *s = (sock_t *) p; + dbg ("sock api listen loop started\n"); + s->run = 1; + + while (s->run) { + tmp.len = sizeof (struct sockaddr_un); + tmp.fd = accept (s->fd, (struct sockaddr*)&tmp.addr, &tmp.len); + if (tmp.fd >= 0) { + sock_t *as = (sock_t *) malloc (sizeof (sock_t)); + if (as == NULL) { + err ("Cannot get memory for socket\n"); + } + *as=tmp; + as->run = 0; + pthread_create (&as->thread, NULL, sock_cmd_loop, as); + } else { + break; + } + pthread_testcancel(); + } + pthread_detach (s->thread); + return NULL; +} + +static sock_t s; +int api_sock_init (const char *cmd_sock_path) +{ + s.addr.sun_family = AF_UNIX; + strcpy (s.addr.sun_path, cmd_sock_path); + s.len = sizeof(struct sockaddr_un); //strlen (cmd_sock_path) + sizeof (s.addr.sun_family); + + if ((s.fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) { + warn ("Cannot get socket %d\n", errno); + return -1; + } + unlink (cmd_sock_path); + if (bind (s.fd, (struct sockaddr*)&s.addr, s.len) < 0) { + warn ("Cannot bind control socket\n"); + return -1; + } + if (chmod(cmd_sock_path, S_IRWXU|S_IRWXG|S_IRWXO)) { + warn ("Cannot chmod 777 socket %s\n", cmd_sock_path); + } + if (listen (s.fd, 5) < 0) { + warn ("Cannot listen on socket\n"); + return -1; + } + return pthread_create (&s.thread, NULL, sock_cmd_listen_loop, &s); +} + +void api_sock_exit (void) +{ + //FIXME memory leak on exit in context structres + s.run=0; + close(s.fd); + + if(pthread_exist(s.thread) && !pthread_cancel (s.thread)) { + pthread_join (s.thread, NULL); + } +} +#endif +#ifdef API_SHM +static api_cmd_t *api_cmd = NULL; +static pthread_t api_cmd_loop_thread; + +static void *api_cmd_loop (void *p) +{ + netceiver_info_list_t *nc_list=nc_get_list(); + tra_info_t *tra_list=tra_get_list(); + while (1) { + nc_lock_list(); + process_cmd (api_cmd, tra_list, nc_list); + nc_unlock_list(); + usleep (1); + pthread_testcancel(); + } + + return NULL; +} + +int api_shm_init (void) +{ + int fd = shm_open (API_SHM_NAMESPACE, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (fd == -1) { + warn ("Cannot get a shared memory handle\n"); + return -1; + } + if (ftruncate (fd, sizeof (api_cmd_t)) == -1) { + err ("Cannot truncate shared memory\n"); + } + api_cmd = mmap (NULL, sizeof (api_cmd_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (api_cmd == MAP_FAILED) { + err ("MMap of shared memory region failed\n"); + } + close (fd); + + memset (api_cmd, 0, sizeof (api_cmd_t)); + + pthread_create (&api_cmd_loop_thread, NULL, api_cmd_loop, NULL); + return 0; +} + +void api_shm_exit (void) +{ + if(pthread_exist(api_cmd_loop_thread) && !pthread_cancel (api_cmd_loop_thread)) { + pthread_join (api_cmd_loop_thread, NULL); + } + shm_unlink (API_SHM_NAMESPACE); +} +#endif +#ifdef API_WIN + +void *api_cmd_loop(void *lpvParam) +{ + netceiver_info_list_t *nc_list=nc_get_list(); + tra_info_t *tra_list=tra_get_list(); + api_cmd_t sock_cmd; + DWORD cbBytesRead, cbWritten; + BOOL fSuccess; + HANDLE hPipe; + + hPipe = (HANDLE) lpvParam; + + while (1) { + fSuccess = ReadFile( + hPipe, // handle to pipe + &sock_cmd, // buffer to receive data + sizeof(sock_cmd), // size of buffer + &cbBytesRead, // number of bytes read + NULL); // not overlapped I/O + + if (! fSuccess || cbBytesRead == 0) { + break; + } + + if (cbBytesRead == sizeof (api_cmd_t)) { + nc_lock_list(); + process_cmd (&sock_cmd, tra_list, nc_list); + nc_unlock_list(); + + fSuccess = WriteFile( + hPipe, // handle to pipe + &sock_cmd, // buffer to write from + sizeof(sock_cmd), // number of bytes to write + &cbWritten, // number of bytes written + NULL); // not overlapped I/O + + if (! fSuccess || sizeof(sock_cmd) != cbWritten) { + break; + } + } else { + sock_cmd.magic = MCLI_MAGIC; + sock_cmd.version = MCLI_VERSION; + sock_cmd.state = API_RESPONSE; + fSuccess = WriteFile( + hPipe, // handle to pipe + &sock_cmd, // buffer to write from + sizeof(sock_cmd), // number of bytes to write + &cbWritten, // number of bytes written + NULL); // not overlapped I/O + + if (! fSuccess || sizeof(sock_cmd) != cbWritten) { + break; + } + break; + } + } + + FlushFileBuffers(hPipe); + DisconnectNamedPipe(hPipe); + CloseHandle(hPipe); + + return NULL; +} + +#define BUFSIZE 2048 +void *api_listen_loop(void *p) +{ + BOOL fConnected; + pthread_t api_cmd_loop_thread; + HANDLE hPipe; + LPTSTR lpszPipename=(LPTSTR)p; + + while(1) { + hPipe = CreateNamedPipe( + lpszPipename, // pipe name + PIPE_ACCESS_DUPLEX, // read/write access + 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 + NULL); // default security attribute + + if (hPipe == INVALID_HANDLE_VALUE) { + err ("CreatePipe failed"); + return NULL; + } + pthread_testcancel(); + fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); + + if (fConnected) { + if(pthread_create(&api_cmd_loop_thread, NULL, api_cmd_loop, hPipe)) { + err ("CreateThread failed"); + return NULL; + } else { + pthread_detach(api_cmd_loop_thread); + } + } + else { + CloseHandle(hPipe); + } + } + return NULL; +} + +pthread_t api_listen_loop_thread; + +int api_init (LPTSTR cmd_pipe_path) +{ + return pthread_create (&api_listen_loop_thread, NULL, api_listen_loop, cmd_pipe_path); +} + +void api_exit (void) +{ + if(pthread_exist(api_listen_loop_thread) && !pthread_cancel (api_listen_loop_thread)) { + TerminateThread(pthread_getw32threadhandle_np(api_listen_loop_thread),0); + pthread_join (api_listen_loop_thread, NULL); + } +} + +#endif diff --git a/mcast/client/.svn/text-base/api_server.h.svn-base b/mcast/client/.svn/text-base/api_server.h.svn-base new file mode 100644 index 0000000..e0f946f --- /dev/null +++ b/mcast/client/.svn/text-base/api_server.h.svn-base @@ -0,0 +1,67 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#define API_SHM_NAMESPACE "/mcli" +#define API_SOCK_NAMESPACE "/var/tmp/mcli.sock" + +typedef enum { API_IDLE, + API_REQUEST, + API_RESPONSE, + API_ERROR +} api_state_t; + +typedef enum { API_GET_NC_NUM, + API_GET_NC_INFO, + API_GET_TUNER_INFO, + API_GET_SAT_LIST_INFO, + API_GET_SAT_INFO, + API_GET_SAT_COMP_INFO, + API_GET_TRA_NUM, + API_GET_TRA_INFO, + API_GET_DEVICE_INFO +} api_cmdval_t; + +typedef enum { API_PARM_NC_NUM=0, + API_PARM_DEVICE_NUM=0, + API_PARM_TUNER_NUM, + API_PARM_SAT_LIST_NUM, + API_PARM_SAT_NUM, + API_PARM_SAT_COMP_NUM, + API_PARM_TRA_NUM, + API_PARM_MAX +} api_parm_t; + +typedef struct { + int magic; + int version; + + api_cmdval_t cmd; + api_state_t state; + int parm[API_PARM_MAX]; + union { + netceiver_info_t nc_info; + tuner_info_t tuner_info; + satellite_list_t sat_list; + satellite_info_t sat_info; + satellite_component_t sat_comp; + tra_t tra; + } u; +} api_cmd_t; + +#ifdef API_SHM +DLL_SYMBOL int api_shm_init (void); +DLL_SYMBOL void api_shm_exit (void); +#endif +#ifdef API_SOCK +DLL_SYMBOL int api_sock_init (const char *cmd_sock_path); +DLL_SYMBOL void api_sock_exit (void); +#endif +#ifdef API_WIN +DLL_SYMBOL int api_init (LPTSTR cmd_pipe_path); +DLL_SYMBOL void api_exit (void); +#endif diff --git a/mcast/client/.svn/text-base/api_shm_test.c.svn-base b/mcast/client/.svn/text-base/api_shm_test.c.svn-base new file mode 100644 index 0000000..fa5a0e7 --- /dev/null +++ b/mcast/client/.svn/text-base/api_shm_test.c.svn-base @@ -0,0 +1 @@ +link api_test.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/api_sock_test.c.svn-base b/mcast/client/.svn/text-base/api_sock_test.c.svn-base new file mode 100644 index 0000000..fa5a0e7 --- /dev/null +++ b/mcast/client/.svn/text-base/api_sock_test.c.svn-base @@ -0,0 +1 @@ +link api_test.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/api_test.c.svn-base b/mcast/client/.svn/text-base/api_test.c.svn-base new file mode 100644 index 0000000..cfe6afd --- /dev/null +++ b/mcast/client/.svn/text-base/api_test.c.svn-base @@ -0,0 +1,127 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" + + +int main (int argc, char **argv) +{ +#ifdef USE_SHM_API + #define API_WAIT_RESPONSE(cmd) { cmd->state=API_REQUEST; while (cmd->state == API_REQUEST) usleep(10*1000); if (cmd->state == API_ERROR) warn ("SHM parameter error\n");} + + int fd = shm_open (API_SHM_NAMESPACE, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (fd == -1 ) { + warn ("Cannot get a shared memory handle\n"); + return -1; + } + + if (ftruncate (fd, sizeof(api_cmd_t)) == -1) { + err ("Cannot truncate shared memory\n"); + } + + api_cmd_t *api_cmd = mmap(NULL, sizeof(api_cmd_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if ( api_cmd == MAP_FAILED ) { + err ("MMap of shared memory region failed\n"); + } + close(fd); +#endif +#ifdef USE_SOCK_API + #define API_WAIT_RESPONSE(cmd) { cmd->state=API_REQUEST; send (sock_comm, &sock_cmd, sizeof(api_cmd_t), 0); recv (sock_comm, &sock_cmd, sizeof(api_cmd_t), 0); if (cmd->state == API_ERROR) warn ("SHM parameter error\n");} + + int sock_comm; + int sock_name_len = 0; + struct sockaddr_un sock_name; + api_cmd_t sock_cmd; + api_cmd_t *api_cmd=&sock_cmd; + sock_name.sun_family = AF_UNIX; + + strcpy(sock_name.sun_path, API_SOCK_NAMESPACE); + sock_name_len = strlen(API_SOCK_NAMESPACE) + sizeof(sock_name.sun_family); + + if((sock_comm = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + warn ("socket create failure %d\n", errno); + return -1; + } + + if (connect(sock_comm, &sock_name, sock_name_len) < 0) { + err ("connect failure\n"); + } +#endif + api_cmd->cmd=API_GET_NC_NUM; + API_WAIT_RESPONSE(api_cmd); + + printf("nc_num: %d\n", api_cmd->parm[API_PARM_NC_NUM]); + int nc_num=api_cmd->parm[API_PARM_NC_NUM]; + int i; + for(i=0;i<nc_num;i++) { + api_cmd->cmd=API_GET_NC_INFO; + api_cmd->parm[API_PARM_NC_NUM]=i; + API_WAIT_RESPONSE(api_cmd); + printf("nc_info.uuid: %s nc_info.lastseen: %u nc_info.tuner_num: %d\n", api_cmd->u.nc_info.uuid, (unsigned int) api_cmd->u.nc_info.lastseen, api_cmd->u.nc_info.tuner_num); + int j; + int tuner_num=api_cmd->u.nc_info.tuner_num; + for(j=0;j<tuner_num;j++) { + api_cmd->cmd=API_GET_TUNER_INFO; + api_cmd->parm[API_PARM_TUNER_NUM]=j; + API_WAIT_RESPONSE(api_cmd); + printf("tuner_info.fe_info.name: %s SatList: %s\n",api_cmd->u.tuner_info.fe_info.name, api_cmd->u.tuner_info.SatelliteListName); + } + + + int sat_list_num=api_cmd->u.nc_info.sat_list_num; + for(j=0;j<sat_list_num;j++) { + api_cmd->cmd=API_GET_SAT_LIST_INFO; + api_cmd->parm[API_PARM_NC_NUM]=i; + api_cmd->parm[API_PARM_SAT_LIST_NUM]=j; + API_WAIT_RESPONSE(api_cmd); + + printf("sat_list_info.Name: %s sat_list_info.sat_num: %d\n", api_cmd->u.sat_list.Name, api_cmd->u.sat_list.sat_num); + + int sat_num=api_cmd->u.sat_list.sat_num; + int k; + for(k=0;k<sat_num;k++) { + api_cmd->cmd=API_GET_SAT_INFO; + api_cmd->parm[API_PARM_SAT_LIST_NUM]=j; + api_cmd->parm[API_PARM_SAT_NUM]=k; + API_WAIT_RESPONSE(api_cmd); + printf("sat_info.Name: %s\n",api_cmd->u.sat_info.Name); + int comp_num=api_cmd->u.sat_info.comp_num; + int l; + for(l=0;l<comp_num;l++) { + api_cmd->cmd=API_GET_SAT_COMP_INFO; + api_cmd->parm[API_PARM_SAT_LIST_NUM]=j; + api_cmd->parm[API_PARM_SAT_NUM]=k; + api_cmd->parm[API_PARM_SAT_COMP_NUM]=l; + API_WAIT_RESPONSE(api_cmd); + printf("sat_comp.Polarisation: %d sat_comp.RangeMin: %d sat_comp.RangeMax: %d sat_comp.LOF: %d\n", api_cmd->u.sat_comp.Polarisation, api_cmd->u.sat_comp.RangeMin, api_cmd->u.sat_comp.RangeMax, api_cmd->u.sat_comp.LOF); + } + } + } + } + + while (1) { + api_cmd->cmd=API_GET_TRA_NUM; + API_WAIT_RESPONSE(api_cmd); + + printf("tra_num: %d\n", api_cmd->parm[API_PARM_TRA_NUM]); + int tra_num=api_cmd->parm[API_PARM_TRA_NUM]; + for(i=0;i<tra_num;i++) { + api_cmd->cmd=API_GET_TRA_INFO; + api_cmd->parm[API_PARM_TRA_NUM]=i; + API_WAIT_RESPONSE(api_cmd); + char host[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, &api_cmd->u.tra.mcg, (char *) host, INET6_ADDRSTRLEN); + + printf("tra.slot:%d tra.fe_type: %d tra.InUse: % 3d tra.mcg: %s tra.uuid: %s tra.lastseen: %u tra.lock:%d tra.strength:%d tra.snr:%d tra.ber:%d\n", api_cmd->u.tra.slot, api_cmd->u.tra.fe_type, api_cmd->u.tra.InUse, host, api_cmd->u.tra.uuid, (unsigned int) api_cmd->u.tra.lastseen, api_cmd->u.tra.s.st, api_cmd->u.tra.s.strength, api_cmd->u.tra.s.snr, api_cmd->u.tra.s.ber); + } + sleep(2); + } + return 0; +} + diff --git a/mcast/client/.svn/text-base/ci_handler.c.svn-base b/mcast/client/.svn/text-base/ci_handler.c.svn-base new file mode 100644 index 0000000..beef8ff --- /dev/null +++ b/mcast/client/.svn/text-base/ci_handler.c.svn-base @@ -0,0 +1,321 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" + +//#define SHOW_TPDU + +static ci_dev_t devs; +static int dev_num = 0; +static int ci_run = 0; +static pthread_t ci_handler_thread; +static int port = 23000; +static char iface[IFNAMSIZ]; + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int ci_connect (ci_dev_t * c) +{ + int ret; + int j; + struct in6_addr nc; + + if (c->connected) { + return 0; + } + + if (c->fd_ci) { + closesocket (c->fd_ci); + } + + c->fd_ci = socket (PF_INET6, SOCK_STREAM, 0); + j = 1; + if (setsockopt (c->fd_ci, SOL_SOCKET, SO_REUSEADDR, (_SOTYPE) & j, sizeof (j)) < 0) { + warn ("setsockopt REUSEADDR\n"); + } + + j = 1; + if (setsockopt (c->fd_ci, SOL_SOCKET, TCP_NODELAY, (_SOTYPE) & j, sizeof (j)) < 0) { + warn ("setsockopt TCP_NODELAY\n"); + } + + inet_pton (AF_INET6, c->uuid, &nc); +#ifdef SHOW_TPDU + char host[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, &nc, (char *) host, INET6_ADDRSTRLEN); + info ("Connect To: %s\n", host); +#endif + struct sockaddr_in6 addr; + memset (&addr, 0, sizeof (struct sockaddr_in6)); + + addr.sin6_family = AF_INET6; + addr.sin6_port = htons (port); + addr.sin6_addr = nc; + addr.sin6_scope_id = if_nametoindex (iface); + + ret = connect (c->fd_ci, (struct sockaddr *) &addr, sizeof (struct sockaddr_in6)); + if (ret < 0) { + warn ("Failed to access NetCeiver CA support\n"); + } else { + c->connected = 1; + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int ci_write_pdu (ci_dev_t * c, ci_pdu_t * tpdu) +{ + int ret = -1; + + dbg ("ci_write_pdu: %p %d\n", tpdu->data, tpdu->len); + + ci_decode_ll (tpdu->data, tpdu->len); + memcpy (c->txdata + 2, tpdu->data, tpdu->len); + c->txdata[0] = tpdu->len >> 8; + c->txdata[1] = tpdu->len & 0xff; + if (!ci_connect (c)) { +#ifdef SHOW_TPDU + int j; + info ("Send TPDU: "); + for (j = 0; j < tpdu->len; j++) { + info ("%02x ", tpdu->data[j]); + } + info ("\n"); +#endif + ret = send (c->fd_ci, (char *) c->txdata, tpdu->len + 2, 0); + if (ret < 0) { + c->connected = 0; + } + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void clean_ci_recv_thread (void *argp) +{ + ci_dev_t *c = (ci_dev_t *) argp; + if (c->txdata) { + free (c->txdata); + } + if (c->rxdata) { + free (c->rxdata); + } + closesocket (c->fd_ci); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void *ci_recv (void *argp) +{ + ci_dev_t *c = (ci_dev_t *) argp; + ci_pdu_t tpdu; + int ret = -1; + + pthread_cleanup_push (clean_ci_recv_thread, c); + + c->rxdata = (u_int8_t *) malloc (CA_TPDU_MAX + 2); + if (!c->rxdata) + err ("ci_recv: out of memory\n"); + c->txdata = (u_int8_t *) malloc (CA_TPDU_MAX + 2); + if (!c->txdata) + err ("ci_recv: out of memory\n"); + + if (c->rxdata && c->txdata) { + c->recv_run = 1; + + while (c->recv_run) { + if (c->connected) { + ret = recv (c->fd_ci, (char *) c->rxdata, CA_TPDU_MAX + 2, 0); + if (ret > 0) { + tpdu.data = c->rxdata; + while (ret > 0) { + tpdu.len = ntohs16 (tpdu.data); + if (tpdu.len >= ret) { + break; + } + tpdu.data += 2; +#ifdef SHOW_TPDU + int j; + info ("Received TPDU: "); + for (j = 0; j < tpdu.len; j++) { + info ("%02x ", tpdu.data[j]); + } + info ("\n"); +#endif + ci_decode_ll (tpdu.data, tpdu.len); + unsigned int slot = (unsigned int) tpdu.data[0]; + if (slot < CA_MAX_SLOTS) { + if (c->handle_ci_slot[slot]) { + c->handle_ci_slot[slot] (&tpdu, c->handle_ci_slot_context[slot]); + } + } + + tpdu.data += tpdu.len; + ret -= tpdu.len + 2; + } + } else { + if (errno == EAGAIN) { + ret = 0; + } else { + c->connected = 0; + } + } + } + usleep (10 * 1000); + } + } + pthread_cleanup_pop (1); + + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int ci_register_handler (ci_dev_t * c, int slot, int (*p) (ci_pdu_t *, void *), void *context) +{ + if (slot < CA_MAX_SLOTS) { + c->handle_ci_slot[slot] = p; + c->handle_ci_slot_context[slot] = context; + return 0; + } + return -1; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int ci_unregister_handler (ci_dev_t * c, int slot) +{ + if (slot < CA_MAX_SLOTS) { + c->handle_ci_slot[slot] = NULL; + c->handle_ci_slot_context[slot] = NULL; + return 0; + } + return -1; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static ci_dev_t *ci_add (void) +{ + ci_dev_t *c = (ci_dev_t *) malloc (sizeof (ci_dev_t)); + if (!c) + return NULL; + memset (c, 0, sizeof (ci_dev_t)); + dvbmc_list_add_head (&devs.list, &c->list); + return c; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void ci_del (ci_dev_t * c) +{ + c->recv_run = 0; + if (pthread_exist(c->ci_recv_thread) && !pthread_cancel (c->ci_recv_thread)) { + pthread_join (c->ci_recv_thread, NULL); + } + dvbmc_list_remove (&c->list); + free (c); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + +ci_dev_t *ci_find_dev_by_uuid (char *uuid) +{ + ci_dev_t *c; + DVBMC_LIST_FOR_EACH_ENTRY (c, &devs.list, ci_dev_t, list) { + if (!strcmp (c->uuid, uuid)) { + return c; + } + } + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void *ci_handler (void *p) +{ + int n; + netceiver_info_list_t *nc_list = nc_get_list (); + ci_run = 1; + while (ci_run) { + nc_lock_list (); + for (n = 0; n < nc_list->nci_num; n++) { + netceiver_info_t *nci = nc_list->nci + n; + char *uuid = nci->uuid; + if (!strlen (uuid) || ci_find_dev_by_uuid (uuid)) { + //already seen + continue; + } + + ci_dev_t *c = ci_add (); + if (!c) { + err ("Cannot get memory for dvb loopback context\n"); + } + + dbg ("allocate ci dev %d for uuid %s\n", dev_num, uuid); + + strcpy (c->uuid, uuid); + c->cacaps = &nci->ci; + c->device = dev_num++; + + info ("Starting ci thread for netceiver UUID %s\n", c->uuid); + int ret = pthread_create (&c->ci_recv_thread, NULL, ci_recv, c); + while (!ret && !c->recv_run) { + usleep (10000); + } + if (ret) { + err ("pthread_create failed with %d\n", ret); + } + } + nc_unlock_list (); + sleep (1); + } + return NULL; +} + +int ci_init (int ca_enable, char *intf, int p) +{ + int ret = 0; + if (intf) { + strcpy (iface, intf); + } else { + iface[0] = 0; + } + if (p) { + port = p; + } + + dvbmc_list_init (&devs.list); + if (ca_enable) { + ret = pthread_create (&ci_handler_thread, NULL, ci_handler, NULL); + while (!ret && !ci_run) { + usleep (10000); + } + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +void ci_exit (void) +{ + ci_dev_t *c; + ci_dev_t *ctmp; + if (pthread_exist (ci_handler_thread)) { + if (pthread_exist(ci_handler_thread) && !pthread_cancel (ci_handler_thread)) { + pthread_join (ci_handler_thread, NULL); + } + + DVBMC_LIST_FOR_EACH_ENTRY_SAFE (c, ctmp, &devs.list, ci_dev_t, list) { + ci_del (c); + } + } +} diff --git a/mcast/client/.svn/text-base/ci_handler.h.svn-base b/mcast/client/.svn/text-base/ci_handler.h.svn-base new file mode 100644 index 0000000..3ecfc02 --- /dev/null +++ b/mcast/client/.svn/text-base/ci_handler.h.svn-base @@ -0,0 +1,30 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +typedef struct { + struct list list; + + pthread_t ci_recv_thread; + char uuid[UUID_SIZE]; + SOCKET fd_ci; + int recv_run; + int device; + int connected; + recv_cacaps_t *cacaps; + u_int8_t *txdata; + u_int8_t *rxdata; + int (*handle_ci_slot[CA_MAX_SLOTS]) (ci_pdu_t *tpdu, void *context); + void *handle_ci_slot_context[CA_MAX_SLOTS]; +} ci_dev_t; + +DLL_SYMBOL int ci_register_handler(ci_dev_t *c, int slot, int (*p) (ci_pdu_t *, void *), void *context); +DLL_SYMBOL int ci_unregister_handler(ci_dev_t *c, int slot); +DLL_SYMBOL int ci_write_pdu(ci_dev_t *c, ci_pdu_t *tpdu); +DLL_SYMBOL ci_dev_t *ci_find_dev_by_uuid (char *uuid); +DLL_SYMBOL int ci_init (int ca_enable, char *intf, int p); +DLL_SYMBOL void ci_exit (void); diff --git a/mcast/client/.svn/text-base/ciparser.c.svn-base b/mcast/client/.svn/text-base/ciparser.c.svn-base new file mode 100644 index 0000000..0a2c0bf --- /dev/null +++ b/mcast/client/.svn/text-base/ciparser.c.svn-base @@ -0,0 +1 @@ +link ../common/ciparser.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/dummy_client.c.svn-base b/mcast/client/.svn/text-base/dummy_client.c.svn-base new file mode 100644 index 0000000..2a397d9 --- /dev/null +++ b/mcast/client/.svn/text-base/dummy_client.c.svn-base @@ -0,0 +1,101 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#define DEBUG 1 +#include "headers.h" + + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dummy_handle_ts (unsigned char *buffer, size_t len, void *p) +{ + FILE *f=(FILE*)p; + fwrite(buffer, len, 1, f); + return len; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dummy_handle_ten (tra_t *ten, void *p) +{ + FILE *f=(FILE*)p; + if(ten) { + fprintf(f,"Status: %02X, Strength: %04X, SNR: %04X, BER: %04X\n",ten->s.st,ten->s.strength, ten->s.snr, ten->s.ber); + } + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +void dummy_client (void) +{ + int i; + int n; + int run=1; + FILE *f; + recv_info_t *r; + recv_sec_t sec; + struct dvb_frontend_parameters fep; + dvb_pid_t pids[3]; + + netceiver_info_list_t *nc_list=nc_get_list(); +#if 0 + printf("Looking for netceivers out there....\n"); + while(run) { + nc_lock_list(); + for (n = 0; n < nc_list->nci_num; n++) { + netceiver_info_t *nci = nc_list->nci + n; + printf("\nFound NetCeiver: %s\n",nci->uuid); + for (i = 0; i < nci->tuner_num; i++) { + printf(" Tuner: %s, Type %d\n",nci->tuner[i].fe_info.name, nci->tuner[i].fe_info.type); + } + } + nc_unlock_list(); + if(nc_list->nci_num) { + break; + } + sleep(1); + } +#endif + f=fopen("out.ts","wb"); + + r = recv_add(); + if (!r) { + fprintf (stderr, "Cannot get memory for receiver\n"); + return; + } + register_ten_handler (r, dummy_handle_ten, stderr); + register_ts_handler (r, dummy_handle_ts, f); + + memset(&sec, 0, sizeof(recv_sec_t)); + sec.voltage=SEC_VOLTAGE_18; + sec.mini_cmd=SEC_MINI_A; + sec.tone_mode=SEC_TONE_ON; + + memset(&fep, 0, sizeof(struct dvb_frontend_parameters)); + fep.frequency=12544000; + fep.inversion=INVERSION_AUTO; + fep.u.qpsk.symbol_rate=22000000; + fep.u.qpsk.fec_inner=FEC_5_6; + + memset(&pids, 0, sizeof(pids)); + pids[0].pid=511; + pids[1].pid=512; + pids[2].pid=511; + pids[2].id=2; + pids[3].pid=511; + pids[3].id=1; + pids[4].pid=-1; + + printf("\nTuning a station and writing transport data to file 'out.ts':\n"); + recv_tune (r, (fe_type_t)FE_QPSK, 1800+192, &sec, &fep, pids); + getchar(); + register_ten_handler (r, NULL, NULL); + register_ts_handler (r, NULL, NULL); + fclose(f); +} diff --git a/mcast/client/.svn/text-base/dummy_client.h.svn-base b/mcast/client/.svn/text-base/dummy_client.h.svn-base new file mode 100644 index 0000000..e79cbf1 --- /dev/null +++ b/mcast/client/.svn/text-base/dummy_client.h.svn-base @@ -0,0 +1,10 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +void dummy_client (void); + diff --git a/mcast/client/.svn/text-base/dvblo_handler.c.svn-base b/mcast/client/.svn/text-base/dvblo_handler.c.svn-base new file mode 100644 index 0000000..875749d --- /dev/null +++ b/mcast/client/.svn/text-base/dvblo_handler.c.svn-base @@ -0,0 +1,716 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" +#include "dvblo_ioctl.h" +#include "dvblo_handler.h" + +//#define SHOW_EVENTS +//#define SHOW_TPDU +//#define SHOW_PIDS + +#define TUNE_FORCED_TIMEOUT 5 + +extern pthread_mutex_t lock; +extern recv_info_t receivers; + +static dvblo_dev_t devs; +static int dev_num = 0; +static int dvblo_run = 1; +static int cidev = 0; +static int reload = 0; +static dvblo_cacaps_t cacaps; + +static int special_status_mode=0; // 1: return rotor mode and tuner slot in status + +static int dvblo_get_nc_addr (char *addrstr, char *uuid) +{ + int len = strlen (uuid); + if (len <= 5) { + return -1; + } + memset (addrstr, 0, INET6_ADDRSTRLEN); + + strncpy (addrstr, uuid, len - 5); + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dvblo_handle_ts (unsigned char *buffer, size_t len, void *p) +{ + dvblo_dev_t * d=( dvblo_dev_t *)p; + return write (d->fd, buffer, len); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dvblo_handle_ten (tra_t * ten, void *c) +{ + dvblo_dev_t *d = (dvblo_dev_t *) c; + dbg ("TEN: %ld %p %p\n", gettid (), ten, d); + + if (ten) { + dvblo_festatus_t stat; + memcpy(&stat, &ten->s, sizeof(dvblo_festatus_t)); + + d->ten = *ten; + + if (special_status_mode) { + stat.st|=(ten->rotor_status&3)<<8; + stat.st|=(1+ten->slot)<<12; + } + + return ioctl (d->fd, DVBLO_SET_FRONTEND_STATUS, (dvblo_festatus_t*)&stat); + } else { + dvblo_festatus_t s; + memset (&s, 0, sizeof (dvblo_festatus_t)); + + return ioctl (d->fd, DVBLO_SET_FRONTEND_STATUS, &s); + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void sig_handler (int signal) +{ + dbg ("Signal: %d\n", signal); + + switch (signal) { + case SIGHUP: + reload = 1; + break; + case SIGTERM: + case SIGINT: + dbg ("Trying to exit, got signal %d...\n", signal); + dvblo_run = 0; + break; + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int dvblo_init (void) +{ + char char_dev[100]; + int j, k = 0; + struct dvb_frontend_info fe_info; + dvblo_festatus_t fe_status; + + dvbmc_list_init (&devs.list); + + memset (&fe_info, 0, sizeof (struct dvb_frontend_info)); + fe_info.type = -1; + strcpy (fe_info.name, "Unconfigured"); + memset (&fe_status, 0, sizeof (dvblo_festatus_t)); + + for (j = 0; j < MAX_DEVICES; j++) { + + sprintf (char_dev, "/dev/dvblo%d", j); + int fd = open (char_dev, O_RDWR); + + if (fd == -1) { + warn ("Cannot Open %s\n", char_dev); + continue; + } + k++; + ioctl (fd, DVBLO_SET_FRONTEND_INFO, &fe_info); + ioctl (fd, DVBLO_SET_FRONTEND_STATUS, &fe_status); + ioctl (fd, DVBLO_SET_CA_CAPS, &cacaps); + dvblo_tpdu_t tpdu; + while (1) { + if (ioctl (fd, DVBLO_GET_TPDU, &tpdu) || !tpdu.len) { + break; + } + } + close (fd); + } + + signal (SIGTERM, &sig_handler); + signal (SIGINT, &sig_handler); + signal (SIGHUP, &sig_handler); + signal (SIGPIPE, &sig_handler); + return k; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dvblo_convert_pids (dvblo_dev_t * d) +{ + dvb_pid_t *dst = d->dstpids; + dvblo_pids_t *src = &d->pids; + int i; +#ifdef SHOW_PIDS + info ("devnum:%d pidnum:%d\n", d->device, src->num); +#endif + for (i = 0; i < src->num; i++) { +#ifdef SHOW_PIDS + printf ("devnum:%d pid:%04x\n", d->device, src->pid[i]); +#endif + dst[i].pid = src->pid[i]; + if (d->ca_enable) { + dst[i].id = ci_cpl_find_caid_by_pid (src->pid[i]); + if (dst[i].id != 0) { + dbg ("pid: %04x id: %04x\n", dst[i].pid, dst[i].id); + } + } + } + dst[i].pid = -1; + return i; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dvblo_tune (dvblo_dev_t * d, int force) +{ + satellite_reference_t satref; + int SatPos; + int mode; + int ret = 0; + + nc_lock_list (); + + for (mode = 0; mode < 3; mode++) { + if (satellite_find_by_diseqc (&satref, (recv_sec_t*)&d->sec, &d->fe_parms, mode)) + break; + } + + if (mode == 3 || (mode == 2 && (d->type == FE_QAM || d->type == FE_OFDM))) { + SatPos = NO_SAT_POS; + } else { + int LOF = 0; + if (mode) { + LOF = satellite_get_lof_by_ref (&satref); + d->fe_parms.frequency += LOF * 1000; + } + SatPos = satellite_get_pos_by_ref (&satref); + recv_sec_t *sec=satellite_find_sec_by_ref (&satref); + memcpy(&d->sec, sec, sizeof(recv_sec_t)); + d->sec.voltage = satellite_find_pol_by_ref (&satref); +#if 1 //def SHOW_EVENTS + printf ("Found satellite position: %d fe_parms: %d LOF: %d voltage: %d mode: %d\n", SatPos, d->fe_parms.frequency, LOF, d->sec.voltage, mode); +#endif + } + nc_unlock_list (); + if (force && d->pids.num == 0) { + d->dstpids[0].pid = 0; + d->dstpids[0].id = 0; + d->dstpids[1].pid = -1; + ret = 2; + } else { + dvblo_convert_pids (d); + } + recv_tune (d->r, d->type, SatPos, (recv_sec_t*)&d->sec, &d->fe_parms, d->dstpids); + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int dvblo_write_ci (ci_pdu_t * pdu, void *context) +{ + dvblo_dev_t *d = (dvblo_dev_t *) context; + dvblo_tpdu_t tpdu; + memcpy (tpdu.data, pdu->data, pdu->len); + tpdu.len = pdu->len; + if (!cmd.reelcammode) + tpdu.data[0] = 0; + return ioctl (d->fd, DVBLO_SET_TPDU, &tpdu); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void clean_dvblo_recv_thread (void *argp) +{ + dvblo_dev_t *d = (dvblo_dev_t *) argp; + recv_del (d->r); + close (d->fd); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void *dvblo_recv (void *argp) +{ + dvblo_dev_t *d = (dvblo_dev_t *) argp; + dvblo_tpdu_t tpdu; + struct dvb_frontend_parameters old_fe_parms; + dvblo_sec_t old_sec; + struct pollfd fds[1]; + int timeout_msecs = 50; + int ret; + time_t last_ci_reset = 0; + char char_dev[100]; + int need_tune = 0; + time_t forced = 0; + unsigned int event = 0; + + dvblo_cacaps_t cacap; + + sprintf (char_dev, "/dev/dvblo%d", d->device); + dbg ("Using character device %s for dvb loopback\n", char_dev); + + d->fd = open (char_dev, O_RDWR); + + if (d->fd < 0) { + err ("Cannot open %s - dvbloop driver loaded?\n", char_dev); + } + + pthread_cleanup_push (clean_dvblo_recv_thread, d); + + fds[0].fd = d->fd; + + if (!ioctl (d->fd, DVBLO_IOCCHECKDEV)) { + if (!ioctl (d->fd, DVBLO_IOCADDDEV)) { + info ("created dvb adapter: %d\n", d->device); + } + } + d->info.frequency_min = 1; + d->info.frequency_max = 2000000000; + + ioctl (d->fd, DVBLO_SET_FRONTEND_INFO, &d->info); + ioctl (d->fd, DVBLO_GET_FRONTEND_PARAMETERS, &d->fe_parms); + ioctl (d->fd, DVBLO_GET_PIDLIST, &d->pids); + ioctl (d->fd, DVBLO_GET_SEC_PARAMETERS, &d->sec); + + old_fe_parms = d->fe_parms; + old_sec = d->sec; +#ifdef DEBUG + print_fe_info (&d->info); +#endif + d->recv_run = 1; + + if (dvblo_tune (d, 1) == 2) { + forced = time (NULL); + } + + while (d->recv_run) { + if (d->cacaps->cap.slot_num) { + nc_lock_list (); +#ifdef SHOW_TPDU + info ("ca_caps->: %p ci_slot:%d info[0]:%02x info[1]:%02x\n", d->cacaps, d->ci_slot, d->cacaps->info[0].flags, d->cacaps->info[1].flags); +#endif + cacap = *d->cacaps; + if (!cmd.reelcammode) { + if (d->ci_slot != 0) { + cacap.info[0] = cacap.info[d->ci_slot]; + } + cacap.cap.slot_num = 1; + } + if ((time (NULL) - last_ci_reset) < cmd.ci_timeout) { + cacap.info[0].flags = 0; + } + ioctl (d->fd, DVBLO_SET_CA_CAPS, &cacap); + nc_unlock_list (); + } + + fds[0].events = POLLIN; + ret = poll (fds, 1, timeout_msecs); + if (ret > 0) { + ioctl (d->fd, DVBLO_GET_EVENT_MASK, &event); + ioctl (d->fd, DVBLO_GET_FRONTEND_PARAMETERS, &d->fe_parms); + ioctl (d->fd, DVBLO_GET_PIDLIST, &d->pids); + ioctl (d->fd, DVBLO_GET_SEC_PARAMETERS, &d->sec); + if (event & EV_MASK_FE) { +#ifdef SHOW_EVENTS + printf ("%p/%p Event Received: FE+Tuner/", d, d->r); + if (event & EV_FRONTEND) { + printf ("Frontend "); + } + if (event & EV_TUNER) { + printf ("Tuner "); + } + if (event & EV_FREQUENCY) { + printf ("Frequency:%d ", d->fe_parms.frequency); + } + if (event & EV_BANDWIDTH) { + printf ("Bandwidth "); + } + printf ("\n"); +#endif + if (memcmp (&d->fe_parms, &old_fe_parms, sizeof (struct dvb_frontend_parameters))) { + old_fe_parms = d->fe_parms; + dbg ("fe_parms have changed!\n"); + need_tune = 1; + if (d->ca_enable) { + ci_cpl_clear (d->ci_slot); + } + } + } + if (event & EV_MASK_SEC) { +#ifdef SHOW_EVENTS + printf ("%p/%p Event Received: SEC/", d, d->r); + if (event & EV_TONE) { + printf ("Tone:%d ", d->sec.tone_mode); + } + if (event & EV_VOLTAGE) { + printf ("Voltage:%d ", d->sec.voltage); + } + if (event & EV_DISEC_MSG) { + printf ("DISEC-Message:"); + int j; + for (j = 0; j < d->sec.diseqc_cmd.msg_len; j++) { + printf ("%02x ", d->sec.diseqc_cmd.msg[j]); + } + } + if (event & EV_DISEC_BURST) { + printf ("DISEC-Burst:%d ", d->sec.mini_cmd); + } + printf ("\n"); +#endif + if (d->sec.voltage == SEC_VOLTAGE_OFF) { + recv_stop (d->r); + memset (&old_fe_parms, 0, sizeof (struct dvb_frontend_parameters)); + need_tune = 0; + dbg ("Stop %p\n", d->r); + } else if (memcmp (&d->sec, &old_sec, sizeof (dvblo_sec_t))) { + dbg ("SEC parms have changed!\n"); + old_sec = d->sec; + need_tune = 1; + if (d->ca_enable) { + ci_cpl_clear (d->ci_slot); + } + } + } + if (event & EV_MASK_CA) { +#ifdef SHOW_EVENTS + printf ("%p/%p Event Received: CA/", d, d->r); +#endif + if (event & EV_CA_WRITE) { +#ifdef SHOW_EVENTS + printf ("WRITE "); +#endif + while (1) { + if (!ioctl (d->fd, DVBLO_GET_TPDU, &tpdu) && tpdu.len) { + if (d->c && d->ca_enable) { + ci_pdu_t pdu; + pdu.len = tpdu.len; + pdu.data = tpdu.data; + if (!cmd.reelcammode) { + pdu.data[0] = d->ci_slot; + } + ci_write_pdu (d->c, &pdu); + event |= EV_PIDFILTER; + } + } else { + break; + } + } + } + if (event & EV_CA_RESET) { +#ifdef SHOW_EVENTS + printf ("RESET "); +#endif + last_ci_reset = time (NULL); + if (d->ca_enable) { + ci_cpl_clear (d->ci_slot); + } + } +#ifdef SHOW_EVENTS + printf ("\n"); +#endif + } + if (need_tune) { + if (dvblo_tune (d, 1) == 2) { + forced = time (NULL); + } + need_tune = 0; + } else if (event & EV_MASK_PID) { +#ifdef SHOW_EVENTS + printf ("%p/%p Event Received: Demux/", d, d->r); + if (event & EV_PIDFILTER) { + printf ("PID filter: %d pids", d->pids.num); + } + printf ("\n"); +#endif + forced = 0; + } + } + if (forced) { + if ((time (NULL) - forced) < TUNE_FORCED_TIMEOUT) { + event &= ~EV_PIDFILTER; + } else { + event |= EV_PIDFILTER; + forced = 0; + } + } + if (event & EV_PIDFILTER) { + dvblo_convert_pids (d); + recv_pids (d->r, d->dstpids); + } + event = 0; + } + pthread_cleanup_pop (1); + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static dvblo_dev_t *dvblo_add (void) +{ + dvblo_dev_t *d = (dvblo_dev_t *) malloc (sizeof (dvblo_dev_t)); + + if (!d) + return NULL; + memset (d, 0, sizeof (dvblo_dev_t)); + dvbmc_list_add_head (&devs.list, &d->list); + return d; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void dvblo_del (dvblo_dev_t * d) +{ + d->recv_run = 0; + if (pthread_exist(d->dvblo_recv_thread) && !pthread_cancel (d->dvblo_recv_thread)) { + pthread_join (d->dvblo_recv_thread, NULL); + } + dvbmc_list_remove (&d->list); + free (d); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void dvblo_exit (void) +{ + dvblo_dev_t *d; + dvblo_dev_t *dtmp; + + DVBMC_LIST_FOR_EACH_ENTRY_SAFE (d, dtmp, &devs.list, dvblo_dev_t, list) { + dvblo_del (d); + } +} + +static dvblo_dev_t *find_dev_by_uuid (dvblo_dev_t * devs, char *uuid) +{ + dvblo_dev_t *d; + DVBMC_LIST_FOR_EACH_ENTRY (d, &devs->list, dvblo_dev_t, list) { + if (!strcmp (d->uuid, uuid)) { + return d; + } + } + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int count_dev_by_type (dvblo_dev_t * devs, fe_type_t type) +{ + int ret = 0; + dvblo_dev_t *d; + DVBMC_LIST_FOR_EACH_ENTRY (d, &devs->list, dvblo_dev_t, list) { + if (type == d->type) { + ret++; + } + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +satellite_list_t *dvblo_get_sat_list (char *SatelliteListName, netceiver_info_t * nci) +{ + int i; + dbg ("looking for %s\n", SatelliteListName); + for (i = 0; i < nci->sat_list_num; i++) { + if (!strcmp (SatelliteListName, nci->sat_list[i].Name)) { + dbg ("found uuid in sat list %d\n", i); + return nci->sat_list + i; + } + } + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int diseqc_write_conf (char *disec_conf_path, char *rotor_conf_path, dvblo_dev_t * devs, int mode) +{ + int j, k; + dvblo_dev_t *d; + char buf[80]; + char tstr[16]; + FILE *f = NULL; + FILE *fr = NULL; + + f = fopen (disec_conf_path, "wt"); + if (f == NULL) { + return 0; + } + fprintf (f, "# diseqc.conf in VDR format auto generated\n\n"); + + if (strlen(rotor_conf_path)) { + special_status_mode=1; + fr = fopen (rotor_conf_path, "wt"); + } + if (fr) + fprintf (fr, "# rotor.conf auto generated\n\n"); + + DVBMC_LIST_FOR_EACH_ENTRY (d, &devs->list, dvblo_dev_t, list) { + satellite_list_t *sat_list = dvblo_get_sat_list (d->nci->tuner[d->tuner].SatelliteListName, d->nci); + if (!sat_list) { + continue; + } + for (j = 0; j < sat_list->sat_num; j++) { + satellite_info_t *sat = sat_list->sat + j; + for (k = 0; k < sat->comp_num; k++) { + satellite_component_t *comp = sat->comp + k; + int newpos = sat->SatPos ^ 1800; + sprintf (buf, "e0 10 6f %02x %02x %02x", newpos & 0xff, (newpos >> 8) & 0xff, comp->Polarisation << 1 | !(comp->sec.tone_mode & 1)); + if (mode) { + sprintf (tstr, "A%d ", d->device + 1); + } else { + tstr[0] = 0; + } + fprintf (f, "%s%s %d %c 0 [ %s ]\n", tstr, sat->Name, comp->RangeMax, comp->Polarisation == POL_H ? 'H' : 'V', buf); + } + fprintf (f, "\n"); + if (j==0 && fr && sat->type==SAT_SRC_ROTOR) { + fprintf(fr, "%s %i %i %i %i %i\n", tstr, sat->SatPosMin, sat->SatPosMax, + sat->AutoFocus, sat->Latitude, sat->Longitude); + } + } + } + info ("created %s\n", disec_conf_path); + fclose (f); + if (fr) { + info ("created %s\n", rotor_conf_path); + fclose(fr); + } + return 1; +} + +void dvblo_handler (void) +{ + int i; + int n; + int nci_num = 0; + int write_conf = strlen (cmd.disec_conf_path); + netceiver_info_list_t *nc_list = nc_get_list (); + memset (&cacaps, 0, sizeof (dvblo_cacaps_t)); + + info ("Device Type Limits: DVB-S: %d DVB-C: %d DVB-T: %d ATSC: %d DVB-S2: %d\n\n", cmd.tuner_type_limit[FE_QPSK], cmd.tuner_type_limit[FE_QAM], cmd.tuner_type_limit[FE_OFDM], cmd.tuner_type_limit[FE_ATSC], cmd.tuner_type_limit[FE_DVBS2]); + + while (dvblo_run) { + nc_lock_list (); + for (n = 0; n < nc_list->nci_num; n++) { + netceiver_info_t *nci = nc_list->nci + n; + for (i = 0; i < nci->tuner_num; i++) { + char *uuid = nci->tuner[i].uuid; + if (nci->tuner[i].preference < 0 || !strlen (uuid) || find_dev_by_uuid (&devs, uuid)) { + //already seen + continue; + } + fe_type_t type = nci->tuner[i].fe_info.type; + + if (type > FE_DVBS2) { + continue; + } + if(dev_num >= MAX_DEVICES) { + dbg("Limit dev_num reached limit of "MAX_DEVICES"\n"); + continue; + } + if (count_dev_by_type (&devs, type) == cmd.tuner_type_limit[type]) { + dbg ("Limit: %d %d>%d\n", type, count_dev_by_type (&devs, type), cmd.tuner_type_limit[type]); + continue; + } + + dvblo_dev_t *d = dvblo_add (); + if (!d) { + err ("Cannot get memory for dvb loopback context\n"); + } + + dbg ("allocate dev %d for uuid %s\n", dev_num, uuid); + + d->info = nci->tuner[i].fe_info; + + if (type == FE_DVBS2) { + d->info.type = FE_QPSK; + } + + strcpy (d->uuid, nci->tuner[i].uuid); + if (!cmd.reelcammode) { + if (cidev < CA_MAX_SLOTS && (cmd.ca_enable & (1 << dev_num))) { + d->cacaps=(dvblo_cacaps_t*)((void *) &nci->ci); + d->ca_enable = 1; + dbg ("Enabling CA support for device %d\n", dev_num); + char addrstr[INET6_ADDRSTRLEN]; + dvblo_get_nc_addr (addrstr, d->uuid); + dbg ("dvblo_get_nc_addr: %s %s\n", addrstr, d->uuid); + d->c = ci_find_dev_by_uuid (addrstr); + if (d->c) { + dbg ("Attaching ci dev %p to dvblo dev %p\n", d->c, d); + ci_register_handler (d->c, cidev, dvblo_write_ci, d); + d->ci_slot = cidev++; + } else { + dvblo_del (d); //retry next time + break; + } + } else { + d->cacaps = &cacaps; + d->ca_enable = 0; + dbg ("Disabling CA support for device %d\n", dev_num); + } + } else { + if (nci->ci.cap.slot_num && cmd.ca_enable) { + d->ca_enable = 1; + dbg ("Enabling CA support for device %d\n", dev_num); + if (!cidev) { + d->cacaps = (dvblo_cacaps_t*)((void *) &nci->ci); + char addrstr[INET6_ADDRSTRLEN]; + dvblo_get_nc_addr (addrstr, d->uuid); + dbg ("dvblo_get_nc_addr: %s %s\n", addrstr, d->uuid); + d->c = ci_find_dev_by_uuid (addrstr); + if (d->c) { + dbg ("Attaching ci dev %p to dvblo dev %p\n", d->c, d); + ci_register_handler (d->c, cidev++, dvblo_write_ci, d); + ci_register_handler (d->c, cidev++, dvblo_write_ci, d); + } else { + dvblo_del (d); //retry next time + break; + } + } else { + d->cacaps = &cacaps; + } + } else { + d->cacaps = &cacaps; + d->ca_enable = 0; + dbg ("Disabling CA support for device %d\n", dev_num); + } + } + + d->r = recv_add (); + if (!d->r) { + err ("Cannot get memory for receiver\n"); + } + + d->device = dev_num++; + d->type = type; + d->tuner = i; + d->nci = nci; + + register_ten_handler (d->r, dvblo_handle_ten, d); + register_ts_handler (d->r, dvblo_handle_ts, d); + + info ("Starting thread for tuner UUID %s [%s] at device %d with type %d\n", d->uuid, nci->tuner[i].fe_info.name, nci->tuner[i].slot, nci->tuner[i].fe_info.type); + int ret = pthread_create (&d->dvblo_recv_thread, NULL, dvblo_recv, d); + while (!ret && !d->recv_run) { + usleep (10000); + } + if (ret) { + err ("pthread_create failed with %d\n", ret); + } + } + } + if (write_conf) { + if (reload || (nci_num != nc_list->nci_num)) { + nci_num = nc_list->nci_num; + diseqc_write_conf (cmd.disec_conf_path, cmd.rotor_conf_path, &devs, cmd.vdrdiseqcmode); + reload = 0; + } + } + nc_unlock_list (); + sleep (1); + } +} diff --git a/mcast/client/.svn/text-base/dvblo_handler.h.svn-base b/mcast/client/.svn/text-base/dvblo_handler.h.svn-base new file mode 100644 index 0000000..beaa7ac --- /dev/null +++ b/mcast/client/.svn/text-base/dvblo_handler.h.svn-base @@ -0,0 +1,40 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#define MAX_DEVICES 8 + +typedef struct dvblo_dev { + struct list list; + + pthread_t dvblo_recv_thread; + char uuid[UUID_SIZE]; + int device; + int fd; + pthread_t dvblo_ca_thread; + int fd_ca; + int recv_run; + int ci_slot; + int ca_enable; + + fe_type_t type; + recv_info_t *r; + ci_dev_t *c; + struct dvb_frontend_info info; + dvblo_cacaps_t *cacaps; + dvblo_pids_t pids; + dvb_pid_t dstpids[RECV_MAX_PIDS]; + dvblo_sec_t sec; + struct dvb_frontend_parameters fe_parms; + tra_t ten; + int tuner; + netceiver_info_t *nci; +} dvblo_dev_t; + +int dvblo_init (void); +void dvblo_exit (void); +void dvblo_handler (void); diff --git a/mcast/client/.svn/text-base/headers.h.svn-base b/mcast/client/.svn/text-base/headers.h.svn-base new file mode 100644 index 0000000..c371395 --- /dev/null +++ b/mcast/client/.svn/text-base/headers.h.svn-base @@ -0,0 +1,32 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#ifndef __HEADERS_H__ +#define __HEADERS_H__ + +#include "defs.h" +#include "version.h" +#include "list.h" +#include "satlists.h" +#include "mcast.h" +#include "input.h" +#include "recv_ccpp.h" +#include "recv_tv.h" +#include "tools.h" +#include "interfaces.h" +#include "mcast.h" +#include "mld.h" +#include "api_server.h" +#include "tca_handler.h" +#include "tra_handler.h" +#include "mld_reporter.h" +#include "ciparser.h" +#include "ci_handler.h" +#include "mmi_handler.h" +#include "siparser.h" +#endif diff --git a/mcast/client/.svn/text-base/inet_aton.c.svn-base b/mcast/client/.svn/text-base/inet_aton.c.svn-base new file mode 100644 index 0000000..1fd34cc --- /dev/null +++ b/mcast/client/.svn/text-base/inet_aton.c.svn-base @@ -0,0 +1 @@ +link ../common/win32/inet_aton.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/inet_ntop.c.svn-base b/mcast/client/.svn/text-base/inet_ntop.c.svn-base new file mode 100644 index 0000000..d11af10 --- /dev/null +++ b/mcast/client/.svn/text-base/inet_ntop.c.svn-base @@ -0,0 +1 @@ +link ../common/win32/inet_ntop.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/inet_pton.c.svn-base b/mcast/client/.svn/text-base/inet_pton.c.svn-base new file mode 100644 index 0000000..7956a55 --- /dev/null +++ b/mcast/client/.svn/text-base/inet_pton.c.svn-base @@ -0,0 +1 @@ +link ../common/win32/inet_pton.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/input.c.svn-base b/mcast/client/.svn/text-base/input.c.svn-base new file mode 100644 index 0000000..f10cf4f --- /dev/null +++ b/mcast/client/.svn/text-base/input.c.svn-base @@ -0,0 +1,145 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" +#define CI_RESET_WAIT 10 + +#ifdef __MINGW32__ +#include <getopt.h> +#endif + +cmdline_t cmd; + +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +static void print_help (int argc, char *argv[]) +{ + printf ("Usage:\n" \ + " mcli --ifname <network interface>\n" \ + " mcli --port <port> (default: -port 23000)\n" \ + " mcli --dvb-s <num> --dvb-c <num> --dvb-t <num> --atsc <num> --dvb-s2 <num>\n" \ + " limit number of device types (default: 8 of every type)\n" \ + " mcli --diseqc-conf <filepath>\n" \ + " mcli --rotor-conf <filepath>\n" \ + " mcli --mld-reporter-disable\n" \ + " mcli --sock-path <filepath>\n"\ + " mcli --ca-enable <bitmask>\n"\ + " mcli --ci-timeout <time>\n"\ + " mcli --vdr-diseqc-bind <0|1>\n"\ + " mcli --reel-cam-mode\n"\ + "\n"); +} + +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +static void init_cmd_line_parameters () +{ + int i; + memset (&cmd, 0, sizeof (cmdline_t)); + + for (i=0; i<=FE_DVBS2; i++) { + cmd.tuner_type_limit[i] = 8; + } + cmd.port = 23000; + cmd.mld_start = 1; + cmd.ca_enable = 3; + cmd.vdrdiseqcmode = 1; + cmd.reelcammode = 0; + cmd.ci_timeout = CI_RESET_WAIT; + strcpy (cmd.cmd_sock_path, API_SOCK_NAMESPACE); + cmd.disec_conf_path[0]=0; + cmd.rotor_conf_path[0]=0; +} + +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void get_options (int argc, char *argv[]) +{ + int tuners = 0, i; + char c; + int ret; + //init parameters + init_cmd_line_parameters (); + while (1) { + //int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + {"port", 1, 0, 0}, //0 + {"ifname", 1, 0, 0}, //1 + {"help", 0, 0, 0}, //2 + {"dvb-s", 1, 0, 0}, //3 + {"dvb-c", 1, 0, 0}, //4 + {"dvb-t", 1, 0, 0}, //5 + {"atsc", 1, 0, 0}, //6 + {"dvb-s2", 1, 0, 0}, //7 + {"diseqc-conf", 1, 0, 0}, //8 + {"mld-reporter-disable", 0, 0, 0}, //9 + {"sock-path", 1, 0, 0}, //10 + {"ca-enable", 1, 0, 0}, //11 + {"ci-timeout", 1, 0, 0}, //12 + {"vdr-diseqc-bind", 1, 0, 0}, //13 + {"reel-cam-mode", 0, 0, 0}, //14 + {"rotor-conf", 1, 0, 0}, //15 + {NULL, 0, 0, 0} + }; + + ret = getopt_long_only (argc, argv, "", long_options, &option_index); + c=(char)ret; + if (ret == -1 || c == '?') { + break; + } + + switch (option_index) { + case 0: + cmd.port = atoi (optarg); + break; + case 1: + strncpy (cmd.iface, optarg, IFNAMSIZ-1); + break; + case 2: + print_help (argc, argv); + exit (0); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + i = atoi (optarg); + if (!tuners) { + memset (cmd.tuner_type_limit, 0, sizeof (cmd.tuner_type_limit)); + } + cmd.tuner_type_limit[option_index - 3] = i; + tuners += i; + break; + case 8: + strncpy (cmd.disec_conf_path, optarg, _POSIX_PATH_MAX-1); + break; + case 9: + cmd.mld_start = 0; + break; + case 10: + strncpy (cmd.cmd_sock_path, optarg, _POSIX_PATH_MAX-1); + break; + case 11: + cmd.ca_enable=atoi(optarg); + break; + case 12: + cmd.ci_timeout=atoi(optarg); + break; + case 13: + cmd.vdrdiseqcmode=atoi(optarg); + break; + case 14: + cmd.reelcammode = 1; + break; + case 15: + strncpy (cmd.rotor_conf_path, optarg, _POSIX_PATH_MAX-1); + break; + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } +} diff --git a/mcast/client/.svn/text-base/interfaces.c.svn-base b/mcast/client/.svn/text-base/interfaces.c.svn-base new file mode 100644 index 0000000..177e32f --- /dev/null +++ b/mcast/client/.svn/text-base/interfaces.c.svn-base @@ -0,0 +1 @@ +link ../common/interfaces.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/main.c.svn-base b/mcast/client/.svn/text-base/main.c.svn-base new file mode 100644 index 0000000..895fced --- /dev/null +++ b/mcast/client/.svn/text-base/main.c.svn-base @@ -0,0 +1,83 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" +#if ! (defined WIN32 || defined APPLE) + #include "dvblo_ioctl.h" + #include "dvblo_handler.h" +#else + #include "dummy_client.h" +#endif + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +int main (int argc, char **argv) +{ + printf ("DVB - TV Client Version " MCLI_VERSION_STR " (c) BayCom GmbH\n\n"); +//#if (defined WIN32 || defined APPLE) +#ifdef WIN32 +#ifndef __MINGW32__ + cmdline_t cmd; + cmd.iface[0]=0; + cmd.port=0; + cmd.mld_start=1; +#else + get_options (argc, argv); +#endif +#else +#ifdef BACKTRACE + signal(SIGSEGV, SignalHandlerCrash); + signal(SIGBUS, SignalHandlerCrash); + signal(SIGABRT, SignalHandlerCrash); +#endif + get_options (argc, argv); +#endif + recv_init (cmd.iface, cmd.port); + + #ifdef API_SHM + api_shm_init(); + #endif + #ifdef API_SOCK + api_sock_init(cmd.cmd_sock_path); + #endif + #ifdef API_WIN + api_init(TEXT("\\\\.\\pipe\\mcli")); + #endif + + if(cmd.mld_start) { + mld_client_init (cmd.iface); + } +#if ! (defined WIN32 || defined APPLE) + ci_init(cmd.ca_enable, cmd.iface, cmd.port); + dvblo_init(); + + dvblo_handler(); + + dvblo_exit(); + ci_exit(); +#else + dummy_client (); +#endif + + if(cmd.mld_start) { + mld_client_exit (); + } + + #ifdef API_SHM + api_shm_exit(); + #endif + #ifdef API_SOCK + api_sock_exit(); + #endif + #ifdef API_WIN + api_exit(); + #endif + + recv_exit (); + + return 0; +} diff --git a/mcast/client/.svn/text-base/mcast.c.svn-base b/mcast/client/.svn/text-base/mcast.c.svn-base new file mode 100644 index 0000000..8900452 --- /dev/null +++ b/mcast/client/.svn/text-base/mcast.c.svn-base @@ -0,0 +1 @@ +link ../common/mcast.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/mld_client.c.svn-base b/mcast/client/.svn/text-base/mld_client.c.svn-base new file mode 100644 index 0000000..1871f5d --- /dev/null +++ b/mcast/client/.svn/text-base/mld_client.c.svn-base @@ -0,0 +1 @@ +link ../common/mld_client.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/mld_common.c.svn-base b/mcast/client/.svn/text-base/mld_common.c.svn-base new file mode 100644 index 0000000..ee607dc --- /dev/null +++ b/mcast/client/.svn/text-base/mld_common.c.svn-base @@ -0,0 +1 @@ +link ../common/mld_common.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/mld_reporter.c.svn-base b/mcast/client/.svn/text-base/mld_reporter.c.svn-base new file mode 100644 index 0000000..e0530ab --- /dev/null +++ b/mcast/client/.svn/text-base/mld_reporter.c.svn-base @@ -0,0 +1,225 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#undef DEBUG +#include "headers.h" + +extern pthread_mutex_t lock; +extern recv_info_t receivers; + +extern int mld_start; +static pthread_t mld_send_reports_thread; +static char iface[IFNAMSIZ]; + +static int find_mcg_in_mld_mcas (struct in6_addr *mld_mca, int len, struct in6_addr *mcg) +{ + int i; + + for (i = 0; i < len; i++) { + if (!memcmp (mld_mca + i, mcg, sizeof (struct in6_addr))) { + return 1; + } + } + return 0; +} +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +typedef struct { + struct in6_addr *mld_mca_add; + struct in6_addr *mld_mca_drop; +} mld_reporter_context_t; + +static void clean_mld_send_reports_thread(void *p) +{ + mld_reporter_context_t *c=(mld_reporter_context_t*)p; + if(c->mld_mca_add) { + free(c->mld_mca_add); + } + if(c->mld_mca_drop) { + free(c->mld_mca_drop); + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +static void *mld_send_reports (void *arg) +{ + recv_info_t *receivers = (recv_info_t *) arg; + + int grec_num_drop; + int grec_num_add; + pid_info_t *p; + pid_info_t *ptmp; + recv_info_t *r; + int maxpids=128; + mld_reporter_context_t c; + memset(&c, 0, sizeof(mld_reporter_context_t)); + + c.mld_mca_add=(struct in6_addr *)malloc(maxpids*sizeof(struct in6_addr)); + if (!c.mld_mca_add) + err ("mld_send_reports: out of memory\n"); + c.mld_mca_drop=(struct in6_addr *)malloc(maxpids*sizeof(struct in6_addr)); + if (!c.mld_mca_drop) + err ("mld_send_reports: out of memory\n"); + + pthread_cleanup_push (clean_mld_send_reports_thread, &c); + + struct intnode *intn = int_find_name (iface); + + if( !c.mld_mca_add || !c.mld_mca_drop) { + err ("Cannot get memory for add/drop list\n"); + } + mld_start=1; + while (mld_start) { + grec_num_drop=0; + pthread_mutex_lock (&lock); + + int pids=count_all_pids(receivers); + if(pids>maxpids) { + maxpids=pids; + c.mld_mca_add=(struct in6_addr *)realloc(c.mld_mca_add, pids*sizeof(struct in6_addr)); + if (!c.mld_mca_add) + err ("mld_send_reports: out of memory\n"); + c.mld_mca_drop=(struct in6_addr *)realloc(c.mld_mca_drop, pids*sizeof(struct in6_addr)); + if (!c.mld_mca_drop) + err ("mld_send_reports: out of memory\n"); + } + + //Send listener reports for all recently dropped MCGs + DVBMC_LIST_FOR_EACH_ENTRY (r, &receivers->list, recv_info_t, list) { + DVBMC_LIST_FOR_EACH_ENTRY_SAFE (p, ptmp, &r->slots.list, pid_info_t, list) { + // prevent a somewhere running mcg on any device to be dropped and prevent to drop same mcg multiple times + if (!p->run) { + if ( p->dropped && !find_any_slot_by_mcg (receivers, &p->mcg) && !find_mcg_in_mld_mcas (c.mld_mca_drop, grec_num_drop, &p->mcg)) { + memcpy (c.mld_mca_drop + grec_num_drop++, &p->mcg.s6_addr, sizeof (struct in6_addr)); + p->dropped--; +#ifdef DEBUG + char host[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, p->mcg.s6_addr, (char *) host, INET6_ADDRSTRLEN); + dbg ("DROP_GROUP %d %s\n", grec_num_drop, host); +#endif + } else { + dvbmc_list_remove(&p->list); + free(p); + } + } + } + } + if(grec_num_drop > maxpids) { + err ("Wrong number of pids: %d>%d\n", grec_num_drop, maxpids); + } + grec_num_add=0; + //Send listener reports for all current MCG in use + DVBMC_LIST_FOR_EACH_ENTRY (r, &receivers->list, recv_info_t, list) { + DVBMC_LIST_FOR_EACH_ENTRY (p, &r->slots.list, pid_info_t, list) { + if (p->run && !find_mcg_in_mld_mcas (c.mld_mca_add, grec_num_add, &p->mcg)) { + memcpy (c.mld_mca_add + grec_num_add++, p->mcg.s6_addr, sizeof (struct in6_addr)); +#ifdef DEBUG + char host[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, &p->mcg.s6_addr, (char *) host, INET6_ADDRSTRLEN); + dbg ("ADD_GROUP %d %s\n", grec_num_add, host); +#endif + } + } + } + + if(grec_num_add > maxpids) { + err ("Wrong number of pids: %d>%d\n", grec_num_add, maxpids); + } + + pthread_mutex_unlock (&lock); + + if (intn && intn->mtu) { + if (grec_num_drop) { + send_mldv2_report (intn, grec_num_drop, c.mld_mca_drop, 0, NULL, MLD2_MODE_IS_INCLUDE); + } + if (grec_num_add) { + send_mldv2_report (intn, grec_num_add, c.mld_mca_add, 0, NULL, MLD2_MODE_IS_EXCLUDE); + } + } + usleep (REP_TIME); + pthread_testcancel(); + } + pthread_cleanup_pop (1); + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int mld_client_init (char *intf) +{ + if(intf) { + strcpy(iface, intf); + } else { + iface[0]=0; + } + + if (!strlen (iface)) { + struct intnode *intn = int_find_first (); + if (intn) { + strcpy (iface, intn->name); + } else { + warn ("Cannot find any usable network interface\n"); + return -1; + } + } + +#if ! (defined WIN32 || defined APPLE) + g_conf->rawsocket = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL)); +#endif +#ifdef WIN32 + g_conf->rawsocket = socket (PF_INET6, SOCK_RAW, IPPROTO_ICMPV6); +#endif +#ifdef APPLE + g_conf->rawsocket = socket (PF_INET6, SOCK_RAW, IPPROTO_HOPOPTS); +#endif + if (g_conf->rawsocket < 0) { + warn ("Cannot get a packet socket\n"); + return -1; + } +#ifdef WIN32 + #define IPV6_HDRINCL 2 + DWORD n=1; + if (setsockopt (g_conf->rawsocket, IPPROTO_IPV6, IPV6_HDRINCL, (char *)&n, sizeof (n)) < 0) { + err ("setsockopt IPV6_HDRINCL"); + } + int idx; + if ((idx = if_nametoindex (iface))>0) { + int ret=setsockopt (g_conf->rawsocket, IPPROTO_IPV6, IPV6_MULTICAST_IF, (_SOTYPE)&idx, sizeof (idx)); + if(ret<0) { + warn("setsockopt for IPV6_MULTICAST_IF failed with %d error %s (%d)\n",ret,strerror (errno), errno); + } + } +#endif + pthread_create (&mld_send_reports_thread, NULL, mld_send_reports, &receivers); + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +void mld_client_exit (void) +{ + if(g_conf) { + mld_start=0; + if(pthread_exist(mld_send_reports_thread)) { + if(pthread_exist(mld_send_reports_thread) && !pthread_cancel (mld_send_reports_thread)) { + pthread_join (mld_send_reports_thread, NULL); + } + } +#if 0 + struct intnode *intn; + unsigned int i; + for (i = 0; i < g_conf->maxinterfaces; i++) { + intn = &g_conf->ints[i]; + if (intn->mtu == 0) + continue; + int_destroy (intn); + } +#endif + closesocket(g_conf->rawsocket); + } +} diff --git a/mcast/client/.svn/text-base/mld_reporter.h.svn-base b/mcast/client/.svn/text-base/mld_reporter.h.svn-base new file mode 100644 index 0000000..3036061 --- /dev/null +++ b/mcast/client/.svn/text-base/mld_reporter.h.svn-base @@ -0,0 +1,11 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +DLL_SYMBOL int mld_client_init (char *intf); +DLL_SYMBOL void mld_client_exit (void); + diff --git a/mcast/client/.svn/text-base/mmi_handler.c.svn-base b/mcast/client/.svn/text-base/mmi_handler.c.svn-base new file mode 100644 index 0000000..716c7f1 --- /dev/null +++ b/mcast/client/.svn/text-base/mmi_handler.c.svn-base @@ -0,0 +1,336 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + * modified by Reel Multimedia, http://www.reel-multimedia.com, info@reel-multimedia.com + * 01042010 DL: use a single thread for reading from network layer (uses less resources) + * + */ + +#include "headers.h" + +//--------------------------------------------------------------------------------------------- +void mmi_print_info (mmi_info_t * m) +{ + char str[INET6_ADDRSTRLEN]; + printf ("------------------\n"); + inet_ntop (AF_INET6, &m->ipv6, (char *) str, INET6_ADDRSTRLEN); + printf ("IP: %s\n", str); + printf ("UUID: %s\n", m->uuid); + printf ("Slot: %d\n", m->slot); + + int i; + for (i = 0; i < m->caid_num; i++) { + caid_mcg_t *cm = m->caids + i; + printf ("%i.SID: %d\n", i, cm->caid); + inet_ntop (AF_INET6, &cm->mcg, (char *) str, INET6_ADDRSTRLEN); + printf ("%i.MCG: %s\n", i, str); + } + printf ("TEXT:\n===================\n %s \n===================\n", m->mmi_text); + +} + +//--------------------------------------------------------------------------------------------- +int mmi_open_menu_session (char *uuid, char *intf, int port, int cmd) +{ + int ret; + int j, sockfd; + struct in6_addr ipv6; + char iface[IFNAMSIZ]; + + inet_pton (AF_INET6, uuid, &ipv6); + + if (!intf || !strlen (intf)) { + struct intnode *intn = int_find_first (); + if (intn) { + strcpy (iface, intn->name); + } + } else { + strncpy (iface, intf, sizeof (iface)); + iface[sizeof (iface) - 1] = 0; + } + if (!port) { + port = 23013; + } + + sockfd = socket (PF_INET6, SOCK_STREAM, 0); + j = 1; + if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, (_SOTYPE) & j, sizeof (j)) < 0) { + err ("setsockopt REUSEADDR\n"); + } + + j = 1; + if (setsockopt (sockfd, SOL_SOCKET, TCP_NODELAY, (_SOTYPE) & j, sizeof (j)) < 0) { + warn ("setsockopt TCP_NODELAY\n"); + } + + dbg ("Connect To: %s\n", uuid); + + struct sockaddr_in6 addr; + memset (&addr, 0, sizeof (struct sockaddr_in6)); + + addr.sin6_family = AF_INET6; + addr.sin6_port = htons (port); + addr.sin6_addr = ipv6; + addr.sin6_scope_id = if_nametoindex (iface); + + ret = connect (sockfd, (struct sockaddr *) &addr, sizeof (struct sockaddr_in6)); + if (ret < 0) { + dbg ("Failed to access NetCeiver MMI support\n"); + return -1; + } + //send init cmd + char buf[128]; + memset (buf, 0, sizeof (buf)); + dbg ("Request CAM slot %d \n", cmd); + sprintf (buf, "%x", cmd); + int n = send (sockfd, buf, strlen (buf) + 1, 0); + if (n < 0) { + dbg ("unable to sent mmi connection cmd !\n"); + closesocket (sockfd); + return -1; + } + dbg ("MMI SESSION : OK\n"); + return sockfd; +} + +//--------------------------------------------------------------------------------------------- +void mmi_close_menu_session (int s) +{ + closesocket (s); +} + +//--------------------------------------------------------------------------------------------- +int mmi_cam_reset (char *uuid, char *intf, int port, int slot) +{ + int cmd = (slot << 12) | 0xfff; + printf ("Reseting slot %d (cmd %x)...\n", slot, cmd); + int sock = mmi_open_menu_session (uuid, intf, port, cmd); + if (sock < 1) { + printf ("Unable to reset slot %d on netceiver %s...\n", slot, uuid); + } + closesocket (sock); + return 0; +} +//--------------------------------------------------------------------------------------------- +int mmi_cam_reinit (char *uuid, char *intf, int port, int slot) +{ + int cmd = (slot << 12) | 0xeee; + printf ("Reinitializing slot %d (cmd %x)...\n", slot, cmd); + int sock = mmi_open_menu_session (uuid, intf, port, cmd); + if (sock < 1) { + printf ("Unable to reset slot %d on netceiver %s...\n", slot, uuid); + } + closesocket (sock); + return 0; +} +//--------------------------------------------------------------------------------------------- +int mmi_get_menu_text (int sockfd, char *buf, int buf_len, int timeout) +{ + int n = -1; + struct pollfd p; + memset (buf, 0, buf_len); + p.fd = sockfd; + p.events = POLLIN; + if (poll (&p, 1, (timeout+999)>>10) > 0) { + n = recv (sockfd, buf, buf_len, 0); //MSG_DONTWAIT); + } + if (n > 0) { + dbg ("recv:\n%s \n", buf); + } + return n; +} + +//--------------------------------------------------------------------------------------------- +int mmi_send_menu_answer (int sockfd, char *buf, int buf_len) +{ + dbg ("send: %s len %d \n", buf, buf_len); + int n; + n = send (sockfd, buf, buf_len, 0); + if (n < 0) { + dbg ("mmi_send_answer: error sending !\n"); + } + return n; +} + +//--------------------------------------------------------------------------------------------- +UDPContext *mmi_broadcast_client_init (int port, char *intf) +{ + UDPContext *s; + char mcg[1024]; + char iface[IFNAMSIZ]; + //FIXME: move to common + strcpy (mcg, "ff18:6000::"); + if (!intf || !strlen (intf)) { + struct intnode *intn = int_find_first (); + if (intn) { + strcpy (iface, intn->name); + } + } else { + strncpy (iface, intf, sizeof (iface)); + iface[sizeof (iface) - 1] = 0; + } + if (!port) { + port = 23000; + } + + s = client_udp_open_host (mcg, port, iface); + if (!s) { + dbg ("client udp open host error !\n"); + } + + return s; +} + +void mmi_broadcast_client_exit (UDPContext * s) +{ + udp_close (s); +} + +//--------------------------------------------------------------------------------------------- +typedef struct +{ + xmlDocPtr doc; + xmlChar *str, *key; +} xml_parser_context_t; + +static void clean_xml_parser_thread (void *arg) +{ + xml_parser_context_t *c = (xml_parser_context_t *) arg; + if (c->str) { + xmlFree (c->str); + } + if (c->key) { + xmlFree (c->key); + } + if (c->doc) { + xmlFreeDoc (c->doc); + } + dbg ("Free XML parser structures!\n"); +} + +//--------------------------------------------------------------------------------------------- +int mmi_get_data (xmlChar * xmlbuff, int buffersize, mmi_info_t * mmi_info) +{ + xml_parser_context_t c; + xmlNode *root_element = NULL, *cur_node = NULL; + + xmlKeepBlanksDefault (0); //reomve this f. "text" nodes + c.doc = xmlParseMemory ((char *) xmlbuff, buffersize); + root_element = xmlDocGetRootElement (c.doc); + pthread_cleanup_push (clean_xml_parser_thread, &c); + + + if (root_element != NULL) { + cur_node = root_element->children; + if (!xmlStrcmp (cur_node->name, (xmlChar *) "Description")) { + root_element = cur_node->children; + while (root_element != NULL) { + c.key = NULL; + c.str = NULL; + if ((xmlStrcmp (root_element->name, (const xmlChar *) "component"))) { + warn ("Cannot parse XML data\n"); + root_element = root_element->next; + continue; + } + cur_node = root_element->children; + if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "Description"))) { + c.str = xmlGetProp (cur_node, (unsigned char *) "about"); + //fprintf(stdout,"\n%s:\n",c.str); + //fprintf(stdout,"-----------------------------------------------------------\n"); + } else { + warn ("Cannot parse XML data\n"); + root_element = root_element->next; + continue; + } + if (c.str && (!xmlStrcmp (c.str, (const xmlChar *) "MMIData"))) { + cur_node = cur_node->children; + while (cur_node != NULL) { + if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "IP"))) { + c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1); + if (c.key) { + dbg ("IP: %s\n", c.key); + inet_pton (AF_INET6, (char *) c.key, &mmi_info->ipv6); + xmlFree (c.key); + } + } else if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "UUID"))) { + c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1); + if (c.key) { + dbg ("UUID: %s\n", c.key); + strcpy (mmi_info->uuid, (char *) c.key); + xmlFree (c.key); + } + } else if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "Slot"))) { + c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1); + if (c.key) { + dbg ("Slot: %s\n", c.key); + mmi_info->slot = atoi ((char *) c.key); + xmlFree (c.key); + } + } else if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "TEXT"))) { + c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1); + if (c.key) { + dbg ("TEXT: %s\n", c.key); + int olen = MMI_TEXT_LENGTH, ilen = strlen ((char *) c.key); + + UTF8Toisolat1 ((unsigned char *) mmi_info->mmi_text, &olen, c.key, &ilen); + + xmlFree (c.key); + } + } + cur_node = cur_node->next; + } + } else if (c.str && (!xmlStrcmp (c.str, (const xmlChar *) "ProgramNumberIDs"))) { + cur_node = cur_node->children; + while (cur_node != NULL) { + if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "MCG"))) { + c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1); + if (c.key) { + dbg ("MCG: %s\n", c.key); + struct in6_addr mcg; + inet_pton (AF_INET6, (char *) c.key, &mcg); + int sid; + mcg_get_id (&mcg, &sid); + mcg_set_id (&mcg, 0); + mmi_info->caids = (caid_mcg_t *) realloc (mmi_info->caids, sizeof (caid_mcg_t) * (mmi_info->caid_num + 1)); + if (!mmi_info->caids) + err ("mmi_get_data: out of memory\n"); + caid_mcg_t *cm = mmi_info->caids + mmi_info->caid_num; + cm->caid = sid; + cm->mcg = mcg; + mmi_info->caid_num++; + xmlFree (c.key); + } + } + cur_node = cur_node->next; + } + } + xmlFree (c.str); + root_element = root_element->next; + } + } + } + + xmlFreeDoc (c.doc); + pthread_cleanup_pop (0); + return 1; +} + +//--------------------------------------------------------------------------------------------- +int mmi_poll_for_menu_text (UDPContext * s, mmi_info_t * m, int timeout) +{ + char buf[8192]; + int n = 0; + if (s) { + n = udp_read (s, (unsigned char *) buf, sizeof (buf), timeout, NULL); + if (n > 0) { + dbg ("recv:\n%s \n", buf); + memset (m, 0, sizeof (mmi_info_t)); + mmi_get_data ((xmlChar *) buf, n, m); + } + } + return n; +} +//--------------------------------------------------------------------------------------------- diff --git a/mcast/client/.svn/text-base/mmi_handler.h.svn-base b/mcast/client/.svn/text-base/mmi_handler.h.svn-base new file mode 100644 index 0000000..37b0af5 --- /dev/null +++ b/mcast/client/.svn/text-base/mmi_handler.h.svn-base @@ -0,0 +1,46 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#ifndef _MMI_HANDLER_H +#define _MMI_HANDLER_H + +#define MMI_TEXT_LENGTH 1024 + +typedef struct caid_mcg { + + int caid; + struct in6_addr mcg; + + +} caid_mcg_t; + +typedef struct mmi_info { + + int slot; + caid_mcg_t *caids; + int caid_num; + + struct in6_addr ipv6; + char uuid[UUID_SIZE]; + + char mmi_text[MMI_TEXT_LENGTH]; + +} mmi_info_t; + +DLL_SYMBOL void mmi_print_info(mmi_info_t *m); +DLL_SYMBOL int mmi_get_menu_text(int sockfd, char *buf, int buf_len, int timeout); +DLL_SYMBOL int mmi_send_menu_answer(int sockfd, char *buf, int buf_len); +DLL_SYMBOL UDPContext *mmi_broadcast_client_init(int port, char *iface); +DLL_SYMBOL void mmi_broadcast_client_exit(UDPContext *s); +DLL_SYMBOL int mmi_poll_for_menu_text(UDPContext *s, mmi_info_t *m, int timeout); +DLL_SYMBOL int mmi_open_menu_session(char *uuid, char *iface,int port, int cmd); +DLL_SYMBOL void mmi_close_menu_session(int s); +DLL_SYMBOL int mmi_cam_reset(char *uuid, char *intf, int port, int slot); +DLL_SYMBOL int mmi_cam_reinit(char *uuid, char *intf, int port, int slot); + +#endif diff --git a/mcast/client/.svn/text-base/recv_ccpp.c.svn-base b/mcast/client/.svn/text-base/recv_ccpp.c.svn-base new file mode 100644 index 0000000..cdd7e14 --- /dev/null +++ b/mcast/client/.svn/text-base/recv_ccpp.c.svn-base @@ -0,0 +1 @@ +link ../common/recv_ccpp.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/recv_tv.c.svn-base b/mcast/client/.svn/text-base/recv_tv.c.svn-base new file mode 100644 index 0000000..f453ed4 --- /dev/null +++ b/mcast/client/.svn/text-base/recv_tv.c.svn-base @@ -0,0 +1,905 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + * modified by Reel Multimedia, http://www.reel-multimedia.com, info@reel-multimedia.com + * 01042010 DL: use a single thread for reading from network layer (uses less resources) + * + */ + +//#define DEBUG 1 +#include "headers.h" +#if ! defined WIN32 || defined __CYGWIN__ +#define RT +#endif + +#define RE 1 + +#if defined(RE) +int set_redirected(recv_info_t *r, int sid); +int check_if_already_redirected(recv_info_t *r, int sid); +#endif + +recv_info_t receivers; +pthread_mutex_t lock; + +int mld_start=0; + +int port=23000; +char iface[IFNAMSIZ]; + +static pthread_t recv_tra_thread; +static pthread_t recv_tca_thread; + +#if ! defined WIN32 || defined __CYGWIN__ +static void sig_handler (int signal) +{ + dbg ("Signal: %d\n", signal); + + switch (signal) { + case SIGUSR1: + recv_show_all_pids (&receivers); + break; + } +} +#endif + +#ifdef MULTI_THREAD_RECEIVER +static void clean_recv_ts_thread (void *arg) +{ + pid_info_t *p = (pid_info_t *) arg; +#ifdef DEBUG + dbg ("Stop stream receiving for pid %d\n", p->pid.pid); +#endif + + if (p->s) { + udp_close (p->s); + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +static void *recv_ts (void *arg) +{ + unsigned char buf[32712]; + unsigned char *ptr; + int n, res; + int cont_old = -1; + + pid_info_t *p = (pid_info_t *) arg; + recv_info_t *r = p->recv; + +#ifdef RT +#if 1 + if (setpriority (PRIO_PROCESS, 0, -15) == -1) +#else + if (pthread_setschedprio (p->recv_ts_thread, -15)) +#endif + { + dbg ("Cannot raise priority to -15\n"); + } +#endif + + pthread_cleanup_push (clean_recv_ts_thread, p); +#ifdef DEBUG + char addr_str[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, p->mcg.s6_addr, addr_str, INET6_ADDRSTRLEN); + dbg ("Start stream receiving for %s on port %d %s\n", addr_str, port, iface); +#endif + p->s = client_udp_open (&p->mcg, port, iface); + if (!p->s) { + warn ("client_udp_open error !\n"); + } else { + p->run = 1; + } + while (p->run>0) { + n = udp_read (p->s, buf, sizeof (buf), 1000, NULL); + if (n >0 ) { + ptr = buf; + if (n % 188) { + warn ("Received %d bytes is not multiple of 188!\n", n); + } + int i; + for (i = 0; i < (n / 188); i++) { + unsigned char *ts = buf + (i * 188); + int adaption_field = (ts[3] >> 4) & 3; + int cont = ts[3] & 0xf; + int pid = ((ts[1] << 8) | ts[2]) & 0x1fff; + int transport_error_indicator = ts[1]&0x80; + + if (pid != 8191 && (adaption_field & 1) && (((cont_old + 1) & 0xf) != cont) && cont_old >= 0) { + warn ("Discontinuity on receiver %p for pid %d: %d->%d at pos %d/%d\n", r, pid, cont_old, cont, i, n / 188); + } + if (transport_error_indicator) { + warn ("Transport error indicator set on receiver %p for pid %d: %d->%d at pos %d/%d\n", r, pid, cont_old, cont, i, n / 188); + } + cont_old = cont; + } + if(r->handle_ts) { + while (n) { + res = r->handle_ts (ptr, n, r->handle_ts_context); + if (res != n) { + warn ("Not same amount of data written: res:%d<=n:%d\n", res, n); + } + if (res < 0) { + warn ("write of %d bytes returned %d\n", n, res); + perror ("Write failed"); + break; + } else { + ptr += res; + n -= res; + } + } + } + } + pthread_testcancel(); + } + pthread_cleanup_pop (1); + + return NULL; + } + +#else +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +static void recv_ts_func (unsigned char *buf, int n, void *arg) { + if (n >0 ) { + pid_info_t *p = (pid_info_t *) arg; + recv_info_t *r = p->recv; + int i; + for (i = 0; i < n; i += 188) { + unsigned char *ts = buf + i; + int adaption_field = (ts[3] >> 4) & 3; + int cont = ts[3] & 0xf; + int pid = ((ts[1] << 8) | ts[2]) & 0x1fff; + int transport_error_indicator = ts[1]&0x80; + + if (pid != 8191 && (adaption_field & 1) && (((p->cont_old + 1) & 0xf) != cont) && p->cont_old >= 0) { + warn ("Discontinuity on receiver %p for pid %d: %d->%d at pos %d/%d\n", r, pid, p->cont_old, cont, i / 188, n / 188); + } + if (transport_error_indicator) { + warn ("Transport error indicator set on receiver %p for pid %d: %d->%d at pos %d/%d\n", r, pid, p->cont_old, cont, i / 188, n / 188); + } + p->cont_old = cont; + } + if (i != n) { + warn ("Received %d bytes is not multiple of 188!\n", n); + } + if(r->handle_ts) { + while (n) { + int res = r->handle_ts (buf, n, r->handle_ts_context); + if (res != n) { + warn ("Not same amount of data written: res:%d<=n:%d\n", res, n); + } + if (res < 0) { + warn ("write of %d bytes returned %d\n", n, res); + perror ("Write failed"); + break; + } else { + buf += res; + n -= res; + } + } + } + } +} +#endif +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int register_ts_handler (recv_info_t * r, int (*p)(unsigned char *, size_t, void *), void *c) +{ + r->handle_ts=(int (*)(unsigned char *buffer, size_t len, void *context))p; + r->handle_ts_context=c; + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static pid_info_t *find_slot_by_pid (recv_info_t * r, int pid, int id) +{ + pid_info_t *slot; + DVBMC_LIST_FOR_EACH_ENTRY (slot, &r->slots.list, pid_info_t, list) { + if (slot->run && slot->pid.pid == pid && (id == -1 || slot->pid.id == id)) { + return slot; + } + } + + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static pid_info_t *find_slot_by_mcg (recv_info_t * r, struct in6_addr *mcg) +{ + pid_info_t *slot; + + DVBMC_LIST_FOR_EACH_ENTRY (slot, &r->slots.list, pid_info_t, list) { + if (slot->run && !memcmp (&slot->mcg, mcg, sizeof (struct in6_addr))) { + return slot; + } + } + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int find_any_slot_by_mcg (recv_info_t * receivers, struct in6_addr *mcg) +{ + recv_info_t *r; + int ret=0; + + DVBMC_LIST_FOR_EACH_ENTRY (r, &receivers->head->list, recv_info_t, list) { + pid_info_t *slot = find_slot_by_mcg (r, mcg); + if(slot) { + ret++; + } + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int count_receivers(recv_info_t *receivers) +{ + int ret=0; + struct list *pos; + + DVBMC_LIST_FOR_EACH (pos, &receivers->list) { + ret++; + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int count_pids(recv_info_t *r) +{ + int ret=0; + struct list *pos; + + DVBMC_LIST_FOR_EACH (pos, &r->slots.list) { + ret++; + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int count_all_pids (recv_info_t * receivers) +{ + int ret=0; + recv_info_t *r; + + DVBMC_LIST_FOR_EACH_ENTRY (r, &receivers->head->list, recv_info_t, list) { + ret += count_pids(r); + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +void recv_show_pids(recv_info_t *r) +{ + pid_info_t *slot; + char addr_str[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, r->mcg.s6_addr, addr_str, INET6_ADDRSTRLEN); + + info("pids on receiver %p (%s):\n",r, addr_str); + DVBMC_LIST_FOR_EACH_ENTRY (slot, &r->slots.list, pid_info_t, list) { + info("%d,", slot->pid.pid); + } + info("\n"); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_show_all_pids (recv_info_t * receivers) +{ + int ret=0; + recv_info_t *r; + DVBMC_LIST_FOR_EACH_ENTRY (r, &receivers->head->list, recv_info_t, list) { + recv_show_pids(r); + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void deallocate_slot (recv_info_t * r, pid_info_t *p) +{ + int nodrop=0; + +#ifdef MULTI_THREAD_RECEIVER + if (pthread_exist(p->recv_ts_thread)) { +#else + if (p->run) { + +#endif //info ("Deallocating PID %d from slot %p\n", p->pid.pid, p); + p->run = 0; + + //Do not leave multicast group if there is another dvb adapter using the same group + if (find_any_slot_by_mcg (r, &p->mcg)) { + dbg ("MCG is still in use not dropping\n"); + p->s->is_multicast = 0; + nodrop=1; + } + +#ifdef MULTI_THREAD_RECEIVER + pthread_join (p->recv_ts_thread, NULL); +#else + udp_close_buff(p->s); +#endif + p->dropped = MAX_DROP_NUM; + } + //printf("NO DROP: %d\n",nodrop); + if(!mld_start || nodrop) { + dvbmc_list_remove(&p->list); + free(p); + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static pid_info_t *allocate_slot (recv_info_t * r, struct in6_addr *mcg, dvb_pid_t *pid) +{ + pid_info_t *p = (pid_info_t *)malloc(sizeof(pid_info_t)); + if(!p) { + err ("Cannot get memory for pid\n"); + } + + dbg ("Allocating new PID %d to Slot %p\n", pid->pid, p); + + memset(p, 0, sizeof(pid_info_t)); + + p->cont_old = -1; + p->mcg = *mcg; + mcg_set_pid (&p->mcg, pid->pid); +#if defined(RE) + if (!check_if_already_redirected(r, pid->id)) { + //printf("PID %d not red. ===> SETTING ID to %d\n",pid->pid,pid->id); + mcg_set_id (&p->mcg, pid->id); + mcg_set_priority(&p->mcg, pid->priority); + } else { + set_redirected(r, pid->id); + //printf("send pid %d to noid mcg !\n",pid->pid); + mcg_set_id(&p->mcg, 0); + mcg_set_priority(&p->mcg, 0); + } + //mcg_set_id(&p->mcg,pid->id); +#else + mcg_set_id (&p->mcg, pid->id); + mcg_set_priority(&p->mcg, pid->priority); +#endif + + +#ifdef DEBUG + print_mcg (&p->mcg); +#endif + p->pid = *pid; + p->recv = r; +#ifdef MULTI_THREAD_RECEIVER + int ret = pthread_create (&p->recv_ts_thread, NULL, recv_ts, p); + while (!ret && !p->run) { + usleep (10000); + } + if (ret) { + err ("pthread_create failed with %d\n", ret); +#else + p->cont_old=-1; + p->s = client_udp_open_cb (&p->mcg, port, iface, recv_ts_func, p); + if (!p->s) { + warn ("client_udp_open error !\n"); + return 0; +#endif + } else { + p->run = 1; + dvbmc_list_add_head (&r->slots.list, &p->list); + } + + return p; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void stop_ten_receive (recv_info_t * r) +{ + dbg ("->>>>>>>>>>>>>>>>>stop_ten_receive on receiver %p\n",r); + if (pthread_exist(r->recv_ten_thread) && r->ten_run) { + dbg ("cancel TEN receiver %p %p\n", r, r->recv_ten_thread); + + r->ten_run=0; + pthread_mutex_unlock (&lock); + do { + dbg ("wait TEN stop receiver %p %p\n", r, r->recv_ten_thread); + usleep(10000); + } while (!r->ten_run); + pthread_mutex_lock (&lock); + r->ten_run=0; + dbg ("cancel TEN done receiver %p\n", r); + pthread_detach (r->recv_ten_thread); + pthread_null(r->recv_ten_thread); + } +} + + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void start_ten_receive (recv_info_t * r) +{ + if (r->pidsnum && !pthread_exist(r->recv_ten_thread)) { +#ifdef DEBUG + char host[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, &r->mcg, (char *) host, INET6_ADDRSTRLEN); + + dbg ("Start TEN for receiver %p %s\n", r, host); +#endif + r->ten_run = 0; + + int ret = pthread_create (&r->recv_ten_thread, NULL, recv_ten, r); + while (!ret && !r->ten_run) { + dbg ("wait TEN startup receiver %p %p\n", r, r->recv_ten_thread); + usleep (10000); + } + if (ret) { + err ("pthread_create failed with %d\n", ret); + } + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int cmppids(const void *p1, const void *p2) +{ + dvb_pid_t *pid1=(dvb_pid_t *)p1; + dvb_pid_t *pid2=(dvb_pid_t *)p2; + + if(pid1->pid == pid2->pid) { + return pid1->id < pid2->id; + } + return pid1->pid < pid2->pid; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void update_mcg (recv_info_t * r, int handle_ten) +{ + int i; + pid_info_t *p; + pid_info_t *ptmp; + + if(handle_ten) { + if(r->pidsnum) { + start_ten_receive(r); + } else { + stop_ten_receive(r); + } + } + dbg("update_mcg(%p, %d)\n", r, handle_ten); + qsort(r->pids, r->pidsnum, sizeof(dvb_pid_t), cmppids); + + DVBMC_LIST_FOR_EACH_ENTRY_SAFE (p, ptmp, &r->slots.list, pid_info_t, list) { + //dbg ("DVBMC_LIST_FOR_EACH_ENTRY_SAFE: %p\n", p); + if(p->run) { + int found_pid = 0; + for (i = 0; i < r->pidsnum; i++) { + // pid already there without id but now also with id required + if (r->pids[i].pid == p->pid.pid && r->pids[i].id && !p->pid.id) { + found_pid = 0; + break; + } + if (r->pids[i].pid == p->pid.pid && r->pids[i].id == p->pid.id) { + found_pid = 1; + } + } + if (!found_pid) { + deallocate_slot (r, p); + } + } + } + + for (i = 0; i < r->pidsnum; i++) { + unsigned int pid = r->pids[i].pid; + if (!find_slot_by_pid (r, pid, -1)) { //pid with any id there? + allocate_slot (r, &r->mcg, r->pids+i); + } + } + + +} +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +static void stop_receive (recv_info_t * r, int mode) +{ + dbg ("stop_receive on receiver %p mode %d\n",r, mode); + int pidsnum=r->pidsnum; + //Remove all PIDs + r->pidsnum = 0; + update_mcg (r, mode); + r->pidsnum=pidsnum; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef RE +#if 0 +static int find_redirected_sid (recv_info_t * r, int id) +{ + pid_info_t *slot; + DVBMC_LIST_FOR_EACH_ENTRY (slot, &r->slots.list, pid_info_t, list) { + if (slot->pid.id == id && slot->pid.re) { + return 1; + } + } + + return 0; +} +#endif + +int check_if_already_redirected(recv_info_t *r, int sid) +{ + int i; + for (i = 0; i < r->pidsnum; i++) { + //printf("PID %d SID %d RE %d\n",r->pids[i].pid, r->pids[i].id, r->pids[i].re); + if (r->pids[i].re && r->pids[i].id == sid) { + return 1; + } + } + + return 0; +} + +int check_if_sid_in(recv_info_t *r, int sid) +{ + int i; + for (i = 0; i < r->pidsnum; i++) { + //printf("PID %d SID %d RE %d\n",r->pids[i].pid, r->pids[i].id, r->pids[i].re); + if (r->pids[i].id == sid) { +// printf("%s: SID in %d!\n",__func__,sid); + return 1; + } + } + + return 0; +} + +int set_redirected(recv_info_t *r, int sid) +{ + int i; + for (i = 0; i < r->pidsnum; i++) { + if (r->pids[i].id == sid) + r->pids[i].re=1; + } + + return 0; +} +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +int stop_sid_mcgs(recv_info_t *r, int sid) +{ + pid_info_t *p; + pid_info_t *ptmp; + + DVBMC_LIST_FOR_EACH_ENTRY_SAFE (p, ptmp, &r->slots.list, pid_info_t, list) { + if(p->run) { + if (p->pid.pid && p->pid.id == sid) { + //info ("Deallocating PID %d ID %d RE %d from slot %p\n", p->pid.pid,p->pid.id,p->pid.re, p); + deallocate_slot (r, p); + } + } + } + + return 0; +} +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +int rejoin_mcgs(recv_info_t *r, int sid) +{ + + int i; + for (i = 0; i < r->pidsnum; i++) { + unsigned int pid = r->pids[i].pid; + unsigned int id = r->pids[i].id; + if (!find_slot_by_pid (r, pid, id) && id == sid) { + char addr_str[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, &r->mcg, addr_str, INET6_ADDRSTRLEN); + //info ("Rejoin mcg %s with no ID (PID %d ID %d RE %d)...\n", addr_str, pid, id, r->pids[i].re); + allocate_slot (r, &r->mcg, r->pids+i); + } + } + + return 0; +} +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif +int recv_redirect (recv_info_t * r, struct in6_addr mcg) +{ + int ret = 0; + + pthread_mutex_lock (&lock); + dbg ("\n+++++++++++++\nIn redirect for receiver %p\n", r); +#if 0 + char addr_str[INET6_ADDRSTRLEN]; + inet_ntop (AF_INET6, &r->mcg, addr_str, INET6_ADDRSTRLEN); + info ("Redirect to ===> %s\n",addr_str); +#endif + int sid; + mcg_get_id(&mcg,&sid); + mcg_set_id(&mcg,0); + + //printf("SID in: %d\n",sid); + + if (!sid || ( !check_if_already_redirected(r, sid) && check_if_sid_in(r, sid)) ) { + if (sid == 0) { + stop_receive (r, 0); + r->mcg = mcg; + update_mcg (r, 0); + ret = 1; + } else { + //stop sid mcgs + stop_sid_mcgs(r, sid); + set_redirected(r, sid); + //start new mcgs with no sid + rejoin_mcgs(r, sid); + } + } + + dbg ("Redirect done for receiver %p\n", r); + pthread_mutex_unlock (&lock); + + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_stop (recv_info_t * r) +{ + pthread_mutex_lock (&lock); + stop_receive (r, 1); + pthread_mutex_unlock (&lock); + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_count_pids(recv_info_t * r) +{ + int i; + for (i=0; r->pids[i].pid!=-1; i++); + return i; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int recv_copy_pids(dvb_pid_t *dst, dvb_pid_t *src) +{ + int i; + for (i=0; (src[i].pid!=-1) && (i<(RECV_MAX_PIDS-1)); i++) { + dst[i]=src[i]; + } + if(i==(RECV_MAX_PIDS-1)) { + warn("Cannot receive more than %d pids\n", RECV_MAX_PIDS-1); + } + return i; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_pids (recv_info_t *r, dvb_pid_t *pids) +{ + pthread_mutex_lock (&lock); + if(pids) { + r->pidsnum=recv_copy_pids(r->pids, pids); + } + update_mcg(r, 1); + pthread_mutex_unlock (&lock); + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_pids_get (recv_info_t *r, dvb_pid_t *pids) +{ + pthread_mutex_lock (&lock); + if(pids) { + memcpy(pids, r->pids, sizeof(dvb_pid_t)*r->pidsnum); + pids[r->pidsnum].pid=-1; + } + pthread_mutex_unlock (&lock); + return r->pidsnum; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_pid_add (recv_info_t * r, dvb_pid_t *pid) +{ + int ret=0; + + pthread_mutex_lock (&lock); + pid_info_t *p=find_slot_by_pid (r, pid->pid, pid->id); + if(!p && (r->pidsnum < (RECV_MAX_PIDS-2))) { +#if defined(RE) + r->pids[r->pidsnum].re = 0; +#endif + r->pids[r->pidsnum]=*pid; + r->pids[++r->pidsnum].pid=-1; + update_mcg(r, 1); + ret = 1; + } + pthread_mutex_unlock (&lock); + + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_pid_del (recv_info_t * r, int pid) +{ + int i; + int ret=0; + + pthread_mutex_lock (&lock); + if(pid>=0) { + for (i = 0; i < r->pidsnum; i++) { + if(r->pids[i].pid==pid || ret) { + r->pids[i]=r->pids[i+1]; + ret=1; + } + } + if(ret) { + r->pidsnum--; + update_mcg(r, 1); + } + } else { + r->pids[0].pid=-1; + r->pidsnum=0; + update_mcg(r, 1); + } + pthread_mutex_unlock (&lock); + + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_tune (recv_info_t * r, fe_type_t type, int satpos, recv_sec_t *sec, struct dvb_frontend_parameters *fe_parms, dvb_pid_t *pids) +{ + pthread_mutex_lock (&lock); + dbg ("kick_tune receiver %p\n", r); + + stop_receive (r, 1); + if(fe_parms) { + r->fe_parms=*fe_parms; + } + if(sec) { + r->sec=*sec; + } + if(pids) { + r->pidsnum=recv_copy_pids(r->pids, pids); + } + + fe_parms_to_mcg (&r->mcg, STREAMING_PID, type, &r->sec, &r->fe_parms, 0); + mcg_set_satpos (&r->mcg, satpos); + + update_mcg (r, 1); + + pthread_mutex_unlock (&lock); + dbg ("kick_tune done receiver %p\n", r); + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +recv_info_t *recv_add (void) +{ + recv_info_t *r=(recv_info_t *)malloc(sizeof(recv_info_t)); + if(!r) { + err ("Cannot get memory for receiver\n"); + } + memset (r, 0, sizeof (recv_info_t)); + r->head=&receivers; + dvbmc_list_init (&r->slots.list); + pthread_mutex_lock (&lock); + dvbmc_list_add_head(&receivers.list, &r->list); + pthread_mutex_unlock (&lock); + return r; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +void recv_del (recv_info_t *r) +{ + pthread_mutex_lock (&lock); + stop_receive (r, 1); + dvbmc_list_remove(&r->list); + pthread_mutex_unlock (&lock); + free(r); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_init(char *intf, int p) +{ + LIBXML_TEST_VERSION; +#ifdef WIN32 + WSADATA wsaData; + if (WSAStartup (MAKEWORD (2, 2), &wsaData) != 0) { + err ("WSAStartup failed\n"); + } +#endif + + if(intf) { + strcpy(iface, intf); + } else { + iface[0]=0; + } + if(p) { + port=p; + } + + g_conf = (struct conf*) malloc (sizeof (struct conf)); + if (!g_conf) { + err ("Cannot get memory for configuration\n"); + exit (-1); + } + + memset (g_conf, 0, sizeof (struct conf)); + update_interfaces (NULL); + + if (!strlen (iface)) { + struct intnode *intn = int_find_first (); + if (intn) { + strcpy (iface, intn->name); + } else { + warn ("Cannot find any usable network interface\n"); + if(g_conf->ints) { + free (g_conf->ints); + } + #ifdef PTW32_STATIC_LIB + pthread_win32_process_detach_np(); + #endif + free(g_conf); + return -1; + } + } + + dvbmc_list_init (&receivers.list); + pthread_mutex_init (&lock, NULL); + receivers.head=&receivers; +#if ! defined WIN32 || defined __CYGWIN__ + signal (SIGUSR1, &sig_handler); +#endif +#ifdef PTW32_STATIC_LIB + pthread_win32_process_attach_np(); +#endif + pthread_create (&recv_tra_thread, NULL, recv_tra, NULL); + pthread_create (&recv_tca_thread, NULL, recv_tca, NULL); + + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int recv_exit(void) +{ + recv_info_t *r; + recv_info_t *rtmp; + if(pthread_exist(recv_tra_thread) && !pthread_cancel (recv_tra_thread)) { + pthread_join (recv_tra_thread, NULL); + } + if(pthread_exist(recv_tca_thread) && !pthread_cancel (recv_tca_thread)) { + pthread_join (recv_tca_thread, NULL); + } + DVBMC_LIST_FOR_EACH_ENTRY_SAFE (r, rtmp, &receivers.head->list, recv_info_t, list) { + recv_del(r); + } +#if ! defined WIN32 || defined __CYGWIN__ + signal (SIGUSR1, NULL); +#endif + g_conf->maxinterfaces=0; + if(g_conf->ints) { + free (g_conf->ints); + } +#ifdef PTW32_STATIC_LIB + pthread_win32_process_detach_np(); +#endif + free(g_conf); + xmlCleanupParser (); + xmlMemoryDump (); + return 0; +} diff --git a/mcast/client/.svn/text-base/recv_tv.h.svn-base b/mcast/client/.svn/text-base/recv_tv.h.svn-base new file mode 100644 index 0000000..9feb673 --- /dev/null +++ b/mcast/client/.svn/text-base/recv_tv.h.svn-base @@ -0,0 +1,96 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + * modified by Reel Multimedia, http://www.reel-multimedia.com, info@reel-multimedia.com + * 01042010 DL: use a single thread for reading from network layer (uses less resources) + * + */ + +#ifndef __RECV_TV_H__ +#define __RECV_TV__H__ + +#define REP_TIME 1000000 +#define MAX_DROP_NUM 5 +#define RECV_MAX_PIDS 256 + +//typedef struct recv_info recv_info_t; + +typedef struct { + int pid; + int id; + int priority; +#if 1 + int re; +#endif +} dvb_pid_t; + +typedef struct pid_info +{ + struct list list; + UDPContext *s; + dvb_pid_t pid; + struct in6_addr mcg; + recv_info_t *recv; + pthread_t recv_ts_thread; + int run; + int dropped; + int cont_old; +} pid_info_t; + +struct recv_info +{ + struct list list; + recv_info_t *head; + pid_info_t slots; + int lastalloc; + pthread_t recv_ten_thread; + struct in6_addr mcg; + int ten_run; + + dvb_pid_t pids[RECV_MAX_PIDS]; + int pidsnum; + recv_sec_t sec; + struct dvb_frontend_parameters fe_parms; + + recv_festatus_t fe_status; + + int (*handle_ten) (tra_t *ten, void *context); + void *handle_ten_context; + + int (*handle_ts) (unsigned char *buffer, size_t len, void *context); + void *handle_ts_context; +}; + +// Internal Stuff +int recv_redirect (recv_info_t * r, struct in6_addr mcg); +int count_all_pids (recv_info_t * receivers); +int count_receivers(recv_info_t *receivers); + +// PID-Handling +DLL_SYMBOL int recv_pid_add (recv_info_t * r, dvb_pid_t *pid); +DLL_SYMBOL int recv_pid_del (recv_info_t * r, int pid); +DLL_SYMBOL int recv_pids (recv_info_t * r, dvb_pid_t *pids); +DLL_SYMBOL int recv_pids_get (recv_info_t *r, dvb_pid_t *pids); +DLL_SYMBOL int recv_show_all_pids (recv_info_t * receivers); +void recv_show_pids(recv_info_t *r); + +// Complete Tune +DLL_SYMBOL int recv_tune (recv_info_t * r, fe_type_t type, int satpos, recv_sec_t *sec, struct dvb_frontend_parameters *fe_parms, dvb_pid_t *pids); + +// Receiver Handling +DLL_SYMBOL recv_info_t *recv_add (void); +DLL_SYMBOL void recv_del (recv_info_t *r); +DLL_SYMBOL int recv_stop (recv_info_t * r); +DLL_SYMBOL int register_ts_handler (recv_info_t * r, int (*p)(unsigned char *, size_t, void *), void *c); + +// Module global functions +DLL_SYMBOL int recv_init(char *intf, int p); +DLL_SYMBOL int recv_exit(void); + + +int find_any_slot_by_mcg (recv_info_t * receivers, struct in6_addr *mcg); + +#endif diff --git a/mcast/client/.svn/text-base/satlists.c.svn-base b/mcast/client/.svn/text-base/satlists.c.svn-base new file mode 100644 index 0000000..6dccb39 --- /dev/null +++ b/mcast/client/.svn/text-base/satlists.c.svn-base @@ -0,0 +1,133 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" + +int satellite_find_by_diseqc (satellite_reference_t * ref, recv_sec_t *sec, struct dvb_frontend_parameters *fep, int mode) +{ + int i, j, k, l; + netceiver_info_list_t *nc_list=nc_get_list(); + char buf[6]; + memcpy(buf,"\xe0\x10\x6f\x0\x0\x0",6); + int freq = fep->frequency/1000; + int ret=0; + int explicit_position=NO_SAT_POS; + + if (sec->diseqc_cmd.msg_len > 6 || !ref || !freq) { + return 0; + } + + for (l = 0; l < nc_list->nci_num; l++) { + netceiver_info_t *nci = nc_list->nci + l; + + for (i = 0; i < nci->sat_list_num; i++) { + satellite_list_t *sat_list = nci->sat_list + i; + + for (j = 0; j < sat_list->sat_num; j++) { + satellite_info_t *sat = sat_list->sat + j; + + for (k = 0; k < sat->comp_num; k++) { + satellite_component_t *comp = sat->comp + k; + int oldpos=sat->SatPos^1800; + int newpos=(sec->diseqc_cmd.msg[3]+(sec->diseqc_cmd.msg[4]<<8))^1800; + // prepare synthetic messsage from satpos and pol./volt. + buf[3]=oldpos; + buf[4]=oldpos>>8; + buf[5]=(comp->Polarisation&1)<<1 | !(comp->sec.tone_mode&1); + dbg("compare: old/new %i/%i, %02x %02x %02x %02x %02x %02x <-> %02x %02x %02x %02x %02x %02x\n", oldpos, newpos, + buf[0]&0xff,buf[1]&0xff,buf[2]&0xff,buf[3]&0xff, buf[4]&0xff, buf[5]&0xff, + sec->diseqc_cmd.msg[0], sec->diseqc_cmd.msg[1], sec->diseqc_cmd.msg[2], + sec->diseqc_cmd.msg[3], sec->diseqc_cmd.msg[4], sec->diseqc_cmd.msg[5]); + + dbg("%i mode %i, len %i, %i > %i , %i < %i, %i < %i, %i > %i\n",sat->type, + mode, sec->diseqc_cmd.msg_len, freq, comp->RangeMin, freq, comp->RangeMax, + sat->SatPosMin, newpos , sat->SatPosMax, newpos); + + // Check if coded sat pos matches + if ((sat->type==SAT_SRC_LNB || sat->type==SAT_SRC_UNI) && mode == 0 && sec->diseqc_cmd.msg_len>0 && + (freq >= comp->RangeMin) && (freq <= comp->RangeMax) && + !memcmp (buf, &sec->diseqc_cmd.msg, sec->diseqc_cmd.msg_len)) { + dbg("Satpos MATCH\n"); + ret=1; + } + // check for rotor + else if (sat->type==SAT_SRC_ROTOR && mode == 0 && sec->diseqc_cmd.msg_len>0 && + (freq >= comp->RangeMin) && (freq <= comp->RangeMax) && + (buf[5]==sec->diseqc_cmd.msg[5]) && + (sat->SatPosMin<=newpos && sat->SatPosMax>=newpos)) { + dbg("ROTOR MATCH %i\n",newpos); + explicit_position=newpos; + ret=1; + } + // check if given diseqc matches raw tuner diseqc + else if (mode == 1 && sec->diseqc_cmd.msg_len>0 && !memcmp (&comp->sec.diseqc_cmd.msg, &sec->diseqc_cmd.msg, sec->diseqc_cmd.msg_len)) { + dbg("Diseqc 1.0 Match %02x %02x %02x %02x %02x %02x\n", + comp->sec.diseqc_cmd.msg[0], comp->sec.diseqc_cmd.msg[1], comp->sec.diseqc_cmd.msg[2], + comp->sec.diseqc_cmd.msg[3], comp->sec.diseqc_cmd.msg[4], comp->sec.diseqc_cmd.msg[5]); + ret=1; + }else if (mode == 2 && (fe_sec_voltage_t)comp->Polarisation == sec->voltage && comp->sec.tone_mode== sec->tone_mode && comp->sec.mini_cmd == sec->mini_cmd) { + dbg("Legacy Match, pol %i, tone %i, cmd %i\n",comp->Polarisation,comp->sec.tone_mode,comp->sec.mini_cmd); + ret=1; + } + if (ret) { + ref->netceiver = l; + ref->sat_list = i; + ref->sat = j; + ref->comp = k; + ref->position=explicit_position; + info("Sat found: %d %d %d %d, rotor %d\n",l,i,j,k, explicit_position); + return ret; + } + } + } + } + } + return ret; +} + +int satellite_get_pos_by_ref (satellite_reference_t * ref) +{ + netceiver_info_list_t *nc_list=nc_get_list(); + netceiver_info_t *nci = nc_list->nci + ref->netceiver; + satellite_list_t *sat_list = nci->sat_list + ref->sat_list; + satellite_info_t *sat = sat_list->sat + ref->sat; + if (sat->type==SAT_SRC_ROTOR && ref->position!=NO_SAT_POS) { + return ref->position; + } + return sat->SatPos; +} + +int satellite_get_lof_by_ref (satellite_reference_t * ref) +{ + netceiver_info_list_t *nc_list=nc_get_list(); + netceiver_info_t *nci = nc_list->nci + ref->netceiver; + satellite_list_t *sat_list = nci->sat_list + ref->sat_list; + satellite_info_t *sat = sat_list->sat + ref->sat; + satellite_component_t *comp = sat->comp + ref->comp; + return comp->LOF; +} + +recv_sec_t *satellite_find_sec_by_ref (satellite_reference_t * ref) +{ + netceiver_info_list_t *nc_list=nc_get_list(); + netceiver_info_t *nci = nc_list->nci + ref->netceiver; + satellite_list_t *sat_list = nci->sat_list + ref->sat_list; + satellite_info_t *sat = sat_list->sat + ref->sat; + satellite_component_t *comp = sat->comp + ref->comp; + return &comp->sec; +} + +polarisation_t satellite_find_pol_by_ref (satellite_reference_t * ref) +{ + netceiver_info_list_t *nc_list=nc_get_list(); + netceiver_info_t *nci = nc_list->nci + ref->netceiver; + satellite_list_t *sat_list = nci->sat_list + ref->sat_list; + satellite_info_t *sat = sat_list->sat + ref->sat; + satellite_component_t *comp = sat->comp + ref->comp; + return comp->Polarisation; +} diff --git a/mcast/client/.svn/text-base/sock_test.c.svn-base b/mcast/client/.svn/text-base/sock_test.c.svn-base new file mode 100644 index 0000000..1b4fd39 --- /dev/null +++ b/mcast/client/.svn/text-base/sock_test.c.svn-base @@ -0,0 +1,93 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" + +#define SHM_WAIT_RESPONSE(cmd) { cmd->state=SHM_REQUEST; send (sock_comm, &sock_cmd, sizeof(shm_cmd_t), 0); recv (sock_comm, &sock_cmd, sizeof(shm_cmd_t), 0); if (cmd->state == SHM_ERROR) warn ("SHM parameter error\n");} + +int main (int argc, char **argv) +{ + int sock_comm; + int sock_name_len = 0; + struct sockaddr sock_name; + shm_cmd_t sock_cmd; + shm_cmd_t *shm_cmd=&sock_cmd; + sock_name.sa_family = AF_UNIX; + + strcpy(sock_name.sa_data, SOCK_NAMESPACE); + sock_name_len = strlen(sock_name.sa_data) + sizeof(sock_name.sa_family); + + if((sock_comm = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + warn ("socket create failure %d\n", errno); + return -1; + } + + if (connect(sock_comm, &sock_name, sock_name_len) < 0) { + err ("connect failure\n"); + } + + shm_cmd->cmd=SHM_GET_NC_NUM; + SHM_WAIT_RESPONSE(shm_cmd); + + printf("nc_num: %d\n", shm_cmd->parm[SHM_PARM_NC_NUM]); + int nc_num=shm_cmd->parm[SHM_PARM_NC_NUM]; + int i; + for(i=0;i<nc_num;i++) { + shm_cmd->cmd=SHM_GET_NC_INFO; + shm_cmd->parm[SHM_PARM_NC_NUM]=i; + SHM_WAIT_RESPONSE(shm_cmd); + printf("nc_info.uuid: %s nc_info.lastseen: %u nc_info.tuner_num: %d\n", shm_cmd->u.nc_info.uuid, (unsigned int) shm_cmd->u.nc_info.lastseen, shm_cmd->u.nc_info.tuner_num); + int j; + int tuner_num=shm_cmd->u.nc_info.tuner_num; + for(j=0;j<tuner_num;j++) { + shm_cmd->cmd=SHM_GET_TUNER_INFO; + shm_cmd->parm[SHM_PARM_TUNER_NUM]=j; + SHM_WAIT_RESPONSE(shm_cmd); + printf("tuner_info.fe_info.name: %s\n",shm_cmd->u.tuner_info.fe_info.name); + } + + + int sat_list_num=shm_cmd->u.nc_info.sat_list_num; + for(j=0;j<sat_list_num;j++) { + shm_cmd->cmd=SHM_GET_SAT_LIST_INFO; + shm_cmd->parm[SHM_PARM_NC_NUM]=i; + shm_cmd->parm[SHM_PARM_SAT_LIST_NUM]=j; + SHM_WAIT_RESPONSE(shm_cmd); + + printf("sat_list_info.Name: %s sat_list_info.sat_num: %d\n", shm_cmd->u.sat_list.Name, shm_cmd->u.sat_list.sat_num); + + int sat_num=shm_cmd->u.sat_list.sat_num; + int k; + for(k=0;k<sat_num;k++) { + shm_cmd->cmd=SHM_GET_SAT_INFO; + shm_cmd->parm[SHM_PARM_SAT_LIST_NUM]=j; + shm_cmd->parm[SHM_PARM_SAT_NUM]=k; + SHM_WAIT_RESPONSE(shm_cmd); + printf("sat_info.Name: %s\n",shm_cmd->u.sat_info.Name); + } + } + } + + while (1) { + shm_cmd->cmd=SHM_GET_TRA_NUM; + SHM_WAIT_RESPONSE(shm_cmd); + + printf("tra_num: %d\n", shm_cmd->parm[SHM_PARM_TRA_NUM]); + int tra_num=shm_cmd->parm[SHM_PARM_TRA_NUM]; + for(i=0;i<tra_num;i++) { + shm_cmd->cmd=SHM_GET_TRA_INFO; + shm_cmd->parm[SHM_PARM_TRA_NUM]=i; + SHM_WAIT_RESPONSE(shm_cmd); + printf("tra uuid: %s lastseen: %u lock:%d str:%d snr:%d ber:%d\n", shm_cmd->u.tra.uuid, (unsigned int) shm_cmd->u.tra.lastseen, shm_cmd->u.tra.s.st, shm_cmd->u.tra.s.strength, shm_cmd->u.tra.s.snr, shm_cmd->u.tra.s.ber); + } + sleep(2); + } + return 0; +} + diff --git a/mcast/client/.svn/text-base/tca_handler.c.svn-base b/mcast/client/.svn/text-base/tca_handler.c.svn-base new file mode 100644 index 0000000..3817332 --- /dev/null +++ b/mcast/client/.svn/text-base/tca_handler.c.svn-base @@ -0,0 +1,84 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" + +static netceiver_info_list_t nc_list; +static pthread_mutex_t nci_lock=PTHREAD_MUTEX_INITIALIZER; + +static netceiver_info_t *nci_find_unique (netceiver_info_list_t * ncl, char *uuid) +{ + int i; + for (i = 0; i < ncl->nci_num; i++) { + if (!strcmp (ncl->nci[i].uuid, uuid)) { + return ncl->nci + i; + } + } + return NULL; +} + +static void nci_free(netceiver_info_t * nc_info) +{ + int i, j; + for (i = 0; i < nc_info->sat_list_num; i++) { + satellite_list_t *sat_list = nc_info->sat_list + i; + + for (j = 0; j < sat_list->sat_num; j++) { + satellite_info_t *sat = sat_list->sat + j; + + free (sat->comp); + } + free (sat_list->sat); + } + free (nc_info->sat_list); + free (nc_info->tuner); +} + +static int nci_add_unique (netceiver_info_list_t * ncl, netceiver_info_t * nci) +{ + netceiver_info_t *ncf=nci_find_unique (ncl, nci->uuid); + if (!ncf) { + ncl->nci = (netceiver_info_t *) realloc (ncl->nci, sizeof (netceiver_info_t) * (ncl->nci_num + 1)); + if (!ncl->nci) { + err ("Cannot get memory for netceiver_info\n"); + } + memcpy (ncl->nci + ncl->nci_num, nci, sizeof (netceiver_info_t)); + (ncl->nci+ncl->nci_num)->lastseen = time(NULL); + ncl->nci_num++; + return 1; + } else { + nci_free(ncf); + memcpy(ncf, nci, sizeof (netceiver_info_t)); + ncf->lastseen = time(NULL); + } + return 0; +} + +netceiver_info_list_t *nc_get_list(void) +{ + return &nc_list; +} + +int nc_lock_list(void) +{ + return pthread_mutex_lock (&nci_lock); +} + +int nc_unlock_list(void) +{ + return pthread_mutex_unlock (&nci_lock); +} + +void handle_tca (netceiver_info_t * nc_info) +{ + nc_lock_list(); + if (nci_add_unique (&nc_list, nc_info)) { + dbg ("New TCA from %s added\n", nc_info->uuid); + } + nc_unlock_list(); +} diff --git a/mcast/client/.svn/text-base/tca_handler.h.svn-base b/mcast/client/.svn/text-base/tca_handler.h.svn-base new file mode 100644 index 0000000..1803b28 --- /dev/null +++ b/mcast/client/.svn/text-base/tca_handler.h.svn-base @@ -0,0 +1,18 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +typedef struct +{ + netceiver_info_t *nci; + int nci_num; +} netceiver_info_list_t; + +DLL_SYMBOL netceiver_info_list_t *nc_get_list(void); +DLL_SYMBOL int nc_lock_list(void); +DLL_SYMBOL int nc_unlock_list(void); +void handle_tca (netceiver_info_t * nc_info); diff --git a/mcast/client/.svn/text-base/tools.c.svn-base b/mcast/client/.svn/text-base/tools.c.svn-base new file mode 100644 index 0000000..d249f01 --- /dev/null +++ b/mcast/client/.svn/text-base/tools.c.svn-base @@ -0,0 +1 @@ +link ../common/tools.c
\ No newline at end of file diff --git a/mcast/client/.svn/text-base/tra_handler.c.svn-base b/mcast/client/.svn/text-base/tra_handler.c.svn-base new file mode 100644 index 0000000..8148a1f --- /dev/null +++ b/mcast/client/.svn/text-base/tra_handler.c.svn-base @@ -0,0 +1,56 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" + +static tra_info_t tra_list; + +static tra_t *tra_find_unique (tra_info_t *trl, char *uuid) +{ + int i; + for (i = 0; i < trl->tra_num; i++) { + if (!strcmp (trl->tra[i].uuid, uuid)) { + return trl->tra + i; + } + } + return NULL; +} + +static int tra_add_unique (tra_info_t *trl, tra_t *tri) +{ + tra_t *trf=tra_find_unique (trl, tri->uuid); + if (!trf) { + trl->tra = (tra_t *) realloc (trl->tra, sizeof (tra_t) * (trl->tra_num + 1)); + if (!trl->tra) { + err ("Cannot get memory for netceiver_info\n"); + } + trf = trl->tra + trl->tra_num; + trl->tra_num++; + } + memcpy (trf, tri, sizeof (tra_t)); + return 1; +} + +tra_info_t *tra_get_list(void) +{ + return &tra_list; +} + +int handle_tra(tra_info_t *tra_info) +{ + int i; + if(tra_info->tra_num) { + for (i = 0; i < tra_info->tra_num; i++) { + tra_add_unique (&tra_list, tra_info->tra+i); + } + memcpy(tra_list.cam, tra_info->cam, MAX_CAMS*sizeof(cam_info_t)); + free (tra_info->tra); + return 1; + } + return 0; +} diff --git a/mcast/client/.svn/text-base/tra_handler.h.svn-base b/mcast/client/.svn/text-base/tra_handler.h.svn-base new file mode 100644 index 0000000..fe5ac2c --- /dev/null +++ b/mcast/client/.svn/text-base/tra_handler.h.svn-base @@ -0,0 +1,10 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +DLL_SYMBOL tra_info_t *tra_get_list(void); +int handle_tra(tra_info_t *tra_info); diff --git a/mcast/client/.svn/text-base/win32.svn-base b/mcast/client/.svn/text-base/win32.svn-base new file mode 100644 index 0000000..c90f0e1 --- /dev/null +++ b/mcast/client/.svn/text-base/win32.svn-base @@ -0,0 +1 @@ +link ../common/win32
\ No newline at end of file |